So far, there are many friends who do not know Webpack packaging tools. Today, Guangzhou Bluestream’s small series will popularize the teaching of technical points. Please collect them well

preface

As we all know, front-end projects use JS only by using it in HTML files

<script>
 console.log('hello');
</script>
​
<script src="./index.js"></script>
Copy the code

JS was originally designed to solve some simple web interaction (such as form verification), but designers have never dreamed that JavaScript is developing very fast, can do more and more things, the amount of code is also more and more. At this point, if all the JS code is placed in

1. The maximum number of concurrent requests from the browser to the same domain name. HTTP client average number of simultaneous connections to the same server is limited (different) for different browsers limit the number of possible, if you meet some JS file processing task takes too long, the poor network speed, etc., so behind the rest of the files will have to wait for the front loaded, create web page loading speed is slow, appear bad situation. 2. Global environmental pollution through

· Use self-executing functions (IIFE)

ES moudle,

let a = (function () { let a = 'hello JS'; return { b: 'IIFE', c: 'IIFE', }; }) ();Copy the code

Creating function scopes by self-executing functions prevents variables from contaminating the global environment. Then, the variables to be used are returned for external use. But there are also problems with this, when the project is large, we use a lot of files to code different functions, and then import the files into HTML. When a project needs a variable to locate the problem, it is difficult to locate the global variable in the JS file, because the dependency between modules is not very clear, and there is a problem of variable name duplication between different modules.

As web code gets bigger and bigger, JavaScript modularization becomes more and more imperative. In ES2015, the modular writing of JavaScript finally emerged.

// a.js
​
import { b } from './b.js';
​
// b.js
​
export const b = 'ES module';
Copy the code

Export is used to expose variables and import is used to import variables. In this way, you can clearly know which module the variable comes from, and there will be no naming conflicts, pollution of the global environment and other problems. Although ES Module support varies from browser to browser, we can use Babel to convert ES6+ code to ES5 for compatibility with different browsers.

Using modular development projects makes it easier to maintain code and locate project problems. However, modular development will also increase the number of files that need to be introduced, so modularization will have the problem of limiting the number of concurrent requests, resulting in slow project loading and long white screen time for the first screen. At this point we needed a tool to automate file merging, translate ES6+ code, and optimize project performance when the project went live. In many packaging tools, Webpack is undoubtedly the most dazzling.

The body of the

The relevant code in this article supports Webpack4 and Webpack5, and the specific version will be indicated in the corresponding position.

Essentially, WebPack is a static module packaging tool for modern JavaScript applications. When WebPack processes the counterpart, it internally builds a dependency diagram that maps to each module required for the project and generates one or more bundles.

Webpack is a static module packaging tool for modern JavaScript applications. Static modules here are not just ES Modules. Modules in Webpack can be of the following types:

  • ES2015 import statement.
  • CommonJS require() statement.
  • AMD DEFINE and require statements.
  • @import statement in CSS /sass/ LESS files.
  • Stylesheeturl () or HTMLImage link in file.

Dependency graph: When WebPack processes an application, it starts processing based on a list of modules defined in command line arguments or configuration files. Starting at the entry point, WebPack recursively builds a dependency diagram that contains each module needed in the application, and then packages all modules into a small number of bundles.

Bundles: Bundles are generated by many different modules and contain the final version of the source files that have been loaded and compiled.

Chunk: During the packaging process, modules are merged into chunks, and chunks are merged into chunks. Chunk groups are the entry fields specified in the WebPack configuration file. Each entry corresponds to a chunk group. And chunk comes in two forms:

Initial is main Chunk of the entry point. This chunk contains all the modules and their dependencies specified for the entry point. Non-initial is a lazy-loaded block. Dynamic imports or SplitChunksPlugin may be used. Chunk corresponds to the process of bundling dependent modules in the packaging process. And bundle refers to the final version generated after compilation.

A brief understanding of webpack related knowledge, then enter the use of Webpack related learning:

1. Install webpack

mkdir webpack-demo 
cd webpack-demo
 npm init -y 
