1. Hot replacement of the module

Reference address – official website

1.1 enable HMR

Enabling this feature requires updating the configuration of Webpack-dev-server and using the built-in HMR plug-in for WebPack.

webpack.config.js

module.exports = {
    // ...
    devServer: {
        // ...
        hot: true}};Copy the code

worker.js

if (module.hot) {
  	module.hot.accept('./print.js'.function() {
        console.log('Accepting the updated printMe module! '); printMe(); })}Copy the code

Pay attention to the point

1.2 HMR modifies the stylesheet

CSS module hot update, with style-loader.

2. Tree shaking

See 1- official website, see 2- blog

2.1 sideEffects

  • falseAll file code has no side effects
  • Array, specifying file code is a side effect

A “side effect” is defined as code that performs special behavior when importing, rather than just exposing one or more exports. For example, polyfill, which affects the global scope, usually does not provide export. No tree Sharking with side effects!

Note that any imported files are affected by Tree shaking. This means that if you use a csS-loader like this in your project and import a CSS file, you need to add it to the Side Effect list to avoid accidentally removing it in production mode.

{
  "name": "your-project"."sideEffects": [
    "./src/some-side-effectful-file.js"."*.css"]}Copy the code

You can also set “sideEffects” in the Module. rules configuration option

2.2 Compressed Output

Starting with Webpack 4, it is also easy to switch to compressed output via the “mode” configuration option, simply set to “Production”.

webpack.config.js

module.exports = {
  // ...
  mode: "production"
};
Copy the code

2.3 Tree Sharking Conditions

  • Using ES2015 module syntax (i.eimportexport)
  • In the projectpackage.jsonFile, add onesideEffectsThe entrance
  • Introduce a minifier that can remove unreferenced dead code (e.gUglifyJSPluginWebpack4 can be set up at the beginningmode: "production"Instead of)

3. devtool

Reference – Official website

In production, when using uglifyjs-webpack-plugin, you must provide sourceMap: true to enable Source Map support.

You are encouraged to enable Source maps in production, as they are useful for debugging source code and running benchmark tests.

3.1 For the development environment

  • evalMap to transformed code
  • eval-source-mapThe number of lines will map correctly and will map to the original code.
  • cheap-eval-source-map– similar to theeval-source-map, used by each moduleeval()The execution. This is aCheap “source mapBecause it does not generate column mapping, it just ** maps the number of rows. It ignores the source map from the Loader, ** and only displays the translated code, as inevalDevtool.
  • cheap-module-eval-source-map– similar to thecheap-eval-source-mapAnd, in this case,The source map from the Loader gets better results. However, the Loader source map is simplified to one mapping per row.

3.2 For the production environment

These options are commonly used in production environments:

  • (None) (omits devtool option) – Does not generate source map. This is a good choice.

  • Source-map – The entire source map is generated as a single file. It adds a reference comment to the bundle so that development tools know where to find it.

    You should configure your server to not allow ordinary users to access the Source map file!

  • Hidden-source-map – same as source-map, but does not add a reference comment to the bundle. This option is useful if you only want the Source Map to map the error stack trace from the error report, but do not want to expose your Source map for browser development tools.

    You should not deploy the Source Map file to the Web server. Instead, use it only for error reporting tools.

  • Nosource-source-map – The source map created does not contain sourcesContent. It can be used to map stack traces on the client without exposing all the source code. You can deploy the Source Map file to the Web server.

    This still exposes the decompiled file name and structure, but it does not expose the original code.

3.3 Specific Scenarios

The following options are not ideal for both development and production environments. They are needed in specific scenarios, for example, for third-party tools.

  • inline-source-map– Source map is converted to DataUrl and added to the bundle.
  • cheap-source-map– If no column mapping source map is available, the loader source map is ignored.
  • inline-cheap-source-map– similar to thecheap-source-map, but the Source map is converted to the DataUrl and added to the bundle.
  • cheap-module-source-map– There is no column mapping source map and loader source map is simplified to one mapping for each row.
  • inline-cheap-module-source-map– similar to thecheap-module-source-mapBut the Source Mapp converts to the DataUrl and is added to the bundle.

