自定义 webpack 配置4:优化配置

参考 webpack教程、create-react-app(eject后)配置,自定义一个适合的、可维护的webpack配置

1. 保持版本最新

较新的版本能够建立更高效的模块树以及提高解析速度。

1.1 Node.js

1.1.1 最新版本

v14.7.0

1.1.2 查看本地版本

node -v
//或者
node --version

1.1.3 下载安装最新版本

1.2 npm

1.2.1 最新版本

v6.14.7

1.2.2 查看本地版本

npm -v
//或者
npm --version

1.2.3 更新版本

1.3 yarn

1.3.1 最新版本

v1.22.4

1.3.2 查看本地版本

yarn -v
//或者
yarn --version

1.3.3 更新版本

  • brew install yarn 无法更新到最新版本
  • curl -o- -L https://yarnpkg.com/install.sh | bash 更新成功

1.3 webpack

1.3.1 最新版本

v4.44.1

1.3.2 查看本地版本

package.json 查看即可

1.3.3 更新版本

  • 使用 npm 更新
  • 使用 yarn 更新

2. 减少 loader 作用范围

以 babel-loader 为例,可以明显减少构建时间

{
    test: /\.(js|mjs|jsx|ts|tsx)$/,
    //include: pathsUtil.appSrc,
    use: {
      loader: "babel-loader",
      options: {
        presets: [["@babel/preset-env"], "@babel/preset-react"],
      },
    },
},


 SMP  ⏱  Loaders
babel-loader took 3.19 secs
  module count = 12
mini-css-extract-plugin, and 
css-loader, and 
postcss-loader took 1.65 secs
  module count = 1
url-loader took 1.57 secs
  module count = 2
html-webpack-plugin took 1.54 secs
  module count = 1
css-loader, and 
postcss-loader took 1.49 secs
  module count = 1
file-loader took 0.002 secs
  module count = 1
{
    test: /\.(js|mjs|jsx|ts|tsx)$/,
    include: pathsUtil.appSrc,
    use: {
      loader: "babel-loader",
      options: {
        presets: [["@babel/preset-env"], "@babel/preset-react"],
      },
    },
},

 SMP  ⏱  Loaders
babel-loader took 0.539 secs
  module count = 4
mini-css-extract-plugin, and 
css-loader, and 
postcss-loader took 0.39 secs
  module count = 1
url-loader took 0.36 secs
  module count = 2
css-loader, and 
postcss-loader took 0.299 secs
  module count = 1
modules with no loaders took 0.286 secs
  module count = 9
html-webpack-plugin took 0.259 secs
  module count = 1
file-loader took 0.002 secs
  module count = 1

3. 自定义 CSS Module 名称

3.1 新增组件和样式文件

<!--Page1.jsx-->
import React from "react";
import styles from "./Page1.css";

export default class Page1 extends React.Component {
  render() {
    return <div className={styles.color}>my-webpack-config</div>;
  }
}

<!--Page1.css-->
.color {
  color: red;
}

<!--打包显示-->
<div class="_3nyJKZ_2xnbZEzEA9FKoRL">my-webpack-config</div>

3.2 自定义显示

3.2.1 新增 getCssModuleName 文件处理显示名称

"use strict";

const loaderUtils = require("loader-utils");
const path = require("path");

module.exports = function getCssModuleName(
  context,
  localIdentName,
  localName,
  options
) {
  // Use the filename or folder name, based on some uses the index.js / index.module.(css|scss|sass) project style
  const fileNameOrFolder = context.resourcePath.match(
    /index\.module\.(css|scss|sass)$/
  )
    ? "[folder]"
    : "[name]";
  // Create a hash based on a the file location and class name. Will be unique across a project, and close to globally unique.
  const hash = loaderUtils.getHashDigest(
    path.posix.relative(context.rootContext, context.resourcePath) + localName,
    "md5",
    "base64",
    5
  );
  // Use loaderUtils to find the file or folder name
  const className = loaderUtils.interpolateName(
    context,
    fileNameOrFolder + "_" + localName + "__" + hash,
    options
  );
  // remove the .module that appears in every classname when based on the file.
  return className.replace(".module_", "_");
};

3.2.2 编辑 css-loader 配置

 {
        test: /\.css$/,
        include: pathsUtil.appSrc,
        use: [
          {
            loader: MiniCssExtractPlugin.loader,
            options: { publicPath: "../../" },
          },
          {
            loader: "css-loader",
            options: {
              importLoaders: 1,
              // modules: true,
              modules: {
                getLocalIdent: getCssModuleName,
              },
            },
          },
          // Use it after css-loader and style-loader, but before other preprocessor loaders like e.g sass|less|stylus-loader, if you use any.
          {
            loader: "postcss-loader",
            options: {
              plugins: [require("autoprefixer")],
            },
          },
        ],
      },
<!--打包显示-->
<div class="Page1_color__KVvDQ">my-webpack-config</div>

4. CSS Tree Shaking

移除没有使用的 CSS 使用 purgecss 来完成,针对 React+webpack+CssModule 只能使用 postcss-purgecss,不能使用 purgecss-webpack-plugin 原因查看详情@goldmont 的回答。

4.1 安装依赖

yarn add -D @fullhuman/postcss-purgecss glob-all

4.2 编辑 APP.jsx 和 APP.module.css 文件

import React from "react";
import styles from "./App.module.css";
import smallImage from "./image/small.png";
import bigImage from "./image/big.png";
export default class App extends React.Component {
  componentDidMount() {
    // console1.log("my-webpack-config");
  }
  render() {
    return (
      <div>
        <div className={styles.color}>my-webpack-config</div>
        <div className={`${styles.color} ${styles.myFirstFont}`}>
          my-webpack-config
        </div>
        <img src={smallImage} alt=""></img>
        <img src={bigImage} alt=""></img>
      </div>
    );
  }
}

.color {
  color: rebeccapurple;
  display: flex;
  box-sizing: border-box;
}

.myFirstFont {
  font-family: myFirstFont;
}

<!--没有使用的属性-->
.color2 {
  color: blue;
}

4.3 编辑 webpack.base.js 文件

{
    loader: "postcss-loader",
    options: {
      plugins: [
        require("autoprefixer"),
        require("@fullhuman/postcss-purgecss")({
          content: [
            pathsUtil.appHtml,
            ...glob.sync(
              path.join(pathsUtil.appSrc, "/**/*.{js,jsx}"),
              {
                nodir: true,
              }
            ),
          ],
        }),
      ],
    },
}

4.4 重新构建对比

<!-- 处理前,多余属性 color2 存在 -->
<!--重新格式化-->
@font-face {
  font-family: myFirstFont;
  src: url(../../static/media/font.d55bf3f0.ttf);
}
.App_color__2ZKCn {
  color: #639;
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-sizing: border-box;
  box-sizing: border-box;
}
.App_color2__2BDwS {
  color: #00f;
}
.App_myFirstFont__q9w-n {
  font-family: myFirstFont;
}


<!-- 处理前,多余属性 color2 已经被删除 -->
<!--重新格式化-->
@font-face {
  font-family: myFirstFont;
  src: url(../../static/media/font.d55bf3f0.ttf);
}
.App_color__2ZKCn {
  color: #639;
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-sizing: border-box;
  box-sizing: border-box;
}
.App_myFirstFont__q9w-n {
  font-family: myFirstFont;
}


代码仓库

参考链接

猜你喜欢

转载自blog.csdn.net/ZWQ0325/article/details/108401396