JavaScript の依存関係を管理するために Webpack を使用して Web アプリに取り組んでいるときに、これから説明する問題に遭遇しました。
文字列を渡す依存関係のロードrequire()
は美しく機能します:
// main.js
var jQuery = require('jquery');
は Bower と共にインストールされ、 Webpackjquery
は Bower モジュールを自動的に解決するように正しく構成されています。
現在、モジュールを条件付きでロードする問題に取り組んでいます。特に、モジュールを CDN からダウンロードする必要がある場合、または CDN が失敗した場合はローカル サーバーからダウンロードする必要がある場合に注意しています。ちなみに、私scriptjs
はCDNから非同期にロードしていました。私が書いているコードは次のようなものです:
var jQuery = undefined;
try {
jQuery = require('jquery-cdn');
} catch (e) {
console.log('Unable to load jQuery from CDN. Loading local version...');
require('script!jquery');
jQuery = window.jQuery;
}
// jQuery available here
このコードも美しく機能します。
ここで、最初に CDN からロードしようとする多くの依存関係 (ハンドルバー、Ember など) があることは明らかであるため、このコードは少し冗長になり始めます。そのため、私がしようとする最も論理的なことは関数にリファクタリングします。
function loadModule(module, object) {
var lib = undefined;
try {
lib = require(module + '-cdn');
} catch (e) {
console.log('Cannot load ' + object + ' from CDN. Loading local version...');
require('script!' + module);
lib = window[object];
}
return lib;
}
var jQuery = loadModule('jquery', 'jQuery');
var Handlebars = loadModule('handlebars', 'Handlebars');
// etc...
問題は、ステートメント内の式を処理するときにWebpack に特定の 動作require
があることです。これにより、上記の方法でモジュールをロードしようとする試みが妨げられます。特に、その中で式を使用するrequire
場合
式で可能なすべてのファイルを含めようとします
上記のコードで Webpack を実行しようとすると、正味の効果として大量のエラー メッセージが表示されます。
リンクされたリソースは、含めるJavaScriptファイルのパスを明示的に宣言することを提案していますが、正確なパスを渡すことができない、または渡したくない場合に同じことを行う方法がわかりませんrequire
が、代わりに示されているように、自動的に解決されたモジュール。
皆さんありがとう
編集:
式を使用してこれらのスクリプトをロードする方法はまだわかりませんが、回避策を設計しました。基本的にはrequire('script')
、コールバック関数内に を明示的に記述し、必要なときにその関数を動的に呼び出すという考え方です。より正確には、次のような構成ファイルを用意しました。
// config.js
'use strict';
module.exports = {
'lib': {
'jquery': {
'object': 'jQuery',
'dev': function() { require('script!jquery'); },
'dist': function() { return require('jquery-cdn'); },
'cdn': '//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js'
},
'handlebars': {
// ...
}
}
};
次に、メイン コード内で、ロードするリソースの配列を次のように定義します。
var config = require('./config.js');
var resources = [ config.lib.jquery, config.lib.handlebars, ... ];
そして、開発バージョンまたは配布バージョンをロードする必要がある場合は、動的に次のように呼び出します。
// Inside some kind of cycle
// resource = resources[index]
try {
window[resource.object] = resource.dist();
} catch (e) {
console.log('Cannot load ' + resource.object + ' from CDN. Loading local version...');
resource.dev();
}
これが実際に行われている、より完全な例を次に示します。