声明:所有的文章demo都在我的仓库

代码分离

代码分离的有点在于:

  1. 切割代码,生成不同的打包文件,按需加载这些文件。
  2. 每个bundle的体积更小
  3. 控制外部资源的加载顺序

常用的方法有:

  1. 入口起点:使用入口entry手动分离
  2. 防止重复:使用SplitChunksPlugin去重和分离chunk
  3. 动态导入:通过模块的内联函数调用分离的代码

入口起点

新增另一个文件another-module.js文件,并在webpack.config.js中进行配置。

entry:{//打包入口
index:'./src/index.js',
another:'./src/another-module.js'
},

进行打包后,结果正常。

优点:常用常规的写法。

缺点:1.如果有相同的模块,不会去重,还是会在每个bundle中被重复的引用。2.不能将核心代码进行分割

防止重复

入口依赖

配置dependOn选项,可以在多个chunk之间进行共享模块。

SplitChunkPlugin

为了解决多个bundle引入相同模块的问题,引入这个模块进行去重。

SplitChunkPlugin将公共的模块引入到已有的入口中,或者提取到新的chunk。

相关配置如下:

//webpack.config.js
optimization:{
splitChunks:{
chunks:'all'
}
},

SplitChunkPlugin创建了新的chunk,如下图所示,shared.bundle.js。将我其他页面所使用的js引入的lodash模块引入这个文件中。

*** 以上代码在webpack-demo5

缓存

通常部署文件是将webpack打包出来的/dist文件,部署到server上,客户端通过访问server的网站及资源。

由于客户端访问server时,非常耗时和耗流量,于是浏览器采用缓存技术,可以直接从缓存中获取相关的内容,降低了请求的速度和流量。但是这也有一个缺点:如果文件名跟之前的一致,浏览器会认为这个文件没有做修改,还是会从缓存中获取相关内容。

我们想要的现象是:文件没做修改时,浏览器从缓存中获取,文件修改了,重新获取。

输出文件的文件名

webpack提供了一个substitution(可替换的模版字符串)的方式,通过带括号字符串来模版化文件名。其中的[contenthash]是根据资源内容创建唯一的hash。当资源内容变化时,[contenthash]也会发生变化。

相关配置如下:

entry:'./src/index.js',
output:{//打包出口
filename:"[name].[contenthash].js",//打包后的文件名称
path:path.resolve(__dirname,'dist')//路径
},

使用contenthash,将内容变化直接反应打包输出文件的变化。

文件不做修改,再次运行npm run build时,文档描述如下:

在我的实际操作中,我的打包文件是不变的。

第一次:

第二次:

可能跟webpack版本的关系所致。。。

模块的概念

runtime:每个模块的加载和模块的解析逻辑。

manifest:解析和映射模块之间的联系

提取引导模版

runtime代码,提取到一个单独的chunk中。optimization.runtimeChunk:'single'表示为所有的chunk创建一个runtime bundle

代码如下:

optimization:{
runtimeChunk:'single'
},

将所有的第三方库,如lodash/react等提取到单独的vendor chunk文件中。由于这些第三方库不会去频繁的修改源代码,所以可以让更少的向server发请求。

配置如下:

const path=require('path');
const {CleanWebpackPlugin}=require('clean-webpack-plugin')
const HtmlWebpackPlugin=require('html-webpack-plugin') module.exports={
mode:'development',
entry:'./src/index.js',
output:{//打包出口
filename:"[name].[contenthash].js",//打包后的文件名称
path:path.resolve(__dirname,'dist')//路径
},
devtool: 'inline-source-map',
devServer:{
contentBase:'./dist'
},
optimization:{
runtimeChunk:'single',
splitChunks:{
cacheGroups:{
vendor:{
test:/[\\/]node_modules[\\/]/,
name:'vendor',
chunks:'all'
}
}
}
},
plugins:[
new CleanWebpackPlugin({
cleanStaleWebpackAssets:false
}),
new HtmlWebpackPlugin({
title:'管理输出'
})
]
}

结果会出现一个带有vendor的文件。

main文件里,不再含有来自node_modulevendor代码,而且体积也减少了。

模块标识符

新增print模块,并在index中进行引入,最终打包的结果跟之前比较结果如下:

我本地打包只有main的文件进行了变化----符合预期

然而官网上展示的例子是不一样,引出了需要引入optimization.moduleIds:'hashed'---苦笑不得

*** 以上代码在webpack-demo6

环境变量

可以在package.json中配置相关的命令行,可以快速的执行开发环境生产环境

"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack",
"start": "webpack serve --env development"
},

表示执行development环境。

模块热替换(HMR)

模块热替换(HMR--hot module replacement):在程序运行过程中,若有替换/添加/删除模块,只更新修改的部分,不需要更新整个页面。

此功能暂不支持生产环境。

代码配置如下:

devServer:{
contentBase:'./dist',
hot:true
},

在index页面加入代码

if(module.hot){
module.hot.accept('./print.js',function(){
console.log('update the module1');
Print()
})
}

注意:执行时使用npm run start,启动服务,可查看热更替。

*** 以上代码在webpack-demo7

模块热更替跟热更新是两回事。模块热更新是指修改了某个部分代码,不会刷新页面,而是在页面更新这个模块。热更新是指及时刷新页面。

Tree shaking

概念

是指在打包的时候,剔除没有用到的代码。

但是只支持ES module的import和export用法。

实践

