阅读 1113

模块开发者使用 ES Modules 的正确姿势

这里指的 ES Modules (esm)是指源代码中使用 'import','export' 方式导入或导出模块.

这种方式成为标准已经好几年了, 各大浏览器厂商全部支持这种写法:

<script type="module">
import mod from 'https://dev.jspm.io/npm:some-module';
</script>
复制代码

问题:  模块开发者发布什么样的的文件才能最好的支持这种方式.


我们知道以往的通用做法是使用 requiremodule.exports, 如果你的模块是这种方式, 那 jspm.io 可以解决多数兼容性问题(毕竟具体写法有很多, jspm 不一定能全部理解和正确处理).

显然 jspm 为这种加载方式付出了额外的工作, 服务器端进行转换, 二次包装, 甚至多次请求.

那么如何使这种成本最低, 也就是所谓的正确姿势?

两种方法:

  1. 采用同时兼容 CJS 和 esm 的格式, 优点: 一个文件解决兼容性
  2. 分离文件, '.js' 文件使用传统 CJS 风格, '.mjs' 文件使用 esm 格式, 优点: 干净

第一种方式的例子: https://unpkg.com/@babel/parser@7.0.0-beta.48/lib/index.js

这是社区使用的兼容方式: Object.defineProperty(exports, '__esModule', { value: true });

第二种会有两个文件: '.js' 和 '.mjs' 的, 其中 '.js' 的不包含 'import','export', '.mjs' 至少要包含 'export'

打包工具通常都支持多种方式(打包工具就是干这个的), 比如 rollupjs

糟糕的方法:

扩展名是 '.js', 里面却使用了 'import','export'. 正如前文所述, 会增加加载成本, 这方法过时了.

扩展名是 '.mjs' 里面却使用 'require' 或者没有使用 'export'. 这完全误用了 '.mjs', 这样用就失去了 '.mjs' 被创造出来意义.

现实中, 很多项目在打包的时候不会考虑到加载成本, 这是一种惯性, 随着时间的推移可能会改变, 也可能会更糟糕. 因为如果多数开发者都不在乎 '.mjs' 这个扩展名的话, 问题只会越来越混乱.





文章分类
前端