webpack优化

优化方向

在这里插入图片描述

热更新

概念

/**

  • hmr: hot module replacement 热模块替换 / 模块热更新
  • 作用: 一个模块发生改变,只会重新打包这一个模块(而不是打包所有模块),极大的提升了构建速度
  • 样式文件: 可以使用hmr功能: style-loader内部实现了热更新功能
  • js文件:默认没有这个功能(会全量刷新)—> 修改js代码,只能处理非入口文件
  • html文件: 默认没有这个功能(会全量刷新)因为项目中只有一个html文件,所以我们不需要做热更新
    */

实现

因为我们在开发环境使用的是webpack-dev-server,所以不需要额外的添加代码,hot默认值为true,自动会热更新。但是对于js我们需要额外的处理。
// 在入口文件中写如下代码

if (module.hot) {// 一旦 module.hot为true, 说明开启了热更新功能,--》让hmr功能代码生效module.hot.accept('./print.js',function() {// 方法会监听到print.js文件的变化,一旦发生变化,其他模块不会重新打包构建// 会执行回调函数print();})
}

source-map

是一种提供源代码到构建后代码的一种映射技术(如果构建后代码出错了,通过映射关系,可以追踪到源代码的错误)。

  1. 配置
  /*** 是一种提供源代码到构建后代码的一种映射技术(如果构建后代码出错了,通过映射关系,可以追踪到源代码的错误)。* [inline-|hidden-|eval-][nosources-][cheap-[module-]]source-map* source-map: 外联   错误代码的准确信息和源代码的错误位置* inline-source-map: 内联 (只生成一个source-map)  错误代码的准确信息和源代码的错误位置* hidden-source-map: 外联    错误代码的原因,但没有错误代码的位置,不能追踪源代码的错误,只能提示构建代码的位置 (防止代码泄露)* eval-source-map: 内联 (每个文件都生成一个source-map,都在eval中)   错误代码的准确信息和源代码的错误位置* nosources-source-map 外联  错误代码准确信息,但没有任何源代码信息 * cheap-source-map  外联   错误代码的准确信息和源代码的错误位置 只能精确到行,不能精确到列* cheap-module-source-map 外联  错误代码的准确信息和源代码的错误位置  module会将loader的source-map加入* * 内联和外联的区别:1. 外联生成了文件,内联没有 2.内联构建速度更快* * 使用:* 开发环境:* 速度快, (eval > inline > cheap) eval-cheap-source-map:速度最快 * 调试更友好 * source-map* cheap-module-source-map* cheap-source-map* *  ----> 开发环境使用:eval-source-map / eval-cheap-module-source-map* 生产环境:源代码要不要隐藏,调试要不要更友好* 内联会让包的体积非常大,所以生产环境一般不用内联* * 隐藏: * nosources-source-map (全部隐藏)*  hidden-source-map (部分隐藏)* 生产环境使用:source-map / cheap-module-source-map*  */  devtool: 'source-map'

oneOf

  • 使用
