在模块化编程中,开发者会将程序分解成功能离散的一些文件,我们把这些文件称之为模块,每个模块都很轻量,这就使得项目的调试、验证、测试比较容易。这些模块提供了可靠的抽象和封装界限。使得应用程序的每个模块具备了条例清晰的设计和明确的目的。
大多数浏览器都支持了esm模块化
ECMAScript模块、CommonJS模块、AMD模块、Assets模块
模块解析
webpack是通过Resolvers实现模块之间的依赖和引用。
所引用的模块可以是来自应用程序的代码,也可以是第三方库。resolver帮助webpack从每个require/import语句中,找到需要引入的bundle中的模块代码。当打包模块时,webpack使用enhance-resolve来解析文件路径。
webpack能够解析三种文件路径:
- 绝对路径(相对于项目的更目录)
/src/math.js
/代表根 - 相对路径
- 模块路径,即全局的node_modules路径
绝对路径:/src/components/Header.js
相对路径:‘./components/Header.js’
模块路径:’import _ from 'lodash'‘
默认在node_modules里找相对应的模块(无.无/)
给一些路径设置别名
const path = require('path');
module.exports = {
//...
resolve:{
alias:{
'@':path.resolve(__dirname,'./src')
},
// 当引入文件时,没有加文件后缀时,左到右的顺序,去识别扩展名【与loader不一样】
extensions:['.json','.js','.vue']
}
外部扩展
有时候我们为了减少bundle的体积,从而把一些不变的第三方库用cdn的形式引入进来,比如jquery
在我们自己开发工具或者做组件库的时候很有用
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js"></script>
引入jquery时,三种模块引入的方式都不行,因此webpack提供了Externals的配置属性,让我们可以配置外部扩展模块
module.exports = {
//...
resolve:{
alias:{
'@':path.resolve(__dirname,'./src')
},
// 当引入文件时,没有加文件后缀时,左到右的顺序,去识别扩展名【与loader不一样】
extensions:['.json','.js','.vue']
}
通过cdn引入jquery,而不是本地npm install
module.exports = {
//...
externalsType:'script',
externals:{
jquery:[ // 该关键词是import $ from 'jquery'
'https://cdn.bootcdn.net/ajax/libs/jquery/3.6.1/jquery.js',
'$'
]
}
}
依赖图(dependency graph)
每当一个文件依赖另一个文件时,webpack会直接将文件视为存在依赖关系。这使得webpack可以获取非代码资源,如images或web字体等。并会把他们作为依赖提供给应用程序。当webpack开始工作时,他会根据我们写好得配置,从入口开始,webpack会递归得构建一个依赖关系图,这个依赖图包含着应用程序中所需得每个模块,然后将所有模块打包为bundle(也就是output的配置项)
(html-webpack-plugin为了在浏览器上看到页面效果)
安装:npm install webpack-bundle-analyzer -D
扩展功能
postCSS是一个用JavaScript工具和插件转换CSS代码的工具。比如可以使用Autoprefixer插件自动获取浏览器的流行度和能够支持的属性,并根据这些数据帮我们自动的为CSS规则添加前缀,将最新的CSS语法转化成大多数浏览器都能理解的语法
例如:写一些css3的代码(display:flex),postcss可以让低版本的浏览器兼容
安装npm install postcss-loader -D
安装插件npm install autoprefixer -D
//帮助加载样式前缀
安装插件npm install postcss-nested -D
//可以写嵌套的样式格式
"browserlist":[
"> 1%", // 应用在全球使用率大于1%的浏览器上
"last 2 versions"
]
实现css模块(嵌套的形式)vue和react脚手架就是用的这种css模块化原理
body body .hduahdaujsaiojioxz (哈希形式)
不能使用import './contain.css'
需要 import style from './contain.css'
div.classList.add(style.box)
另外
module.exports = {
//...
module:{
rule:[
{
test:/\.css$/,
use:[
'style-loader',
{
loader:'css-loader',
options:{
modules:true,
}
},
'postcss-loader'
}
]
}
}
也可以部分开启CSS模块模式,比如全局样式可以冠以.global前缀,如
*.global.css 普通模式
*.css css module模式
可以用正则表达式匹配文件
Web Works
有时候需要在客户端做大量的运算,但又不想阻塞js主线程的执行,
1.异步,但时间比较长的异步也会阻塞浏览器的事件循环,造成浏览器的假死状态
2.Web Work是html5的新特性,Web Works提供了js的后台处理线程的api,它允许把复杂的耗时的js执行语句放在后台线程中执行,让js线程不阻塞ui线程的渲染。多个线程间也是通过相通的方法进行传递的
webpack4需要使用work-loader,而webpack5中内置了这个loader
const worker = new Worker(new URL('./work.js',import.meta.url))
worker.postMessage({
question:'主线程的复杂任务'
})
worker.onmessage = (message)=>{
console.log(message.data.answer);
}
work.js
self.onmessage = (message) =>{
self.postMessage({
answer:'finish'
})
}
webpack会对work做额外的打包(dist打包文件中 src_work_js.js)
该库查找声明安装方式的地址:https://www.typescriptlang.org/dt/search?search=
比如我们安装react的类型声明: npm i @types/react --save-dev
lodash内部这个库里面没有声明文件,有可能有人在types这个库里面写好了这个lodash的声明文件,自己去下载就好了。react也是,types这个库里面有它的声明。