npm install webpack webpack-cli --save-dev
Copy the code
  • Webpack-cli: Used to run Webpack on the command line interface

2. Configure entry and output.

Create the SRC folder, webpack.config.js, in the project root

- webpack-demo  
   | - src    
   | - webpack.config.js    
   | - package.json
Copy the code

Configure the Webpack configuration file (webpack.config.js)

// webpack.config.js
const path = require('path');
​
module.exports = {
  entry: './src/main.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'js/bundle.js',
  },
};
Copy the code

Module.exports exposes an object in which different key names are used to specify different WebPack configurations. Entry is used to specify the entry file for webPack compilation. Webpack uses the entry file as a starting point to generate the project dependency diagram, which is used to package the project. The default value is./ SRC /index.js. Output is used to specify the output location of the project compilation file. The filename attribute is used to specify the filename of the compiled bundle file. Path is used to specify the location of the compiled file output. The default value is./dist

The path in the code above is the path for node to process files and directories. Since the path for output requires an absolute path, the node path resolve method is used here, which processes the path fragment into an absolute path. Where __dirname refers to the absolute path of the corresponding JS file when it is called. Since webpack.config.js is in the root directory of the project, the compiled file will be generated to the dist folder under the root directory. The folder is created.

Create the main.js file

// src/main.js console.log('Hello webpack! ');Copy the code

Configure the NPM command in package.json:

{
   "scripts": {
     "build": "webpack"
  }
}
Copy the code

Run commands on the command line

npm run build
Copy the code

Run webpack-cli by executing build command, webpack default command is build command (can be omitted),build command will call webpack to complete the compilation of the project.

After compiling, a dist folder is generated in the root directory, and a JS folder contains the generated bundle.js. Create index.html in a new public folder under the project root directory. You then import bundle.js into your HTML file and open it to your browser, where you can see the output “Hello Webpack!” on the console. ;

In the above example code, we configure only one entry for Entry. The common single entry project is called single page application (SPA). For example, the development mode of VUE-CLI is single page application. If we want to configure multi-entry: multi-page application (MPA), we can write the object as follows:

// webpack.config.js
const path = require('path');
​
module.exports = {
 entry: {
 main: './src/main.js',
 index: './src/index.js',
},
 output: {
 path: path.resolve(__dirname, 'dist'),
 filename: 'js/[name].[contenthash].js',
},
};
// src/index.js
​
console.log('index.js');
Copy the code
// src/index.js 
 console.log('index.js');
Copy the code

Re-execute the build command:

npm run build
Copy the code

Running the command generates two new files in dist. Above, we modified the configuration file of Webpack and assigned entry to an object. The key in the object is the name of chunk and the value describes the file path of chunk. Since we use multiple entries, we should not have a fixed file name for the output file, otherwise we will get an error during the packaging process. Webpack provides a way to template file names through bracketed strings called Substitution template Strings. [name]: the name of the chunk, otherwise the ID of the chunk is used. [contenthash] : Hash value of this chunk, which creates a unique hash based on the content of the resource.

Browsers use a technique called caching. You can hit caches to reduce network traffic and make websites load faster, but if you do not change the file name of a resource when deploying a new version, the browser may assume it has not been updated and will use its cached version. Use contenthash to create a unique hash based on the content of the resource. When the content changes, the file name changes accordingly, avoiding the browser using cached versions.

3. Configure common Loaders

Webpack can only handle JavaScript and JSON files, which are built-in capabilities available out of the box. Loader enables WebPack to process other types of files and convert them into valid modules for use by applications and to be added to dependency diagrams.

3.1 deal with CSS

Create a CSS style file and import the style file into main.js:

/*src/assets/style.css*/
​
html,
body {
 margin: 0;
 padding: 0;
}
​
body {
 background-color: skyblue;
}
Copy the code
// src/main.js import './assets/css/style.css'; console.log('Hello webpack! '); // Webpack can import CSS and SCSS filesCopy the code

