《webpack+Babel入门与实例详解》 读书笔记(二)

94 阅读4分钟

前言

哈喽,这里是前端小菜北,最近看完了第二章资源入口和出口的相关配置,其实大部分在日常开发中都使用过,只不过可能对其更深层的涵义一知半解。其中收益最多的是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:

image.png

b.js

image.png

打包产物 bundle.js

image.png

还可以使用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是一样的,只要修改了某个文件,项目中所有文件名称都会被改,缓存都会失效

image.png

image.png

[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名称,包括异步模块,分包后的模块