1/* 2 * Copyright 2020, The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17'use strict'; 18 19const webpack = require('webpack'); 20const {merge} = require('webpack-merge'); 21const path = require('path'); 22const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin'); 23const MiniCSSExtractPlugin = require('mini-css-extract-plugin'); 24const CompressionPlugin = require('compression-webpack-plugin'); 25const commonConfig = require('./webpack.config.common'); 26const isProd = process.env.NODE_ENV === 'production'; 27const environment = 28 isProd ? require('./env/prod.env') : require('./env/staging.env'); 29 30 31const webpackConfig = merge(commonConfig, { 32 mode: 'production', 33 output: { 34 path: path.resolve(__dirname, 'dist'), 35 publicPath: '/', 36 filename: 'js/[hash].js', 37 chunkFilename: 'js/[id].[hash].chunk.js', 38 }, 39 optimization: { 40 runtimeChunk: 'single', 41 minimizer: [ 42 new OptimizeCSSAssetsPlugin({ 43 cssProcessorPluginOptions: { 44 preset: ['default', {discardComments: {removeAll: true}}], 45 }, 46 }), 47 ], 48 splitChunks: { 49 chunks: 'all', 50 maxInitialRequests: Infinity, 51 minSize: 0, 52 cacheGroups: { 53 vendor: { 54 test: /[\\/]node_modules[\\/]/, 55 name(module) { 56 const packageName = module.context 57 .match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/)[1]; 58 return `npm.${packageName.replace('@', '')}`; 59 }, 60 }, 61 styles: { 62 test: /\.css$/, 63 name: 'styles', 64 chunks: 'all', 65 enforce: true, 66 }, 67 }, 68 }, 69 }, 70 plugins: [ 71 new webpack.EnvironmentPlugin(environment), 72 new MiniCSSExtractPlugin({ 73 filename: 'css/[name].[hash].css', 74 chunkFilename: 'css/[id].[hash].css', 75 }), 76 new CompressionPlugin({ 77 filename: '[path].gz[query]', 78 algorithm: 'gzip', 79 test: new RegExp('\\.(js|css)$'), 80 threshold: 10240, 81 minRatio: 0.8, 82 }), 83 new webpack.HashedModuleIdsPlugin(), 84 ], 85}); 86 87if (!isProd) { 88 webpackConfig.devtool = 'source-map'; 89 90 if (process.env.npm_config_report) { 91 const BundleAnalyzerPlugin = 92 require('webpack-bundle-analyzer').BundleAnalyzerPlugin; 93 webpackConfig.plugins.push(new BundleAnalyzerPlugin()); 94 } 95} 96 97module.exports = webpackConfig; 98