Webpack profile
Webpack is actually a static module packaging tool
When WebPack works on a project, it recursively builds a Dependency graph of each module the application needs, and then packages all of those modules into one or more bundles.
Principle of packaging
- Identification entry file
- Identify module dependencies layer by layer. Commonjs, AMD, or ES6 imports are analyzed by WebPack. To get code dependencies)
- What WebPack does is analyze the code. Transform code, compile code, output code
- The result is packaged code
Package debug command
npm run dev
npm run build
Copy the code
packages.json
."scripts": {
"dev_def": "webpack-dev-server --inline --public --config build/dev.js"."dev": "nodemon --watch config/index.js --exec \"webpack-dev-server --inline --public --config build/dev.js\""."start": "npm run dev"."build": "cross-env NODE_ENV=production node build/build.js"}...Copy the code
webpack-dev-server
Is a lightweight server, after modifying the source file, automatically refresh the page to synchronize the changes to the page
webpack-dev-server --inline --public --config build/dev.js
Copy the code
- Inline mode: A script will be inserted into the package to handle real-time reloads, and the build message will be displayed in the browser console.
module.exports = {
//...
devServer: {
inline: true}};Copy the code
- [–public XXX] When using inline mode and proxying dev-server, the inline client script does not always know where to connect. It will try to guess window.location based on the URL of the server, but will need to use it if it fails
- [–config XXX] Specifies the configuration file
- [–progress] Prints the running progress to the console.
nodemon
It will monitor the files in the project and automatically restart the application once any changes are found in the files
- 【–watch XXX 】 Monitors specified files or directories
- 【–exec XXX 】 execute the specified command
nodemon --watch config/index.js --exec \"webpack-dev-server --inline --public --config build/dev.js\"
Copy the code
Use nodemon to monitor the config/index.js file. If there is any change, run the webpack-dev-server –inline –public –config build/dev.js command again
The [webpack-dev-server –inline –public –config build/dev.js] command has the hot update function for the project itself, but the change of the webpack configuration file does not take effect. With Nodemon, the service is restarted when the WebPack configuration file is modified, which is an automatic supplement
cross-env
Addresses cross-platform setup and scripting using environment variables, such as variable names and paths
- Cross -env NODE_ENV=production smoothen cross-platform environment variable Settings
The basic configuration
Module.exports = {// exports file entry: {app:'./src/js/index.js'}, // Where to export the bundles it creates: {filename:'[name].bundle.js',
path: path.resolve(__dirname, 'dist'),
publicPath: '/'// Make sure file resources are properly accessed at http://localhost:3000}, // developer toolssource-map
devtool: 'inline-source-map'// Create devServer: {contentBase:'./dist',
hot: trueNew CleanWebpackPlugin(['dist'// new HtmlWebpackPlugin({title:'Output Management'}), / / in order to more easily view to repair (patch) rely on new webpack. NamedModulesPlugin (), / / hot update module new webpack. HotModuleReplacementPlugin ()], / / environment mode:"development"// loader configuration module: {rules: [{test: /\.css$/,
use: [
'style-loader'.'css-loader'] {},test: /\.(png|svg|jpg|gif)$/,
use: [
'file-loader'}]}}Copy the code
__dirname: absolute path of the current file folder
Entry (Entry file configuration)
Single entry syntax (short)
entry: './path/to/my/entry/file.js'// Or entry: {main:'./path/to/my/entry/file.js'
}
Copy the code
Multi-page applications
entry: {
pageOne: './src/pageOne/index.js',
pageTwo: './src/pageTwo/index.js',
pageThree: './src/pageThree/index.js'
}
Copy the code
Note: Written before Webpack (not recommended)
entry:{
vendor:[resolve('src/lib/polyfill.js'), 'vue'.'vue-router'], // do not recommend app: resolve('src/main.ts')}Copy the code
In versions prior to Webpack4, it was common to add a vendor as a separate entry point to compile it into a separate file vendor (combined with CommonsChunkPlugin)
This is discouraged in WebPack 4. Instead, the optimization.splitchunks option is responsible for separating vendor and application modules and creating separate files. Do not create an entry for a vendor or something else that is not a starting point for execution.
Output (Output file configuration)
output: {
filename: '[name].bundle.js',
chunkFilename: [name].min.js,
path: path.resolve(__dirname, 'dist'),
publicPath: '/'// Make sure file resources are properly accessed at http://localhost:3000}Copy the code
- Filename: indicates the output filename
- ChunkFilename: This option determines the name of the non-entry file
- Path: indicates the destination path of all output files
- PublicPath: specifies the directory referenced by the resource file, the file after build, and the prefix of the resource reference path
Devtool (Debugging tool: File Mapping)
// dev
devtool: 'eval-source-map'
// prod
devtool: 'source-map'
Copy the code
Key words revealed:
The keyword | meaning |
---|---|
eval | At packaging time, generated bundle.js files, modules are wrapped in eval, followed by sourceUrl, pointing to the original file |
source-map | This configuration generates a.map file that maps to the original file and is used to locate the original code during debugging |
cheap | Low consumption packaging, which is when the map file is packaged, does not store the column position of the original code, only contains the row position, so this explains the explanation behind the official image (row only). |
. | . |
devServer
devServer: {
compress: true,
port: 9000,
hot: true,
https: true,
overlay: {
warnings: false,
errors: true
},
publicPath: '/platform/redapply/'
}
Copy the code
- Compress: Enables gzip compression
- Port: the port number
- Hot: Indicates whether to enable the Hot Module Replacement feature
- HTTPS: you can use a self-signed certificate, can also customize signing certificate | Boolean, object
- Overlay: full screen compile errors or warnings on the browser | Boolean, object
- PublicPath: the packaged file will be deployed to the path corresponding to the configuration. http://localhost:8080/platform/redapply/index.html
Mode (tells Webpack to use its built-in optimizations accordingly)
// dev
mode: 'development'
// build
mode: 'production'
Copy the code
Plugins
plugins: [
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: '"production"'}}),]Copy the code
Module. rules (Loader configuration)
module: {
rules: [
{
test: /\.css$/,
use: [
'style-loader'.'css-loader'] {},test: /\.(png|svg|jpg|gif)$/,
use: [
'file-loader']]}}Copy the code
The execution sequence of the Loader is from back to front
Common Project Configuration
Resolve (resolve)
resolve: {
extensions: ['.js'.'.ts'.'.vue'.'.json'].alias: {
'@lib': resolve('src/lib'),
'@models': resolve('build/models'),
'@components': resolve('src/components'),
'@data': resolve('src/data'),
The '@': resolve('src')}}Copy the code
- Extensions that parse path default file names (try in order)
- Alias User-defined path symbol definition
Preloaded file
For example, define some common SCSS files. In order not to introduce this file on every page. We can set file preloading
module: {
rules: [
...
{
test: /\.sass|scss|css$/,
use: [
...
{
loader: 'sass-resources-loader',
options: {
resources: [
path.resolve(__dirname, '.. /src/assets/css/vars.scss'),
path.resolve(__dirname, '.. /src/assets/css/common.scss']}}]}Copy the code
Optimization (optimize configuration items, configure at build)
optimization: {
minimize: true// The default istrueThe effect is to compress js code. Minimizer: [// New TerserPlugin(), new OptimizeCSSAssetsPlugin({})], runtimeChunk: {// Default isfalseTo extract the common code block at the time of shipment. name:'manifest'
},
splitChunks:{
chunks: 'all', // You must choose one of three:"initial" | "all"| (recommended)"async"(async by default) minSize: 30000, // Minimum number of bytes generated chunks, 30000 minChunks: 1, // Minimum number of times referenced maxAsyncRequests: // maxInitialRequests: 3, // maxInitialRequests: 3true, // the name of the packaged chunks cacheGroups: {// the cache configuration common: {name:'common'// chunks to cache:'initial', // You must choose one of three:"initial" | "all" | "async"Priority: 11, enforce:true,
reuseExistingChunk: true, // You can set whether to reuse the chunktest: / / / / node_modules / [\] (vue | Babel \ - polyfill | mint \ - UI) /}, vendor: {/ / entry name defined in the key for the entry name:'vendor'// chunks to cache:'initial', // You must choose one of three:"initial" | "all" | "async"Priority: 10, enforce:true,
reuseExistingChunk: true, // You can set whether to reuse the chunktest: /node_modules\/(.*)\.js/
},
styles: {
name: 'styles'.test: /\.(scss|css)$/,
chunks: 'all',
minChunks: 1,
reuseExistingChunk: true,
enforce: true}}}}Copy the code
runtimeChunk
The default is false, and the common code block is extracted at the time of shipment
What is runtime?
JS in the browser can call the browser provided by the API, such as the window object, DOM related API. These interfaces are not provided by the V8 engine, they exist in the browser. So in simple terms, these related external interfaces can be called by JS at RunTime, as well as JS Event loops and Callback queues, called RunTime. Some places also consider the core lib library used by JS as part of the RunTime.
The chunk runtime
The environment (method) on which chunk is executed
splitChunks
chunks
function (chunk) | string
This indicates which blocks will be selected for optimization
string:
- Initial-entry chunk. Files imported asynchronously are not processed
- Async – asynchronous chunk, only for files imported asynchronously (personal understanding)
- All-all Chunk
function:
splitChunks: {
chunks (chunk) {
// exclude `my-excluded-chunk`
returnchunk.name ! = ='my-excluded-chunk'; }}Copy the code
cacheGroups
The cache group can inherit and/or override any option splitChunks.*; To disable any default cache group, set it to false.
- Priority: a module can belong to multiple cache groups and will be allocated to a chunk with a higher priority
- ReuseExistingChunk indicates that an existing chunk can be used, that is, if a conditional chunk already exists, the existing chunk is used instead of creating a new chunk
- Enforce minSize, minChunks, and maxInitialRequests options for quickly creating chunks
- Test Indicates the rule of the cache group, which indicates that the matches are added to the current cache group
optimization: {
splitChunks: {
chunks: 'async',
minSize: 30000,
minChunks: 1,
maxAsyncRequests: 3,
maxInitialRequests: 3,
name: true,
cacheGroups: {
common: {
name: 'common',
chunks: 'initial',
priority: 11,
enforce: true,
reuseExistingChunk: true, // You can set whether to reuse the chunktest: /[\/|\\]node_modules[\/|\\](vue|babel\-polyfill|mint\-ui)/
},
vendor: {
name: "vendor",
chunks: "initial",
priority: 10,
test: /[\/|\\]node_modules[\/|\\](.*)\.js/
},
styles: {
name: 'styles'.test: /\.(scss|css|less)$/,
chunks: 'initial',
minChunks: 1,
reuseExistingChunk: true,
enforce: true}}}}Copy the code
Note:
Test match path test match path
. common: { name:'common',
chunks: 'initial',
priority: 11,
enforce: true,
reuseExistingChunk: true.test: /[\/]node_modules[\/](vue|babel\-polyfill|mint\-ui)/
}
...
Copy the code
The test match is based on the Linux environment path. (such as: node_modules/vue)
But the Window path, unlike the Linux path, is a backslash. (such as: node_modules \ vue)
So we’re going to change the re to
/[\/|\\]node_modules[\/|\\](vue|babel\-polyfill|mint\-ui)/
Copy the code
This allows for compatibility with both environments
Configuration in the project
Webpack typically requires three configuration files
- Webpack.base.conf.js // Common configuration
- Webpack.dev.conf.js // Development environment configuration
- Webpack.prod.conf.js // Production environment configuration
But the configuration you see in our project is not exactly the same as the one described above.
This is because: We already integrated the basic configuration of WebPack when we scaffolded the project.
They’re all under @zz/webpack-vue
Only a few configuration object entries are exposed in our project.
The configuration item structure exposed is slightly different from that of WebPack itself.
Developers can customize these objects, which are then merged with the default configuration to form the final configuration parameters.
(This article is a share of the internal thematic study Webpack, the content is relatively basic)