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

webpack5(高级)

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

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

一、提升开发体验

1. sourceMap

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

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

..
..
loader
pligins
mode
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的处理和检查。

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

4、打包缓存

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

用法:

babel在options中开启缓存:

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

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

new ESLintPlugin({
    cache:true,
})

5.多进程打包

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

使用:

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

 三、减少代码体积

1.Tree Shaking

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

2.@babel/plugin-transform-runtime

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

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

{
    loader:"babel-loader",
    options:{
        ...
        plugins:["@babel/plugin-tranform-runtime"],
    }
}

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

module.exports = {
    entry:{
        app:"./src/app.js",
        main:"./src/main.js",
    },
    output:{
        path:path.resolve(__dirname,"dist"),
        filename:"[name].js",//webpack,命名方式,[name]以文件名自己命名
    }
}

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

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

 修改配置:

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

使用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、引入、使用

import preloadWebpackPlugin from "@vue/preload-webpack-plugin"

export default{
    plugins:[
        new preloadWebpackPlugin({
            rel:"preload",
            as:"script",
            //rel:"prefetch"  //不需要as
        })
    ]
}

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

3.network cache

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

使用:

optimization:{
    runtimeChunk:{
        name:(entrypoint)=>`runtime~${entrypoint.name}.js`,
    }
}

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中进行配置)

module.exports = {
    presets:[
        [
            "@babel/preset-env",
            {
                useBuiltIns: "usege",//按需引入
                corejs:3,
            }
        ]
    ]
}

5.离线缓存PWA

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

使用:

plugins中:

 main.js中:

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

相关文章:

  • Python从入门到数据分析第一篇—Python简介- Python介绍与初探
  • Element-UI+Vue实现主页布局——侧边栏用户布局(上)
  • java16-多线程
  • 数据分析可视化03 技术框架:数据可视化分析的两种武器
  • 模拟实现atoi
  • Go 和 C# 的速度比较来了
  • 谷歌Guava LoadingCache介绍
  • 第二章:微服务架构构建
  • Python 基础阶段
  • 我发现凡是给offer的公司,面试时基本不问技术细节,那些问得又多又细的公司,后面就没下文了
  • 【微搭低代码】JavaScript基础知识-变量定义及初始化
  • Linux常见指令(下)
  • Vue组件学习、组件通信
  • 西瓜书研读——第五章 神经网络:BP神经网络
  • 有了这个库,这些爬虫都不用亲自写了!
  • 【Redis学习笔记】2018-06-28 redis命令源码学习1
  • 【翻译】Mashape是如何管理15000个API和微服务的(三)
  • 【跃迁之路】【735天】程序员高效学习方法论探索系列(实验阶段492-2019.2.25)...
  • Bootstrap JS插件Alert源码分析
  • CentOS学习笔记 - 12. Nginx搭建Centos7.5远程repo
  • ESLint简单操作
  • happypack两次报错的问题
  • input实现文字超出省略号功能
  • java2019面试题北京
  • JavaScript对象详解
  • nodejs调试方法
  • PAT A1050
  • spring boot 整合mybatis 无法输出sql的问题
  • ⭐ Unity 开发bug —— 打包后shader失效或者bug (我这里用Shader做两张图片的合并发现了问题)
  • Wamp集成环境 添加PHP的新版本
  • 飞驰在Mesos的涡轮引擎上
  • 关于Java中分层中遇到的一些问题
  • 让你的分享飞起来——极光推出社会化分享组件
  • 一个普通的 5 年iOS开发者的自我总结,以及5年开发经历和感想!
  • 用Canvas画一棵二叉树
  • 正则表达式小结
  • 曜石科技宣布获得千万级天使轮投资,全方面布局电竞产业链 ...
  • ​secrets --- 生成管理密码的安全随机数​
  • #mysql 8.0 踩坑日记
  • #ubuntu# #git# repository git config --global --add safe.directory
  • (1)虚拟机的安装与使用,linux系统安装
  • (三)c52学习之旅-点亮LED灯
  • (学习日记)2024.01.19
  • (原)Matlab的svmtrain和svmclassify
  • .equals()到底是什么意思?
  • .net安装_还在用第三方安装.NET?Win10自带.NET3.5安装
  • .NET国产化改造探索(三)、银河麒麟安装.NET 8环境
  • .net中调用windows performance记录性能信息
  • /boot 内存空间不够
  • @Bean有哪些属性
  • [ 手记 ] 关于tomcat开机启动设置问题
  • [Android]创建TabBar
  • [Android]使用Retrofit进行网络请求
  • [C# 开发技巧]实现属于自己的截图工具
  • [C#]C# OpenVINO部署yolov8图像分类模型