Webpack does not have the ability to process CSS files. Therefore, you need to download the corresponding Loader to process CSS files and convert the CSS files into modules that WebPack can process.

npm install style-loader css-loader --save-dev
Copy the code
  • Style-loader: Inserts CSS into the DOM.

  • Css-loader: handles @import and URL () in the same way that JS interprets import/require().

// webpack.config.js const path = require('path'); // webpack.config.js const path = require('path'); module.exports = { entry: { main: './src/main.js', index: './src/index.js', }, output: { path: path.resolve(__dirname, 'dist'), filename: 'js/[name].[contenthash].js', }, module: { rules: [ { test: /\.css$/i, use: ['style-loader', 'css-loader'], }, ], }, };Copy the code

The Module option determines how different types of modules in a project are handled. Rules is used to create processing rules for different types of modules. The test option is used to import all modules that pass the assertion test, and the use option determines which loaders are used for processing modules that pass the assertion test. Loaders can be called in a chain order by passing multiple calls: From right to left (bottom to top), each loader returns the result of its own processing to the next loader to process. In the above example code, csS-loader is used to process the CSS file in main.js at compile time, and then returns the processing result to style-loader, which can insert the CSS code into the DOM.

module.exports = { module: { rules: [ { test: /\.css$/i, use: ['style-loader'], }, { test: /\.css$/i, use: ['css-loader'], }, ], }, }; // The above code has the same effect as the above code, the loader is parsed from right to left or from bottom to top.Copy the code

After configuring the CSS processing rules, re-run the package command and import the packaged file into index.html. You can see that the style tag has been introduced into the page. Webpack handles CSS files correctly with csS-loader and style-loader.

3.2 processing SCSS | sass

If want to use in the project development SCSS | sass, so we need to install the sass – loader, due to the sass – loader is dependent on the Dart sass or Node sass, it is recommended to use the Dart sass.

npm install sass-loader sass --save-dev
Copy the code

Dart sass: NPM install sass –save-dev

node sass: npm install node-sass –save-dev

  • Sass-loader: Loads sASS /SCSS files and compiles them to CSS
/*src/assets/scss/style.scss*/
$bgcolor: skyblue;
​
* {
 margin: 0;
 padding: 0;
}
​
body {
 background-color: $bgcolor;
}
Copy the code
// src/main.js import './assets/css/style.scss'; console.log('Hello webpack! ');Copy the code

Modify the webpack. Config. Js:

// webpack.config.js
​
const path = require('path');
​
module.exports = {
 entry: {
 main: './src/main.js',
 index: './src/index.js',
},
 output: {
 path: path.resolve(__dirname, 'dist'),
 filename: 'js/[name].[contenthash].js',
},
 module: {
 rules: [
    {
 test: /\.(css|scss|sass)$/i,
 use: ['style-loader', 'css-loader', 'sass-loader'],
      },
    ],
  },
};
Copy the code

If you are using less, you can use less-loader. If you use stylus, you can use the Stylus-Loader.

3.3 Processing Image Resources

Prior to Webpack 5, WebPack used file-loader and url-loader to process image resources.

  • Url-loader: inline files into bundles as data urls

  • File-loader: sends files to the output directory

Take an image and place it in the SRC/Assets /images folder and modify style.scss

// src/assets/css/style.scss $bgcolor: skyblue; * { margin: 0; padding: 0; } body { width: 100vw; height: 100vh; background-color: $bgcolor; background-image: url('.. /images/1.jpg'); background-size: cover; background-repeat: no-repeat; }Copy the code

Modify the webpack. Config. Js

/ / webpack. Config. Js/rules/add image resources processing module exports = {module: {rules: [{test: / \. (PNG | jpe? G | | GIF SVG) $/ I use: ['file-lodaer'], }, ], }, };Copy the code

After the configuration, run the build command again. After compiling, you can see that the image resources introduced in the SCSS file are generated under the dist folder. File-loader sends the resource to the output directory and returns the correct path after the output to the original location for replacement.

We can also configure the output path and file name of the image resource by configuring the options option to file-loader

