跳转到内容
aswind7
GitHub
Blog

阅读「Webpack实战:入门、进阶与调优(第2版)」

这个周末在微信读书上读完了这本居玉皓大佬写的Webpack实战,感觉webpack原理和使用讲的还是很清楚的。缺点是webpack5的内容较少 主要基于webpack4的,然后书中有些细节错误。

俗话说温故而知新,阅读这本书还是能吸收到一些有价值的内容,比如原理部分和配置部分。

下面讲下我从中获得的启发。

CJS与ES Module的动态与静态

CommonJS与ES6 Module最本质的区别在于前者对模块依赖的解决是“动态的”,而后者是“静态的”。在这里“动态”的含义是,模块依赖关系的建立发生在代码运行阶段;而“静态”则表示模块依赖关系的建立发生在代码编译阶段。

对于CommonJS来说获取的是一份导出值的副本;而在ES6 Module中则是值的动态映射,并且这个映射是只读的。

  • cjs是动态的,也就是说可以在运行时进行require,并且路径也是可以拼接的; 而es module必须写到最顶层,且路径不能拼接。同时这也是es能静态分析,tree shaking的原因;
  • cjs模块导出的变量是值复制,另一个模块操作import的模块中的变量并不会影响原来模块的变量的值;而es module会影响,因为他是动态映射的;
  • 模块之间的循环依赖会造成导出的是空对象(commonjs)或者 undefined(es6规范),排查时可以尝试把常量改写成函数试试(利用到es的动态映射特点); 尽量不要循环依赖,很难排查

installedModules对象,每个模块只在第一次被加载的时候执行,之后其导出值就被存储到这个对象里面,当再次被加载的时候webpack会直接从这里取值,而不会重新执行该模块。

  • require 多次 只会执行第一次; 后面的require会直接取缓存的内容
  • chunkhashcontenthash 的应用场景不同:
    • chunkhash主要用于chunk js块,contenthash用于css、image和entry的js块(因为entry是指定了filename)

Loader工作是有顺序的

output = loaderA(loaderB(loaderC(input)))

npm包相对路径安装

相对路径安装 npm install ./xxx/xxloader 感觉比link 命令方便;因为link需要执行两次并且不直观。

sourcemap与sentry

  • 由于需要sentry统计代码debug,但又不能直接暴露map文件因为会被查到源码,可以这样:
    • hidden-source-map 隐藏map文件地址
    • nosources-source-map 我们仍然可以在Console控制台中查看源代码的错误栈,或者console日志的准确行,但是文件的具体内容会被隐藏起来
    • map文件设置内网白名单

唯一的compiler

无论是在build模式下还是在watch模式下,都仅仅会创建一个Compiler实例,这也是我们在watch模式下修改Webpack的配置时新的配置不会生效的原因。只有在我们停下当前控制台的进程再重新启动Webpack时,这些配置才会随着新的Compiler实例初始化而生效。

  • 运行后只会创建一个Compiler实例,这就是为什么配置更改后需要重启才能生效

AST

webpack太慢的一部分原因: AST多次转换

image-20230925113913910

Parcel快的原因,只需转一次AST

image-20230925113957958

参考阅读

https://weread.qq.com/web/bookDetail/845323407299950f8450b99