关于webpack:从零配置一个前端开发环境webpack优化

4次阅读

共计 4736 个字符,预计需要花费 12 分钟才能阅读完成。

前端开发开发环境系列文章的 github 在这, 如果您在看的过程中发现了什么有余和谬误,感谢您能指出!

作为一个前端开发,Webpack 肯定不生疏,在前端这一畛域,大多数的我的项目应该都是用 webpack 作为一个模块打包工具。然而当我的项目的规模变大后,应该都或多或少的遇到了性能相干的问题。

而以 webpack 作为工具,则能够将性能分为两种:

  1. 构建速度
  2. 页面加载速度

以这两个为目标,对咱们的我的项目进行优化。

尽量应用高版本的 webpack 和 node

Webpack 和 Node 每次一大版本的更新都会随同着性能优化,这是最间接显著的

speed-measure-webpack-plugin

该插件的作用就是剖析 loader 和 plugin 的打包速度,针对信息定制优化计划

装置 yarn add speed-measure-webpack-plugin -D

webpack.config.js

const SpeedMeasureWebpackPlugin = require('speed-measure-webpack-plugin')
const swp = new SpeedMeasureWebpackPlugin()

module.exports = swp.wrap(yourConfig);

webpack-bundle-analyzer

剖析打包模块体积

多线程进行 TypeScript 的类型查看

在我的项目中应用了 ts-loader 后,我的项目中 ts 文件的类型查看会十分的耗时。所以咱们通过 ts-loader 的配置敞开类型查看,并是应用 fork-ts-checker-webpack-plugin 在别的线程查看。这会大大减少 webpack 的编译工夫。

yarn add fork-ts-checker-webpack-plugin -D

module.exports = {
    module: {
        rules: [
            {test: /\.ts(x)?$/,
                use: [
                {
                    loader: 'ts-loader',
                    options: {
                    // 敞开类型查看,即只进行转译
                    // 类型查看交给 fork-ts-checker-webpack-plugin 在别的的线程中做
                    transpileOnly: true,
                    },
                },
                ],
                exclude: /node_modules/,
            },
        ]
    },

    plugins: [new ForkTsCheckerWebpackPlugin(),
    ]
}

预编译资源模块(该计划在 webpack4 之后,优化成果就不是很显著了)

应用 webpack 官网的 DllPlugin 进行分包

  • 思路:将一些根底且比较稳定的包打包成一个文件,如 react、react-dom、redux、react-redux
  • 办法:DLLPlugin 分包,DllReferencePlugin 对 manifest.json 援用。援用 manifest.json 会主动关联 DllPulugin 中的包

这须要一个独自的 webpack.dll.js 配置文件

const path = require('path');
const webpack = require('webpack');

module.exports = {
  mode: 'development',
  resolve: {extensions: ['.js', '.jsx', '.json', '.less', '.css'],
    modules: [__dirname, 'node_modules']
  },
  entry: {
    // 制订须要拆散的包
    react: ['react', 'react-dom', 'redux', 'react-redux'],
  },
  output: {filename: '[name].dll.js',
    path: path.join(__dirname, 'dll/'),
    library: '[name]_[fullhash]',
  },
  plugins: [
    new webpack.DllPlugin({name: '[name]_[fullhash]',
      path: path.join(__dirname, 'dll', 'manifest.json'),
    }),
  ],
};

在根目录创立一个 dll 目录,而后运行 webpack --config webpack.dll.js,将一些根底包提前编译进去,dll 目录下会有 manifest.json react.dll.js 两个文件

而后在次要的 webpack 配置中援用

须要装置一个插件将 dll 文件导入到 html 中
yarn add add-asset-html-webpack-plugin -D

module.exports = {
    plugins: [
        // 将预编译的公共库导入到 html 中
        new AddAssetHtmlPlugin({filepath: require.resolve('./dll/react.dll.js') }),
        // webpack4 之后 dllPlugin 对性能的晋升就不大了
        new webpack.DllReferencePlugin({
            context: __dirname,
            // manifest.json 就是对咱们要引入包的形容
            manifest: require('./dll/manifest.json'),
        }),
    ],
}

多过程并行压缩 js 代码, css 代码压缩

module.exports = {

  optimization: {
    minimize: true,
    minimizer: [
        // js 压缩
        new TerserPlugin({parallel: 4 // 默认为以后电脑 cpu 的两倍 os.cpus().length - 1
        })
        // css 压缩
        new CssMinimizerPlugin(),]
  }
}

放大构建指标