4. Specify environment variables

Reference – Official website

4.1 Basic Usage

Many libraries will associate the process.env.node_env environment variable to determine what should be referenced in the library. For example, when not in production, some libraries may add additional logging and tests to make debugging easier. In fact, ** When using process.env.node_env === ‘production’, some libraries may optimize their code for user-specific environments to remove or add important code. ** We can define this variable for all dependencies using the DefinePlugin built into WebPack:

NODE_ENV attributes:

  1. This variable is not directly present in pocess. Env, but is set.
  2. You can distinguish between a development environment and a production environment by determining this variable.

webpack.prod.js

  const webpack = require('webpack');
  const merge = require('webpack-merge');
  const common = require('./webpack.common.js');

  module.exports = merge(common, {
    plugins: [
      new webpack.DefinePlugin({
        'process.env.NODE_ENV': JSON.stringify('production')]}}));Copy the code

Technically, NODE_ENV is a system environment variable exposed by Node.js to execute scripts. Typically used to determine the behavior of server tools, build scripts, and client libraries in development vs. production (dev-VS-PROd) environments. However, contrary to expectations, process.env.node_env cannot be set to “production” in the build script webpack.config.js, see #2537.

For example,process.env.NODE_ENV === 'production' ? '[name].[hash].bundle.js' : '[name].bundle.js'Such conditional statements, in the WebPack configuration file, do not work as expected.

Any native code at/SRC can be associated with the process.env.node_env environment variable, so the following checks are also valid:

src/worker.js

  import { cube } from './math.js';

  if(process.env.NODE_ENV ! = ='production') {
    console.log('Looks like we are in development mode! ');
  }
Copy the code

4.2 is it?

Why does webpack website say:

process.env.NODE_ENV === ‘production’ ? Conditional statements like ‘[name].[hash].bundle.js’ : ‘[name].bundle.js’ do not work as expected in webPack configuration files.

However, the MiniCssExtractPlugin website can be used as follows:

constdevMode = process.env.NODE_ENV ! = ='production'
Copy the code

4.3 to reassure

Reference – netizen blog

  1. In its initial state”The configuration file ” 和 ” SRC file below“The output ofprocess.env.NODE_ENVValues areundefined.
  2. The variables defined in the WebPack Config file are for the files you will be packaging. The configuration is as follows:
/ / way
new webpack.DefinePlugin({
    'process.env.NODE_ENV': JSON.stringify('production')})2 / / way
{
    mode: 'production'
}
Copy the code

If only NODE_ENV is set, mode is automatically set.

  1. How to inwebpackObtained from the configuration fileNODE_ENVWe can define the related parameters according to the different values.corss-env, add the following configuration to package.json:
"scripts": {
    "build-cross-env":"cross-env NODE_ENV=production webpack"
}
Copy the code

With cross-env NODE_ENV=production, the information is passed to the webpack configuration file, which is not accessible below SRC.

5. Code separation

Reference – Official website

5.1 an overview of the

Separate the code into different bundles, and you can load these files on demand or in parallel. Code separation can be used to obtain smaller bundles and control resource load priorities, which, when used properly, can greatly affect load times.

There are three common ways to separate code:

  • Entry starting point: Manually detach code using the Entry configuration.
  • Prevent duplication: Use CommonsChunkPlugin to deduplicate and separate chunks.
  • Dynamic import: Separation of code through inline function calls to modules.

5.2 Dynamic Imports

Webpack provides two similar techniques when it comes to dynamic code splitting. For dynamic imports, the first and preferred approach is to use the import() syntax that conforms to the ECMAScript proposal. The second is to use webpack-specific require.ensure. Let’s try the first one…

