当前位置: 首页 > article >正文

webpack5提升打包构建速度(四)

1、SourceMap:找到映射后源代码出错位置

SourceMap(源代码映射)是一个用来生成源代码与构建后代码一一映射的文件的方案。

它会生成一个 xxx.map 文件,里面包含源代码和构建后代码每一行、每一列的映射关系。当构建后代码出错了,会通过 xxx.map 文件,从构建后代码出错位置找到映射后源代码出错位置,从而让浏览器提示源代码文件出错位置,帮助我们更快的找到错误根源。

/* 
 * ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development").
 * This devtool is neither made for production nor for readable output files.
 * It uses "eval()" calls to create a separate source file in the browser devtools.
 * If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
 * or disable the default devtool with "devtool: false".
 * If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
 */
/******/ (() => { // webpackBootstrap
/******/    "use strict";
/******/    var __webpack_modules__ = ({

/***/ "./node_modules/css-loader/dist/cjs.js!./node_modules/less-loader/dist/cjs.js!./src/less/index.less":
/*!**********************************************************************************************************!*\
  !*** ./node_modules/css-loader/dist/cjs.js!./node_modules/less-loader/dist/cjs.js!./src/less/index.less ***!
  \**********************************************************************************************************/
/***/ ((module, __webpack_exports__, __webpack_require__) => {

eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var _node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../node_modules/css-loader/dist/runtime/noSourceMaps.js */ \"./node_modules/css-loader/dist/runtime/noSourceMaps.js\");\n/* harmony import */ var _node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../node_modules/css-loader/dist/runtime/api.js */ \"./node_modules/css-loader/dist/runtime/api.js\");\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__);\n// Imports\n\n\nvar ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default()));\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, \".box2 {\\n  width: 100px;\\n  height: 100px;\\n  background-color: deeppink;\\n}\\n\", \"\"]);\n// Exports\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);\n\n\n//# sourceURL=webpack://webpack5/./src/less/index.less?./node_modules/css-loader/dist/cjs.js!./node_modules/less-loader/dist/cjs.js");

/***/ }),
// 其他省略

打包完代码出错完全找不到哪里出错了,如果在配置文件中配置好属性,就能方便的找到打包后出错的代码所在行。

如何配置?

开发模式下配置:cheap-module-source-map
优点:打包编译速度快,只包含行映射
缺点:没有列映射

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

生产模式:source-map
优点:包含行/列映射
缺点:打包编译速度更慢

module.exports = {
  // 其他省略
  mode: "production",
  devtool: "source-map",
};
2、HMR/模块热替换(HotModuleReplacement):在程序运行中,替换、添加或删除模块,而无需重新加载整个页面。

如何配置?
在devServer中配置hot:true

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

经过上面的设置, css 样式经过 style-loader 处理,已经具备 HMR 功能了。但是 js 还不行。js要经过下面的设置方式:

import count from './js/count'
import sum from './js/sum'
import './css/index.css'
import './css/index.less'
import './css/index.sass'

const result = count(8, 2)
console.log(result, 'result')
console.log(count(8, 2))
console.log(sum(2, 3))

// 判断是否支持HMR功能  这样设置是指这两个js文件更新时,局部刷新内容
if (module.hot) {
    module.hot.accept("./js/count.js", function(count) {
        const result1 = count(2, 1);
        console.log(result1);
    });

    module.hot.accept("./js/sum.js", function(sum) {
        const result2 = sum(5, 6);
        console.log(result2);
    });
}

上面的写法还是比较麻烦的,之后我们还是会用到loader去处理:vue-loader, react-hot-loader

3、OneOf:匹配上一个 loader, 剩下的就不忽略了。

如何配置?
在module中rules的loader用oneOf全部都包起来。生产模式也是这样配置。

 module: {
        rules: [{
            oneOf: [{
                    // 用来匹配 .css 结尾的文件
                    test: /\.css$/,
                    // use 数组里面 Loader 执行顺序是从右到左
                    use: ["style-loader", "css-loader"],
                },
                {
                    test: /\.less$/,
                    use: ["style-loader", "css-loader", "less-loader"],
                },
                {
                    test: /\.sass$/,
                    use: ["style-loader", "css-loader", "sass-loader"],
                },
                {
                    test: /\.(png|jpe?g|gif|webp)$/,
                    type: "asset",
                    parser: {
                        dataUrlCondition: {
                            maxSize: 10 * 1024 // 小于10kb的图片会被base64处理
                        }
                    },
                    //设置图片打包后的路径
                    generator: {
                        filename: 'dist/images/[hash:10][ext][query]'
                    }
                },
            ]
        }],
    },
4、Include/Exclude:在对 js 文件处理时,要排除 node_modules 下面的文件。

include:包含,只处理 xxx 文件
exclude:排除,除了 xxx 文件以外其他文件都处理

如何设置

例如 module中这样设置:

{
       test: /\.js$/,
       // exclude: /node_modules/, // 排除node_modules代码不编译
       include: path.resolve(__dirname, "../src"), // 也可以用包含
       loader: "babel-loader",
},

插件中也可以这样设置:

 plugins: [
    new ESLintWebpackPlugin({
      // 指定检查文件的根目录
      context: path.resolve(__dirname, "../src"),
      exclude: "node_modules", // 默认值
    }),
]
5、多进程打包:开启电脑的多个进程同时干一件事,速度更快

需要注意:请仅在特别耗时的操作中使用,因为每个进程启动就有大约为 600ms 左右开销。

如何设置
我们启动进程的数量就是我们 CPU 的核数。

  1. 如何获取 CPU 的核数,因为每个电脑都不一样。
// nodejs核心模块,直接使用
const os = require("os");
// cpu核数
const threads = os.cpus().length;
  1. 下载包
npm i thread-loader -D

3.使用
在module的rules中的引入babel-loader的use中添加如下代码

{
    loader: "thread-loader", // 开启多进程
     options: {
          workers: threads, // 数量
      },
 },

在plugins的new ESLintWebpackPlugin中配置 threads, // 开启多进程
最后在optimization中new TerserPlugin中配置如下设置:

  optimization: {
    minimize: true,
    minimizer: [
      // css压缩也可以写到optimization.minimizer里面,效果一样的
      new CssMinimizerPlugin(),
      // 当生产模式会默认开启TerserPlugin,但是我们需要进行其他配置,就要重新写了
      new TerserPlugin({
        parallel: threads // 开启多进程
      })
    ],
  },

所以总的module代码配置如下:

module.exports = {
    //入口文件
    entry: {
        index: './src/main.js',
        admin: './src/main2.js',
    },
    //出口文件
    output: {
        path: undefined, // 开发模式没有输出,不需要指定输出目录
        filename: "static/js/[name]main.js", // 将 js 文件输出到 static/js 目录中
        clean: true, // 开发模式没有输出,不需要清空输出结果
    },
    module: {
        rules: [{
            oneOf: [{
                    // 用来匹配 .css 结尾的文件
                    test: /\.css$/,
                    // use 数组里面 Loader 执行顺序是从右到左
                    use: ["style-loader", "css-loader"],
                },
                {
                    test: /\.less$/,
                    use: ["style-loader", "css-loader", "less-loader"],
                },
                {
                    test: /\.sass$/,
                    use: ["style-loader", "css-loader", "sass-loader"],
                },
                {
                    test: /\.(png|jpe?g|gif|webp)$/,
                    type: "asset",
                    parser: {
                        dataUrlCondition: {
                            maxSize: 10 * 1024 // 小于10kb的图片会被base64处理
                        }
                    },
                    //设置图片打包后的路径
                    generator: {
                        filename: 'dist/images/[hash:10][ext][query]'
                    }
                },
                {
                    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",
}

这个时候再打包试试看,其实目前文件比较小的话,实际打包的速度比之前是慢的,只有文件的内容足够大时,处在一个临界值的时候,才发现用这个方法打包速度大大提高!


http://www.kler.cn/a/416071.html

相关文章:

  • Android 图形系统之三:SurfaceControl
  • RuoYi排序
  • mp4视频流推送的学习
  • 内核模块里获取当前进程和父进程的cmdline的方法及注意事项,涉及父子进程管理,和rcu的初步介绍
  • 用go语言写一个小服务
  • Spring Boot 同时接受文件和实体及 Postman 测试实战
  • 详解 YOLOv5 模型运行参数含义以及设置及在 PyCharm 中的配置方法
  • uniapp首页样式,实现菜单导航结构
  • 【LeetCode热题100】优先级队列
  • 微软要求 Windows Insider 用户试用备受争议的召回功能
  • 显卡驱动更新无法更新怎么办 显卡驱动无法更新原因及解决
  • Java知识及热点面试题总结(一)
  • 嵌入式 FPGA开发
  • GAMIT 单北斗sV antenna offsets for SVN c232 not found in antmod.dat
  • 华为CloudEngine S16700 V600R023C00 VXLAN概念
  • Flink CDC 锁表原理详解
  • Docker使用教程
  • go的math/rand随机数生成器
  • 蓝桥杯——递归
  • 技术总结(四十一)
  • 基于Java Springboot考研论坛系统
  • 部署kvm
  • Github 2024-11-27 C开源项目日报 Top9
  • Redis中HGETALL和ZRANGE命令
  • 中介者模式 (Mediator Pattern)
  • 无人机飞行控制系统多机控制技术详解