Skip to content

webpack 配置优化攻略(一)

网站性能

网站性能对用户体验的重要性非常重要,一个快速响应的网站可以提供更好的用户体验。

衡量一个网站性能的指标:

  • Largest Contentful Paint (LCP):衡量加载性能。
  • First Input Delay (FID):衡量互动。
  • Cumulative Layout Shift (CLS):衡量的是视觉稳定性。

看来我们要提升网站的性能是有很多事情要做的,最容易下手的可能就是提升LCP了。也许你听说过code splitting来将代码拆分成多个小块,实现按需加载,减小首次加载时间;使用Tree Shaking来删除未使用的代码,减小打包体积...

如果你想深入了解这些方法具体如何实施,这篇文章就介绍一个很好的入手点,从React的官方create-react-app脚手架学习他们的webpack是如何进行配置的。

创建一个新的project

bash
npx create-react-app my-app

这样一个叫my-app的React应用就创建好了。

Create React App 是官方支持的一种创建单页 React 应用程序的方式。它提供了一个现代的构建设置,无需配置。

这时你会发现你看不到任何webpack配置,要自定义配置怎么办呢?

暴露出官方的配置

默认官方收起了所有打包相关的配置,来使开发者把精力放在编程本身。他们在package.json提供了一个script来暴露webpack配置:

npm run reject

注意!!!这个操作是单向的,一旦你执行了,会影响你当前的项目结构包括package.json。

执行完成后可以看到打包的相关依赖会被提取到package.json中,项目根目录增加了config和script目录。package.json启动script也变成了:

bash
"scripts": {
  "start": "node scripts/start.js",
  "build": "node scripts/build.js",
  "test": "node scripts/test.js"
},

在config中出现了webpack.config.js,里边包含了:optimization(可以发现他用的代码压缩工具TerserPlugin)、output、各种插件等相关重要配置。

js
module.exports = function (webpackEnv) {
  const isEnvDevelopment = webpackEnv === "development";
  const isEnvProduction = webpackEnv === "production";

  return {
    target: ["browserslist"],
    // Webpack noise constrained to errors and warnings
    stats: "errors-warnings",
    mode: isEnvProduction ? "production" : isEnvDevelopment && "development",
    // Stop compilation early in production
    bail: isEnvProduction,
    devtool: isEnvProduction
      ? shouldUseSourceMap
        ? "source-map"
        : false
      : isEnvDevelopment && "cheap-module-source-map",
    // These are the "entry points" to our application.
    // This means they will be the "root" imports that are included in JS bundle.
    entry: paths.appIndexJs,
    output: {
      // The build folder.
      path: paths.appBuild,
    },
    optimization: {
      minimize: isEnvProduction,
      minimizer: [
        // This is only used in production mode
        new TerserPlugin({
          terserOptions: {
            parse: {
              // We want terser to parse ecma 8 code. However, we don't want it
              // to apply any minification steps that turns valid ecma 5 code
              // into invalid ecma 5 code. This is why the 'compress' and 'output'
              // sections only apply transformations that are ecma 5 safe
              // https://github.com/facebook/create-react-app/pull/4234
              ecma: 8,
            },
            compress: {
              ecma: 5,
              warnings: false,
              // Disabled because of an issue with Uglify breaking seemingly valid code:
              // https://github.com/facebook/create-react-app/issues/2376
              // Pending further investigation:
              // https://github.com/mishoo/UglifyJS2/issues/2011
              comparisons: false,
              // Disabled because of an issue with Terser breaking valid code:
              // https://github.com/facebook/create-react-app/issues/5250
              // Pending further investigation:
              // https://github.com/terser-js/terser/issues/120
              inline: 2,
            },
            mangle: {
              safari10: true,
            },
            // Added for profiling in devtools
            keep_classnames: isEnvProductionProfile,
            keep_fnames: isEnvProductionProfile,
            output: {
              ecma: 5,
              comments: false,
              // Turned on because emoji and regex is not minified properly using default
              // https://github.com/facebook/create-react-app/issues/2488
              ascii_only: true,
            },
          },
        }),
        // This is only used in production mode
        new CssMinimizerPlugin(),
      ],
    },
    ...
  }
}

你可以对照webpack官方文档来修改这个文件。

继续探索

webpack.config.js中提供了相当多的配置,官方的配置堪称很优秀了。当我们需要自定义webpack配置时可以从上面提到的方法入手,加油。

Released under the MIT License.