Create-React-App 打包优化

8,186 阅读3分钟

本文主要记录对create-react-app这个cli的默认配置进行修改,添加gzip压缩、关闭sourceMap、添加antd/material-ui的按需加载、添加编译进度条、添加打包后各包大小查看插件。

yarn add customize-cra react-app-rewired progress-bar-webpack-plugin webpack-bundle-analyzer compression-webpack-plugin cross-env -D

若需修改antd主题,额外添加yarn add less less-loader -D

config-overrides.js

const {
  override,
  fixBabelImports,
  addLessLoader,
  addWebpackAlias,
  addWebpackPlugin,,
  // addLessLoader,
  // addPostcssPlugins,
} = require("customize-cra");
const path = require("path");
const ProgressBarPlugin = require("progress-bar-webpack-plugin");
const { BundleAnalyzerPlugin } = require("webpack-bundle-analyzer");
const CompressionWebpackPlugin = require("compression-webpack-plugin");

const isEnvProduction = process.env.NODE_ENV === "production";

const addCompression = () => config => {
  if (isEnvProduction) {
    config.plugins.push(
      // gzip压缩
      new CompressionWebpackPlugin({
        test: /\.(css|js)$/,
        // 只处理比1kb大的资源
        threshold: 1024,
        // 只处理压缩率低于90%的文件
        minRatio: 0.9
      })
    );
  }

  return config;
};

// 查看打包后各包大小
const addAnalyzer = () => config => {
  if (process.env.ANALYZER) {
    config.plugins.push(new BundleAnalyzerPlugin());
  }

  return config;
};

module.exports = override(
  //!!!! 按需加载 此处如果仅配置单个按需引入如antd,需要去掉第二参数的中括号,否则配置会失效
  fixBabelImports("import", [
    {
      libraryName: "antd",
      libraryDirectory: "es",
      // 若修改antd主题,"css"需改为true
      style: "css"
    },
    {
      libraryName: "@material-ui/core",
      libraryDirectory: "esm",
      camel2DashComponentName: false
    }
  ]),
  // 移动端适配,px转rem 需要安装postcss-pxtorem
  // addPostcssPlugins([
  //  require("postcss-pxtorem")({
  //    // rem 转换基数
  //    rootValue: 16,
  //    // 保留五位小数点
  //    unitPrecision: 5,
  //    // 所有属性都转换
  //    propList: ["*"],
  //    // 低于2px不转换
  //    minPixelValue: 2,
  //    // 排除antd样式
  //  selectorBlackList:[/^\.ant-/,"html"]
  //  }),
  // 修改antd 主题 需 yarn add less less-loader -D 添加依赖包
  // addLessLoader({
  //   javascriptEnabled: true
  //   modifyVars: { '@primary-color': '#1DA57A' },
  // }),
  addCompression(),
  addAnalyzer(),
  addWebpackPlugin(
    // 终端进度条显示
    new ProgressBarPlugin()
  ),
  addWebpackAlias({
    ["@"]: path.resolve(__dirname, "src")
  })
);

package.json

package.json处声明全局变量GENERATE_SOURCEMAP=false,而不是在config-overrides.js添加devtool配置(devtool的配置仅对webpack有效,但对postcss-loader无效,eject后webpack的postcss-loader的options:sourceMap: isEnvProduction && shouldUseSourceMap可以看出缘由)。

build:view 方式打包完后,会自动打开分析各模块包大小的仪表盘。

 "scripts": {
    "start": "react-app-rewired start",
    "build": "cross-env GENERATE_SOURCEMAP=false react-app-rewired build",
    "build:view": "cross-env GENERATE_SOURCEMAP=false ANALYZER=true react-app-rewired build",
    "test": "react-app-rewired test",
    "eject": "react-scripts eject"
  },

环境变量

对于api的前缀路径,可以通过环境变量或者添加代理来区分。

少量环境变量可直接在package.jsonscripts处进行配置。参考如上。

或者可在根目录添加.env<.development|.prodcution|.test|.local>可多个叠加,详细说明请查阅Adding Custom Environment Variables

配置

注意!必须以REACT_APP_开头!

.env.development

REACT_APP_HOST = "http://localhost:5000"

.env.production

REACT_APP_HOST = "http://xxx.xxx.xxx.xxx:5000"

使用

process.env.REACT_APP_HOST直接可获取。

镜像源配置

根目录创建.npmrc文件

sass_binary_site=https://npm.taobao.org/mirrors/node-sass/
electron_mirror=https://npm.taobao.org/mirrors/electron/
registry=https://registry.npm.taobao.org
disturl=https://npm.taobao.org/dist

以下是一些碎碎念

关于CDN

CDN本质是通过从第三方在线引入库的方式降低打包文件大小,对于普通项目,实际并没什么需求需要用上CDN,毕竟react、react-dom之类的库,gzip后也就几KB或者几十KB,这点大小的文件CDN了也没啥意义。而大一点的库,如antd或material-ui等,CDN引入无法做到按需引入,用了CDN反而得不偿失。所以没啥特别需求也没必要上CDN(大型项目另说)。

关于DLL打包

DLL打包其实就是一种手动缓存库的操作,现在webpack4的性能已经不差了,DLL打包也就节省那几秒时间(亲测基于cra添加尝试过),没什么意义。cra和vue-cli也都取消DLL打包插件,自己再手动添加上去未免有点多此一举= =。并且webpack5已经不用它了,替代它的是hard-source-webpack-plugin

关于多线程打包

主流有两个库thread-loaderhappypack,未进行尝试过,个人喜欢直接服务器build,阿里学生机就一核一线😂,配了也白配。