前言
哈喽,这里是前端小菜北,最近看完了第二章资源入口和出口的相关配置,其实大部分在日常开发中都使用过,只不过可能对其更深层的涵义一知半解。其中收益最多的是filename的几个hash的区别以及他们分别与浏览器缓存的关系。秉持着好记性不如烂笔头的原理,记录下来防止以后忘记~
1 js模块化
1.1 什么是模块化
将一些复杂的功能或程序单独封装到一个模块中,每个模块内部数据是私有的,只是向外部暴露一些接口与其他模块进行通信。
目前js模块化使用的主要是es6 module和commonjs两种,webpack也对现在常用的模块化进行了兼容
1.2 es6 module
//1. b.js export导出
//1.1 导出固定模块
var age = '18'
export var year = '2023'
export { age }
//1.2 导出默认模块
export default function myFun() {
console.log('my fun')
}
//2. a.js import导入
//2.1 导入固定模块
import { year } from './b.js'
//2.2 导入默认模块
import fun from './b.js'
//2.3 导入整个模块 - 这种方式不支持导入默认模块
import * as b from './b.js'
使用上述方式进行导入时都会执行模块的代码,而且经过测试发现即使在a.js中只引入变量【year】,其他导出的模块也会被引入,只不过是不会暴露给a.js使用,所以import是会将模块全部引入的,从打包产物来看也确实如此。
a.js:
b.js
打包产物 bundle.js
还可以使用import './b.js'进行引入,这种方法也会执行模块的内容,但是不会暴露出该模块对外提供的接口。
另外有一点需要注意的是,只要import了外部模块,即使不使用它暴露出来的接口也会对其代码进行打包,所以在日常开发中要尽量避免无用的import
除了上述引用方式外,es2020提案里提出可以用import()方式动态引入模块,使用动态方式引入的模块会被单独打到一个bundle里,可以通过import().then()拿到导出的接口进行使用
import('./b.js').then((res)=>{ res.myFun() })
1.3 commonjs
常见于node的模块化规范
//b.js 导出模块
module.exports = { year: '2023', month: '02' }
// a.js 导入模块
var time = require('./b.js')
commonjs中通过require.ensure动态导入模块
2 资源入口entry
2.1 字符串形式
打包的入口js文件
2.2 数组形式
本质是单一入口,数组最后一个文件是资源的入口文件,其余文件会被预先构建到入口文件中
module.exports = { entry: ['core-js/stable', './a.js'] }
//上述代码的写法等同于:
//a.js
import 'core-js/stable'
//webpack.config.js
module.exports = { entry: './a.js' }
2.3 对象形式
多入口配置,打包后会生成多个js文件
2.4 函数形式
取函数返回值作为入口配置,返回值是上述三种形式
3 资源出口output
3.1 filename
资源名称,可以是一个固定名称,或者是变量
在了解变量之前,需要先了解浏览器缓存:客户端请求资源时,如果每次请求都返回资源会比较消耗时间,因此首次访问时会将资源缓存在本地,二次请求时,对于同名且在有效期内的资源会优先从本地读取不去向服务器请求。如果我们在部署新版本时不更新资源的文件名,浏览器会认为没有更新,则会使用缓存版本,无法保证资源的准确性。因此通过webpack配置打包生成的文件名称,保证在文件内容改变时能请求到新的文件。
支持的变量:
[name] :模块名称,单入口的话值为main,多入口的值为对象的key值
[id]:webpack为每个chunk生成的唯一序号
[hash] : 在webpack5中替换为[fullhash] ,每次构建中项目的出口文件的hash是一样的,只要修改了某个文件,项目中所有文件名称都会被改,缓存都会失效
[chunkhash]:顾名思义,根据chunk生成的hash值,同一个chunk内的文件共享名称,只要chunk内某个文件改了则其他文件名称也会同步被改
[contenthash]:根据文件内容生成hash值
3.2 path
打包后输出的位置,绝对路径,默认是dist
3.3 publicPath
资源访问路径,我理解是项目中打包出的chunk以及动态引入的模块等引用路径
1)基于当前页面的相对路径 ""或者包含 ./ ../等
2)基于服务器地址 “/”
3)绝对http协议 常用于cdn方式访问
4)相对http协议 与3)同理 省略协议头的写法
3.4 chunkFilename
非入口文件的chunk名称,包括异步模块,分包后的模块