打包过程分成3部分:

  1. import会被打包成/* harmony import */做前缀,表明这段是import进来的
  2. export会被打包成/* harmony export */做前缀,表明这段是export
  3. 纯函数,会被打包成/*#__PURE__*/,表明这个函数是纯函数,可以被tree shaking

代码如下:

package.json

"name": "webpack-demo8",
"sideEffects":false,

webpack.config.js

optimization:{
usedExports:true
}

*** 以上代码在webpack-demo8

我的仓库地址,github,欢迎star~~

(完)

webpack5文档解析(下)的更多相关文章

  1. webpack5文档解析(上)

    webpack5 声明:所有的文章demo都在我的仓库里 webpack5 起步 概念 webpack是用于编译JavaScript模块. 一个文件依赖另一个文件,包括静态资源(图片/css等),都会 ...

  2. JavaScript : DOM文档解析详解

    JavaScript DOM  文档解析 1.节点(node):来源于网络理论,代表网络中的一个连接点.网络是由节点构成的集合 <p title=“a gentle reminder”> ...

  3. Android XML文档解析(一)——SAX解析

    ---------------------------------------------------------------------------------------------------- ...

  4. iOS网络编程笔记——XML文档解析

    今天利用多余时间研究了一下XML文档解析,虽然现在移动端使用的数据格式基本为JSON格式,但是XML格式毕竟多年来一直在各种计算机语言之间使用,是一种老牌的经典的灵活的数据交换格式.所以我认为还是很有 ...

  5. ios-XML文档解析之SAX解析

    首先SAX解析xml *xml文档的格式特点是节点,大体思路是把每个最小的子节点作为对象的属性,每个最小子节点的'父'节点作为对象,将节点转化为对象,输出. 每个节点都是成对存在的,有开始有结束.有始 ...

  6. jsoup -- xml文档解析

    jsoup -- xml文档解析 修改 https://jsoup.org/cookbook/modifying-data/set-attributes https://jsoup.org/cookb ...

  7. (二)发布第一个WebService服务与DSWL文档解析

    1. 编写接口 package service; import javax.jws.WebService; /** * 第一个webservice服务, * @WebService注解表示这是一个we ...

  8. 读取EXCEL文档解析工具类

    package test;import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException ...

  9. 嵌套iframe中的HTML的文档解析类型

    问题:页面整个刷新时,IE11输入框显示的宽度和高度正常,对页面中的iframe部分刷新时,IE11输入框的宽度和高度就变小了. 原因:网页的头部定义了文档类型<!DOCTYPE html> ...

随机推荐

  1. 科普,想成为厉害的 Java 后端程序员,你需要懂这些

    站在运筹帷幄的角度来看,一名厉害的 Java 后端程序员都需要懂得哪些知识呢?我想,这也是很多读者迫切想知道的一个问题,因为如果不站在一个宏观的角度的话,所有学过的知识点都是零散的,就感觉像一只迷路的 ...

  2. Object类:又回到最初的起点

    Object类大概是每个JAVA程序员认识的第一个类,因为它是所有其他类的祖先类.在JAVA单根继承的体系下,这个类中的每个方法都显得尤为重要,因为每个类都能够调用或者重写这些方法.当你JAVA学到一 ...

  3. C++11 随机数生成器

    背景 考试想造浮点数然后发现不会 正好下午被虎哥茶话会 谈到了一些不会的问题balabala的 被告知\(C++11\)有些神奇特性(哦豁) 然后就学习了一手看上去没什么用的随机数生成器\(QwQ\) ...

  4. selenium的文档API

    你用WebDriver要做的第一件事就是指定一个链接,一般我们使用get方法: from selenium import webdriver from selenium.webdriver.commo ...

  5. 【JAVA】mysql数据库常见知识点

    目录 1.事务四大特性 2.数据库隔离等级 3.Mysql两种存储引擎的区别 4.哈希索引和B+树索引 5.聚簇索引和非聚簇索引 6.索引的优缺点,什么时候使用索引,什么时候不能使用索引 7.索引的底 ...

  6. Redis散列(Hash)的相关命令

    散列 就像一个减配的Redis 内部及其类似Java的Map 内容就是key:value结构 hash类型在面向对象编程的运用中及其适合,因为它可以直接保存编程语言中的实体类关系 增 hset hse ...

  7. kafka学习(五)Spring Boot 整合 Kafka

    文章更新时间:2020/06/08 一.创建Spring boot 工程 创建过程不再描述,创建后的工程结构如下: POM文件中要加入几个依赖: <?xml version="1.0& ...

  8. kafka学习(一)初识kafka

    文章更新时间:2020/06/08 一.简介 定义:kafka是一个分布式,基于zookeeper协调的发布/订阅模式的消息系统,本质是一个MQ(消息队列Message Queue),主要用于大数据实 ...

  9. org.springframework.dao.InvalidDataAccessApiUsageException: The given id must not be null!; nested exception is java.lang.IllegalArgumentException: The given id must not be null

    通过这个简单的案例,手把手教给你分析异常信息(适合初学者看) org.springframework.dao.InvalidDataAccessApiUsageException: The given ...

  10. [vscode直接运行js文件报错]: To load an ES module, set "type": "module" in the package.json or use the .mjs extension.

    报错示例: 报错原因: 在vscode里面编写了一段js代码,使用了import来引入一个函数并调用 代码复现 // inherit() returns a newly created object ...