TIP

简单来说,模块化就是将一个大文件拆分成相互依赖的小文件,再进行统一的拼装和加载。

# 一.JS 的模块化

在 ES6 之前,JavaScript 一直没有模块系统,这对开发大型复杂的前端工程造成了巨大的障碍。对此社区制定了一些模块加载方案,如 CommonJS、AMD 和 CMD 等。

现在 ES6 已经在语言层面上规定了模块系统,完全可以取代现有的 CommonJS 和 AMD 规范,而且使用起来相当简洁,并且有静态加载的特性。

Webpack + Babel 将所有模块打包成一个文件同步加载,也可以搭乘多个 chunk 异步加载;用 System+Babel 主要是分模块异步加载;用浏览器的<script type="module">加载。

# 二.css 的模块化

虽然 SASS、LESS、Stylus 等预处理器实现了 CSS 的文件拆分,但没有解决 CSS 模块化的一个重要问题:选择器的全局污染问题。

按道理,一个模块化的文件应该要隐藏内部作用域,只暴露少量接口给使用者。而按照目前预处理器的方式,导入一个 CSS 模块后,已存在的样式有被覆盖的风险。虽然重写样式是 CSS 的一个优势,但这并不利于多人协作。

  1. 为了避免全局选择器的冲突,需要制定 CSS 命名风格:BEM 风格、Bootstrap 风格

  2. 但是这毕竟是弱约束,所以从工具层面入手。

从工具层面,社区又创造出 Shadow DOMCSS in JSCSS Modules 三种解决方案。

  • Shadow DOM 是 WebComponents 的标准。它能解决全局污染问题,但目前很多浏览器不兼容,对我们来说还很久远;

  • CSS in JS 是彻底抛弃 CSS,使用 JS 或 JSON 来写样式。这种方法很激进,不能利用现有的 CSS 技术,而且处理伪类等问题比较困难;

  • CSS Modules 仍然使用 CSS,只是让 JS 来管理依赖。它能够最大化地结合 CSS 生态和 JS 模块化能力,目前来看是最好的解决方案。Vue 的 scoped style 也算是一种。

# 三.资源的模块化

Webpack 的强大之处不仅仅在于它统一了 JS 的各种模块系统,取代了 Browserify、RequireJS、SeaJS 的工作。更重要的是它的万能模块加载理念,即所有的资源都可以且也应该模块化。

  1. 资源模块化后,优点是:
  • 依赖关系单一化。所有 CSS 和图片等资源的依赖关系统一走 JS 路线,无需额外处理 CSS 预处理器的依赖关系,也不需处理代码迁移时的图片合并、字体图片等路径问题;
  • 资源处理集成化。现在可以用 loader 对各种资源做各种事情,比如复杂的 vue-loader 等等; 项目结构清晰化。使用 Webpack 后,你的项目结构总可以表示成这样的函数: dest = webpack(src, config)。

# 参考

https://www.jianshu.com/p/88ed70476adb