目标:尽可能的少构建模块

比方 babel-loader 不解析 node_modules

优化 resolve.modules 配置(缩小模块搜寻层级)

优化 resolve.mainFields 配置

优化 resolve.extensions 配置

正当应用 alias

应用 tree shaking 擦除无用的 js 和 css

webpack 中,只有应用的是 es6 的语法,默认都会对 js 代码进行 tree shaking

然而 css 代码并不能 tree shaking,所以须要应用到 purgecss-webpack-plugin

装置 yarn add purgecss-webpack-plugin@4.1.3 -D.

为什么要装置 4.1.3 版本呢?因为我应用的是 webpack5,这个最新版本 5.0.0 在 webpakc 中有一个 Constructor Error 的谬误,具体请看

const path = require('path');
const glob = require('glob');
const PATHS = {src: path.join(__dirname, 'src'),
};
module.exports = {
    plugins: [
        new PurgecssPlugin({paths: glob.sync(`${PATHS.src}/**/*`, {nodir: true}),
        }),
    ]
}

对图片进行压缩

首先装置对应插件
yarn add image-minimizer-webpack-plugin @squoosh/lib -D

在这个装置的过程中可能会呈现谬误 (我是在应用 imagemin 时呈现的,可能和 @squoosh/lib 无关 ),能够依照以下办法逐渐排除(我的是在 mac 中呈现的,如果是在别的环境,就依照别的环境的命令装置)

  • node lib/install.js error: brew install automake autoconf libtool https://github.com/imagemin/imagemin-mozjpeg/issues/11
  • Permission denied @ apply2files: sudo chown -R ${LOGNAME}:staff /usr/local/lib/node_modules https://stackoverflow.com/questions/61899041/macos-permission-denied-apply2files-usr-local-lib-node-modules-expo-cli-n
  • Build error: no nasm (Netwide Assembler) found: brew install nasm

而后就是在生产构建流程中退出以下配置

module.exports = {
  optimization: {

    minimizer: [
      //...

      new ImageMinimizerPlugin({
        minimizer: {
          implementation: ImageMinimizerPlugin.squooshMinify,
          options: {
            // Your options for `squoosh`
            // The document where you can find options is https://github.com/webpack-contrib/image-minimizer-webpack-plugin#optimize-with-squoosh
          },
        },
      }),
    ]
  }
}

对我的项目进行分包 更多细节能够看这篇文章

根本分包策略:

  1. 公共的库是肯定要尽量拆的。
  2. 公共的库尽量做到按需加载,这也是优化首屏加载须要留神的。
  3. 分包不能太细,0KB 至 10 KB 的包是极小的包,该当思考合并。10 KB 至 100 KB 的包是小包,比拟适合;100 KB 至 200 KB 的包只能是比拟外围重要的包,须要重点关注,大于 200KB 的包就须要思考拆包了。当然,也不排除一些非凡状况。
module.exports = {
  
  optimization: {
    runtimeChunk: 'single',
    splitChunks: {
      // chunks: 'async',
      // minSize: 20000,
      // minRemainingSize: 0,
      // minChunks: 1,
      // maxAsyncRequests: 30,
      // maxInitialRequests: 30,
      // enforceSizeThreshold: 50000,
      cacheGroups: {
        // 提取公共资源
        vendor: {test: /[\\/]node_modules[\\/]_?react(.*)/,
          name: 'vendors-react-bucket',
          priority: 20,
          chunks: 'all',
        },
      },
    },
  },
}

应用 externals 将第三方库排除在打包的 bundle 外

将一些比较稳定的,罕用的第三方库拆散出打包流程中,应用 cdn 进行加载,能很无效的升高 bundle 的体积,放慢首屏渲染工夫,冲破浏览器对同一域名下资源并发申请的限度

module.exports = {

  // 应用 cdn 来减少浏览器针对同一域名的并发限度,应用 externals 将这些库排除在 bundle 外
  externals: {
    react: 'react',
    'react-dom': {
      commonjs: 'react-dom',
      amd: 'react-dom',
      root: '_', // 指向全局变量
    },
    redux: 'redux',
    'react-redux': 'react-redux',
    'react-router': 'react-router',
    'react-router-dom': 'react-router-dom',
  },
}

其余文章

  • 开发一个 react+ ts+webpack 的前端开发环境 (一)—— 根底环境搭建
  • 开发一个 react+ ts+webpack 的前端开发环境 (二)—— 配置 eslint、prettier、husky 等代码标准查看工具
正文完
 0