module:{rules:[{oneOf: [// loader ]}]
}

正常情况中我们每个文件都会被所有的loader“处理一下”,但是在oneOf中的loader,他匹配到之后就不会接着执行下面的loader了,所以oneOf,**可以提升构建速度 **,当一类文件,配置了多个的情况下,可以将其他的放到oneOf外面处理

缓存

  1. babel缓存

就是要在babel下,添加 cacheDirectory: true, 个人实验没啥效果(构建速度提升不明显)

 {//  1. js兼容性处理: babel-loader @babel/core  @babel/preset-env//  问题:babel只能转换基础的语法,如promise则不能进行转换//  2. 全部兼容  @babel/polyfill//  问题:可以解决兼容性问题,但是引入了所有的兼容性代码,体积太大//  3. 需要做兼容性的处理就ok,按需加载---> core-jstest: /\.js$/,exclude: /node_modules/,loader: 'babel-loader',options: {// 预设: 指示babel做怎样的兼容性处理presets: [['@babel/preset-env',{useBuiltIns: 'usage', //按需加载corejs: {version: 3, // 指定core-js版本},targets: {  // 指定兼容浏览器版本chrome: '60',firefox: '60',ie: '9',safari: '10',edge: '17'}}]],// 开启babel缓存,第二次构建,会读取之前的缓存cacheDirectory: true,}},
  1. 全局加cache ,构建速度显著提升(从2778ms–>419ms)
module.export = {cache: {type: 'filesystem',allowCollectingMemory: true,},
}
  1. 文件资源缓存,提升线上访问速度
// 通过修改文件名来实现缓存的效果,输出文件全部加上[contenthash:10]/*** 缓存* babel缓存:cacheDirectory:true  --》让代码第二次构建打包速度更快*  文件资源缓存*  hash: 每次webpack构建时会生成一个唯一的hash值*   问题: js和css同时使用一个hash值*   如何重新打包,会导致所有的缓存失效*   chunkhash: 根据chunk生成的hansh值,如果打包来源于同一个chunk,那么hash值就一样    chunkid modeid*   contenthash: 文件内容不变,hash值不变  ---》让代码线上运行缓存更好使用* */ 
例如:output: {filename: 'budle.[contenthash:10].js',path: resolve(__dirname,'build')},

tree sharking

去掉没有用的代码,只留下引用了的代码,减小代码体积。

/***  tree shaking 去除无用代码*  前提: 1. 必须使用es6模块化(使用import export 导入导出)  2. 开启production环境*  在package.json中配置*   "sideEffects": false 所有代码都没有副作用(度可以进行tree shaking)*   问题: 可能会把css /  @babel/polyfill 文件干掉*   解决:"sideEffects": ["*.css"]*   在sideEffects配置不需要删除的代码* */ 

code split

  1. 多入口

适合多页面开发

entry: {main: './src/index.js',test: './src/print.js'
}
output: {filename: '[name].[contenthash:10].js', // 这里的【name】,在入口文件中配置了, main test将成为文件名path: resolve(__dirname,'build');
}
  1. chunk
 // 将node_modules中代码单独打包成一个chunk最终输出  //  自动分析多入口chunk中有没有公共的文件,如果有会打包成单独一个chunkoptimization: {splitChunks: {chunks: 'all'}}
  1. import

注意:!!! 如果你配置了eslint,可能会报错,因为eslint不能够解析import动态引入的语法,不报错的话就不需要使用babel-eslint。

// 通过js代码,让某个文件单独被打包成一个chunk
// import动态导入
import(/* webpackChunkName: 'test' */'./print').then(({print,mul}) => {console.log(3, 6);
}).catch(e) {console.log("文件加载失败",e)
}

下载
npm i -D babel-eslint

在package.json文件中加入parser配置

 "eslintConfig": {"extends": "airbnb-base","parser": "babel-eslint","parserOptions": {"sourceType": "module", "allowImportExportEverywhere": true }},

懒加载

  1. 将import动态引入放入异步函数中
document.querySelector('#btn').onclick = function() {import(/*webpackChunkName: 'test'*/'./print').then(({mul}) => {console.log(mul(4, 5));}).catch((err) => {console.log(err)})
}

预加载

document.querySelector('#btn').onclick = function() {
// 懒加载: 当文件需要使用才加载
// prefetch: 预加载,提前加载js文件  等其他资源加载完毕,浏览器空闲了,在偷偷加载资源
// 正常加载:可以认为是并行加载(同一时间加载多个js文件)
import(/* webpackChunkName: 'test',webpackPrefetch: true */'./print')
.then(({ mul }) => {console.log(mul(3, 9));
})
.catch((e) => {console.log('文件加载失败',e);
})
}

PWA

  1. 下载插件

npm i -D workbox-webpack-plugin

  1. 代码 webpack.config.js中
/*** PWA: 渐进式网络开发应用程序(离线可访问)* workbox --> workbox-webpack-plugin*/
const WorkboxWebpackPlugin = require('workbox-webpack-plugin');
plugins: [// 生成一个serviceworker配置文件new WorkboxWebpackPlugin.GenerateSW({clientsClaim: true,  // 帮助serviceworker快速启动skipWaiting: true, // 删除旧的 serviceworker  })
]
  1. 入口文件
//  注册serviceworker
//  处理兼容性问题
// eslint不认识window navigator全局变量
// 解决: 修改package.json中的eslintConfig配置
//  "env": {
//    "browser": true
//  }
// servicework代码必须构建在服务器上
if ('serviceWorker' in navigator) {window.addEventListener('load',() => {navigator.serviceWorker.register('/service-worker.js').then(() => {console.log('serviceWorker注册成功')}).catch(() => {console.log('serviceWorker注册失败~')})})
}
  1. package.json文件中
"eslintConfig": {..."env": {"browser": true}},

多进程开发

  1. 下载

npm i thread-loader -D

  1. 代码
/*** 开启多进程打包                         * 进程启动大概600ms,进程通信也有开销                           * 只有工作消耗时间比较长,才需要多进程打包 * 一般用来处理js文件消耗比较大的时候使用* */                          
{loader: 'thread-loader',options: {workers: 3,}
},

externals

让一些额外的包,不打包到build.js中

externals: {jquery: '$', // 外部可以通过$直接访问,不需要引入了
},

index.html中引入jquery文件

 <scriptsrc="https://code.jquery.com/jquery-3.1.0.js"integrity="sha256-slogkvB1K3VOkzAI8QITxV3VzpOnkeNVsKvtkYLMjfk="crossorigin="anonymous"></script>

dll

  1. 根目录下创建webpack.dll.js文件
/*** 使用dll技术,对某些库(第三方库: jquery, react, vue...)进行单独打包* 当运行webpack时默认查找webpack.config.js配置文件* 需求: 我们需要运行webpack.dll.js文件    webpack --config ./webpack.dll.js* */ 
const { resolve } = require('path');
const webapck = require('webpack');module.exports = {entry: {// 最终打包生成的[name] ---> jqueryjquery: ['jquery']},output: {filename: '[name].js',path: resolve(__dirname, 'dll'),library: '[name]_[hash:10]', //打包的库里面向外暴露出去的内容名字},plugins: [// 打包生成一个 mainfest.json ---> 提供和jquery映射关系new webapck.DllPlugin({name: '[name]_[hash:10]', // 映射库暴露的内容名称path: resolve(__dirname, 'dll/mainfest.json') // 输出文件路径})],mode: 'production'
}
  1. 执行该文件

webpack -c ./webpack.dll.js -c是 --config缩写

  1. 下载包

npm i -D add-asset-html-webpack-plugin

  1. 在webpack.config.js中加入如下代码
plugins: [// 告诉webpack那些库不参与打包,同时使用时的名称也得改变new webpack.DllReferencePlugin({manifest: resolve(__dirname,'dll/mainfest.json')}),// 将某个文件打包输出去,并在html中自动引入该资源new AddAssetHtmlWebpackPlugin({filepath: resolve(__dirname, 'dll/jquery.js'),outputPath: 'auto', // 生成的index.html文件中多了一层auto目录}),
]

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/45991.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Facebook:数字时代的社交瑰宝

在当今数字化飞速发展的时代&#xff0c;社交媒体已经成为人们日常生活中不可或缺的一部分&#xff0c;而Facebook作为其中的领军者&#xff0c;不仅连接了全球数十亿的用户&#xff0c;更深刻地改变了人们的社交方式和生活方式。本文将探讨Facebook如何成为数字时代的社交瑰宝…

再谈有关JVM中的四种引用

1.强引用 强引用就是我们平时使用最多的那种引用&#xff0c;就比如以下的代码 //创建一个对象 Object obj new Object();//强引用 这个例子就是创建了一个对象并建立了强引用&#xff0c;强引用一般就是默认支持的当内存不足的时候&#xff0c;JVM开始垃圾回收&#xff0c…

防火墙的冗余基础知识+实验检测

将之前先理清需要注意的知识点&#xff1a; 1、注意防火墙冗余时的会话表必须保持一致&#xff0c;这里HRP技术已经做到 2、vrrp是自动开启抢占的&#xff0c;且是根据优先级进行抢占的 3、免费ARP的作用&#xff1a;告诉交换机的某个IP的mac地址变成了我的这个mac地址 4、HRP …

C++ | Leetcode C++题解之第231题2的幂

题目&#xff1a; 题解&#xff1a; class Solution { private:static constexpr int BIG 1 << 30;public:bool isPowerOfTwo(int n) {return n > 0 && BIG % n 0;} };

强化学习——多臂老虎机问题(MAB)【附python代码】

文章目录 一、问题描述1.1 问题定义1.2 形式化描述1.3 累积懊悔1.4 估计期望奖励 二、解决方法2.1 ϵ-贪婪算法2.2 上置信界算法2.3 汤普森采样算法2.4 小结 一、问题描述 1.1 问题定义 有一个用于 K 根拉杆的老虎机&#xff0c;每一根拉杆都对应一个关于奖励的概率分布 R 。每…

【C++题解】1154. 数组元素的查找

问题&#xff1a;1154. 数组元素的查找 类型&#xff1a;数组找数 题目描述&#xff1a; 给你 m 个整数&#xff0c;查找其中有无值为 n 的数&#xff0c;有则输出该数第一次出现的位置,没有则输出 −1 。 输入&#xff1a; 第一行一个整数 m 代表数的个数 ( 0≤m≤100 ) 。…

Qt基础 | Qt全局定义 | qglobal头文件中的数据类型、函数、宏定义

文章目录 一、数据类型定义二、函数三、宏定义 QtGlobal头文件包含了 Qt 类库的一些全局定义 &#xff0c;包括基本数据类型、函数和宏&#xff0c;一般的Qt类的头文件都会包含该文件。 详细内容可参考&#xff1a;https://doc.qt.io/qt-5/qtglobal.html 一、数据类型定义 为了…

数据可视化在智慧医疗中的重要应用

在现代智慧医疗的推动下&#xff0c;数据可视化技术正日益成为医疗领域的重要工具。通过将复杂的医疗数据转换为直观的图表和图形&#xff0c;数据可视化不仅提升了医疗服务的效率&#xff0c;还极大地改善了患者的就医体验。 在智慧医疗中&#xff0c;数据可视化首先在电子病历…

客流统计系统优化景区服务流程,增强游客满意度

在当今旅游业蓬勃发展的时代&#xff0c;景区面临着越来越多的挑战和机遇。如何提供更优质、更高效的服务&#xff0c;满足游客日益增长的需求&#xff0c;成为了景区管理者们关注的焦点。客流统计系统作为一种创新的技术手段&#xff0c;正逐渐成为优化景区服务流程、增强游客…

MySQL主从同步的原理与思考

摘要 分析主从同步出现的原因&#xff0c;MySQL实现主从同步的原理&#xff0c;思考实现原理的局限性和优点 背景 在实际应用中主从同步常用于实现备份、负载均衡和高可用。数据冗余的目的是提高数据的安全性&#xff0c;避免因磁盘损坏导致数据丢失的问题。读写分离的目的是…

基于CNN的MINIST手写数字识别项目代码以及原理详解

文章目录 项目简介项目下载地址项目开发软件环境项目开发硬件环境前言一、数据加载的作用二、Pytorch进行数据加载所需工具2.1 Dataset2.2 Dataloader2.3 Torchvision2.4 Torchtext2.5 加载项目需要使用的库 三、加载MINIST数据集3.1 数据集简介3.2 数据预处理3.3 加载数据集 四…

2.10、matlab中字符、数字、矩阵、字符串和元胞合并为字符串并将字符串以不同格式写入读出excel

1、前言 在 MATLAB 中&#xff0c;可以使用不同的数据类型&#xff08;字符、数字、矩阵、字符串和元胞&#xff09;合并为字符串&#xff0c;然后将字符串以不同格式写入 Excel 文件。 以下是一个示例代码&#xff0c;展示如何将不同数据类型合并为字符串&#xff0c;并以不…

重生奇迹mu魔法师瞬间移动技能

瞬间移动是勇士大陆魔法师所拥有的一项技能。一开始&#xff0c;许多玩家对这种技能的用处感到困惑。实际上&#xff0c;这种技能只能在游戏中不同的位置间进行移动&#xff0c;不能随机传送到地图的其他坐标位置。 一位重生奇迹mu魔法师在PK中不小心使用了一项技能&#xff0c…

labview使用斑马打印机打印标签

使用ZebraDesigner 3设计标签样式 设计完成后打印至文件&#xff0c;生成prn文件 用记事本打开prn文件 ^MMT 标签撕下 ^MMP 标签剥离 按照需求替换FD--------^FS中间内容

路由上传一个ui_control参数(uint32类型)控制页面UI显隐

前言&#xff1a;传一个uint32类型的值&#xff0c;通过 按位或操作符&#xff08;|&#xff09;来设置ui_control的值&#xff0c;通过按位与操作符&#xff08;&&#xff09;来检测是否显示或隐藏 简单介绍一下两个概念&#xff1a; 按位与操作符和按位或操作符都是二进…

etcd的备份与恢复

一 为什么使用etcd 与ZooKeeper相比&#xff0c;etcd更简单&#xff0c;安装、部署和使用更加容易&#xff0c;并且etcd的某些功能是ZooKeeper所没有的。因此&#xff0c;在很多场景下&#xff0c;etcd 比ZooKeeper更受用户的青&#xff0c;具体表现在如下几个方面: 1 etcd更…

鑫创SSS1700USB音频桥芯片USB转IIS芯片

鑫创SSS1700支持IIC初始外部编&#xff08;EEPROM选项),两线串行总线&#xff08;I2C总线&#xff09;用于外部MCU控制整个EEPROM空间可以通过MCU访问用于主机控制同步的USB HID外部串行EEPROM&#xff08;24C02~24C16&#xff09;接口&#xff0c;用于客户特定的USB视频、PID、…

jmeter之变量随机参数化以及解决多线程不会随机变化

参考链接&#xff1a; https://www.cnblogs.com/Testing1105/p/12743475.html jmeter 使用random函数多线程运行时数据不会随机变化&#xff1f;_jmeter 线程组循环执行时 变量不变-CSDN博客 1、如下图所示&#xff0c;需要对请求参数 autor 和phone进行随机参数化 2、目前有…

MyBatis源码中的设计模式2

组合模式的应用 组合模式介绍 组合模式(Composite Pattern) 的定义是&#xff1a;将对象组合成树形结构以表示整体和部分的层次结构。组合模式可以让用户统一对待单个对象和对象的组合。 比如&#xff1a;Windows操作系统中的目录结构&#xff0c;通过tree命令实现树形结构展…

【系统架构设计师】十二、系统质量属性与架构评估(开发期质量属性|运行期质量属性|面向架构评估的质量属性|质量属性效用树|质量属性场景)

目录 一、软件系统质量属性 1.1 开发期质量属性 1.2 运行期质量属性 1.3 面向架构评估的质量属性 1.4 质量属性效用树 1.5 质量属性场景 1.5.1 可用性质量属性场景描述 1.5.2 可修改性质量属性场景描述 1.5.3 性能质量属性场景描述 相关推荐 历年真题练习 历…