在使用Webpack处理Web应用程序来管理JavaScript依赖关系时,我偶然发现了我要描述的问题。
加载将字符串传递给require()
的依赖项可以很好地工作:
// main.js
var jQuery = require('jquery');
此处,jquery
与Bower一起安装,并且Webpack已正确配置为自动解析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
并且此代码也可以很好地工作。
现在,因为我显然有很多依赖项(Handlebars,Ember等),我想先尝试从CDN加载,这段代码开始变得有点多余,所以我尝试了最合乎逻辑的事情做的是将它重构成一个函数:
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
语句中的表达式时有particular behaviour,这妨碍了我以上述方式加载模块的尝试。特别是,在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': {
// ...
}
}
};
然后,在我的主代码I中,定义要加载的资源数组,例如:
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();
}
Here这是一个更完整的例子。