1, Introduction to webpack
-
What is webpack
webpack is a front-end resource building tool and a static module packer
In webpack, all file resources in the front end (js/json/css/img/less) are treated as modules. It will perform static analysis according to the dependency of the module and package the corresponding static resources.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> // Record processing less <link rel="stylesheet" href="./index.less"> </head> <body> <div id="box">hello Ha ha ha</div> Record processing js In file es6 grammar <script src="./index.js"></script> </body> </html>
Enter from the entry file, record according to different modules to form a code block chunk, then process according to different modules, and then output to form a bundle.
-
Core concept
- Entry
Entry, indicating which file is the starting point for webpack to start packaging, analyze and build the internal dependency graph
- Output
Output, indicating where the resource bundles packaged by the webpack are output
- Loader
loader enables webpack to handle non js files (webpack itself only understands js)
- Plugins
Plug-ins that can perform a wider range of tasks. Plug ins range from packaging optimization and compression to redefining variables in the environment.
- Mode
Mode, indicating that the webpack uses the configuration of the corresponding mode
[external chain picture transfer failed, the source station may have anti-theft chain mechanism, It is recommended to save the picture and upload it directly (img-etaxy8tv-1630850415882)( https://le88510hbg.feishu.cn/space/api/box/stream/download/asynccode/?code=MjdlZTgyYzA0NDE3ZDg2Y2VkZGI4ZmMyOTgyODdmMGJfWmI4bmpvUnRBTDR0U0xkeG1XSzhvc2NRTHVLc1B4ZllfVG9rZW46Ym94Y25HMHBUMFg0NUI0Y0hSZHljczllZUZnXzE2MzA4NTAzOTI6MTYzMDg1Mzk5Ml9WNA )]
2, Basic usage
- Initialize package file
npm init
- Download package file (Global installation)
npm i webpack webpack-cli -g
3, Package style file
- webpack.config.js
Configuration file for webpack
Function: instruct webpack to do those things (the configuration will be loaded when running the webpack instruction)
All construction tools are run based on nodejs platform, and common JS is adopted by default for modularization
- Basic configuration
Install style loader and CSS loader
npm i style-loader css-loader -D
Create a new webpack.config.js file
const { resolve } = require("path"); // webpack configuration // Entrance starting point module.exports = { //output entry: './src/index.js', output: { //Output file name filename: 'built.js', //Output path //__ The dirname nodejs variable represents the absolute path of the current file directory path: resolve(__dirname, 'build') }, //loader configuration module: { rules: [ // Detailed loader configuration // Different files must be configured with different loader s for processing { // Used to match those files test: /\.css$/, // Use those loader s for processing use: [ // The execution order in the use array: from left to right, from top to bottom // Create a style tag, insert the style resource in js, and add it to the head to take effect 'style-loader', // Change the css file into a commonjs module and load it into js. The content inside is the style string 'css-loader' ] } ] }, //plugins configuration plugins: [ //Detailed plugin configuration ], //pattern mode: 'development' // mode: 'production' }
- Processing css files
{ // Used to match those files test: /\.css$/, // Use those loader s for processing use: [ // The execution order in the use array: from left to right, from top to bottom // Create a style tag, insert the style resource in js, and add it to the head to take effect 'style-loader', // Change the css file into a commonjs module and load it into js. The content inside is the style string // minimize in CSS loader? minimize tells CSS loader to enable CSS compression 'css-loader?minimize' ] }
Loader can be regarded as a translator with file conversion function. The module.rules array in the configuration configures a set of rules to tell Webpack which loader to use to load and convert when encountering which files. The above configuration tells Webpack to use CSS loader to read the CSS file when it encounters a file ending in. CSS, and then give it to style loader to inject the CSS content into JavaScript.
You can also use the Object method:
use: [ 'style-loader', { loader:'css-loader', options:{ minimize:true, } } ]
- Processing less files
Install less and less loader
{ test: /\.less$/, use: [ 'style-loader', 'css-loader', // Compile less files into css files // You need to download less loader and less 'less-loader' ] }
In addition to configuring the Loader in the webpack.config.js configuration file, you can also specify what Loader to use in the source code to process the file. Take loading CSS file as an example, modify main.js in the above example as follows:
// Entry file, where css files are imported require('style-loader!css-loader?minimize!./main.css');
In this way, you can specify to use CSS loader first and then style loader conversion for. / main.css file.
- Processing sass files
Install sass loader
{ // Added support for SCSS files test: /\.scss$/, // The processing order of SCSS files is sass loader, CSS loader and style loader use: ['style-loader', 'css-loader', 'sass-loader'], },
4, Packaging html resources
- Download plug-ins
npm i html-webpack-plugin -D
- Usage path of loader and plugins
loader: 1. Download 2. Use (configure loader)
plugins: 1. Download 2. Import 3. Use
- Use html webpack plugin to process packaged html resources
const { resolve } = require("path"); const HtmlWebpackPlugin = require('html-webpack-plugin') module.exports = { entry: './src/index.js', output: { filename: 'built.js', path: resolve(__dirname, 'build') }, module: { rules:[ ] }, plugins: [ // plugins configuration // html-webpack-plugin // Function: an empty html will be created by default, and all resources (js/css) for packaged output will be automatically introduced // Requirements: a structured html file is required new HtmlWebpackPlugin({ // Copy the '. / src/index.html' file and automatically import all resources (js/css) for packaged output template: './src/index.html' }) ], mode: 'development' }
5, Package picture resources
- Download plug-ins
npm i url-loader -D
- Handle picture references in less files
const { resolve } = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { entry: './src/index.js', output: { filename: 'built.js', path: resolve(__dirname, 'build') }, module: { rules: [ { test: /\.less$/, // To use multiple loader s, use use: ['style-loader', 'css-loader', 'less-loader'] }, { // Problem: img images in html cannot be processed by default // Processing picture resources test: /\.(jpg|png|gif)$/, // Use a loader // Download URL loader file loader loader: 'url-loader', options: { // If the image size is less than 8kb, it will be processed by base64 // Advantages: reduce the number of requests (reduce server pressure) // Disadvantages: larger picture size (slower file request) limit: 8 * 1024, // Problem: the URL loader uses es6 modular parsing by default, while the picture introduced by HTML loader is commonjs // There will be a problem when parsing: [object Module] // Solution: turn off es6 modularization of URL loader and use commonjs for parsing esModule: false, // Rename picture // [hash:10] take the first 10 bits of the hash of the picture // [ext] get the original file extension name: '[hash:10].[ext]' } } ] }, plugins: [ new HtmlWebpackPlugin({ template: './src/index.html' }) ], mode: 'development' };
Handle picture references in html files
{ test: /\.html$/, // Process img images of html files (responsible for introducing img so that it can be processed by URL loader) loader: 'html-loader', options: { esModule: false } }
6, Package other resources
- Install plug-ins
npm i file-loader -D
- Configure in loader
module: { rules: [ { test: /\.css$/, use: ['style-loader', 'css-loader'] }, // Package other resources (resources other than html/css/js resources) { // exclude exclude: /\.(css|js|html)$/, loader: 'file-loader', option: { name: '[hash:10].[ext]' } } ] }
7, devServer (Automation)
- Install the devServer plug-in
npm i webpack-dev-server -D
- use
Development server devServer: used for automation (automatic compilation, automatic browser opening, automatic browser refreshing)
Features: it will only compile in memory without any output. The webpack startup above will generate the build folder and output all packaged files.
const HtmlWebpackPlugin = require("html-webpack-plugin"); const { resolve } = require("path"); module.exports = { entry: './src/index.js', output: { filename: 'built.js', path: resolve(__dirname, 'build') }, module: { rules: [ { test: /\.css$/, use: ['style-loader', 'css-loader'] }, { exclude: /\.(css|js|html)$/, loader: 'file-loader' } ] }, plugins: [ new HtmlWebpackPlugin({ template: './src/index.html' }) ], mode: 'development', // Development server devServer: used for automation (automatic compilation, automatic browser opening, automatic browser refreshing) // Features: only compile in memory without any output // The instruction to start devServer is: NPX webpack dev server devServer: { // Project post build path contentBase: resolve(__dirname, 'build'), // Start gzip compression compress: true, // Port number port: 3000, // Open browser automatically open: true } }
The start command is
webpack serve
8, Development environment configuration
When packaging with the webpack command, specify the output path:
Export the entry js file to the following file:
output: { filename: 'js/built.js', path: resolve(__dirname, 'build') },
Output the loader file to the specified path:
{ test: /\.(jpg|png|gif)$/, loader: 'url-loader', options: { limit: 8 * 1024, esModule: false, name: '[hash:10].[ext]', outputPath: 'images' } }
The output image file will be put into the images file
Complete development environment configuration:
/* Development environment configuration: it can make the code run Run project instructions: webpack The packaging results will be output npx webpack-dev-server It will only compile and package in memory without output */ const { resolve } = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { entry: './src/js/index.js', output: { filename: 'js/built.js', path: resolve(__dirname, 'build') }, module: { rules: [ // Configuration of loader { // Handling less resources test: /\.less$/, use: ['style-loader', 'css-loader', 'less-loader'] }, { // Handling css resources test: /\.css$/, use: ['style-loader', 'css-loader'] }, { // Processing picture resources test: /\.(jpg|png|gif)$/, loader: 'url-loader', options: { limit: 8 * 1024, name: '[hash:10].[ext]', // Turn off es6 modularization esModule: false, outputPath: 'imgs' } }, { // Processing img resources in html test: /\.html$/, loader: 'html-loader' }, { // Processing other resources exclude: /\.(html|js|css|less|jpg|png|gif)/, loader: 'file-loader', options: { name: '[hash:10].[ext]', outputPath: 'media' } } ] }, plugins: [ // plugins configuration new HtmlWebpackPlugin({ template: './src/index.html' }) ], mode: 'development', devServer: { contentBase: resolve(__dirname, 'build'), compress: true, port: 3000, open: true } };
9, Package css into a separate file
- Install plug-ins
npm i mini-css-extract-plugin -D
- Replace the style loader with the loader in MiniCssExtractPlugin and rename the plug-in
const { resolve } = require("path"); const HtmlWebpackPlugin = require("html-webpack-plugin"); const MiniCssExtractPlugin = require('mini-css-extract-plugin') module.exports = { entry: './src/js/index.js', output: { filename: 'js/built.js', path: resolve(__dirname, 'build') }, module: { rules: [ { test: /\.css$/, use: [ // Create a style label and put the style into // 'style-loader', // This loader replaces the style loader // Function: extract css in js into a separate file MiniCssExtractPlugin.loader, 'css-loader' ] } ] }, plugins: [ new HtmlWebpackPlugin({ template: './src/index.html' }), new MiniCssExtractPlugin({ // Rename the output css file filename: 'css/built.css' }) ], mode: 'development' }
10, css compatibility processing
- Install plug-ins
npm i postcss-loader postcss-preset-env -D
- Configuration rules
// >1% // default // dead // last 2 version
- Method 1: in package.json
"browserslist": { // Development environment -- > set node environment variable: process.env.NODE_ENV = development "development": [ "last 1 chrome version", "last 1 firefox version", "last 1 safari version" ], // Production environment: the default is the production environment "production": [ ">0.2%", "not dead", "not op_mini all" ] }
- Method 2: configure in. Browserlistrc
In the. Browserlistrc file:
> 1% last 2 version not dead
- Method 1: configure in the webpack.config.js file:
const { resolve } = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); // Set nodejs environment variable // process.env.NODE_ENV = 'development'; module.exports = { entry: './src/js/index.js', output: { filename: 'js/built.js', path: resolve(__dirname, 'build') }, module: { rules: [ { test: /\.css$/, use: [ MiniCssExtractPlugin.loader, 'css-loader', /* css Compatibility processing: postcss -- > postcss loader postcss preset env Help postcss find the configuration in the browserslist in package.json, and load the specified css compatibility style through the configuration */ // Use the default configuration of loader // 'postcss-loader', // Modify the configuration of the loader // Postcss preset env: preset, plug-in collection { loader: 'postcss-loader', options: { postcssOptions: { plugins: [['postcss-preset-env',{}]] } } } ] } ] }, plugins: [ new HtmlWebpackPlugin({ template: './src/index.html' }), new MiniCssExtractPlugin({ filename: 'css/built.css' }) ], mode: 'development' };
- Method 2: postcss.config.js file
module.exports = { plugins: [ 'postcss-preset-env' ] } // Configuration in webpack.config.js use: [ 'style-loader', 'css-loader', 'postcss-loader' ]
- After css generation
[external chain picture transfer failed, the source station may have anti-theft chain mechanism, It is recommended to save the picture and upload it directly (img-xex9ix2y-1630850415884)( https://le88510hbg.feishu.cn/space/api/box/stream/download/asynccode/?code=MWE0ZTc2OTA4Y2JmNmQ3MTgwNGJhYjAzMDgwMzljMmVfcEw5TXBGWXEzeTAzYUxiNWtYYUlBTUN6VENid0haSU9fVG9rZW46Ym94Y255c1p4UE9hcGNvZmJiN3RCYWVzTmpjXzE2MzA4NTAzOTI6MTYzMDg1Mzk5Ml9WNA )]
11, Compress css
- Install plug-ins
npm i optimize-css-assets-webpack-plugin -D // Introducing plug-ins const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin') plugins: [ new HtmlWebpackPlugin({ template: './src/index.html' }), new MiniCssExtractPlugin({ filename: 'css/built.css' }), // Compress css new OptimizeCssAssetsWebpackPlugin() ]
12, js syntax check (eslint)
When compiling and packaging, prompt errors according to the syntax rules specified by eslint.
- Install plug-ins
npm i eslint-loader eslint -D npm i eslint-config-airbnb-base eslint-plugin-import -D
- Set the syntax rules in package.json
// Set syntax rules "eslintConfig": { "extends": "airbnb-base" }
- use
const { resolve } = require("path"); module.exports = { entry: './src/js/index.js', output: { filename: 'js/built.js', path: resolve(__dirname, 'build') }, module: { rules: [ // Note: only check the code written by yourself, and the code of the third-party library does not need to be checked { test: /\.js$/, // Exclude code from third-party libraries exclude: /node_modules/, loader: 'eslint-loader', // Turn on automatic repair of errors in eslint check options: { fix: true } } ] }, plugins: [ ], mode: 'development' }
be careful
// All rules of eslint in the next line are invalid (the next line does not check the eslint code) // eslint-disable-next-line console.log(add(3,4))
13, js compatibility processing
-
Basic js compatibility processing
A. Install plug-ins
npm i babel-loader @babel/core @babel/preset-env -D
Problem: only basic syntax can be converted, such as promise advanced syntax
{ test: /\.js$/, exclude: /node_modules/, loader: 'babel-loader', options: { presets: [ ['@babel/preset-env'] ] } }
-
All js compatibility processing
Problem: as long as some compatibility problems are solved, but all compatibility codes are introduced, the volume is too large~
A. Install plug-ins
npm i @babel/polyfill -D
Directly introduced in js code
// Introduce @ babel/polyfill import '@babel/polyfill'; const add = (x, y) => { return x + y; }; console.log(add(2, 5)); const promise = new Promise(resolve => { setTimeout(() => { console.log('The timer has finished executing~'); resolve(); }, 1000); }); console.log(promise);
-
Load on demand (recommended)
A. Install plug-ins
npm i core-js -D
Use in combination with the first method:
const { resolve } = require('path'); module.exports = { entry: './src/index.js', output: { filename: 'built.js', path: resolve(__dirname, 'build') }, module: { rules: [ { test: /\.js$/, exclude: /node_modules/, loader: 'babel-loader', options: { // Preset: indicates how babel handles compatibility presets: [ [ '@babel/preset-env', { // Load on demand useBuiltIns: 'usage', // Specify the core JS version corejs: { version: 3 }, // Specify which version of browser to use targets: { chrome: '60', firefox: '60', ie: '9', safari: '10', edge: '17' } } ] ] } } ] }, plugins: [ ], mode: 'development' };
14, Compress html and js
-
js compression
After changing the mode to the production environment, js compression is automatically enabled
mode: 'production'
-
html compression
plugins: [ new HtmlWebpackPlugin({ template: './src/index.html', // Compress html code minify: { // Remove spaces collapseWhitespace: true, // Remove comment removeComments: true } }) ]
15, Production environment configuration
- File types to be processed
- Html
plugins:
A. Processing html files - > html webpack plugin
B. Handle html compression
- Css
plugins:
A. Package css into a separate file - > Mini css extract plugin
B. Enable css compression - > optimize css assets webpack plugin
Loader:
A. Package as a separate file - > minicssextractplugin.loader
B. Handling css files - > css loader
C. Handling css style compatibility - > postcss loader (you need to define browserlist in package.json)
D. Handling less files - > less loader
E. Do not generate separate files, css and js together - > style loader
- Js
Loader:
A. js code check - > eslint loader
B. js code compatibility - > Babel loader + corejs (version needs to be specified)
C. js code automatic compression
- picture
Loader:
A. Processing image resources in css files - > URL loader
B. processing image resources in html files - > html loader
- Other documents
Loader:
A. Processing other files - > file loader
- Detailed configuration
const { resolve } = require('path'); // Package css into a separate file const MiniCssExtractPlugin = require('mini-css-extract-plugin'); // css compression const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin'); // Processing html files const HtmlWebpackPlugin = require('html-webpack-plugin'); // Define nodejs environment variables: determine which environment to use for the browserlist process.env.NODE_ENV = 'production'; // Reuse loader const commonCssLoader = [ MiniCssExtractPlugin.loader, 'css-loader', { // css compatibility handling postcss loader // You also need to define the browserlist in package.json loader: 'postcss-loader', options: { postcssOptions: { plugins:['postcss-preset-env',[]] } } } ]; module.exports = { entry: './src/js/index.js', output: { filename: 'js/built.js', path: resolve(__dirname, 'build') }, module: { rules: [ { test: /\.css$/, use: [...commonCssLoader] }, { test: /\.less$/, use: [...commonCssLoader, 'less-loader'] }, /* Normally, a file can only be processed by one loader. When a file needs to be processed by multiple loaders, the order of execution of loaders must be specified: Execute eslint first and babel later */ { // js syntax check eslint // Eslintconfig -- > airbnb in package.json test: /\.js$/, exclude: /node_modules/, // Priority implementation enforce: 'pre', loader: 'eslint-loader', options: { fix: true } }, { // js compatibility processing Babel loader + corejs test: /\.js$/, exclude: /node_modules/, loader: 'babel-loader', options:{ presets: [ '@babel/preset-env', { useBuiltInt: 'usage', corejs: { verson: 3 }, target: { chrome: '60', firebox: '60' } } ] } }, { // Image processing: in css file test: /\.(jpg|png|gif)/, loader: 'url-loader', options: { limit: 8 * 1024, name: '[hash:10].[ext]', outputPath: 'imgs', esModule: false } }, { // Image processing: in html file test: /\.html$/, loader: 'html-loader', options: { esModule: false, name: '[hash:10].[ext]' } }, { // Other document processing exclude: /\.(js|css|less|html|jpg|png|gif)/, loader: 'file-loader', options: { outputPath: 'media' } } ] }, plugins: [ new MiniCssExtractPlugin({ filename: 'css/built.css' }), new OptimizeCssAssetsWebpackPlugin(), new HtmlWebpackPlugin({ template: './src/index.html', minify: { collapseWhitespace: true, removeComments: true } }) ], mode: 'production' };