// webpack.config.js
​
module.exports = {
 module: {
 rules: [
    {
 test: /\.(png|jpe?g|gif|svg)$/i,
 loader: 'file-loader',
 options: {
 name: '[name].[ext]',
 outputPath: 'images',
        },
      },
    ],
  },
};
Copy the code

Change the configuration options of file-loader to provide options.name with custom output file name, [name] for the original file name of the image, and [ext] for the original suffix of the image. Options. output is used to set the path where the file output from file-loader will be placed. The final output path of the image in the example code is dist/images

File-loader copies resource files to the output directory and resolves the imported image resource path to the correct path. Url-loader processes image resources as base64 urls by default

Let’s modify the image processing rules in webpack.config.js:

// webpack.config.js
​
module.exports = {
 module: {
 rules: [
    {
 test: /\.(png|jpe?g|gif|svg)$/i,
 use: ['url-loader'],
    },
  ],
},
}; 
Copy the code

Re-run the build command to import the compiled JS file into index.html. You can see that the URL of the background image generates a base64 string. If the resource image is too large, it is not appropriate to use urL-loader to generate base64 strings at this time. Therefore, we need to set a resource size limit for urL-loader. Only below this limit will image resources be converted to Base64 strings.

// webpack.config.js
​
module.exports = {
 module: {
 rules: [
    {
 test: /\.(png|jpe?g|gif|svg)$/i,
 loader: 'url-loader',
 options: {
 limit: 1024 * 10,
      },
    },
  ],
},
};
Copy the code

By setting the options.limit option to urL-loader, you can limit the size of resource images that urL-loader can process. The unit of limit is B(byte). In the above example code, we set that if the image resource is greater than or equal to 10KB, the image resource will not be processed into a Base64 string using urL-loader, but will be output to the output directory using file-loader, and the corresponding path will be resolved. If file-loader is not downloaded, an error will be reported if the image exceeds the limit.

In webpack5, instead of using file-loader and url-loader for image resources, we use the built-in Asset Modules to replace the original loader.

  • Asset/Resource sends a separate file and exports the URL. This was previously implemented using file-loader.

  • Asset /inline exports the data URI of a resource. This was previously implemented using urL-loader.

  • Asset automatically selects between exporting a data URI and sending a separate file. Previously, the urL-loader was used and the resource volume limit was configured.

// webpack.config.js
​
module.exports = {
 module: {
 rules: [
    {
 test: /\.(png|jpe?g|gif|svg)$/i,
 type: 'asset',
    },
  ],
},
};
Copy the code

In the example code above, using url-loader and configuring the limit option before replacing Webpack5 with type: ‘asset’ achieves the same effect. Type: ‘asset’ will choose between type: asset/resource and type: asset/inline. By default, files smaller than 8KB will use type: asset/inline, otherwise type: The asset/resource. If you want to modify the file size limit, can modify the Rule. The parser. DataUrlCondition. MaxSize

// webpack.config.js
​
module.exports = {
 module: {
 rules: [
    {
 test: /\.(png|jpe?g|gif|svg)$/i,
 type: 'asset',
 generator: {
 filename: '[name].[ext]',
      },
 parser: {
 dataUrlCondition: {
 maxSize: 1024 * 10,
        },
      },
    },
  ],
},
};
Copy the code

By adding a parser. DataUrlCondition. 8 KB limit maxSize to change the default. Filename is the output name of the set file.

3.4 Escaping ES6+ code

Since support for ECMA Script syntax varies from browser to browser, we use Babel to compile ES6+ code into ES5 code to be compatible with different browser versions.

npm install babel-loader @babel/core @babel/preset-env --save-dev
Copy the code
  • Babel-core: Analyze JS code into AST, convenient for each plug-in to analyze syntax for corresponding processing

  • Babel-preset -env: Compile modern JS to ES5

  • **babel-loader ** : for webpack

Configuration rules:

// webpack.config.js module.exports = { module: { rules: [ { test: /\.js$/i, use: { loader: 'babel-loader', options: {presets: ['@babel/preset-env'],},}, // Exclude: /node_modules/,},},};Copy the code

