Webpack – God like presence. No matter how many times write, meet again, is still the first. Sometimes I develop vUE projects and feel grateful for the great VUE – CLI. But, but, but… Not their own things, really do not want to toss. So, we have to go inside and cp them us. So, I spent two days, referring to some other people’s articles, looking up some official configuration, here is a little record.
This configuration parsing is based on the latest version of the Vue WebPack Template. However, I highly recommend that you stop reading my article and go through it sentence by sentence. And then look again. After all, it’s the collision of ideas that makes new discoveries.
Basic directory structure:
Config ├ ─ ─ dev. Env. Js / / dev environment variable configuration ├ ─ ─ index. The js / / dev and prod environment of some basic configuration └ ─ ─ the prod. The env. Js / / prod environment variable configuration build ├ ─ ─ build. Js / / ├── flag flag.png Flag Flag ── utils. ├─ webpack.base.conf.js // dev/prod Public Configuration ├── Vue -loader.conf.js // vue-loader.conf ├ ─ propack.prod.conf. Js // setup of the prod environmentCopy the code
Here we will analyze the source code in the following order:
config/index.js -> build/utils.js -> build/vue-loader.conf.js -> build/webpack.base.conf.js -> build/webpack.dev.conf.js -> build/webpack.prod.conf.js -> build/check-versions.js -> build/build.js
config/index.js
: Configuration of some basic properties (we can change these configurations according to our own needs)
'use strict'
// This file is mainly a basic configuration for the development and production environments
const path = require('path')
module.exports = {
// A basic configuration of the development environment
dev: {
// Compile the output secondary directory
assetsSubDirectory: 'static'.// Compile and publish the root directory, can be configured as the resource server domain name or CDN domain name
assetsPublicPath: '/'.// Interface that needs proxyTable proxy (cross-domain)
proxyTable: {},
// Access domain name at development time. You can set it yourself using environment variables.
host: 'localhost'.// can be overwritten by process.env.HOST
// Port at development time. This can be set using the environment variable PORT. If a port is occupied, an unused port is randomly assigned
port: 8080.// Whether to open the browser automatically
autoOpenBrowser: false.// Both of the following are ways for browsers to display errors
// Whether to display error masking in the browser
errorOverlay: true.// Whether to display error notifications
notifyOnErrors: true.// This is an option of watchOptions for webpack-dev-servr that specifies how webpack checks files
// Because WebPack uses the file system to get notification of file changes. In some cases, this may not work. For example, when using NFC,
Vagrant also has many problems with this, in which case the poll option (polling to see if the file has changed) can be set to true
// Or a specific value, specifying the specific period of file query.
poll: false.// Whether to use the ESLint Loader to check code
useEslint: true.// If set to true, esLint errors and warnings will be masked in browsers.
showEslintErrorsInOverlay: false./** * Source Maps */
// The format of source maps
devtool: 'eval-source-map'.// Specifies whether to create a cache of the Source map by adding a query string after the file name
cacheBusting: true.// Close the CSS source map
cssSourceMap: false,},build: {
// where the HTML file is generated
index: path.resolve(__dirname, '.. /dist/index.html'),
// The directory to compile the generated files
assetsRoot: path.resolve(__dirname, '.. /dist'),
// Directory of static files generated by compilation
assetsSubDirectory: 'static'.// Compile and publish the root directory, can be configured as the resource server domain name or CDN domain name
assetsPublicPath: '/'./** * Source Maps */
productionSourceMap: true.devtool: '#source-map'.// Whether to enable gzip compression in the production environment
productionGzip: false.// Suffix name of the file for which gzip compression is enabled
productionGzipExtensions: ['js'.'css'].// If this option is true, a Bundler report will be generated in the browser after build
bundleAnalyzerReport: process.env.npm_config_report
}
}
Copy the code
build/utils.js
: methods for generating CSS loaders and style loaders
'use strict'
// The nodejs path module is introduced to manipulate paths
const path = require('path')
// Import the template configuration file. What basic configuration does this file have
const config = require('.. /config')
// A plugin that extracts specific files, such as CSS files into a file
const ExtractTextPlugin = require('extract-text-webpack-plugin')
// Load the package.json file
const packageConfig = require('.. /package.json')
// Generate a secondary directory for compilation output
exports.assetsPath = function (_path) {
const assetsSubDirectory = process.env.NODE_ENV === 'production'
? config.build.assetsSubDirectory
: config.dev.assetsSubDirectory
Posix is a cross-platform implementation of the path module (the path representation is different on different platforms)
return path.posix.join(assetsSubDirectory, _path)
}
// To provide a unified generation method for different CSS preprocessors, that is, to handle the packaging problem of various CSS types uniformly.
// This is the CSS type for use in style in vue files
exports.cssLoaders = function (options) {
options = options || {}
// Package the CSS module
const cssLoader = {
loader: 'css-loader'.options: {
sourceMap: options.sourceMap
}
}
// Compile the postCSS module
const postcssLoader = {
// Use postCSs-loader to package postCSS modules
loader: 'postcss-loader'.// Configure the source map
options: {
sourceMap: options.sourceMap
}
}
// Create a loader string, used with the extract Text plug-in
/ * * * *@param {loader name} loader
* @param {Options configuration object for loader} loaderOptions
*/
function generateLoaders (loader, loaderOptions) {
// usePostCSS to indicate whether postcss is used
const loaders = options.usePostCSS ? [cssLoader, postcssLoader] : [cssLoader]
// If the loader name is specified
if (loader) {
// Add the corresponding loader to the array of loaders
An important point is that the loader in an array executes from right to left.
loaders.push({
// Name of the loader
loader: loader + '-loader'.// The corresponding loader configuration object
options: Object.assign({}, loaderOptions, {
sourceMap: options.sourceMap
})
})
}
// If it is explicitly specified that static files need to be extracted
/ / ExtractTextPlugin. Extract ({}) to wrap our CSS processor.
if (options.extract) {
return ExtractTextPlugin.extract({
use: loaders,
// Fallback is a fallback option
// WebPack by default compiles various CSS type files from right to left according to loaders in loaders. If all goes well, in loaders
// After each loader runs, the CSS file will be imported into the specified file, if not successful, continue to use vue-style-loader to process
/ / CSS files
fallback: 'vue-style-loader'})}else {
// If there is no extract behavior, then use vue-style-loader to process CSS last
return ['vue-style-loader'].concat(loaders)
}
}
return {
// css-loader
css: generateLoaders(),
// postcss-loader
postcss: generateLoaders(),
// less-loader
less: generateLoaders('less'),
// The options behind sass-loader indicate that sass uses indented render
sass: generateLoaders('sass', { indentedSyntax: true }),
// scss-loader
scss: generateLoaders('sass'),
// stylus-loader The stylus file has two suffixes: stylus and styl
stylus: generateLoaders('stylus'),
// stylus-loader
styl: generateLoaders('stylus')}}// Use this function to create loader configurations for those separate style files.
exports.styleLoaders = function (options) {
// Save the loader configuration variables
const output = []
// Get loaders for all CSS file types
const loaders = exports.cssLoaders(options)
for (const extension in loaders) {
const loader = loaders[extension]
// Generate the loader configuration
output.push({
test: new RegExp('\ \. + extension + '$'),
use: loader
})
}
return output
}
exports.createNotifierCallback = () = > {
// Node-notifier is a cross-platform package that presents information in the form of browser-like notifications.
const notifier = require('node-notifier')
return (severity, errors) = > {
// Display only error information
if(severity ! = ='error') return
const error = errors[0]
const filename = error.file && error.file.split('! ').pop()
// The contents of the error message to display
notifier.notify({
// The title of the notification
title: packageConfig.name,
// The body of the notification
message: severity + ':' + error.name,
/ / subtitle
subtitle: filename || ' '.// Notification display icon
icon: path.join(__dirname, 'logo.png')}}}Copy the code
build/vue-loader.conf.js
: Basic configurations of vue-loader
'use strict'
const utils = require('./utils')
const config = require('.. /config')
// Set the production environment
const isProduction = process.env.NODE_ENV === 'production'
// Import different Source map profiles for different environments
const sourceMapEnabled = isProduction
? config.build.productionSourceMap
: config.dev.cssSourceMap
module.exports = {
// CSS Loader configuration in vue file
loaders: utils.cssLoaders({
sourceMap: sourceMapEnabled,
// In production, the CSS file is extracted into a separate file
extract: isProduction
}),
// CSS source map file configuration
cssSourceMap: sourceMapEnabled,
// CSS source map file cache control variables
cacheBusting: config.dev.cacheBusting,
transformToRequire: {
video: ['src'.'poster'].source: 'src'.img: 'src'.image: 'xlink:href'}}Copy the code
build/weback.base.conf.js
: common configuration in dev and PROd environments
'use strict'
const path = require('path')
const utils = require('./utils')
const config = require('.. /config')
const vueLoaderConfig = require('./vue-loader.conf')
// Generates an absolute path relative to the root directory
function resolve (dir) {
return path.join(__dirname, '.. ', dir)
}
// esLint rules
const createLintingRule = () = > ({
// Eslint checks.js and.vue files
test: /\.(js|vue)$/./ / use eslint - loader
loader: 'eslint-loader'.// Enforce may be pre and post. Pre is similar to the preLoader configuration in webpack@1.
// Post and postLoader in v1 have similar meanings. Indicates the call time of loader
Call this rule for code style checking before calling any other loader
enforce: 'pre'.// Where the directory for files to be checked by ESLint exists
include: [resolve('src'), resolve('test')].// Options to specify during eslint-loader configuration
options: {
// Check the file style formatter, where the third-party ESlint-friendly-formatter is used
formatter: require('eslint-friendly-formatter'),
// Whether eslint outputs warnings
emitWarning: !config.dev.showEslintErrorsInOverlay
}
})
// The following is the basic configuration information for WebPack (which can be immediately made common to both development and production environments)
module.exports = {
// The root directory where webpack parses the file (if you put webpack.config.js) under the root directory of the project, this configuration can be omitted
context: path.resolve(__dirname, '.. / '),
// Specify the entry file for the project
entry: {
app: './src/main.js'
},
// Project output configuration
output: {
// When the project is built, the generated file is stored in the path (here is the path.. /dist)
path: config.build.assetsRoot,
// The name of the generated file
filename: '[name].js'.// Output directory of parsed files, url relative to HTML page (generated HTML files, static files such as CSS and JS URL prefix)
publicPath: process.env.NODE_ENV === 'production'
? config.build.assetsPublicPath
: config.dev.assetsPublicPath
},
// Configure some options for module parsing
resolve: {
// Specify which types of files can be referenced without the suffix
extensions: ['.js'.'.vue'.'.json'].// Alias, which can be used when importing files
alias: {
'vue$': 'vue/dist/vue.esm.js'.// You can import files in the SRC folder with the @ symbol
The '@': resolve('src'),}},// Here are the specific configurations for specific modules
// The following configuration syntax uses version >= @2
module: {
// Rules is an array where each element is an object that is configured for a specific type of file.
rules: [
//.vue file configuration
{
// This property is a regular expression used to match files. The match here is the.vue file
test: /\.vue$/.// Specify the loader name for this type of file
loader: 'vue-loader'.// Specific configuration for this loader
For the previous analysis, this configuration object contains the configuration of various CSS type files, CSS Source map configuration, and some transform configuration
options: vueLoaderConfig
},
{
//.js file configuration
test: /\.js$/.// Babel-loader is used for processing js files. No specific compilation rules are specified here, and babel-loader will automatically
The Babel configuration in the. Babelrc directory is used to compile js files
{/ * * * * / / use the preset "presets" : [/ / Babel - preset - env: ["env", {// modules set to false, does not convert module "modules": false}], // babel-stage-2: preset () Stage2 syntax "stage-2"], // babel-plugin-transform-runtime: // To support new apis, introduce babel-polyfill "plugins": ["transform-runtime"]} */
loader: 'babel-loader'.// Specify the path to the file to compile
// Only files in the SRC and test folders are compiled
include: [resolve('src'), resolve('test')]}, {// Configure the image resource to compile
// Specify the type of file
test: /\.(png|jpe? g|gif|svg)(\? . *)? $/.// Use url-loader to compile file resources
loader: 'url-loader'.// Url-loader configuration options
options: {
A dataUrl is returned if the file size is less than 10000 bytes (10KB)
limit: 10000.// Save path and suffix of the generated file
name: utils.assetsPath('img/[name].[hash:7].[ext]')}}, {// Package and compile the video file
test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\? . *)? $/,
loader: 'url-loader'.options: {
limit: 10000.name: utils.assetsPath('media/[name].[hash:7].[ext]')}}, {// Package the font file
test: /\.(woff2? |eot|ttf|otf)(\? . *)? $/,
loader: 'url-loader'.options: {
limit: 10000.name: utils.assetsPath('fonts/[name].[hash:7].[ext]'}}]},// These options are used to polyfill or mock certain Node.js global variables and modules.
// This enables the code originally written for NodeJS to run on the browser side
node: {
// This configuration is an object in which each property is the name of a nodeJS global variable or module
// prevent webpack from injecting useless setImmediate polyfill because Vue
// source contains it (although only uses it if it's native).
// false means that nothing is supplied. If you retrieve the code for this object, a ReferenceError may be raised because you can't retrieve the object
setImmediate: false.// prevent webpack from injecting mocks to Node native modules
// that does not make sense for the client
// Set to empty to provide an empty object
dgram: 'empty'.fs: 'empty'.net: 'empty'.tls: 'empty'.child_process: 'empty'}}Copy the code
build/weboack.dev.conf.js
: Configuration of the Dev environment
'use strict'
// We will introduce some utility methods. We need to go to the util file to see what the corresponding utility methods are
const utils = require('./utils')
// Introduce the Webpack module
const webpack = require('webpack')
// Import the configuration file
// This configuration file contains some basic configurations for the dev and Production environments
const config = require('.. /config')
// Introduce the webpack-merge module. This module is used to combine multiple WebPack configurations into a single configuration, which overrides the previous configuration.
const merge = require('webpack-merge')
// Introduces the basic Settings for Webpack, which contains some common configurations for both the development and production environments
const baseWebpackConfig = require('./webpack.base.conf')
// A plug-in for generating HTML files
const HtmlWebpackPlugin = require('html-webpack-plugin')
// This plugin can better see errors and warnings when WebPack is running on the terminal. Can improve the development experience.
const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
// Find an unused port
const portfinder = require('portfinder')
// Get the host environment variable, which is used to configure the development environment domain name
const HOST = process.env.HOST
// Get the POST environment variable, which is used to configure the port number for the development environment
const PORT = process.env.PORT && Number(process.env.PORT)
// Complete configuration file for the development environment,
const devWebpackConfig = merge(baseWebpackConfig, {
module: {
// Add loader configuration for those separate CSS type files (styles not written in the style tag of vue files)
rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true})},// The development environment uses source map in 'eval-source-map' mode
// Because of the speed
devtool: config.dev.devtool,
// these devServer options should be customized in /config/index.js
// The following is the basic configuration of the webpack-dev-server option. This configuration information can be found in /config/index.js
// Customize the configuration in the file.
devServer: {
// Used to configure the log level displayed in the development tool console
// Note that this is not a configuration for errors and warnings from the bundle, but for messages before it is generated
clientLogLevel: 'warning'.// indicates that any 404 response needs to be replaced with index.html when using HTML5's history API
historyApiFallback: true.// Enable webPack's hot replace feature
hot: true.// All services need to use gzip compression
Content-encoding :gzip Response header content-encoding :gzip response header content-encoding :gzip response header
compress: true.// Specify the use of a host. The default is localhost
// If you want external server access (through our computer IP address and port number to access our application)
// You can specify 0.0.0.0
host: HOST || config.dev.host,
// Specify the port number to listen for requests
port: PORT || config.dev.port,
// Whether to open the browser automatically
open: config.dev.autoOpenBrowser,
// Do you want to display a full-screen mask in the browser to show error messages when compiling errors
overlay: config.dev.errorOverlay
// Displays only error information but no warning information
// If both want to be displayed, set both items to true
? { warnings: false.errors: true }
// Set to false to display nothing
: false.// Specify the root directory of webpack-dev-server, where all files are directly accessible through the browser
// It is recommended to set output.publicPath to the same value
publicPath: config.dev.assetsPublicPath,
// Configure the proxy so that we can access some interfaces across domains
// The interface we access, if configured for this option, will forward our request through a proxy server
proxy: config.dev.proxyTable,
// With quiet enabled, nothing is printed to the console except the initial startup information. This also means that errors or warnings from Webpack are not visible on the console.
quiet: true.// necessary for FriendlyErrorsPlugin
// Control options related to monitoring files.
watchOptions: {
// If this option is true, changes to our files will be checked by polling, which is inefficient
poll: config.dev.poll,
}
},
plugins: [
// Create a global variable that can be configured at compile time
new webpack.DefinePlugin({
'process.env': require('.. /config/dev.env')}),// Enable the hot replacement module
// Remember, we should never use HMR in production environment again
new webpack.HotModuleReplacementPlugin(),
// The main function of this plugin is to return the name of the updated file, not the id of the file, during hot loading
new webpack.NamedModulesPlugin(),
// Use this plugin to skip the output phase if a compilation error occurs, thus ensuring that the output resource does not contain errors.
new webpack.NoEmitOnErrorsPlugin(),
// This plugin basically generates an HTML file
new HtmlWebpackPlugin({
// The name of the generated HTML file
filename: 'index.html'.// The name of the template to use
template: 'index.html'.// Insert all static files at the end of the body file
inject: true})]})module.exports = new Promise((resolve, reject) = > {
portfinder.basePort = process.env.PORT || config.dev.port
// This method of getting a port returns a promise
portfinder.getPort((err, port) = > {
if (err) {
reject(err)
} else {
// Set the obtained PORT number to the value of the environment variable PORT
process.env.PORT = port
// Resets the port value of webpack-dev-server
devWebpackConfig.devServer.port = port
// Add FriendlyErrorsPlugin to the webPack configuration file
devWebpackConfig.plugins.push(new FriendlyErrorsPlugin({
// Output information when compiling successfully
compilationSuccessInfo: {
messages: [`Your application is running here: http://${devWebpackConfig.devServer.host}:${port}`],},/ / when the compiler error, according to the config. Dev. NotifyOnErrors to determine whether to need to display the error notification box in the upper right corner of the desktop
onErrors: config.dev.notifyOnErrors
? utils.createNotifierCallback()
: undefined
}))
// resolve our config file
resolve(devWebpackConfig)
}
})
})
Copy the code
build/webpack.prod.conf.js
: Basic configuration of the PROD environment
'use strict'
// Introduce the path module
const path = require('path')
// Introduce tool methods
const utils = require('./utils')
// Introduce the Webpack module
const webpack = require('webpack')
// Introduce the basic configuration
const config = require('.. /config')
// Introduce the webpack-merge module
const merge = require('webpack-merge')
// Introduce configurations common to both development and production environments
const baseWebpackConfig = require('./webpack.base.conf')
// Introduce the copy-webpack-plugin module
// This module is mainly used to copy files and folders in webpack
const CopyWebpackPlugin = require('copy-webpack-plugin')
// Introduce the htmL-webpack-plugin
// This plugin is mainly used to generate HTML files based on templates
const HtmlWebpackPlugin = require('html-webpack-plugin')
// Introduce extract-text-webpack-plugin
// This plugin is mainly used to move all chunks in the entry into a separate CSS file
const ExtractTextPlugin = require('extract-text-webpack-plugin')
// Import the optimize- CSS -assets-webpack-plugin
// This plugin is mainly used to compress CSS modules
const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')
// Introduce uglifyjs-webpack-plugin
// This plugin is mainly used to compress JS files
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
// Introduce some basic variables for the production environment
const env = require('.. /config/prod.env')
// Merge the common and production-specific configurations and return a WebPack configuration file for the production environment
const webpackConfig = merge(baseWebpackConfig, {
// Some Loader configurations for production environments
module: {
rules: utils.styleLoaders({
sourceMap: config.build.productionSourceMap,
// Use the extract option in production, which pulls the CSS code from Thunk into a separate CSS file
extract: true.usePostCSS: true})},// Configure the form of source map to be used in the production environment. In this case, the production environment uses the form # Source Map
devtool: config.build.productionSourceMap ? config.build.devtool : false.output: {
// The directory where the files generated by build are stored
path: config.build.assetsRoot,
// The name of the file after build
// where [name] and [chunkhash] are placeholders
// Where [name] refers to the module name
// [chunkhash] Chunk hash character string, 20 characters in length
filename: utils.assetsPath('js/[name].[chunkhash].js'),
// [id] is also a placeholder for the module identifier.
chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')},plugins: [
// http://vuejs.github.io/vue-loader/en/workflow/production.html
new webpack.DefinePlugin({
'process.env': env
}),
// A plug-in to compress javascript
new UglifyJsPlugin({
// Some basic configuration for compressing JS
uglifyOptions: {
// Configure compression behavior
compress: {
// Displays warning messages when deleting unused variables, etc. The default is false
warnings: false}},// Use the source map to map the location of the error message to the module (this will slow down compilation)
// Do not use cheap source-map
sourceMap: config.build.productionSourceMap,
// Use multi-process parallel running and file caching to speed up builds
parallel: true
}),
// Extract the CSS file into a separate file
new ExtractTextPlugin({
// Where the CSS file is stored after extraction
// Where [name] and [contenthash] are placeholders
// [name] indicates the module name
// [contenthash] Hash generated based on the extracted file contents
filename: utils.assetsPath('css/[name].[contenthash].css'),
// Extract CSS content from all additional chunks
// (by default, it is only extracted from the initial chunk)
/ / when using CommonsChunkPlugin and extraction in public the chunk chunk (from ExtractTextPlugin. Extract)
// This option needs to be set to true
allChunks: false,}).// duplicated CSS from different components can be deduped.
// Use this plugin to compress CSS, mainly because the same CSS can be removed from different components
new OptimizeCSSPlugin({
// All configuration for this option is passed to the cssProcessor
// The cssProcessor uses these options to determine the behavior of compression
cssProcessorOptions: config.build.productionSourceMap
// Safe means "safe". Please leave a message to let us know...
? { safe: true.map: { inline: false}}, {safe: true}}),// Create an HTML file
new HtmlWebpackPlugin({
// The name of the generated file
filename: config.build.index,
// The name of the template to use
template: 'index.html'.// Place the script and link tags at the bottom of the body
inject: true.// Configure HTML compression behavior
minify: {
// Remove comments
removeComments: true.// Remove whitespace and newlines
collapseWhitespace: true.// Remove quotes and empty attributes from attributes as much as possible
removeAttributeQuotes: true
// more options:
// https://github.com/kangax/html-minifier#options-quick-reference
},
// Control the order of the chunks
// it can also be a function that defines its own collation rules
chunksSortMode: 'dependency'
}),
// keep module.id stable when vender modules does not change
// Generate a four-digit hash for the module ID based on the relative path of the module
new webpack.HashedModuleIdsPlugin(),
// Every module webPack2 processes is wrapped with a function
// The problem with this is that it reduces the efficiency of javascript execution in browsers, mainly because closure functions slow down the parsing speed of the JS engine.
// In webpack3, you can use the following plugin to connect some related modules,
// Put it in a closure function to speed up JS execution by reducing the number of closure functions.
new webpack.optimize.ModuleConcatenationPlugin(),
// This plugin is used to extract the public modules of multi-entry chunks
// By extracting the public modules, the resultant file can be loaded once at the beginning
// It is then cached for later use, which increases speed.
new webpack.optimize.CommonsChunkPlugin({
// This is the name of Common Chunk
name: 'vendor'.// Extract all files imported from mnode_modules into vendor
minChunks (module) {
return (
module.resource &&
/\.js$/.test(module.resource) &&
module.resource.indexOf(
path.join(__dirname, '.. /node_modules'= = =))0)}}),// In order to remove third-party dependencies from the project, the official documentation recommends using this plug-in. When we actually use it in the project,
// Find that once you change the code in app.js, the vendor.js hash will also change, so the next time you go online,
// The user still needs to download vendor.js and app.js again -- thus losing the point of caching. So the second new is to solve this problem
Reference: / / https://github.com/DDFE/DDFE-blog/issues/10
new webpack.optimize.CommonsChunkPlugin({
name: 'manifest'.minChunks: Infinity
}),
new webpack.optimize.CommonsChunkPlugin({
name: 'app'.async: 'vendor-async'.children: true.minChunks: 3
}),
// copy custom static assets
// Copy static resources into the build folder
new CopyWebpackPlugin([
{
// Define the source directory of the resource to be copied
from: path.resolve(__dirname, '.. /static'),
// Define the destination directory of the resource to copy
to: config.build.assetsSubDirectory,
// Ignore copying the specified file. Fuzzy matching can be used
ignore: ['*']}])]})if (config.build.productionGzip) {
// If gzip is enabled in the production environment
const CompressionWebpackPlugin = require('compression-webpack-plugin')
webpackConfig.plugins.push(
new CompressionWebpackPlugin({
// Name of the target resource
// [path] will be replaced with the original resource path
// [query] is replaced with the original query string
asset: '[path].gz[query]'./ / gzip algorithm
// This option can be configured for each algorithm in the zlib module
// Also (buffer, cb) => cb(buffer)
algorithm: 'gzip'.// Process all resources that match this regular expression
test: new RegExp(
'\ \. (' +
config.build.productionGzipExtensions.join('|') +
'$'
),
// Only resources larger than this value are processed
threshold: 10240.// Only resources with compression rates lower than this value will be processed
minRatio: 0.8}}))if (config.build.bundleAnalyzerReport) {
// If you need to generate a bundle report, you need to use the plug-in below
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
webpackConfig.plugins.push(new BundleAnalyzerPlugin())
}
module.exports = webpackConfig
Copy the code
build/check-versions.js
: Check the version of NPM and Node
'use strict'
// Display different styles for different fonts on the terminal
const chalk = require('chalk')
// Parse the version of NPM package
const semver = require('semver')
// Import package.json file
const packageConfig = require('.. /package.json')
// Node version of uninx shell command
const shell = require('shelljs')
// The function that executes the command
function exec (cmd) {
return require('child_process').execSync(cmd).toString().trim()
}
const versionRequirements = [
{
name: 'node'.// Node version
// process.version is the node version
/ / semver. Clean (' v8.8.0 ') = > 8.8.0
currentVersion: semver.clean(process.version),
// The range of node versions defined in package.json
versionRequirement: packageConfig.engines.node
}
]
// equivalent to which NPM
if (shell.which('npm')) {
// If NPM exists
versionRequirements.push({
name: 'npm'.// Check the NPM version => 5.4.2
currentVersion: exec('npm --version'),
// The version of NPM defined in package.json
versionRequirement: packageConfig.engines.npm
})
}
module.exports = function () {
const warnings = []
for (let i = 0; i < versionRequirements.length; i++) {
const mod = versionRequirements[i]
// semver.distribution () for comparison between versions
if(! semver.satisfies(mod.currentVersion, mod.versionRequirement)) {If the existing NPM or Node version is lower than the defined version, a warning is generated
warnings.push(mod.name + ':' +
chalk.red(mod.currentVersion) + ' should be ' +
chalk.green(mod.versionRequirement)
)
}
}
if (warnings.length) {
console.log(' ')
console.log(chalk.yellow('To use this template, you must update following to modules:'))
console.log()
for (let i = 0; i < warnings.length; i++) {
const warning = warnings[i]
console.log(' ' + warning)
}
console.log()
// Exit the program
process.exit(1)}}Copy the code
build/build.js
: build a project
'use strict'
// Check NPM and Node versions
require('./check-versions') ()// Set the value of the environment variable NODE_ENV to production
process.env.NODE_ENV = 'production'
// Terminal spinner
const ora = require('ora')
// Node.js rm -rf
const rm = require('rimraf')
// Introduce the path module
const path = require('path')
// Introduce the display terminal color module
const chalk = require('chalk')
// Introduce the Webpack module
const webpack = require('webpack')
// Import the basic configuration file
const config = require('.. /config')
// Import webPack configuration files in production environment
const webpackConfig = require('./webpack.prod.conf')
//
const spinner = ora('building for production... ')
spinner.start()
// Delete the files in the package target directory
rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err= > {
if (err) throw err
// Do the packing
webpack(webpackConfig, (err, stats) = > {
// The package is complete
spinner.stop()
if (err) throw err
// Outputs the status of packaging
process.stdout.write(stats.toString({
colors: true.modules: false.children: false.chunks: false.chunkModules: false
}) + '\n\n')
// If there is an error in packaging
if (stats.hasErrors()) {
console.log(chalk.red(' Build failed with errors.\n'))
process.exit(1)}// The package is complete
console.log(chalk.cyan(' Build complete.\n'))
console.log(chalk.yellow(
' Tip: built files are meant to be served over an HTTP server.\n' +
' Opening index.html over file:// won\'t work.\n'))})})Copy the code
Reprinted in: Understand vue- CLI vue Webpack Template configuration