• webpack5(高级)


    主要讲解如何进行webpack优化(why,what,how)。从以下几点优化角度来介绍:

    • 提升开发体验
    • 提升打包构建速度
    • 减少代码体积
    • 优化代码运行性能

    一、提升开发体验

    1. sourceMap

    作用:为解决构建后代码出错位置难定位的问题。它会生成一个.map文件,里面包含源代码和构建后代码的映射关系,帮助定位原文件中对应位置。

    用法:在配置文件中新增一个配置

    1. ..
    2. ..
    3. loader
    4. pligins
    5. mode
    6. devtool:"cheap-module-source-map",//生产环境用"source-map"

    cheap-module-source-map:只有行的映射关系

    source-map:有行、列的映射

    二、提升打包速度

    1.HotModuleReplacement(只有开发模式使用)

    作用:开发时只改变某个文件而要重新打包,却需要将所有模块全部重新打包,速度慢。HMR可以实现在程序运行中增删改模块,而无需重新加载整个页面。(webpack5中是默认配置,在devServer中,hot:false可以关闭HMR)

    注:js不会默认开启HMR,需要手动配置。在vue或react项目中,有相应loader可以帮助js开启HMR

    2.OneOf

    只用一个loader处理文件,而不需要每个loader都看一遍

    3.include/exclude

    只能用一个,常用于处理js文件时(babel、eslint),排除对node_modules的处理和检查。

    1. relus:[
    2. test:/\.js/,
    3. include:path.resolve(__dirname,"../src"),只处理src下的文件
    4. //exclude:/node_mudules/,排除node_modules
    5. loader:"babel-loader",
    6. ]

    4、打包缓存

    作用:第二次及以后的打包时,不用打包所有,只对修改的文件进行重新打包。(babel、eslint)

    用法:

    babel在options中开启缓存:

    1. options:{
    2. cacheDirectory:true,//开启babel缓存
    3. cacheCompression:false,//关闭缓存文件压缩
    4. }

    eslint在新建ESLintPlugin时,传参数(已经默认开启缓存):

    1. new ESLintPlugin({
    2. cache:true,
    3. })

    5.多进程打包

    作用:对js文件的babel、eslint、等处理,开启多进程。

    使用:

    1. 获取cpu数量:
      const threads = require("os").cpus(  ).length
    2. babel-loader中:
      1. use:[ //当使用多个loader时,就用rules:[]
      2. {
      3. loader:"thread-loader",//开启多进程
      4. options:{
      5. works:threads,//进程数
      6. }
      7. },
      8. {
      9. loader:"babel-loader",
      10. ...
      11. }
      12. ]
    3. eslint中:
      1. new ESLintPlugin({
      2. ...
      3. threads:threads,
      4. })
    4. terser中:
      1. optimization:{
      2. new CssMinimizerPlugin(),//css压缩,webpack5以后习惯放在optimization配置中了
      3. new TerserWebpackPlugin({ //js压缩,一般只在生产模式使用
      4. parallel:threads,
      5. }),
      6. }

     三、减少代码体积

    1.Tree Shaking

    作用:移除js中没有使用到的代码。依赖ES模块化,默认已开启。

    2.@babel/plugin-transform-runtime

    作用:babel为编译的每个文件都插入了辅助代码,是代码体积过大,使用以上插件可以将辅助代码作为一个独立模块避免重复引入。

    使用:安装插件后,在使用babel-loader是,将其添加到options中:

    1. {
    2. loader:"babel-loader",
    3. options:{
    4. ...
    5. plugins:["@babel/plugin-tranform-runtime"],
    6. }
    7. }

    3.压缩本地图片(非链接引入):image-minimazer-webpack-plugin

     作用:压缩本地图片

    使用:

    首先下载两个包:image-minimizer-webpack-plugin、imagemin

    无损压缩再需要下载:imagemin-gifsicle、imagemin-jpegtran、imagemin-optipng、imagemin-svgo

    有损压缩再需要下载:imagemin-gifsicle、imagemin-mozjpeg、imagemin-pngquant、imagemin-svgo

     四、优化代码运行性能

    1.Code Split、懒加载

    作用:为了在后续使用预加载懒加载等技术,所以不能将所有js文件打包到一个文件中,而需要将代码进行分割。实现按需加载,这样请求数量少,速度更快。

    使用1:多入口entry

    1. module.exports = {
    2. entry:{
    3. app:"./src/app.js",
    4. main:"./src/main.js",
    5. },
    6. output:{
    7. path:path.resolve(__dirname,"dist"),
    8. filename:"[name].js",//webpack,命名方式,[name]以文件名自己命名
    9. }
    10. }

    使用2: 复用 splitChunks。当多个入口对应的模块有公共代码,想要把这些公共代码提取成一个单独的,使用时再引入。

    1. optimization:{
    2. splitChunks:{
    3. chunks:"all",//对所有模块都进行分割
    4. ... //下面是一些默认配置粘在下面的图里
    5. }
    6. }

     修改配置:

    1. cacheGroups:{
    2. ...
    3. default:{
    4. minSize:0,//打包文件的最小体积
    5. minChunk:2,//被引用两次以上就单独打包
    6. priority:-20,
    7. reuseExistingChunk:true,
    8. }
    9. }

    使用3:按需加载 

    例如vue中的组件按需加载import,在组件展示时才去加载。如果使用了import,webpack会自动将动态导入的文件代码拆分成单独的模块,在使用时才自动加载。

    打包输出的文件名是随机数命名,不方便后续追踪,如何给文件取名?        1)在文件导入时给文件命名 import(/*webpackChunkName: "mychunkname" */ "./js/mychunk")         2)在output中添加配置项:chunkFilename:"static/js/[name].js"

    2.preload、prefetch 预加载

    作用:在文件还没使用的时候,且浏览器空闲,将这些文件加载回来。

    preload:立即加载,优先级高,只能加载当前页面需要使用的资源,兼容性更好

    prefetch:空闲时加载,优先级低,可以加载当前页面和下一页面所用资源,兼容性差

    使用:安装@vue/preload-webpack-plugin、引入、使用

    1. import preloadWebpackPlugin from "@vue/preload-webpack-plugin"
    2. export default{
    3. plugins:[
    4. new preloadWebpackPlugin({
    5. rel:"preload",
    6. as:"script",
    7. //rel:"prefetch" //不需要as
    8. })
    9. ]
    10. }

    注:一般在加载当前页且优先级较高时用preload,加载其他页资源时用prefetch.

    3.network cache

    作用:当一个文件内容改变,这个文件的hash名也变化,那么依赖这个文件的其他文件由于使用了这个文件名,导致其他文件内容也改变了,所以其他文件的hash也变了,缓存就失效了。对于缓存不友好。为解决以上问题,在optimization中配置runtimeChunk,从而生成一个runtime文件,类似于映射文件,能保证依赖文件hash不变。

    使用:

    1. optimization:{
    2. runtimeChunk:{
    3. name:(entrypoint)=>`runtime~${entrypoint.name}.js`,
    4. }
    5. }

    4.core-js

    作用:es6以上API无法用babel做处理,例如promise、数组的一些高级语法等。core-js是专门用来做polyfill(补丁)的。就是用社区上提供的一段代码,让我们在低版本浏览器上使用高级语法。

    使用1:安装core-js,并将core-js全部引入。

    import 'core-js'

    使用2:按需加载

    import 'core-js/es/promise'

    使用3:自动引入 (在babel.config.js中进行配置)

    1. module.exports = {
    2. presets:[
    3. [
    4. "@babel/preset-env",
    5. {
    6. useBuiltIns: "usege",//按需引入
    7. corejs:3,
    8. }
    9. ]
    10. ]
    11. }

    5.离线缓存PWA

    作用:web端的离线缓存。插件叫做 workbox-webpack-plugin。兼容性差

    使用:

    plugins中:

     main.js中:

     有可能因为路径问题导致加载失败,需要用serve这个包部署静态资源服务器。

  • 相关阅读:
    优化预算管理流程:Web端实现预算编制的利器
    万宾科技智能井盖,实现对井盖的监测
    【第五部分 | JS WebAPI】5:1W字详解Bom对象
    java健身房信息管理系统计算机毕业设计MyBatis+系统+LW文档+源码+调试部署
    marquee标签的用法
    Three.js 绘制动态模型
    【webpack】HMR热更新原理
    .net core 3.0 NLog 日志的使用
    物联网“遇上”云原生,会擦出怎样的火花?
    (附源码)springboot高校宿舍交电费系统 毕业设计 031552
  • 原文地址:https://blog.csdn.net/qq_36582776/article/details/127162737