After configuring the above rules, let’s enter a snippet of arrow function code in main.js to see what Babel will do with our arrow function when compiled.

We can see in the compiled JS that the arrow function has been changed to ES5 function form.

4. Configure common plugins

Loaders are used to transform certain types of modules, while plug-ins can be used to perform a wider range of tasks. Including: package optimization, resource management, injection of environment variables. To use a plug-in, require() for the plug-in, and then create an instance using the new operator that you add to the plugins array.

ref=”webpack.luxiangfan.club/#/? Id = _41 – h… HtmlWebpckPlugin HtmlWebpckPlugin can help us after each packaging, the packed JS file into the HTML file, so that there is no need to manually import files every time packaging.

npm install html-webpack-plugin --save-dev
Copy the code
// webpack.config.js const HtmlWebpackPlugin = require('html-webpack-plugin'); let chunks = ['main', 'index']; let htmlPlugins = chunks.map((ele) => { return new HtmlWebpackPlugin({ template: '. / public/index. HTML ', / / generate HTML template file, can be used in the template < % = htmlWebpackPlugin. Options. The title % > introduce configuration in the title field, specify the title of the HTML content. Favicon: './public/favicon.ico', // specify the generated HTML file to import the ICO icon title: 'Hello webpack', // title filename: '${ele}.html', // HTML filename chunks: [ele], // chunks generated by this plugin instance that need to be imported}); }); module.exports = { plugins: [...htmlPlugins], };Copy the code
<! -- public/index.html--> <! 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 > < % = htmlWebpackPlugin. Options. The title % > < / title > < / head > < body > < / body > < / HTML >Copy the code

In the example code above, since we configured multiple entries at the beginning, we need to create a corresponding number of htmlWebPackPlugin instances. By configuring the chunk option in the object, we determine the chunk groups that each instance needs to introduce.

ref=”webpack.luxiangfan.club/#/? Id = _42 – c… The cleanWebpackPlugin causes the dist folder to be clutter-free because each run of the build command generates a bundle with a different name. So use the clean-webpack-plugin to clean up the dist folder before packaging.

npm install clean-webpack-plugin --save-dev
Copy the code
// webpack.config.js
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
​
module.exports = {
 plugins: [new CleanWebpackPlugin()],
};
Copy the code

Now re-execute the build command and the dist folder will contain only the files that were compiled this time.

5.devServer

Running the NPM run build manually every time the code is compiled can be cumbersome and detrimental to development. Webpack provides a tool called webpack-dev-server to help you automatically compile code and refresh the browser when it changes.

First we need to download the webpack-dev-server tool

npm install webpack-dev-server --save-dev
Copy the code

Configure the serve command:

// package.json
​
{
 "scripts": {
 "serve": "webpack serve --mode=development --open"
}
}
Copy the code

Set the mode of Webpack to development through cli, which will be discussed below. –open: Opens the service url in the default browser.

Run NPM run serve, webpack-dev-server will start the service, and the address of the service will be opened in the default browser. Next, you modify the code in the project, and WebPack recompiles it automatically and refreshes the page when it’s finished.

Note: Webpack-dev-server does not write the compiled files to any output directory, but instead keeps the bundle files in memory and serves them to the server. You can type webpack-dev-server after the url where the service is started to see the location of the service file. For example: http://localhost:8080/webpack-dev-server

Webpack provides the devServer option to change the behavior of webpack-dev-server.

Add devServer configuration to webpack.config.js:

// webpack.config.js module.exports = {devServer: {open: true, // automatically opens the service url to the default browser, which can be set as above in cli or devServer. In addition to Boolean, it can also be string, such as 'Chrome' host: '0.0.0.0',// specify host, default is 'localhost', if you want local access, set to '0.0.0.0', so that localhost can be accessed with IP address 127.0.0.1: HotOnly: true, // Enable hot module replacement port: 8080 // Set the port number, default: '8080' // set the reverse proxy proxy: { '/api': { target: 'http://localhost:3000', pathRewrite: { '^/api': '' } } } } }Copy the code

