模組開發者使用 ES Modules 的正確姿勢

DJ不語發表於2018-06-10

這裡指的 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' 這個副檔名的話, 問題只會越來越混亂.





相關文章