'use strict'; const path = require('path'); const utils = require('./utils'); const webpack = require('webpack'); const config = require('../config'); const {merge} = require('webpack-merge'); const baseWebpackConfig = require('./webpack.base.conf'); const CopyWebpackPlugin = require('copy-webpack-plugin'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const CssMinimizerPlugin = require("css-minimizer-webpack-plugin"); const env = require('../config/prod.env'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const webpackConfig = merge(baseWebpackConfig, { devtool: config.build.productionSourceMap ? config.build.devtool : false, mode: 'production', output: { path: config.build.assetsRoot, filename: utils.assetsPath('js/[name].[chunkhash].js'), chunkFilename: utils.assetsPath('js/[id].[chunkhash].js'), }, optimization: { minimizer: [ new CssMinimizerPlugin() ] }, plugins: [ // http://vuejs.github.io/vue-loader/en/workflow/production.html new webpack.DefinePlugin({ 'process.env': env, // bundler feature flags https://github.com/vuejs/vue-next/tree/master/packages/vue#bundler-build-feature-flags __VUE_OPTIONS_API__: true, // default, but explicit __VUE_PROD_DEVTOOLS__: false, // default, but explicit }), // extract css into its own file new MiniCssExtractPlugin({ filename: utils.assetsPath('css/[name].[contenthash].css'), }), // generate dist index.html with correct asset hash for caching. // you can customize output by editing /index.html // see https://github.com/ampedandwired/html-webpack-plugin new HtmlWebpackPlugin({ filename: config.build.index, template: 'index.html', ...require('../config/prod.env'), minify: { // defaults from https://github.com/jantimon/html-webpack-plugin#minification collapseWhitespace: true, keepClosingSlash: true, removeComments: true, removeRedundantAttributes: true, removeScriptTypeAttributes: true, removeStyleLinkTypeAttributes: true, useShortDoctype: true, }, // necessary to consistently work with multiple chunks via CommonsChunkPlugin chunksSortMode: 'auto', }), // keep module.id stable when vendor modules does not change new webpack.ids.HashedModuleIdsPlugin(), // split vendor js into its own file // todo: https://gist.github.com/sokra/1522d586b8e5c0f5072d7565c2bee693 // todo: do we need this? probably default is fine // new webpack.optimize.CommonsChunkPlugin({ // name: 'vendor', // minChunks (module) { // // any required modules inside node_modules are extracted to vendor // return ( // module.resource && // /\.js$/.test(module.resource) && // module.resource.indexOf( // path.join(__dirname, '../node_modules') // ) === 0 // ) // } // }), // extract webpack runtime and module manifest to its own file in order to // prevent vendor hash from being updated whenever app bundle is updated // new webpack.optimize.CommonsChunkPlugin({ // name: 'manifest', // minChunks: Infinity // }), // This instance extracts shared chunks from code splitted chunks and bundles them // in a separate chunk, similar to the vendor chunk // see: https://webpack.js.org/plugins/commons-chunk-plugin/#extra-async-commons-chunk // new webpack.optimize.CommonsChunkPlugin({ // name: 'app', // async: 'vendor-async', // children: true, // minChunks: 3 // }), // copy custom static assets new CopyWebpackPlugin({ patterns: [ { from: path.resolve(__dirname, '../static'), to: config.build.assetsSubDirectory, globOptions: { ignore: ['.*'], }, }, ], }), ], }); if (config.build.productionGzip) { const CompressionWebpackPlugin = require('compression-webpack-plugin'); webpackConfig.plugins.push( new CompressionWebpackPlugin({ asset: '[path].gz[query]', algorithm: 'gzip', test: new RegExp( '\\.(' + config.build.productionGzipExtensions.join('|') + ')$', ), threshold: 10240, minRatio: 0.8, }), ); } if (config.build.bundleAnalyzerReport) { const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; webpackConfig.plugins.push(new BundleAnalyzerPlugin()); } module.exports = webpackConfig;