6. Development mode (development) | production (production)

There are differences in build goals between development and production environments. In a development environment, you need a powerful source map and a Localhost Server with live reloading or hot Module replacement capabilities. Production environment goals move to other areas, such as bundle compression, lightweight source maps, resource optimization, etc. So we usually differentiate webPack configuration by environment.

Create the build folder in the root directory of the project, and create three JS files in the file: webpack.base.conf.js, webpack.dev.conf.js, and webpack.prod.conf.js

  • Webpack.base.conf. js: Configure common configurations, such as portals and common loaders, for production and development environments

  • Webpack.dev.conf. js: Configure the development environment configuration, such as devServer, mode, source map, etc

  • Webpack.prod.conf. js: Configure the production environment configuration, such as cleanWebpackPlugin, mode, resource optimization, etc

When differentiating environments, you need to download the WebPack-Merge tool, which is a Webpack configuration for merging different files.

npm install webpack-merge --save-dev
Copy the code

In addition to Webpack-Merge, some other tools need to be downloaded:

npm install cross-env postcss-loader postcss autoperfixer mini-css-extract-plugin css-minimizer-webpack-plugin uglifyjs-webpack-plugin --save-dev
Copy the code
  • Cross-env: This plug-in is used to set or use the correct environment variables on different platforms

  • Postcss-loader: indicates the loader that uses postCSS to process CSS

  • Postcss: PostCSS is a tool that allows you to transform styles using JS plug-ins. For example: add style prefixes, use advanced CSS syntax, etc

  • Autoprefixer: Adds different browser prefixes to styles

  • Mini-css-extract-plugin: Extract CSS into a separate file.

  • Css-minimizer-webpack-plugin: Optimize and compress CSS using CSsnano.

  • Uglifyjs-webpack-plugin: Use uglify-js to compress JavaScript.

Configuration webpack. Base. Conf. Js:

// build/webpack.conf.js const path = require('path'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); // Extract CSS styles into separate CSS files const HtmlWebpackPlugin = require('html-webpack-plugin'); const htmlPlugins = ['main', 'index'].map((ele) => { return new HtmlWebpackPlugin({ template: './public/index.html', favicon: './public/favicon.ico', title: 'Hello webpack', filename: `${ele}.html`, chunks: [ele], }); }); // Add MiniCssExtractPlugin const plugins = process.env.node_env === 'production'? [...htmlPlugins, new MiniCssExtractPlugin()] : [...htmlPlugins]; module.exports = { entry: { index: './src/index.js', main: './src/main.js' }, output: { path: path.resolve(__dirname,'dist'), filename: '[name].[contenthash].bundle.js' }, module: { rules: [ { test: /\.(css|scss|sass)$/i, use: [ process.env.NODE_ENV === 'production' ? MiniCssExtractPlugin.loader : 'style - loader', 'CSS - loader', 'postcss - loader', 'sass - loader']}, {test: / \. (PNG | jpe? G | | GIF SVG) $/ I, type: 'asset', generator: { filename: '[name].[ext]', }, parser: { dataUrlCondition: { maxSize: 1024 * 8, }, }, }, { test: /\.js$/i, use: { loader: 'babel-loader', options: { presets: ['@babel/preset-env'],},}, // Exclude: /node_modules, avoid waste of performance. Exclude: /node_modules/,},]}, preset: plugins, resolve: { alias: { '@': path.resolve(__dirname, '.. /src'), assets: path.resolve(__dirname, '.. /src/assets'), }, extensions: ['.mjs', '.js', '.jsx', '.vue', '.json', '.wasm'], }, }Copy the code

