目录

前言一、HMR 热更新1、什么是HMR2、HMR实现

二、source-map1、什么是source-map2、Source Map的配置项3、source-map实现

三、oneOf1、oneOf的作用2、oneOf使用

四、缓存1、babel 缓存2、文件资源缓存

五、小结

前言

大家都知道,webpack是现在主流的模块化打包工具,随着项目中打包出来的js体积越来越大,构建速度越来越慢,对其进行性能优化也是我们必做的事情。本篇文章会从各个性能方面进行讲解,希望对学习webpack的小伙伴们有所帮助。

一、HMR 热更新

1、什么是HMR

HMR 全称 Hot Module Replacement,翻译为模块热更新。当一个模块发生变化时,只会对该模块重新进行打包,而不会打包所有模块,这个特性对于开发环境来说非常重要,我们所需要做的就是更新我们的webpack-dev-server配置。

2、HMR实现

webpack5已经自动实现HRM热更新替换功能,所以我们在devServer中不需要添加任何代码,但html文件无法实现热更新,所以我们需要在主文件入口中将html文件引入

entry: ['./src/js/index.js', './src/index.html'],

另外新的模块替换老的模块后,业务层代码并不知道代码已经发生了变化,所以我们需要在业务层代码中添加处理模块更新函数,即在index.js中添加如下:

// index.js

if(module.hot) {

module.hot.accept('./other.js', function() {

hello()

})

}

判断HMR热模块替换已经开启的标识如下:

二、source-map

1、什么是source-map

sourcemap 本质上是一个信息文件,里面储存着打包前后代码的映射为位置关系及信息,可方便开发者快速定位错误。

2、Source Map的配置项

以上表格可能看不清,具体配置项详情可以参考官网:https://webpack.js.org/configuration/devtool/#root

3、source-map实现

devtool: 'eval-source-map'

在开发环境想要实现开发速度快,调试更友好,可采用eval-cheap–module-souce-map eval-source-map 在生产环境若需要隐藏代码,可采用nosources-source-map / hidden-source-map,若想速度快,可source-map / cheap-module-souce-map 注意:生产环境考虑到文件体积的原因,一般将映射文件生成到外部。 具体配置结合项目情况

三、oneOf

1、oneOf的作用

一般情况下,所有文件在执行的时候,都会将loader的rules过一遍,如果符合,就被相应的loader处理,不符合就直接过,这样非常浪费性能。oneOf是一个规则数组,当规则匹配时,只使用其中的第一个规则。

2、oneOf使用

若一个文件要被多个loader处理,那可以将将其放在oneOf外面

四、缓存

在这里会介绍两种缓存优化,即babel 缓存 和 文件资源缓存

1、babel 缓存

默认未设置缓存。当设置时,给定的目录将用于缓存加载器的结果。未来的webpack构建将尝试从缓存中读取,以避免在每次运行时都需要运行可能昂贵的Babel重新编译过程。cacheDirectory: true中将该值设置为true,加载器将使用node_modules/中的默认缓存目录。如果在任何根目录中都没有node_modules文件夹,则缓存/babel-loader或回退到默认的OS临时文件目录。

{

test: /\.js$/,

exclude: /node_modules/,

loader: 'babel-loader',

options: {

presets: [

[

'@babel/preset-env',

{

useBuiltIns: 'usage',

corejs: { version: 3 },

targets: {

chrome: '60',

firefox: '50'

}

}

]

],

// 开启babel缓存

// 第二次构建时,会读取之前的缓存

cacheDirectory: true

}

},

2、文件资源缓存

当请求的资源或者文件名称未出现变化时,浏览器会拿取缓存里面的资源,不会重新从服务器请求资源。

文件资源缓存有三种实现方案

hash:每次wepack构建时会生成一个唯一的hash值。可这会出现一个问题,即所有文件同时使用一个hash值,重新打包,所有文件的 hsah 值都改变,会导致所有缓存失效chunkhash:根据chunk生成的hash值。如果打包来源于同一个chunk,那么hash值就一样。产生的问题,由于css实在js中内引入的,所以它们的hash值还是一样的contenthash: 根据文件的内容生成hash值。不同文件hash值一定不一样。最优方案。

简单创建一个node服务器:

const express = require('express');

const app = express();

//需要将dist文件作为静态资源缓存

app.use(express.static('dist', { maxAge: 2000 * 3600 }));

app.listen(9000);

启动服务器后在需要缓存的文件后面加上contenthash即可

实现效果

五、小结

最终整体代码:

const path = require('path');

const HtmlWebpackPlugin = require('html-webpack-plugin'); //通过 npm 安装

const MiniCssExtractPlugin = require('mini-css-extract-plugin')

const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");

// 设置nodejs环境变量

process.env.NODE_ENV = 'development';

const config = {

entry:'./src/js/index.js',

output: {

path: path.resolve(__dirname, 'dist'),

filename: 'js/dist[contenthash:10].js'

},

module: {

rules: [

{

oneOf: [

{

test: /\.css$/,

use: [

MiniCssExtractPlugin.loader,

'css-loader',

{

loader: "postcss-loader",

options: {

postcssOptions: {

plugins: [

[

"postcss-preset-env",

{}

],

],

},

}

}

],

},

{

//打包图片资源 处理 css 文件的 img背景 图片

test:/\.(jpg|png|gif)$/,

type: 'asset/resource',

generator:{

filename:'img/[hash:10][ext]',

},

},

{

// 处理 html 文件的 img 图片

test:/\.html$/,

loader:'html-loader',

},

{

//打包图标字体资源

test: /\.(ttf|eof|woff2)$/,

type: 'asset/resource',

generator:{

filename:'font/[hash:10][ext]',

},

},

{

//打包图标字体资源

exclude: /\.(ttf|eof|woff2|css|html|js|png|gif|jpg)$/,

type: 'asset/resource',

generator:{

filename:'other/[hash:10][ext]',

}

},

{

test: /\.js$/,

exclude: /(node_modules|bower_components)/,

use: {

loader: 'babel-loader',

options: {

presets: [

[

'@babel/preset-env',

{

// 按需加载

useBuiltIns: 'usage',

// 指定core-js版本

corejs: {

version: 3

},

// 指定兼容性做到哪个版本浏览器

targets: {

chrome: '60',

firefox: '60',

ie: '9',

safari: '10',

edge: '17'

}

}

]

],

// 开启babel缓存

// 第二次构建时,会读取之前的缓存

cacheDirectory: true

}

}

}

]

}

]

},

plugins:[

new HtmlWebpackPlugin({

template : './src/index.html',

// 压缩html代码

minify: {

// 移除空格

collapseWhitespace: true,

// 移除注释

removeComments: true

}

}),

// 使用单独生成css文件的插件,打包时会将css文件独立出去

new MiniCssExtractPlugin({

// 指定文件的输出路径和文件名

filename: 'css/index[contenthash:10].css'

}),

],

optimization: {

//这将使CSS优化只在生产模式。

// 如果你想在开发中运行它,设置优化。最小化选项为true:

minimizer: [

new CssMinimizerPlugin(),

],

minimize: true,

},

mode:'development',

devServer: {

//热加载 npx webpack server

static: {

directory: path.join(__dirname, 'build'),

},

compress: true,

port: 9000,

open: true,

/* hot: true*/

},

};

module.exports = config;

各位小伙伴们,由于webpack性能优化考虑的地方较多,所以先介绍到这里,后面会更新webpack性能二。创作不易,若你觉得对你有所帮助的话麻烦点赞关注一下哟。若有什么不足的地方,也麻烦各位大佬指点出来。

文章链接

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: