webpack5 (三)

 webpack 高级配置

其实就是对 webpack 进行优化,让代码在编译/运行时性能更好

1. 提升开发体验
2. 提升打包构建速度
3. 减少代码体积
4. 优化代码运行性能

一、提升开发体验

sourcemap

在编译打包后所有的 css 和 js 都合并为了一个文件,并多了很多其他代码,如果此时代码运行出错,提示的错误位置很难定位。所以开发者需要更准确的错误提示来进行开发工作。

SourceMap 源代码映射,是一个用来生成源代码与构建后代码一一映射的文件的方案。

它会生成一个 xxx.map 文件,里面包含源代码和构建后代码每一行、每一列的映射关系。当构建后代码出错后,会通过 xxx.map 文件,从构建后代码的出错位置找到映射后源代码的出错位置,从而让浏览器提示源代码的错误位置。

使用:

Devtool | webpack 中文文档 | webpack 中文文档 | webpack 中文网

实际开发中只需要关注两种情况:

  • 开发模式:cheap-module-source-map
    • 优点:打包编译速度快,只包含行映射
    • 缺点:没有列映射
module.export = {//其他省略mode:'development',devtool:'cheap-module-source-map'};
  • 生产模式:source-map
    • 优点:包含行/列映射
    • 缺点:打包编译速度更慢
module.export = {//其他省略mode:'production',devtool:'source-map'};

生产模式下一定要关心列的位置,因为生产模式打完完成后只有一行代码,如果不看列位置,也就无法定位错误位置。

二、提升打包构建速度

HMR(HotModuleReplacement)热模块替换

只在开发模式下有效,生产模式中是不存在的。

开发时如果修改了其中某一个模块的代码,webpack 默认会将所有模块全部重新打包编译,速度比较慢。

所以需要做到修改某个模块的代码时,就只有这个模块的代码需要重新打包编译,其他的模块不变,这样打包的速度也会更快。

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

HotModuleReplacementPlugin | webpack 中文文档 | webpack 中文文档 | webpack 中文网

css 经过 style-loader 处理已经具备 HMR 的功能了,但是 js 还不行,在实际开发中,一般使用其他 loader 来解决。比如 vue-loader 和 react-hot-loader 。 

oneOf

正常文件在进入配置文件时,是会查看所有的loader的,即使 css 文件在第一个 css-loader 已经进行处理后,也会将全部 loader 都查看一遍。

oneOf 让文件只让一个 loader 进行处理。

只需要将 rule 下的 loader 都用 oneOf 包裹起来就可以了。这样在执行时,如果第一个 loader 被命中,就不会再查看后续 loader。

module.exports = {//...module: {rules: [{test: /\.css$/,oneOf: [{resourceQuery: /inline/, // foo.css?inlineuse: 'url-loader',},{resourceQuery: /external/, // foo.css?externaluse: 'file-loader',},],},],},
};

include/exclude 只针对 js 文件进行处理

开发时需要使用第三方的库或者插件,所有文件都下载到 node_modules 文件夹中,而这些文件是不需要编译,可以直接使用的。

所以在对 js 文件进行打包处理时,需要排除 node_modules 文件夹下目录。

  • include 包含,只处理 xxx 文件
  • exclude 排除,除了 xxx 文件以外的其他文件都被处理。

只是用来处理 js 文件的,样式文件等都不可用

 只能使用一个,不能同时使用 

cache

每次打包时 js 文件都要经过 Eslint 检查和 babel 编译,速度比较慢。可以设置缓存之前的 Eslint 检查和 babel 编译结果,这样二次打包时速度就会更快。

作用就是对 Eslint 检查和 babel 编译结果进行缓存。

    // 配置loadermodule: {rules: [// 处理 js{test:/\.jsx?$/,include:path.resolve(__dirname,'../src'),loader:'babel-loader',//babel 也需要有一个 babel 的配置文件options:{catchDirectory:true,catchCompression:false,plugins:['react-refresh/babel',//用来解决react脚手架下 js不能热更新的问题]}}]},// 配置plugin// 处理html plugin:[//eslint 插件也是需要有自己的配置文件new EslintWebpackPlugin({context:path.resolve(__dirname,'../src'),exclude:'node_modules',cache:true, cacheLocation:path.resolve(__dirname,'../node_modules/.catch/.eslintcache'),}),new HtmlWebpackPlugin({template:path.resolve(__dirname,'../public/index.html'),}),new ReactRefreshWebpackPlugin()//用来解决react脚手架下 js不能热更新的问题],

 Thead

当项目越来越大时,打包的速度会越来越慢,想要继续提升打包速度,其实就是要提升 js 的打包速度(因为 js 文件是量最多的),而对 js 文件处理主要是三个工具:eslint、babel、Terser 三个工具,所以需要提升工具的运行速度。

可以开启多进程同时处理 js 文件,这样速度就会比之前的单进程打包更快。

⚠️注意:开启多线程仅需要在特别耗时的操作中使用,因为每个进程启动大概就会有 600 ms的开销。

启动进程的数量就是 CPU 的核数,获取 cpu 核数:

// node js 的核心模块,可以直接使用

const os = require('os');

// cpu 核数

const threads = os.cpus().length;

const TerserPlugin = require("terser-webpack-plugin");module.exports = {optimization: {minimize: true,minimizer: [new TerserPlugin({parallel: threads,//启用多进程并发运行并设置并发运行次数})],},
};

 optimization 选项专门用来放置压缩文件插件的,css、js、图片等压缩插件都可以在里面 new。

三、减少代码体积

Tree Shaking

开发时会定义一些工具函数库,或者引用第三方工具函数库或组件库。

如果没有经过特殊处理,打包时会引入整个库,但是实际上可能业务中只用到了极小一部分功能,整个库打包进代码体积过大。

Tree Shaking 是一个术语,描述为移除 js 中没有使用上的代码。依赖于 ES Module。

webpack 已经默认开启了该功能,无需其他配置。

babel

babel-loader | webpack 中文文档 | webpack 中文文档 | webpack 中文网

babel 为编译的每个文件都插入了辅助代码,使代码体积比较大,babel对一些公共方法使用了非常小的辅助代码,如_extend。默认情况下会被添加到每一个需要它的文件中。可以将这些辅助代码 Babel runtime 作为一个独立的模块,来避免重复引入。

下面的配置禁用了 Babel 自动对每个文件的 runtime 注入,而是引入 @babel/plugin-transform-runtime 并且使所有辅助代码从这里引用。

rules: [// 'transform-runtime' 插件告诉 Babel// 要引用 runtime 来代替注入。{test: /\.m?js$/,exclude: /(node_modules|bower_components)/,use: {loader: 'babel-loader',options: {presets: ['@babel/preset-env'],plugins: ['@babel/plugin-transform-runtime']}}}
]

Image Minimizer

ImageMinimizerWebpackPlugin | webpack 中文文档 | webpack 中文文档 | webpack 中文网

开发的项目中如果引用了较多的图片,那么图片体积就会比较大,将来请求的速度比较慢,可以对图片进行压缩,减少图片体积。

⚠️注意:如果项目中图片为在线链接,就不用压缩,压缩的前提是必须为本地项目静态图片

四、优化代码的运行性能

Code Split

打包代码时,会将所有的 js 文件打包到一个文件中,体积太大了。如果只渲染首页,就应该只加载首页的 js 文件,其他文件暂时不加载。

所以需要对打包生成的文件进行代码分割,生成多个 js 文件,渲染哪个页面就只加载某个js文件,这样加载的资源少,速度更快。

代码分割(Code Split)主要做了两件事:

  1. 分割文件:将打包生成的文件进行分割,生成多个 js 文件。
  2. 按需加载:需要哪个文件就加载哪个文件。​

多入口

    entry: {//多个入口文件main: './src/main.js',app: './src/app.js',},output: {path: path.resolve(__dirname, '../dist'),//设置出口文件路径filename: 'static/js/[name].[contenthash:10].js',//加入哈希值chunkFilename: 'static/js/[name].[contenthash:10].chunk.js',//加入哈希值assetModuleFilename: 'static/media/[hash:10][etx][query]',clean: true,//将上次打包内容清空},

多入口提取公共组件

在多个入口文件存在着相同的模块时,将相同部分单独抽离出来,变成可复用的文件。在 optimization 模块下的设置 splitChunks 。

optimization: {//代码分割配置splitChunks: {chunks: 'all'},
}

按需加载 动态引入

import 动态导入,会将动态导入的文件进行代码分割,拆分成单独的模块,在需要的时候自动加载。

单文件 单入口

如果在进行动态导入时,eslint 不能识别,需要在 eslint 配置文件中进行单独配置,设置 plugins:["import"],用来解决动态导入语法报错。

统一命名规则

需要用到的地方:

output 中入口文件打包输出的文件名 filename,动态加载打包输出的其他文件名 chunkFilename。loader 模块 module 中图片、字体图标等命名 filename。
plugins 插件中打包样式的命名 filename 。

    output: {path: path.resolve(__dirname, '../dist'),//设置出口文件路径filename: 'static/js/[name].[contenthash:10].js',//加入哈希值chunkFilename: 'static/js/[name].[contenthash:10].chunk.js',//加入哈希值assetModuleFilename: 'static/media/[hash:10][etx][query]',clean: true,//将上次打包内容清空},

Preload/ Prefetch

前面使用的代码分割,同时会使用动态导入语法来进行按需加载(懒加载)。但是加载速度不够好,比如:

当用户点击按钮时才加载这个资源,如果资源的体积很大,那么用户会感觉到卡顿。

如果想在浏览器空闲时间,加载后续需要使用的资源,就用到 preload/prefetch 技术。

  • Preload:通知浏览器立即加载资源。
  • Prefetch:通知浏览器在空闲时间时才开始加载资源。

共同点:

  • 都只会加载资源,并不执行。
  • 都有缓存。

不同点:

  • preload 加载的优先级高;prefetch 加载优先级低。
  • preload只能加载当前页面需要使用的资源;prefetch可以加载当前页面资源,也可以加载下一个页面需要使用的资源。

在当前页面优先级高的资源用 preload 加载,下一个页面需要使用的资源用 prefetch 加载。二者的兼容性都比较差,preload 相对于 prefetch 兼容性好一点,可以去Can I Use 网站查询 API 的兼容性问题。

Network Cache

如果 a 文件依赖于 b 文件,而 b 文件进行了修改,那么 a 文件也需要重新打包,为了解决这种问题,需要把文件依赖的哈希值抽成一个 runtime 文件,这样在依赖发生修改时,只有该依赖文件和 runtime 文件的缓存失效,缓存更持久化。

CoreJs

解决 js 兼容性问题

过去使用 babel 对 js 代码进行兼容性处理,其中使用@babel/preset-env 智能预设来处理兼容性问题。它能将 ES6 的一些语法进行编译转换,比如箭头函数,扩展运算符等。但是如果是 async 函数、promise 对象、数组的一些方法等,就没有办法处理。

所以此时代码中依然存在着 js 兼容性问题,一旦遇到低版本浏览器会直接报错。所以用 core-js 来解决。

core-js 是专门用来做 ES6 及以上 API 的 polyfill。polyfill 翻译为垫片/补丁,就是用社区上提供的一段代码,让在不兼容某些新特性的浏览器上使用该新特性。​

方式一:入口文件 main.js 直接引入

import 'core-js';

按需加载:import 'core-js/es/promise';(只使用promise),需要使用什么新语法就直接加载哪个包,但此时也会带来新的问题,在代码越写越多时,一旦用到新写法都要进行重新引入。

方式二: babel 配置文件的智能预设选项

module.exports = {presets: [['@babel/preset-env',{useBuiltins:"usage"//按需加载 自动引入corejs:3 //corejs版本}]],
};

PWA

 

​ 

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

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

相关文章

APS系统设计经验分享(时间推导II - 2023.09)

在前一篇关于APS系统设计分享文章(《APS系统设计经验分享(时间推导 - 2023.03)》)中,我们提到将会分享使用OptaPlanner作为规划引擎开发APS系统过程中,遇到的一些时间相关的设计建议与异常情况分析。后来一直忙于项目工作,直到现在才想起仍欠…

CC-TAIX01 HONEYWELL 霍尼韦尔连接工厂热智商远程监测系统

CC-TAIX01 HONEYWELL 霍尼韦尔连接工厂热智商远程监测系统 -霍尼韦尔宣布霍尼韦尔连接工厂热智商,一种基于云的远程监测系统,旨在监测和管理关键的热过程数据。这是霍尼韦尔资产绩效管理(APM)投资组合的一部分。 热智商是工业和商业热应用的远程监测解决方案。它将燃烧设备连…

Flink基础实操-计算单词出现次数

🥇🥇【大数据学习记录篇】-持续更新中~🥇🥇 个人主页:beixi 本文章收录于专栏(点击传送):【大数据学习】 💓💓持续更新中,感谢各位前辈朋友们支持…

【云原生】容器编排工具Kubernetes

目录 一、 K8S介绍 官网地址: 1.1docker编排与k8s编排相比 1.2特性 1.3功能 二、K8S重要组件 2.1核心组件 (1)Kube-apiserver (2)Kube-controller-manager (3)Kube-scheduler &#x…

DevOps管理软件生命周期

整体的软件开发流程 PLAN:开发团队根据客户的目标制定开发计划 CODE:根据PLAN开始编码过程,需要将不同版本的代码存储在一个库中。GIT,SVN BUILD:编码完成后,需要将代码构建并且运行。MAVEN TEST:成功构建…

【性能优化】聊聊性能优化那些事

针对于互联网应用来说,性能优化其实就是一直需要做的事情,因为系统响应慢,是非常影响用户的体验,可能回造成用户流失。所以对于性能非常重要。最近正好接到一个性能优化的需求,需要对所负责的系统进行性能提升。目前接…

Windows环境下RabbitMQ下载安装

一、准备安装文件 1、下载Erlang 登录网站Downloads - Erlang/OTP,选择“Download Windows installer”,如下图所示: 弹出框中,选在下载保存地址,保存文件,如下图所示: 2、下载RabbitMQ 登录…

ElasticSearch简介

一、基本概念 1、Index(索引) 动词,相当于 MySQL 中的 insert; 名词,相当于 MySQL 中的 Database 2、Type(类型) 在 Index(索引)中,可以定义一个或多个类…

无需公网IP,在家SSH远程连接公司内网服务器「cpolar内网穿透」

文章目录 1. Linux CentOS安装cpolar2. 创建TCP隧道3. 随机地址公网远程连接4. 固定TCP地址5. 使用固定公网TCP地址SSH远程 本次教程我们来实现如何在外公网环境下,SSH远程连接家里/公司的Linux CentOS服务器,无需公网IP,也不需要设置路由器。…

unity tolua热更新框架教程(2)

Lua启动流程 增加脚本luamain,继承luaclient 建立第一个场景GameMain,在对象GameMain挂载脚本LuaMain,启动场景 看到打印,lua被成功加载 lua入口及调用堆栈 这里会执行main.lua文件的main函数 C#接口导出 在此处配置C#导出的代码 …

【Python】爬虫练习-爬取豆瓣网电影评论用户的观影习惯数据

目录 前言 一、配置环境 1.1、 安装Python 1.2、 安装Requests库和BeautifulSoup库 1.3.、安装Matplotlib 二、登录豆瓣网(重点) 2.1、获取代理 2.2、测试代理ip是否可用 2.3、设置大量请求头随机使用 2.4、登录豆瓣网 三、爬取某一部热门电影…

【51单片机实验笔记】声学篇(一) 蜂鸣器基本控制

目录 前言硬件介绍PWM基础蜂鸣器简介 原理图分析蜂鸣器驱动电路 软件实现蜂鸣器短鸣蜂鸣器功能封装 总结 前言 蜂鸣器在生活中的应用实则相当广泛。通过本章你将学会制造噪声 (笑~)你将学会驱动它们,并发出响声。 硬件介绍 PWM基础 占空比…

shell bash中设置命令set

1 Preface/Foreword set命令用于shell脚本在执行命令时候,遇到异常的处理机制。 2 Usage 2.1 set -e 当执行命令过程中遇到异常,那么就退出脚本,不会往下执行其它命令。 #!/bin/bash #set -eroot GIT_TAG${CI_BUILD_TAG-NOTAG} GIT_REV…

设计模式之建造者模式与原型模式

目录 建造者模式 简介 使用场景 优缺点 模式结构 实现 原型模式 简介 应用场景 优缺点 模式结构 实现 建造者模式 简介 将复杂对象的构建与表示进行分离,使得同样的构建过程可以创建不同的表示。是一个将复杂的对象分解为多个简单的对象,然…

npm版本升级报错

解决方法: 执行npm install --legacy-peer-deps依赖对等 npm install xxx --legacy-peer-deps命令用于绕过peerDependency里依赖的自动安装;它告诉npm忽略项目中引入的各个依赖模块之间依赖相同但版本不同的问题,以npm v4-v6的方式去继续执行…

8天长假快来了,Python分析【去哪儿旅游攻略】数据,制作可视化图表

目录 前言环境使用模块使用数据来源分析 代码实现导入模块请求数据解析保存 数据可视化导入模块、数据年份分布情况月份分布情况出行时间情况费用分布情况人员分布情况 前言 2023年的中秋节和国庆节即将来临,好消息是,它们将连休8天!这个长假…

Docker 使用

简介 Docker是一个开源的容器引擎,它有助于更快地交付应用。 Docker可将应用程序和基础设施层隔离,并且能将基础设施当作程序一样进行管理。使用 Docker可更快地打包、测试以及部署应用程序,并可以缩短从编写到部署运行代码的周期。 Docker…

uniapp 项目实践总结(二)从零开始搭建一个项目

导语:本篇文章主要是项目方面的技术开发总结,新建一个项目可以选择使用可视化界面,也可以使用命令行搭建。 目录 可视化界面命令行搭建安卓开发环境苹果开发环境可视化界面 安装软件 使用官方推荐的 HbuilderX 软件,开发方式比较简单,内置相关环境以及终端,无需配置 no…

【python】可视化

柱状图 matplotlib之pyplot模块之柱状图(bar():基础参数、外观参数)_plt.bar_mighty13的博客-CSDN博客 bar()的基础参数如下: x:柱子在x轴上的坐标。浮点数或类数组结构。注意x可以为字符串数组! height&…

Unity中Shader的UV扭曲效果的实现

文章目录 前言一、实现的思路1、在属性面板暴露一个 扭曲贴图的属性2、在片元结构体中,新增一个float2类型的变量,用于独立存储将用于扭曲的纹理的信息3、在顶点着色器中,根据需要使用TRANSFORM_TEX对Tilling 和 Offset 插值;以及…