外部からWebpackedコードを呼び出す(HTMLスクリプトタグ)


130

このようなクラス(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設定ファイル


Webpack構成を追加してください。私はvar EntryPoint = require('EntryPoint')あなたのonload方法にに沿った何かが欠けていると信じています。
マーティンVseticka

2
@MartinVseticka私は私の設定を追加しました。確かに何かrequireが必要かもしれませんが、以下のインポートと同じです、とそれは言いrequire is not definedます。私がやろうとしていることは、プレーンなJavaScriptからバンドルされたコンテンツを使用することですが、使用するためにいくつかのフレームワークは必要ないでしょうrequireか?しかし、私はそれを避けようとしています。それが理にかなっていると思います。
レイヴン

回答:


147

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

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>

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


20
複数のエントリポイントがあるため、出力セクションでは、代わりにそれを作成しましたlibrary: ["GlobalAccess", "[name]"],。次に、varを各エントリポイントのメンバーを持つオブジェクトにします:GlobalAccess.EntryPointFoo、GlobalAccess.EntryPointBarなど
John Hatton

3
これは機能しますnam run buildが、を使用したdev envでは機能しませんwebpack-dev-server。エクスポートしたEntryPointは空のオブジェクトです。何か案は?
nkint 2016年

1
エントリの状況についてはどうですか:{page1:['module1.js'、 'module2.js']、page2: 'module3.js'} @JohnHattonの提案が機能しないようです。page1.module2にはアクセスできますが、page1.module1にはアクセスできません。ただ最後のものをとるようです。
シーマス

1
手順に従い、設定を変更し、再構築しましたが、それでもキャッチされないReferenceError:EntryPointが定義されていません
user889030

2
index.jsをexport function run() {}fromに変更することで、babel + webpack v3.10.0で動作する同様の例を取得しましたmodule.exports = ...
dworvos

55

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

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

ここに画像の説明を入力してください

参考までに、これが私のweback.config.jsファイルです。

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


3
es6なしでこれを行うチャンスはありますか?そうでなければ私は得るUncaught SyntaxError: Unexpected token import。または、あなたindex.jsもバンドルされていますか(私はエントリポイントとして見ていますが、わかりません)?
レイヴン

ええ、index.jsもバンドルされています-ここにインポート文を含めました
Matt

3
バンドルに属していないスクリプトからバンドルされているものにアクセスしようとしています。バンドルがライブラリであるように、私はそのメソッドに外部からアクセスしようとしました。それは可能ですか?
レイヴン

4
この解決策は非常にシンプルで、問題が発生してすぐにそれについて考えなかったことを恥ずかしく思います。
cav_dan 2017年

1
私はこの問題に何時間も行き詰っていました。スクリプトを私のバンドルに移動するつもりでしたが、それはさらに多くの問題を引き起こしたでしょう。簡単な答えをありがとう!
Stephen Agwu

14

私の状況では、作成時にウィンドウに関数を書き込むことで、別のスクリプトからバンドルされた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>

私はバベルを使うことができなかったので、これは私のために働いた。


これは非常にきちんとしたソリューションです。
Teoman Shipahi

1

私も同様の課題を抱えていました。移動中に複数のページのバンドルを作成し、各ページにコードへの独自のエントリポイントを持たせ、ページごとに個別のバンドルを持たせないようにしました。

カートウィリアムズと非常によく似ていますが、少し異なる角度から、これも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

WEBPACK.CONFIG.JS

1.UMDの使用

module.exports={
            mode:'development',
            entry:'./yourentry.js',
            output:{
            path:path.resolve(__dirname,"dist"),
            filename:'main.js',
            publicPath:'/dist/',
            libraryTarget:'umd', 
            library:'rstate',
            umdNamedDefine: true,
            libraryExport: 'default' 
        }
    }

index.html

<script src="dist/main.js"></script>
<script>
  window.onload = function () {
  rstate()=>{}
</script>

main.js

export default function rstate(){
console.log("i called from html")
}

2.VARの使用

module.exports={
            mode:'development',
            entry:'./yourentry.js',
            output:{
            path:path.resolve(__dirname,"dist"),
            filename:'main.js',
            publicPath:'/dist/',
            libraryTarget:'var', 
            library: 'EntryPoint'
        }
    }

index.html

<script>
  window.onload = function () {
  EntryPoint.rstate()=>{}
</script>

main.js

module.exports={
rstate=function(){
console.log("hi module")
}
}

3. AMDをライブラリとして使用する(libを作成したい場合)

define(['jquery', './aux-lib.js'], function ($) { ..(1).. });

-4

App.ts:

namespace mytypescript.Pages {

        export class Manage {

     public Initialise() {
     $("#btnNewActivity").click(() => {
                    alert("sdc'");
                });
        }
    }
}

mypage.html:

 <input class="button" type="button" id="btnNewActivity" value="Register New Activity" />

 <script type="text/javascript">
    var page = new mytypescript.Pages.Manage();
    page.Initialise();
</script>
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.