This is the second day of my participation in the August More Text Challenge

Found a piece of xiang elder brother’s photo, to the Olympic athletes cheer up!! 🤞

Get to the point! Get to the point!

1. Automatically clear the build directory

  • Avoid repeatedly removing dist files manually or by command
plugins: [
    new MiniCssExtractPlugin({
      filename: "[name]_[contenthash:8].css",}).new OptimizeCss({
      assetNameRegExp: /\.css$/g,
      cssProcessor: require("cssnano"),}),// Deletes the output directory specified by output by default
    new CleanWebpackPlugin(),
  ]
Copy the code

2. Inline resources

  • The code level
    • Initialization script for the page frame
    • Report relevant measures
    • The CSS is inlined to avoid page flashing
  • Request layer: Reduce HTTP network requests
    • Inlining small images or fonts (URL-load)
<head>
  // raw-loader inlines HTML
  // Use version 0.5.1< % =require('raw-loader! ./meta.html') % ><title>Document</title>
  // raw-loader inline js
  <script>< % =require('raw-loader! babel-loader! . /.. /node_modules/lib-flexible/flexible.js') % ></script>
</head>
cs
Copy the code

3. Package multi-page applications

  • Page decoupling
  • Be more SEO friendly
  • You do not need to add or delete a page
const glob = require("glob");
const HtmlWebpackPlugin = require("html-webpack-plugin");

const setMPA = () = > {
  const entry = {};
  const htmlWebpackPlugin = [];
  EntryFiles is an array of directories for entryFiles
  const entryFiles = glob.sync(path.join(__dirname, "./src/*/index.js"));

  Object.keys(entryFiles).map((index) = > {
    const entryFile = entryFiles[index];
    // Regex matches
    const match = entryFile.match(/src\/(.*)\/index\.js/);
    const pageName = match && match[1];
    entry[pageName] = entryFile;
    htmlWebpackPlugin.push(
      new HtmlWebpackPlugin({
        template: path.join(__dirname, `src/${pageName}/index.html`),
        filename: `${pageName}.html`.// The packaged JS CSS files are automatically injected into HTML
        inject: true.// Which chunk is used for the generated HTML
        chunks: [pageName],
        minify: {
          html5: true.collapseWhitespace: true.preserveLineBreaks: false.minifyCSS: true.minifyJS: true.removeComments: false,}})); });return {
    entry,
    htmlWebpackPlugin,
  };
};
const { entry, htmlWebpackPlugin } = setMPA();

module.exports = {
  entry: entry, // Single-entry string multi-entry for object key-value pair writing
  plugins: [].concat(htmlWebpackPlugin),
};

Copy the code

4. sourcemap

  • Locate the source code by sourcemap
  • The development environment is on, the online environment is off
    • You can upload Sourcemap to the error monitoring system when troubleshooting problems online
    • The popular science links: www.ruanyifeng.com/blog/2013/0…
  • Source map keyword
    • Eval: Wrap code blocks in eval
    • Source map: generates a. Map file
    • Cheap: Does not contain column information
    • Inline: inserts. Map as a DataURL, does not generate a separate map file
    • Module: includes sourcemap of loader

// Follow up
devtool:'source-map'
Copy the code

5. Extract page public resources

  • Base library separation CDN introduction
  const HtmlWebpackExternalPlugin = require("html-webpack-externals-plugin");
    
  plugins: [
    new HtmlWebpackExternalPlugin({
      externals: [{module: "react".entry: "https://unpkg.com/react@16/umd/react.production.min.js".global: "React"}, {module: "react-dom".entry:
            "https://unpkg.com/react-dom@16/umd/react-dom.production.min.js".global: "ReactDOM",},],}),]Copy the code
  • splitChunksPlugin
    • Webpack4 built-in
    • Chunks Parameter Description
      • Async: separation of libraries introduced asynchronously (default)
      • Initial: Synchronizes the imported libraries for separation
      • All: Separation of all imported libraries (recommended)
    • Webpack address: webpack.docschina.org/plugins/spl…
