webpack学习 4 - 进阶优化

SourceMap

SourceMap(源代码映射)是一个用来生成源代码与构建后代码一一映射的文件的方案。使用后会生成xxx.map文件,里面包含源代码与构建后代码每一行、每一列的映射关系。当构建后代码出错了,会通过xxx.map文件,从构建后代码出错的位置找到映射后源代码的出错位置,这样浏览器就能提示源代码文件的出错位置,让我们能够在开发调试时快速的定位到错误的原因。
sourceMap的值有很多种,可以参考官网的文档
实际使用时,在开发时我们一般用cheap-module-source-map,他的优点是打包编译的速度快,但是映射是只包含行映射。

module.exports = {
  // ...
  mode: "development",
  devtool: "cheap-module-source-map",
};

而在生产模式下则直接配置为source-map即可,它将会包含行列映射,相应的打包编译时速度也会慢一些

module.exports = {
  // ...
  mode: "production",
  devtool: "source-map",
};

HotModuleReplacement

HotModuleReplacement(热模块替换)简称为HMR,是指在程序运行中,替换、添加或删除模块,而无需重新加载整个页面。
在开发时进行配置即可:

module.exports = {
  // 其他省略
  devServer: {
    host: "localhost", // 启动服务器域名
    port: "3000", // 启动服务器端口号
    open: true, // 是否自动打开浏览器
    hot: true, // 开启HMR功能(只能用于开发环境,生产环境不需要了)
  },
};

在实际的开发中我们还需要使用其他的比如react-hot-loader或vue-loader来实现HMR。

OneOf

打包时每个文件都会经过所有的loader处理,虽然有test作为匹配但还是需要过一遍,比较慢,在最外层加上一个oneOf就可以实现只要匹配上一个loader剩下就不匹配的效果:

module.exports = {
  module: {
    rules: [
      {
        oneOf: [
          // 相关loader配置
        ],
      },
    ],
  },
};

Include/Exclude

Include即包含,只处理xxx文件
exclude即排除,除了xxx文件外都处理
可以在module和pulgins里配置

Cache

可以对之前的Eslint检查和Babel编译结果进行缓存,使得第二次及之后的打包速度变快:

module.exports = {
  module: {
    rules: [
      {
        oneOf: [
          {
            test: /\.js$/,
            // exclude: /node_modules/, // 排除node_modules代码不编译
            include: path.resolve(__dirname, "../src"), // 也可以用包含
            loader: "babel-loader",
            options: {
              cacheDirectory: true, // 开启babel编译缓存
              cacheCompression: false, // 缓存文件不要压缩
            },
          },
        ],
      },
    ],
  },
  plugins: [
    new ESLintWebpackPlugin({
      // 指定检查文件的根目录
      context: path.resolve(__dirname, "../src"),
      exclude: "node_modules", // 默认值
      cache: true, // 开启缓存
      // 缓存目录
      cacheLocation: path.resolve(
        __dirname,
        "../node_modules/.cache/.eslintcache"
      ),
    }),
  ],
};

需要注意的是module和plugins中使用cache的方式不同

Thead

我们可以开启多进程同时处理js文件,这样打包的速度就会比之前的单进程打包要快许多。

const os = require("os");
const path = require("path");
const ESLintWebpackPlugin = require("eslint-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
const TerserPlugin = require("terser-webpack-plugin");

// cpu核数
const threads = os.cpus().length;

module.exports = {
  entry: "./src/main.js",
  output: {
    path: path.resolve(__dirname, "../dist"), // 生产模式需要输出
    filename: "static/js/main.js", // 将 js 文件输出到 static/js 目录中
    clean: true,
  },
  module: {
    rules: [
      {
        oneOf: [
          {
            test: /\.js$/,
            // exclude: /node_modules/, // 排除node_modules代码不编译
            include: path.resolve(__dirname, "../src"), // 也可以用包含
            use: [
              {
                loader: "thread-loader", // 开启多进程
                options: {
                  workers: threads, // 数量
                },
              },
              {
                loader: "babel-loader",
                options: {
                  cacheDirectory: true, // 开启babel编译缓存
                },
              },
            ],
          },
        ],
      },
    ],
  },
  plugins: [
    new ESLintWebpackPlugin({
      // 指定检查文件的根目录
      context: path.resolve(__dirname, "../src"),
      exclude: "node_modules", // 默认值
      cache: true, // 开启缓存
      // 缓存目录
      cacheLocation: path.resolve(
        __dirname,
        "../node_modules/.cache/.eslintcache"
      ),
      threads, // 开启多进程
    }),
    // ...
  ],
  optimization: {
    minimize: true,
    minimizer: [
      // css压缩也可以写到optimization.minimizer里面,效果一样的
      new CssMinimizerPlugin(),
      // 当生产模式会默认开启TerserPlugin,但是我们需要进行其他配置,就要重新写了
      new TerserPlugin({
        parallel: threads // 开启多进程
      })
    ],
  },
  mode: "production",
  devtool: "source-map",
};

你可能感兴趣的:(webpack学习 4 - 进阶优化)