zoukankan      html  css  js  c++  java
  • 655 webpack的Tree Shaking、Scope Hoisting:usedExports,sideEffects,CSS实现Tree Shaking,PurgeCss

    什么是Tree Shaking


    webpack实现Tree Shaking


    usedExports


    sideEffects


    Webpack中tree shaking的设置


    CSS实现Tree Shaking

    • cnpm install purgecss-webpack-plugin -D


    配置PurgeCss


    Scope Hoisting


    目录结构


    main.js

    import { sum } from './math';
    
    // 【有副作用的模块不会删除,没有的会删除。有副作用:就是对整个项目代码有影响。】
    // 【没有写在sideEffects的数组中的,就是没有副作用,会被删除。】
    import "./format";
    import("./abc").then(res => {
      
    });
    import "./style.css";
    
    console.log(sum(20, 30));
    
    console.log(window.abc);
    

    package.json

    {
      "name": "webpack_devserver",
      "sideEffects": false,
      "version": "1.0.0",
      "description": "",
      "main": "index.js",
      "scripts": {
        "build": "webpack --config ./config/webpack.common.js --env production",
        "serve": "webpack serve --config ./config/webpack.common.js --env development"
      },
      "author": "",
      "license": "ISC",
      "devDependencies": {
        "@babel/core": "^7.12.17",
        "@babel/preset-env": "^7.12.17",
        "@babel/preset-react": "^7.12.13",
        "@pmmmwh/react-refresh-webpack-plugin": "^0.4.3",
        "babel-loader": "^8.2.2",
        "clean-webpack-plugin": "^3.0.0",
        "css-loader": "^5.0.2",
        "css-minimizer-webpack-plugin": "^1.2.0",
        "html-webpack-plugin": "^5.2.0",
        "mini-css-extract-plugin": "^1.3.9",
        "purgecss-webpack-plugin": "^4.0.2",
        "react-refresh": "^0.9.0",
        "style-loader": "^2.0.0",
        "vue-loader": "^15.9.6",
        "vue-template-compiler": "^2.6.12",
        "webpack": "^5.23.0",
        "webpack-cli": "^4.5.0",
        "webpack-dev-server": "^3.11.2",
        "webpack-merge": "^5.7.3"
      },
      "dependencies": {
        "axios": "^0.21.1",
        "dayjs": "^1.10.4",
        "express": "^4.17.1",
        "lodash": "^4.17.21",
        "react": "^17.0.1",
        "react-dom": "^17.0.1",
        "react-router-dom": "^5.2.0",
        "terser": "^5.6.0",
        "vue": "^2.6.12",
        "webpack-dev-middleware": "^4.1.0"
      }
    }
    

    webpack.common.js

    const resolveApp = require("./paths");
    const HtmlWebpackPlugin = require("html-webpack-plugin");
    const VueLoaderPlugin = require("vue-loader/lib/plugin");
    const TerserPlugin = require("terser-webpack-plugin");
    const MiniCssExtractPlugin = require('mini-css-extract-plugin');
    const webpack = require('webpack');
    
    const { merge } = require("webpack-merge");
    
    const prodConfig = require("./webpack.prod");
    const devConfig = require("./webpack.dev");
    
    const commonConfig = (isProduction) => {
      return {
        entry: {
          main: "./src/main.js",
          // index: "./src/index.js"
        },
        output: {
          path: resolveApp("./build"),
          filename: "js/[name].[chunkhash:6].bundle.js",
          chunkFilename: "js/[name].[contenthash:6].chunk.js",
          publicPath: ""
        },
        resolve: {
          extensions: [".wasm", ".mjs", ".js", ".json", ".jsx", ".ts", ".vue"],
          alias: {
            "@": resolveApp("./src"),
            pages: resolveApp("./src/pages"),
          },
        },
        optimization: {
          // 对代码进行压缩相关的操作
          // natural: 使用自然数(不推荐),
          // named: 使用包所在目录作为name(在开发环境推荐)
          // deterministic: 生成id, 针对相同文件生成的id是不变
          // chunkIds: "deterministic",
          splitChunks: {
            // async异步导入
            // initial同步导入
            // all 异步/同步导入
            chunks: "all",
            // 最小尺寸: 如果拆分出来一个, 那么拆分出来的这个包的大小最小为minSize
            minSize: 20000,
            // 将大于maxSize的包, 拆分成不小于minSize的包
            maxSize: 20000,
            // minChunks表示引入的包, 至少被导入了几次
            minChunks: 1,
            cacheGroups: {
              vendor: {
                test: /[\/]node_modules[\/]/,
                filename: "js/[id]_vendors.js",
                // name: "vendor-chunks.js",
                priority: -10
              },
              // bar: {
              //   test: /bar_/,
              //   filename: "[id]_bar.js"
              // }
              default: {
                minChunks: 2,
                filename: "common_[id].js",
                priority: -20
              }
            }
          },
          // true/multiple
          // single
          // object: name
          // runtimeChunk: {
          //   name: function(entrypoint) {
          //     return `why-${entrypoint.name}`
          //   }
          // }
        },
        module: {
          rules: [
            {
              test: /.jsx?$/i,
              use: "babel-loader",
            },
            {
              test: /.vue$/i,
              use: "vue-loader",
            },
            {
              test: /.css/i,
              // style-lodader -> development
              use: [
                isProduction ? MiniCssExtractPlugin.loader : "style-loader",
                "css-loader"
              ],
              // 【有副作用的模块不会删除,没有的会删除。有副作用:就是对整个项目代码有影响】
              // 【没有写在sideEffects的数组中的,就是没有副作用,会被删除。】
              // 只要是匹配到css文件,就是有副作用的,都不删除
              sideEffects: true // react 脚手架中
            },
          ],
        },
        plugins: [
          new HtmlWebpackPlugin({
            template: "./index.html",
          }),
          new VueLoaderPlugin(),
          // 当在代码中遇到某一个变量找不到时, 我们会通过ProvidePlugin, 自动导入对应的库
          // new webpack.ProvidePlugin({
          //   axios: "axios",
          //   get: ["axios", "get"]
          // })
        ],
      };
    }
    
    module.exports = function (env) {
      const isProduction = env.production;
      process.env.NODE_ENV = isProduction ? "production" : "development";
    
      const config = isProduction ? prodConfig : devConfig;
      const mergeConfig = merge(commonConfig(isProduction), config);
    
      return mergeConfig;
    };
    

    webpack.prod.js

    const { CleanWebpackPlugin } = require('clean-webpack-plugin');
    const MiniCssExtractPlugin = require('mini-css-extract-plugin');
    const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
    const TerserPlugin = require('terser-webpack-plugin');
    const PurgeCssPlugin = require('purgecss-webpack-plugin');
    const webpack = require('webpack');
    const glob = require('glob');
    
    const resolveApp = require('./paths');
    
    const isProduction = true;
    
    module.exports = {
      mode: "development",
      devtool: "source-map",
      externals: {
        lodash: "_",
        dayjs: "dayjs"
      },
      optimization: {
        // 【usedExports:做tree shaking,设置为true,要和minimize、Terser配合使用。】
        // usedExports: 目的是标注出来哪些函数是没有被使用 unused 
        usedExports: true, // production模式下默认就是true
        minimize: true,
        minimizer: [
          // 由Terser将未使用的函数, 从我们的代码中删除
          new TerserPlugin({
            parallel: true,
            extractComments: false,
            terserOptions: {
              compress: {
                arguments: false,
                dead_code: true
              },
              mangle: true,
              toplevel: true,
              keep_classnames: true,
              keep_fnames: true
            }
          })
        ]
      },
      plugins: [
        // 生成环境
        new CleanWebpackPlugin({}),
        new MiniCssExtractPlugin({
          filename: "css/[name].[contenthash:6].css"
        }),
        new CssMinimizerPlugin(),
        // 【Scope Hoisting:对作用域进行提升】
        new webpack.optimize.ModuleConcatenationPlugin(),
        // purge: 清除
        new PurgeCssPlugin({
          // 写绝对路径,所有文件夹里的所有文件,不是文件夹,注意是paths,有s
          paths: glob.sync(`${resolveApp("./src")}/**/*`, {nodir: true}),
          // 白名单
          safelist: function() {
            return {
              standard: ["body", "html"]
            }
          }
        })
      ]
    }
    

    webpack.dev.js

    const { CleanWebpackPlugin } = require('clean-webpack-plugin');
    const MiniCssExtractPlugin = require('mini-css-extract-plugin');
    const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
    const TerserPlugin = require('terser-webpack-plugin');
    const PurgeCssPlugin = require('purgecss-webpack-plugin');
    const webpack = require('webpack');
    const glob = require('glob');
    
    const resolveApp = require('./paths');
    
    const isProduction = true;
    
    module.exports = {
      mode: "development",
      devtool: "source-map",
      externals: {
        lodash: "_",
        dayjs: "dayjs"
      },
      optimization: {
        // 【usedExports:做tree shaking,设置为true,要和minimize、Terser配合使用。】
        // usedExports: 目的是标注出来哪些函数是没有被使用 unused 
        usedExports: true, // production模式下默认就是true
        minimize: true,
        minimizer: [
          // 由Terser将未使用的函数, 从我们的代码中删除
          new TerserPlugin({
            parallel: true,
            extractComments: false,
            terserOptions: {
              compress: {
                arguments: false,
                dead_code: true
              },
              mangle: true,
              toplevel: true,
              keep_classnames: true,
              keep_fnames: true
            }
          })
        ]
      },
      plugins: [
        // 生成环境
        new CleanWebpackPlugin({}),
        new MiniCssExtractPlugin({
          filename: "css/[name].[contenthash:6].css"
        }),
        new CssMinimizerPlugin(),
        // 【Scope Hoisting:对作用域进行提升】
        new webpack.optimize.ModuleConcatenationPlugin(),
        // purge: 清除
        new PurgeCssPlugin({
          // 写绝对路径,所有文件夹里的所有文件,不是文件夹,注意是paths,有s
          paths: glob.sync(`${resolveApp("./src")}/**/*`, {nodir: true}),
          // 白名单
          safelist: function() {
            return {
              standard: ["body", "html"]
            }
          }
        })
      ]
    }
    

  • 相关阅读:
    1.Python进阶 词典dict
    10.Python基础 反过头来看看
    test
    地图添加标记物 并添加点击弹出框
    百度地图里面添加覆盖物的事件显示最后一个?
    css3之animation制作闪烁文字效果 转
    ajax beforeSend中无效果
    jquery 中 $('div','li')是什么意思?
    SQL 单引号转义
    jQuery 遍历
  • 原文地址:https://www.cnblogs.com/jianjie/p/14551770.html
Copyright © 2011-2022 走看看