0


【前端webpack5高级优化】提升打包构建速度几种优化方案

HotModuleReplacement

(HMR/热模块替换)

开发时我们修改了其中一个模块代码,

Webpack 

默认会将所有模块全部重新打包编译,速度很慢

所以我们需要做到修改某个模块代码,就只有这个模块代码需要重新打包编译,其他模块不变,这样打包速度就能很快

使用

HotModuleReplacement

(HMR/热模块替换):在程序运行中,替换、添加或删除模块,而无需重新加载整个页面

使用流程

1.基本配置

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

此时

css 

样式经过

style-loader 

处理,已经具备

HMR

功能了。 但是

js 

还不行

  1. js
    
    配置
// main.jsimport count from"./js/count";import sum from"./js/sum";// 引入资源,Webpack才会对其打包import"./css/iconfont.css";import"./css/index.css";import"./less/index.less";import"./sass/index.sass";import"./sass/index.scss";import"./styl/index.styl";const result1 =count(2,1);
console.log(result1);const result2 =sum(1,2,3,4);
console.log(result2);// 判断是否支持HMR功能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(1,2,3,4);
    console.log(result2);});}

上面这样写会很麻烦,所以实际开发我们会使用其他

loader

来解决。

比如:

vue-loader

,

 react-hot-loader

OneOf

打包时每个文件都会经过所有

loader

处理,虽然因为

 test

正则原因实际没有处理上,但是都要过一遍,比较慢

使用

OneOf

:顾名思义就是只能匹配上一个

loader

, 剩下的就不匹配了

使用流程

const path =require("path");const ESLintWebpackPlugin =require("eslint-webpack-plugin");const HtmlWebpackPlugin =require("html-webpack-plugin");