module.exports = {
  / /...
  optimization: {
    splitChunks: {
      chunks: 'async'.// Remove the minimum volume of the public package
      minSize: 20000.minRemainingSize: 0.// The number of uses
      minChunks: 1.// The number of asynchronous resources requested by the browser
      maxAsyncRequests: 30.maxInitialRequests: 30.enforceSizeThreshold: 50000.cacheGroups: {
         commons: {
          test: /(react|react-dom)/.// Name is to be used synchronously on chunks of htmlWebpackPlugin
          name: "vendors".chunks: "all",},default: {
          minChunks: 2.priority: -20.reuseExistingChunk: true,},},},},};/ / use
 htmlWebpackPlugin.push(
  new HtmlWebpackPlugin({
    template: path.join(__dirname, `src/${pageName}/index.html`),
    filename: `${pageName}.html`.// The packaged JS CSS files are automatically injected into HTML
    inject: true.// Which chunk is used for the generated HTML
    // For the name above
    chunks: [pageName, 'vendors'].minify: {
      html5: true.collapseWhitespace: true.preserveLineBreaks: false.minifyCSS: true.minifyJS: true.removeComments: false,}}));Copy the code

6. Tree shaking

  • Modules may have multiple methods, and only the methods that are used are packaged into the bundle. Tree shaking puts only used methods into the bundle, and not used methods are erased during the Uglify phase
  • Webpack4 is supported by default,
  • Mode: Production is enabled by default
  • Requirement: must be es6 syntax, CJS mode is not supported (dynamic import)
  • Tree shaking fails when code is written with side effects

DCE(Elimination)

  • Code will not be executed, not reachable
  • Code execution results are not used
  • The code only affects dead variables (write, not read)

Tree shaking

  • Use es6 module features
    • Can only be a statement at the top level of a module
    • The module name of import can only be a string variable
    • Import binding is immutable
  • Code erasure
    • The Uglify phase removes useless code

7. scope hoisting

The phenomenon of

  • There is a lot of closure code after the build

Lead to problems

  • A large number of function closures wrap code, resulting in an increase in size (the more modules, the more obvious)
  • Running code creates functions with more scope and more memory overhead

Module transformation analysis

conclusion

  • Modules transformed by WebPack are wrapped in a layer
  • Import will be converted to _webpack_require

Further analyze the module mechanism of Webpack

Scope collieries

  • Place all module code in a function scope in reference order, and then rename some variables appropriately to prevent variable name conflicts
  • Reduce function declaration code and memory overhead
  • Webpack4-production is supported by default
  • Requirement: must be es6 syntax, CJS mode is not supported (dynamic import)

8. Code segmentation

meaning

  • For large Web applications, having all of your code in one file is obviously not efficient, especially if your code modules will be used at specific times. Webpack has a feature that breaks your code into chunks and loads them when they are needed

Applicable Scenarios

  • Pull the same code into a shared block
  • The script loads lazily, making the initial download smaller

Lazy way to load JS scripts

  • CommonJS: require.ensure
  • ES6: Dynamic import (no native support yet, Babel conversion required)
/ /. Babelrc file
{
    "plugins": ["@babel/plugin-syntax-dynamic-import"]}/ / index. Js file
  loadComponent = () = > {
    import("./text.js").then((Text) = > {
      this.setState({
        Text: Text.default,
      });
    });
  };
  // loadComponent executes when text.js loads
  // import("./text.js") is a promise object
Copy the code

9.ESLint

Follow the Rules (Suggestions)

  • Don’t duplicate wheels, based on ESLint: Recommend configuration and improved
  • Enable all rules that help you find code errors
  • Helps keep the team’s code style consistent, rather than limiting the development experience

ESLint implementation lands

  • Integration with CI/CD systems

  • And webpack integration
    • Use eslint – loader
rules: [
      {
        test: /.js$/.// include: path.resolve("src"),
        use: [
          / / {
          // loader: "thread-loader",
          // options: {
          // // Three processes
          // workers: 3,
          / /},
          // },
          "babel-loader".// "happypack/loader",
          "eslint-loader"].exclude: /node_modules/,},]// Create a.eslintrc.js file

module.exports = {
  // Specify the parser
  "parser": "babel-eslint".// Inherit multiple array writes to the installed frame
  "extends": "airbnb".// Custom rules
  "rules": {
      "semi": "error"
  },
  // The effective environment
  "env": {
    "browser": true."node": true}}// For details, see the esLint website https://eslint.org/
Copy the code