Import () calls will use promises internally. If you use import() in older browsers, remember to use a polyfill library (such as ES6-Promise or promise-polyfill) to shim promises.

worker.js

/ / way
const _ = await import(/* webpackChunkName: "lodash" */ 'lodash');

2 / / way
import(/* webpackChunkName: "print" */ './print').then(module= > {
      var print = module.default;
      print();
});
Copy the code

Note that when the IMPORT () method of the ES6 module is called (importing the module), it must point to the module’s.default value, as ** is the actual Module object * returned after the promise is processed. *

webpack.config.js

output: {
    filename: '[name].bundle.js'.chunkFilename: '[name].bundle.js'.path: path.resolve(__dirname, 'dist')}Copy the code

5.3 bundle analysis

Reference – official website

6. The cache

6.1 Differences between Hash, Chunkhash, and Contenthash

Reference – netizen blog

hash

Relative to the entire WebPack build project, the hash value is different each time the project builds, even if the project file has not made ** “any changes” **.

There are changes, because every webPack compilation injects the Webpack runtime code, causing the entire project to change, so the hash value changes every time.

chunkhash

** According to different Entry files, dependency files are parsed, corresponding chunks are constructed, and corresponding hash values are generated. ** In the production environment, separate some public libraries from the program entry files, package them separately, and use chunkhash to generate hash values, so as long as the code of the public library is not changed, the hash value can be guaranteed not to be affected.

After using chunkhash for CSS, it shares chunkhash with the chunk that depends on it. After testing, it will be found that the CSS and JS file name have the same value of chunkhash. Js and CSS interact with each other.

Contenthash is best used for CSS files.

contenthash

Contenthash indicates the hash value generated by the file content. The contenthash value varies with the content.

6.2 Image/font cache

For static resources such as images and fonts, the corresponding file hash value is calculated by the corresponding file-loader.

So what hash values are used for these static files?

It’s the hash property value. This hash is not a webpack-built hash for each project, it is calculated by file-loader from the contents of the file, not a Webpack-built hash.

7. Webpack configuration Types

Reference – Official website