In webpack. Base. Conf. Js modified the style file processing rules, the first in a production environment using MiniCssExtractPlugin. The loader to extract the CSS file to a separate CSS file, To add styles through style-loader, you need to wait until the JS file is loaded, and then add styles to the tags by manipulating DOM to generate style tags. So when js loads are blocked or the network is slow, styles don’t take effect in time and the page layout gets messy. Postcss-loader is then added before CSS-loader processing, which can be used to add browser prefixes to styles or use styles not yet supported by browsers, etc. There needs to be in the root directory new postcss. Config. Js, postcss default will be used under the root directory of the file as configuration items. Resolve is added in the shared configuration. Resolve. Alias is used to configure alias names for common paths. Resolve. extensions are used to ignore file suffixes, and WebPack attempts to resolve them in order of the defined resolve.extensions. If multiple files have the same file name but different suffixes, WebPack will use the file with the first suffix found in the array as the resolution object. The rest will be skipped.

Note: Process is a global variable in Node that provides information about the current process. Process. env returns an object containing information about the user’s environment. NODE_ENV is not a property of the env itself, but a custom property that is used to set and retrieve environment variables in front-end engineering. Cross-env is used to set environment variables in NPM command for compatibility with different platforms.

Module. exports = {plugins: [require('autoprefixer')],};Copy the code

With the shared configuration complete, let’s add the configuration for the development environment.

// build/webpack.dev.conf.js const { merge } = require('webpack-merge'); const webpackBaseConf = require('./wbepack.base.conf.js'); const webpackDevConf = { mode: 'development', devtool: 'eval-source-map', devServer: { hot: true, hotOnly: true, port: 8090, host: '0.0.0.0', overlay: true, proxy: {'/ API ': {target: 'http://localhost:3000', pathRewrite: {'^/ API ': ",},},},},},}; module.exports = merge(webpackBaseConf, webpackDevConf);Copy the code

In the development environment, we first set mode to development, and Webpack has built-in optimization for different modes. Then set devtool to eval-source-map, which controls whether and how the Source map is generated. Eval-source-map Each module executes using eval() and adds the source map to eval() after converting it to a DataUrl. Initializing the source map is slow, but it will provide speed when rebuilding and generate the actual file. It maps to the original code. It produces the best quality source map for the development environment.

The Source Map is an information file that stores location information. Used to map post-transformation code to the location of pre-transformation code.

Production environment:

// build/webpack.prod.conf.js const {merge} = require('webpack-merge'); const webpackBaseConf = require('./wbepack.base.conf.js'); const { CleanWebpackPlugin } = require('clean-webpack-plugin'); const UglifyJsPlugin = require('uglifyjs-webpack-plugin'); // js const CssMinimizerPlugin = require('css-minimizer-webpack-plugin'); // Save CSS const webpackProdConf = {mode: 'production', plugins: [new CleanWebpackPlugin()], optimization: {minimizer: [new UglifyJsPlugin({uglifyOptions: {UglifyJs: {// Does not output warnings when UglifyJs deletes code that is not used: false, compress: Collapse_vars {// Delete all 'console' statements, compatible with IE drop_console: true, // The inline variable collapse_vars is defined only once: Reduce_vars: true,}, output: {beautify: false, // Remove all comments: false, }, }, }), new CssMinimizerPlugin(), ], }, } module.exports = merge{webpackBaseConf,webpackProdConf};Copy the code

In the production environment, in addition to setting mode, clean-webpack-plugin was added to empty the dist file before executing the packing command. You also add the Optimization option, which configures some optimization options when compiling code. The optimization.minimizer option allows you to add one or more compression tools that override the default compression tool. It uses UglifyJS to compress code, remove comments, console, etc., through these options to reduce the size of JS code. CSS code compression uses the CSS MinimizerPlugin, which uses CSsnano to compress code.

By default, when executing the webpack command, the webpack.config.js file in the root directory of the project will be resolved as the webpack configuration option. If you want to specify the Webpack configuration file, use –config

{
 "scripts": {
 "serve": "cross-env NODE_ENV=development webpack serve --open --config build/webpack.dev.conf.js",
 "build": "cross-env NODE_ENV=production webpack --config build/webpack.dev.conf.js"
}
} 
Copy the code

Cross-env sets the NODE_ENV variable

The above is the common webpack in the project development, more can refer to the webpack official website.