async defer commonJs esm
1.浏览器执行普通的script脚本,他不支持require。因为要防止阻塞,采用AMD(利用onload事件和script脚本的创建)。
async 和 defer 仅管理script脚本的加载 async是在下载完立刻执行。 defer推迟到DOM解析完(DOMLoadedContent)。async 和 defer 哪个按照顺序执行?async不按照顺序(不确定哪个先下载完)。 defer可以确定顺序。
2.esm 在script中添加(type = module) 在编译时确定依赖关系,并行加载,不像AMD和CommonJS在运行时确定关系。基本数据类型会绑定,类似于响应式。模块的加载不会阻塞页面。
webpack
打包:
浏览器不支持像是commonJs的模块引入方式和一些特殊格式的语法,像是裸模块或者图片引入。所以需要对代码进行打包组合到一起,转换成浏览器看得懂的代码。
webpack会从配置的起始文件进行递归的依赖分析,分析出依赖项,然后构建出依赖地图。
然后将代码进行loader处理,转换成浏览器看的懂的代码,像是图片的import变成路径,ts转换成js,css转换成html内的css等,es6转换成es5等。
接着将代码进行打包成一个或者多个bundle模块,这里会进行一系列的优化,像是如压缩代码、删除死代码 Tree-Shaking、提取公共模块 SplitChunks。
运行时:
通过服务器来返回html文件,使用websocket进行双向连接。当本地使用的库监听到代码发生变化之后,便重新分析收到影响的模块,通过websocket给到浏览器新的代码,然后对代码进行替换,通过vue的render函数进行重新的渲染。
tree-Shaking:
loader:
plugin:
这个过程中是非常的耗时的。
但是esm中浏览器会构建模块的依赖图谱,同时并行加载文件(加载指的是获取并读取文件的内容)
vite
打包:
运行时:
1.解析正确的路径。 将裸模块和路径解析到正确的文件和路径。
2.将.vue文件进行分割成template script style,将scrpit部分先获取,然后返回给浏览器 script + 'import template'
部分,浏览器检测到import 对template部分进行二次请求编译处理。
热更新: 借助 WebSocket 建立前后端的连接,通过类似于 chokidar 这样的文件监听的库来实时监听整个项目中的所有文件资源,当有资源发生变更的时候就向客户端推送一个更新通知,客户端做刷新项目的操作。
rollup & esbuild
bun
- webpack 如何解析不同模块规范(CommonJS、ES6 Module、AMD、UMD)?
- webpack 的代码分割(Code Splitting)有哪几种实现方式,对比 "同步代码分割" 与 "动态 import (() => import ())"