module-bundlerを作りながらmoduleへの理解を深める
はじめに
本ブログは11tyで作成されているが、ts化に向けて色々しているうちにES Modulesなどへの理解が浅いことが身にしみてわかった。
hiroppyさんの下記記事を参考にmodule bundlerを作ることでその辺への理解を深められたらなと思っている。
コードはkobakazu0429/module-bundlerにある
各コードの詳細はブログを参照
環境構築
コミット: 6ba3e09
hiroppy/the-sample-of-module-bundlerから基礎的なもの(e.g. tests/)をコピーしつつ環境構築した
entryファイルからrequireされているファイルの列挙(準備編 node_modulesのファイルを読み込む まで)
基本的にはbabelを使ってtraverseするだけ
まだbundlerらしさはない
bundle(準備編 ランタイムのコード作成 まで)
requireの解決を行なって複数ファイルを1つのファイルにbundleできるようになった
実際にファイルに書き込んで実行すると実行できるのでちょっと感動
前回bundlerらしさがないって言ったばかりなのにもう完全にbundler
bundlerの成長は早い
node_modules.js
はreactのversionを出力するだけなのに不要なコード(reactのほとんどすべて)がbundleされているので確かにDead Code Eliminationの必要性を感じた
あとはtemplateの部分が個人的にはなんとなく興味深かった
ES Modules対応(ECMAScript Modules編 すべて)
import/exportなどのES Modulesに対応した (hiroppy/the-sample-of-module-bundler: 132a136まで)
完全なbundlerになった
hiroppy/the-sample-of-module-bundlerのmasterからtestsをcloneしたので未対応の部分がある(e.g. common/interopなど)
地道にastを操作してコードの書き換えを行なっており、プログラミングは魔法ではないことを再確認できたのがよかった
次はhiroppy/the-sample-of-module-bundlerのcommitを追いつつ修正をしてテストを通る予定にする
CommonJSとES ModulesのinteropとImportDeclarationの実装
c160d73まで
(terserによるminifyは除く)
これでcommon/interopもbundleできるようになった
minify
bundleされたコードをterserを使って[name].min.js
にminifyされるようにした
prettierによる整形もあったが同様にするだけなので省略した
細かいrefactorに関しても本筋ではないのでこちらも省略した
感想
CommonJSとES Modulesの歴史的背景だったり、より詳細な話には触れなかったがbundlerの大まかな仕組みが理解できたのでかなりよかった
その他
const { Script, runInContext, createContext } = require('vm');
というコードを見つけた
vmモジュールを初めて見た
多分サンドボックス環境を作って安全にスクリプトを実行できるのではないかと思う
いつか触ってみたい