49617


TypeScriptで書いたコードをWebpackでバンドル化し、パッケージの中に定義したオブジェクトに  
HTMLのスクリプトから設定値をセットしたいと考えています。

構成は以下の状態です。

html  

[code]

    <script src="dist/bundle.js"></script>
    <script type ="text/javascript" src="./item/SOME_OBJECT.js"></script>
    <!--  myLib.SOME_OBJECT = { "aaa": "bbbb", "cccc": "dddd" } -->
    
    <script type="text/javascript">
        $(window).load(() => {
            myLib.sampleAlert.showSomeObject(); 
            <!-- この中で呼びされるSOME_OBJECTは 
            SOME_OBJECT.jsでセットした値になって欲しいがObject{}になる -->
        })
    </script>
    
[/code]

index.ts

[code]

    import { sampleAlert as _sampleAlert } from "./sampleAlert";
    import { SOME_OBJECT } from "./SomeObject";
    const sampleAlert: _sampleAlert = new _sampleAlert();
    export {sampleAlert , SOME_OBJECT};
    
[/code]

sampleAlart.ts

[code]

    import { Message } from "./Message";
    import { SOME_OBJECT } from "./SomeObject";
    
    export class sampleAlert {
      public showSomeObject() {
        console.log(SOME_OBJECT);
      }
    }
    
[/code]

SomeObject.ts

[code]

    export let SOME_OBJECT: Object = {};
    
[/code]

webpack.config.js

[code]

    module.exports = {
        mode: "development",
    
        entry: "./src/index.ts",
        devtool: 'source-map',
        output: {
            library: "myLib",
            libraryTarget: 'umd',
            filename: 'bundle.js'
        },
    
        module: {
            rules: [
                {
                    test: /\.ts$/,
                    use: "ts-loader",
                    exclude: /node_modules/
                }
            ]
        },
        resolve: {
            extensions: [
                ".ts", ".js"
            ]
        }
    };
    
[/code]

どうすれば./item/SOME_OBJECT.jsに記載した内容をバンドル内部のSomeObject.ts
のSOME_OBJCTにセットすることができますか？


CC BY-SA 4.0
2018-10-24T03:30:31.423
49597
2018-10-24T12:19:22.137
12195
question
javascript html webpack
Webpackで作ったパッケージにHTMLのScriptからオブジェクトをセットしたい


一つの方法は、SomeObject.tsからSOME_OBJECTを書き換える関数を提供することです。

**SomeObject.ts**

[code]

    export let SOME_OBJECT: Object = {};
    
    export function setSomeObject(newObj: Object) {
        SOME_OBJECT = newObj;
    }
    
[/code]

index.tsからもexportして外部から使えるようにします。

**index.ts**

[code]

    import { sampleAlert as _sampleAlert } from "./sampleAlert";
    import { SOME_OBJECT, setSomeObject } from "./SomeObject";
    const sampleAlert: _sampleAlert = new _sampleAlert();
    export {sampleAlert , SOME_OBJECT, setSomeObject};
    
[/code]

そして、使う側はSOME_OBJECTを書き換えたいときにsetSomeObjectを呼び出します。

[code]

    myLib.setSomeObject({ "aaa": "bbbb", "cccc": "dddd" });
    
[/code]

実は、これでちゃんとSOME_OBJECTが書き換わります。sampleAlart.tsなどを見るとすでにSOME_OBJECTはインポート済みなのにとお思いになるかもしれませんが、SOME_OBJECTの大元が書きかわれば、インポート済みのSOME_OBJECTも書き換わります。

これでうまく動くはずですが、さすがにあとからSOME_OBJECTが書き換わるのが気持ち悪いという場合は、SOME_OBJECTを直にエクスポートする代わりに、内部に保存されているSOME_OBJECTの値を得るgetSomeObject()みたいな関数をエクスポートするという手もあります。

* * *

上記の方法がおすすめですが、一応もう一つの方法を紹介しておきます。それは、SOME_OBJECTをグローバル変数にマップする方法です。webpackのexternalsの設定を用いると、特定のモジュール名の中身として特定のグローバル変数を参照させることができます。まず、webpack.config.jsに以下のように設定します。

[code]

    module.exports = {
      // ...中略...
      externals: {
        'SOME_OBJECT': '_myLib_SOME_OBJECT',
      },
    };
    
[/code]

これは、_myLib_SOME_OBJECTというグローバル変数をSOME_OBJECTというモジュールの中身として扱ってくださいということです。

SOME_OBJECTを使う側はこのようにします。（TypeScriptということなので、SOME_OBJECTモジュールに対する型定義を適当にでっち上げる必要がありますが省略します。）

[code]

    import SOME_OBJECT from 'SOME_OBJECT';
    
[/code]

外側からこのSOME_OBJECTをセットする場合は、グローバル変数に代入します。

[code]

    _myLib_SOME_OBJECT = { "aaa": "bbbb", "cccc": "dddd" };
    
[/code]


CC BY-SA 4.0
2018-10-24T12:19:22.137
49617
2018-10-24T12:19:22.137
30079
49597
answer