7.1 Export as a function

 module.exports = function(env, argv) {
   return {
     mode: env.production ? 'production' : 'development'.devtool: env.production ? 'source-maps' : 'eval'.plugins: [
       new webpack.optimize.UglifyJsPlugin({
         compress: argv['optimize-minimize'] // It can only be passed -p or --optimize-minimize}})]; };Copy the code

When a WebPack configuration object is exported as a function, an “environment object” can be passed up. It can also be configured using cross-env NODE_ENV=production webpack” in [Specifying environment variables](#4. Specifying environment variables)

webpack --env.NODE_ENV=local --env.production --progress
Copy the code

Production sets –env.production to true by default if the env variable is set and no value is assigned. There are other syntaxes you can use. See the Webpack CLI documentation for more information.

7.2 Exporting a Promise

Webpack will run the functions exported from the configuration file and wait for the Promise to return. Facilitate the need to load the required configuration variables asynchronously.

module.exports = (a)= > {
  return new Promise((resolve, reject) = > {
    setTimeout((a)= > {
      resolve({
        entry: './app.js'./ *... * /})},5000)})}Copy the code

7.3 Exporting a Configuration Object

7.4 Exporting Arrays, Multiple configuration objects

8. Webpack-dev-server refresh mode inline and iframe details

Reference – Blog

iframe

  1. Embedded one in the web pageiframeTo inject our own application into thisiframe.
  2. There is a prompt box at the top of the page that displays status information about the build process.
  3. To load thelive.bundle.jsThe file is not only creatediframeThe tag also containssocket.iotheclientCode to andwebpack-dev-serverforwebsocketCommunication, so as to complete automatic compilation packaging, page automatic refresh function.

inline

  1. The build message is displayed in the browser console.
  2. socket.iotheclientThe code is packaged into your package (bundle), in order towebpack-dev-serverforwebsocketCommunication, so as to complete automatic compilation packaging, page automatic refresh function.
  3. However, each entry file will be inserted into one of the above scripts to make the packagedbundleThe files are bloated.

conclusion

  1. Iframe modeandInline modeThe final effect is the same, are listening to the file changes, and then push the compiled file to the front end, complete the pagereload.
  2. By setting thedevServer.inlineSwitch between two modes. The default value isinlineMode.
  3. This parameter is recommended when using the HMR functioninline mode.

Mode of 9.

Reference – Official website

Remember that setting only NODE_ENV does not automatically set mode.

9.1 usage

Only provide the mode option in the configuration:

module.exports = {
  mode: 'production'
};
Copy the code

Or from the CLI parameter:

webpack --mode=production
Copy the code

9.2 production

The value of process.env.node_env is set to production. Enable FlagDependencyUsagePlugin FlagIncludedChunksPlugin, ModuleConcatenationPlugin NoEmitOnErrorsPlugin, OccurrenceOrderPlugin SideEffectsFlagPlugin and UglifyJsPlugin.

mode: production

// webpack.production.config.js
module.exports = {
+  mode: 'production',
-  plugins: [
-    new UglifyJsPlugin(/ *... * /),
-    new webpack.DefinePlugin({ "process.env.NODE_ENV": JSON.stringify("production")}), -new webpack.optimize.ModuleConcatenationPlugin(),
-    new webpack.NoEmitOnErrorsPlugin()
-  ]
}
Copy the code

9.3 development

The value of process.env.node_env is set to development. Enable NamedChunksPlugin and NamedModulesPlugin.

mode: development

// webpack.development.config.js
module.exports = {
+ mode: 'development'
- plugins: [
-   new webpack.NamedModulesPlugin(),
-   new webpack.DefinePlugin({ "process.env.NODE_ENV": JSON.stringify("development")}), -]}Copy the code

10. output

10.1 the output. The library

For general-purpose libraries, we want it to be compatible with different environments, such as CommonJS, AMD, Node.js or as a global variable. To make your library usable in all consumption environments, add the Library attribute to output.

To make the Library compatible with other environments, you also need to add the libraryTarget attribute to the configuration file. This is the option to control how the library is exposed in different ways. The default option for output.libraryTarget is var.

  output: {
      path: path.resolve(__dirname, 'dist'),
      filename: 'webpack-numbers.js'.library: 'webpackNumbers'
      library: 'webpackNumbers'.libraryTarget: 'umd'
    },
Copy the code

10.2 the output. PublicPath and devServer. PublicPath

PublicPath and devServer.publicPath

The purpose of devServer.publicPath is to determine what path external users can use to access files built in memory through devServer. The explicit value of the output.publicPath field is used (if output.publicPath has a value, its default value is used otherwise). The purpose of output.publicPath is to generate a prefix for a built file that meets specific requirements and provide this prefix to the required resolver, plugin, or other configuration fields.

Filename in HtmlWebpackPlugin also depends on public.publicPath

See the blog – you’ll be sure to read the meaning of devServer.publicPath, output.publicPath, and output.path

10.3 the output path

This field only works in the production configuration. If you try it out, you’ll see that in the development configuration, no matter what value you set it to (it must be a compliant absolute address), it won’t affect your access to the files built in memory at development time. So in the development configuration, just ignore it. Also, its default value is’ path.resolve(__dirname, ‘./dist’).

11. webpack.optimize.ModuleConcatenationPlugin

New in Webpack 3: Scope collieries

In the past, one of the trade-offs in Webpack packaging was to package each module in the bundle individually into a closure. These packaging functions make your JavaScript process more slowly in the browser. In contrast, tools like Closure Compiler and RollupJS can hoist or precompile all modules into a Closure, speeding up your code execution in the browser. This plugin implements the above precompiled functionality in Webpack.

12. devServer

The files devServer builds are in memory, not on your computer’s disk, but if the desired file is not found in memory, devServer will try to find it on your computer’s disk based on the path of the file.

If a file with the same file name exists in the real disk path under memory and contentBase at the time of development, devServer returns the one in memory

12.1 devServer.historyApiFallback

 historyApiFallback: {
     rewrites: [{from: /. * /.to: path.posix.join(devConfig.assetsPublicPath, 'index.html')},],},Copy the code

When using the HTML5 History API, any 404 response may need to be replaced with index.html. Enable by passing in the following:

historyApiFallback: true
Copy the code

This behavior can be further controlled by passing in an object, such as using the rewrites option:

historyApiFallback: {
  rewrites: [{from: $/ / ^ \ /.to: '/views/landing.html' },
    { from: /^\/subpage/.to: '/views/subpage.html' },
    { from: / /..to: '/views/404.html'}}]Copy the code

12.2 devServer.publicPath

Determines the path through which the built file can be accessed externally.

[查看](#10.2 output.publicPath and devserver. publicPath)

13. Vue-cli common configurations

Reference – Blog

13.1. Babelrc file

This file is placed under the root directory to set transcoding rules. For example, to use ES6 in your code, configure “presets”: [” ES2015 “] in this file. Plugins: [” transform-Runtime “, “transform-vue-jsx”]. Plugins: [“transform-runtime”, “transform-vue-jsx”]

13.2. Editorconfig file

This file configures the encoding style of the editor

EditorConfig Introduction – Blogs

13.3 .eslintrc

Reference – Blog

Configuration ESLint

ESLint can be configured in one of three ways:

  • Use.eslintrc files (JSON and YAML syntax supported);
  • Add an eslintConfig config block to package.json;
  • Defined directly in the code file.

An example.eslintrc file:

{
  "env": {
    "browser": true,},"globals": {
    "angular": true,},"rules": {
    "camelcase": 2."curly": 2."brace-style": [2."1tbs"]."quotes": [2."single"]."semi": [2."always"]."space-in-brackets": [2."never"]."space-infix-ops": 2,}}Copy the code

In the project root directory, it will be applied to the entire project; If the subdirectory also contains an.eslintrc file, the subdirectory ignores the configuration file in the root directory and applies the configuration file in that directory. This makes it easy to apply different rules to code in different environments.

13.4. Eslintignore file

If you want to introduce tripartite JS libraries that do not conform to the ESLint specification, you can omit them in this file, for example:

build/*.js
config/*.js
static
Copy the code

13.5. Gitignore file

This file is used to configure files that do not need to be added to version management, for example:

.DS_Store
node_modules/
npm-debug.log
test/unit/coverage
test/e2e/reports
selenium-debug.log
.idea
/clear
/src/modules/cache.js
Copy the code

13.6 .browserslist

Reference – Blog

NPM address – official website

The configuration of the target browser and Node.js version is shared between different front-end tools.

Method of use

(1) Package. json (recommended)

{
  "browserslist": [
    "last 1 version"."1%" >."maintained node versions"."not dead"]}Copy the code

(2) .browserslistrc

# Browsers that we support

last 1 version
> 1%
maintained node versions
not dead
Copy the code

Browserslist’s data comes from Can I Use. You can use online Demo if you want to know the query result of configuration statement

13.7. Postcssrc. Js

Reference – Official website

It is one of many configuration methods

module.exports = {
  "plugins": {
    "postcss-import": {},
    "postcss-url": {},
    // to edit target browsers: use "browserslist" field in package.json
    "autoprefixer": {}}}Copy the code

14. eslint

Reference – Chinese official website

15. Watch and watchOption

Reference – webpack

Watch mode is enabled by default in Webpack-dev-server and Webpack-dev-Middleware.

16. SplitChunksPlugin

See 1- Webpack – English

Reference 2- Blog – Chinese

The default configuration is our recommended Web best practice, but the optimal strategy for your project may vary depending on the type of project

By default, all modules from node_modules are assigned to the cache group called venders, and all modules referenced more than twice are assigned to the default cache group.