module.exports ={entry:"./src/main.js",output:{path:undefined,// 开发模式没有输出,不需要指定输出目录filename:"static/js/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:/\.s[ac]ss$/,use:["style-loader","css-loader","sass-loader"],},{test:/\.styl$/,use:["style-loader","css-loader","stylus-loader"],},{test:/\.(png|jpe?g|gif|webp)$/,type:"asset",parser:{dataUrlCondition:{maxSize:10*1024,// 小于10kb的图片会被base64处理},},generator:{// 将图片文件输出到 static/imgs 目录中// 将图片文件命名 [hash:8][ext][query]// [hash:8]: hash值取8位// [ext]: 使用之前的文件扩展名// [query]: 添加之前的query参数filename:"static/imgs/[hash:8][ext][query]",},},{test:/\.(ttf|woff2?)$/,type:"asset/resource",generator:{filename:"static/media/[hash:8][ext][query]",},},{test:/\.js$/,exclude:/node_modules/,// 排除node_modules代码不编译loader:"babel-loader",},],},],},plugins:[newESLintWebpackPlugin({// 指定检查文件的根目录context: path.resolve(__dirname,"../src"),}),newHtmlWebpackPlugin({// 以 public/index.html 为模板创建文件// 新的html文件有两个特点:1. 内容和源文件一致 2. 自动引入打包生成的js等资源template: path.resolve(__dirname,"../public/index.html"),}),],// 开发服务器devServer:{host:"localhost",// 启动服务器域名port:"3000",// 启动服务器端口号open:true,// 是否自动打开浏览器hot:true,// 开启HMR功能},mode:"development",devtool:"cheap-module-source-map",};

Include/Exclude

开发时我们需要使用第三方的库或插件,所有文件都下载到

node_modules 

中了。而这些文件是不需要编译可以直接使用的。

所以我们在对

js

文件处理时,要排除

node_modules

下面的文件

**使用

Include/Exclude

:**

include

包含,只处理

 xxx

文件

exclude

排除,除了

xxx

文件以外其他文件都处理

使用流程

const path =require("path");const ESLintWebpackPlugin =require("eslint-webpack-plugin");const HtmlWebpackPlugin =require("html-webpack-plugin");

module.exports ={entry:"./src/main.js",output:{path:undefined,// 开发模式没有输出,不需要指定输出目录filename:"static/js/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:/\.s[ac]ss$/,use:["style-loader","css-loader","sass-loader"],},{test:/\.styl$/,use:["style-loader","css-loader","stylus-loader"],},{test:/\.(png|jpe?g|gif|webp)$/,type:"asset",parser:{dataUrlCondition:{maxSize:10*1024,// 小于10kb的图片会被base64处理},},generator:{// 将图片文件输出到 static/imgs 目录中// 将图片文件命名 [hash:8][ext][query]// [hash:8]: hash值取8位// [ext]: 使用之前的文件扩展名// [query]: 添加之前的query参数filename:"static/imgs/[hash:8][ext][query]",},},{test:/\.(ttf|woff2?)$/,type:"asset/resource",generator:{filename:"static/media/[hash:8][ext][query]",},},{test:/\.js$/,// exclude: /node_modules/, // 排除node_modules代码不编译include: path.resolve(__dirname,"../src"),// 也可以用包含loader:"babel-loader",},],},],},plugins:[newESLintWebpackPlugin({// 指定检查文件的根目录context: path.resolve(__dirname,"../src"),exclude:"node_modules",// 默认值}),newHtmlWebpackPlugin({// 以 public/index.html 为模板创建文件// 新的html文件有两个特点:1. 内容和源文件一致 2. 自动引入打包生成的js等资源template: path.resolve(__dirname,"../public/index.html"),}),],// 开发服务器devServer:{host:"localhost",// 启动服务器域名port:"3000",// 启动服务器端口号open:true,// 是否自动打开浏览器hot:true,// 开启HMR功能},mode:"development",devtool:"cheap-module-source-map",};

Cache

每次打包时

 js

文件都要经过

Eslint

检查 和

Babel

编译,速度比较慢。

我们可以缓存之前的

Eslint 

检查 和

Babel

编译结果,这样第二次打包时速度就会更快了

**使用

Cache

** : 对

Eslint

检查 和

Babel

编译结果进行缓存

使用流程

const path =require("path");const ESLintWebpackPlugin =require("eslint-webpack-plugin");const HtmlWebpackPlugin =require("html-webpack-plugin");

module.exports ={entry:"./src/main.js",output:{path:undefined,// 开发模式没有输出,不需要指定输出目录filename:"static/js/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:/\.s[ac]ss$/,use:["style-loader","css-loader","sass-loader"],},{test:/\.styl$/,use:["style-loader","css-loader","stylus-loader"],},{test:/\.(png|jpe?g|gif|webp)$/,type:"asset",parser:{dataUrlCondition:{maxSize:10*1024,// 小于10kb的图片会被base64处理},},generator:{// 将图片文件输出到 static/imgs 目录中// 将图片文件命名 [hash:8][ext][query]// [hash:8]: hash值取8位// [ext]: 使用之前的文件扩展名// [query]: 添加之前的query参数filename:"static/imgs/[hash:8][ext][query]",},},{test:/\.(ttf|woff2?)$/,type:"asset/resource",generator:{filename:"static/media/[hash:8][ext][query]",},},{test:/\.js$/,// exclude: /node_modules/, // 排除node_modules代码不编译include: path.resolve(__dirname,"../src"),// 也可以用包含loader:"babel-loader",options:{cacheDirectory:true,// 开启babel编译缓存cacheCompression:false,// 缓存文件不要压缩},},],},],},plugins:[newESLintWebpackPlugin({// 指定检查文件的根目录context: path.resolve(__dirname,"../src"),exclude:"node_modules",// 默认值cache:true,// 开启缓存// 缓存目录cacheLocation: path.resolve(
        __dirname,"../node_modules/.cache/.eslintcache"),}),newHtmlWebpackPlugin({// 以 public/index.html 为模板创建文件// 新的html文件有两个特点:1. 内容和源文件一致 2. 自动引入打包生成的js等资源template: path.resolve(__dirname,"../public/index.html"),}),],// 开发服务器devServer:{host:"localhost",// 启动服务器域名port:"3000",// 启动服务器端口号open:true,// 是否自动打开浏览器hot:true,// 开启HMR功能},mode:"development",devtool:"cheap-module-source-map",};

Thead

当项目越来越庞大时,打包速度越来越慢,甚至于需要一个下午才能打包出来代码。这个速度是比较慢的。

我们想要继续提升打包速度,其实就是要提升

js

的打包速度,因为其他文件都比较少。

而对

js 

文件处理主要就是

eslint

babel

Terser 

三个工具,所以我们要提升它们的运行速度。

我们可以开启多进程同时处理

 js

文件,这样速度就比之前的单进程打包更快了

**使用

Thead

多进程打包**:开启电脑的多个进程同时干一件事,速度更快。

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

600ms

左右开销

使用流程

我们启动进程的数量就是我们

CPU 

的核数

**1.如何获取

CPU

的核数,因为每个电脑都不一样**

// nodejs核心模块,直接使用const os =require("os");// cpu核数const threads = os.cpus().length;

2.下载包

npm i thread-loader -D

3.使用

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;// 获取处理样式的LoadersconstgetStyleLoaders=(preProcessor)=>{return[
    MiniCssExtractPlugin.loader,"css-loader",{loader:"postcss-loader",options:{postcssOptions:{plugins:["postcss-preset-env",// 能解决大多数样式兼容性问题],},},},
    preProcessor,].filter(Boolean);};

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:[{// 用来匹配 .css 结尾的文件test:/\.css$/,// use 数组里面 Loader 执行顺序是从右到左use:getStyleLoaders(),},{test:/\.less$/,use:getStyleLoaders("less-loader"),},{test:/\.s[ac]ss$/,use:getStyleLoaders("sass-loader"),},{test:/\.styl$/,use:getStyleLoaders("stylus-loader"),},{test:/\.(png|jpe?g|gif|webp)$/,type:"asset",parser:{dataUrlCondition:{maxSize:10*1024,// 小于10kb的图片会被base64处理},},generator:{// 将图片文件输出到 static/imgs 目录中// 将图片文件命名 [hash:8][ext][query]// [hash:8]: hash值取8位// [ext]: 使用之前的文件扩展名// [query]: 添加之前的query参数filename:"static/imgs/[hash:8][ext][query]",},},{test:/\.(ttf|woff2?)$/,type:"asset/resource",generator:{filename:"static/media/[hash:8][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:[newESLintWebpackPlugin({// 指定检查文件的根目录context: path.resolve(__dirname,"../src"),exclude:"node_modules",// 默认值cache:true,// 开启缓存// 缓存目录cacheLocation: path.resolve(
        __dirname,"../node_modules/.cache/.eslintcache"),
      threads,// 开启多进程}),newHtmlWebpackPlugin({// 以 public/index.html 为模板创建文件// 新的html文件有两个特点:1. 内容和源文件一致 2. 自动引入打包生成的js等资源template: path.resolve(__dirname,"../public/index.html"),}),// 提取css成单独文件newMiniCssExtractPlugin({// 定义输出文件名和目录filename:"static/css/main.css",}),// css压缩// new CssMinimizerPlugin(),],optimization:{minimize:true,minimizer:[// css压缩也可以写到optimization.minimizer里面,效果一样的newCssMinimizerPlugin(),// 当生产模式会默认开启TerserPlugin,但是我们需要进行其他配置,就要重新写了newTerserPlugin({parallel: threads // 开启多进程})],},// devServer: {//   host: "localhost", // 启动服务器域名//   port: "3000", // 启动服务器端口号//   open: true, // 是否自动打开浏览器// },mode:"production",devtool:"source-map",};
标签: 前端 webpack

本文转载自: https://blog.csdn.net/qq_53270554/article/details/137349970
版权归原作者 Luxine. 所有, 如有侵权,请联系我们删除。

“【前端webpack5高级优化】提升打包构建速度几种优化方案”的评论:

还没有评论