フロントエンドモジュールの開発

2019-05-13 08:01:17

 npmに公開しているJavaScript-Window-Frameworkなのですが、モジュールの作り方が独特すぎて、WebPackのsource-mapを使うと、正常にコンパイルが完了しないという問題が発生していました。amd形式でファイルを統合するオプションを使うと駄目なようです。

 そもそもの作り方が、複数ファイルにまたがるTypeScriptのクラスを、exportしないnamespaceで囲って、モジュール出力用のファイルを一つ作って、そこでexportをかけるという手法を使っていました。たぶんこんな手を使っている人は他にいません。

 なぜこんな方法でやっていたかというと、モジュールローダやモジュールバンドラを使わないグローバルライブラリとソースコードの共通化を図るためです。モジュール形式を選んだ時点で、宣言系の作法が変わってしまうので面倒くさいことになるのです。

 結局、source-mapが使えない(tsコンパイル後のjsなら可能)のはそれなりに困るので、各ファイルごとにexportを入れる、まっとうなやり方に直しました。こうするとモジュール形式を作成したときは何の問題もありません。今度はグローバルライブラリにしたときに問題が出ます。

 今度の問題は何かというと、d.tsの宣言ファイルの形式です。dts-bundleを使って、ファイルを一つに統合するところまでは良かったのです。しかしグローバルライブラリとして出力したときの、モジュールインスタンス変数に対応した形でnamespaceを出したかったのですが、そんな機能はありません。

 例えば宣言はFrameWindowになっていますが、実際に使うときはJWF.FrameWindowのような形で使用します。これを直すすべがありません。いや、あります。手動で挿入すれば良いのです。

 これは自分でプラグインを作れと言うことでしょうか?

 それと、dts-bundleを使うためのプラグインの宣言が、ネット上に載っている情報が古いらしく、やり方が古いという警告が出ました。

 これが修正版です。
class DtsBundlePlugin {
    constructor(p){
        this.p = p
    }
    apply(compiler) {
        compiler.hooks.done.tap('DtsBundlePlugin', () => {
            var dts = require('dts-bundle');
            dts.bundle(this.p)
        })
    }
}

 使い方はこんな感じです。
  plugins: [
       new DtsBundlePlugin({
            name: '名前',
            main: path.resolve(__dirname, '入力ファイル.d.ts'),
            out: path.resolve(__dirname, '出力ファイル.d.ts'),
            removeSource: true,
            outputAsModuleFolder: true
        })
    ]