web-dev-qa-db-ja.com

外部からWebパックされたコードを呼び出す(HTMLスクリプトタグ)

このようなクラス(TypeScriptで記述)があり、webpackでbundle.jsにバンドルするとします。

export class EntryPoint {
    static run() {
        ...
    }
}

Index.htmlにバンドルを含めますが、その静的メソッドも呼び出したいと思います。

<script src="build/bundle.js"></script>
<script>
    window.onload = function() {
        EntryPoint.run();
    }
</script>

ただし、この場合、EntryPointは未定義です。バンドルされたjavascriptを別のスクリプトから呼び出すにはどうすればよいですか?

追加Webpack config file

99
Raven

library としてwebpackバンドルを公開したいようです。 EntryPointなどの独自の変数内のグローバルコンテキストでライブラリを公開するようにwebpackを構成できます。

TypeScriptがわからないため、この例ではプレーンJavaScriptを代わりに使用します。ただし、ここで重要なのはwebpack構成ファイル、特にoutputセクションです。

webpack.config.js

module.exports = {
  entry: './index.js',
  output: {
    path: './lib',
    filename: 'yourlib.js',
    libraryTarget: 'var',
    library: 'EntryPoint'
  }
};

index.js

module.exports = {
  run: function () {
    console.log('run from library');
  }
};

その後、期待どおりにライブラリメソッドにアクセスできるようになります。

<script src="lib/yourlib.js"></script>
<script>
  window.onload = function () {
    EntryPoint.run();
  };
</script>

Gist を実際のコードで確認してください。

116
dreyescat

Main/index.jsファイルから呼び出したimportステートメントを使用するだけで、これ以上のwebpack.config.js変更なしでこれを機能させることができました。

import EntryPoint from './EntryPoint.js';
window.EntryPoint = EntryPoint;

enter image description here

参考のために、ここに私の weback.config.js ファイルがあります。

最初はrequireを使用して同じことを達成しようとしましたが、実際のクラスではなく、モジュールラッパーをwindow.EntryPointに割り当てました。

46
Matt

私の環境では、関数を作成するときにウィンドウに関数を書き込むことで、別のスクリプトからバンドルされたJavaScript内から関数を呼び出すことができました。

// In the bundled script:
function foo() {
    var modal = document.createElement('div');
}
// Bind to the window
window.foo = foo;
// Then, in the other script where I want to reference the bundled function I just call it as a normal function
<button onClick="window.foo()">Click Me</button>

Babelを使用できなかったため、これでうまくいきました。

8
Kurt William

同様の課題がありました。旅行中に複数のページのバンドルを作成し、各ページにコードへの独自のエントリポイントを持たせ、各ページに個別のバンドルを持たせたくありませんでした。

ここに私のアプローチがあります。これはカートウィリアムズに非常に似ていますが、わずかに異なる角度から、またwebpack構成を変更しません。

JourneyMaster.js

import { getViewData } from './modules/common';
import { VIEW_DATA_API_URL } from './modules/constants';
import { createLandingPage, createAnotherPage } from './modules/components/pageBuilder';

window.landingPageInit = () => {
    getViewData(VIEW_DATA_API_URL).then(viewData => {
        createLandingPage(viewData);
    });
};

window.anotherPageInit = () => {
    getViewData(VIEW_DATA_API_URL).then(viewData => {
        createAnotherPage(viewData);
    });
};

// I appreciate the above could be one liners,
// but readable at a glance is important to me

次に、htmlページの最後にこれらのメソッドを呼び出す方法の例を示します。

<script src="/js/JourneyMaster.js"></script>
<script>window.landingPageInit();</script>
0
Darren Sweeney