web-dev-qa-db-ja.com

webpackを使用して実行時にJSファイルを動的に要求する

ライブラリをgrunt/requirejsからwebpackに移植しようとしていますが、問題に遭遇しました。

私が移植しようとしているライブラリには、設定ファイルから取得したファイル名に基づいて、複数のモジュールをアプリにロードして評価する機能があります。コードは次のようになります(コーヒー):

loadModules = (arrayOfFilePaths) ->
  new Promise (resolve) ->
    require arrayOfFilePaths, (ms...) ->
      for module in ms
        module ModuleAPI
      resolve()

ここのrequireは、実行時に呼び出され、requireJSの場合と同様に動作する必要があります。 Webpackは「ビルドプロセス」で何が起こるかだけを気にしているようです。

これは、webpackが基本的に気にしないものですか?その場合、requireJSを使用できますか?実行時にアセットを動的にロードするための優れたソリューションは何ですか?

編集:loadModuleは、このライブラリのビルド時に存在しないモジュールをロードできます。それらは、私のライブラリを実装するアプリによって提供されます。

24
sra

そのため、「pack-compile-time」ではなく「app-compile-time」でのみ利用可能ないくつかのファイルをランタイムにロードするという私の要件は、webpackでは簡単に実現できないことがわかりました。

ライブラリがファイルをもう必要としないようにメカニズムを変更しますが、必要なモジュールを渡す必要があります。とにかく、これはより良いAPIになりそうです。

明確にするために編集:

基本的に、次の代わりに:

# in my library
load = (path_to_file) ->
  (require path_to_file).do_something()

# in my app (using the 'compiled' libary)
cool_library.load("file_that_exists_in_my_app")

私はこれをします:

# in my library
load = (module) ->
  module.do_something()

# in my app (using the 'compiled' libary)
module = require("file_that_exists_in_my_app")
cool_library.load(module)

最初のコードはrequire.jsで機能しましたが、webpackでは機能しませんでした。

後知恵では、とにかく実行時にサードパーティライブラリのファイルをロードするのはかなり間違っていると感じています。

15
sra

contexthttp://webpack.github.io/docs/context.html )という名前の概念があり、動的な要求を可能にします。

また、コード分割ポイントを定義する可能性があります: http://webpack.github.io/docs/code-splitting.html

function loadInContext(filename) { 
    return new Promise(function(resolve){
        require(['./'+filename], resolve);
    })
}

function loadModules(namesInContext){
    return Promise.all(namesInContext.map(loadInContext));
}

そして、次のように使用します:

loadModules(arrayOfFiles).then(function(){
    modules.forEach(function(module){
        module(moduleAPI);
    })
});

ただし、必要なものではない可能性があります。必要なすべてのモジュールを含む1つのバンドルではなく、多くのチャンクがあり、最適ではない可能性があります。

設定ファイルで必要なモジュールを定義し、ビルドに含めることをお勧めします。

// modulesConfig.js
module.exports = [
   require(...),
   ....
]

// run.js
require('modulesConfig').forEach(function(module){
    module(moduleAPI);
})
9
Bogdan Savluk

次のようなライブラリを使用して試すこともできます。 https://github.com/Venryx/webpack-runtime-require

免責事項:私はその開発者です。実行時にモジュールのコンテンツに自由にアクセスできないことにも不満を感じていたので、書きました。 (私の場合、コンソールからのテスト用)

2
Venryx