使用webpack在运行时动态地需要JS文件

时间:2015-06-01 13:37:48

标签: javascript requirejs webpack

我正在尝试将一个库从grunt / requirejs移植到webpack并偶然发现一个问题,这可能是这项努力的破坏者。

我尝试移植的库有一个函数,它根据我们从配置文件中获取的文件名加载和评估多个模块到我们的应用程序中。代码看起来像这样(咖啡):

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

此处require需要在运行时调用,其行为与requireJS相同。 Webpack似乎只关心“构建过程”中发生的事情。

这是webpack从根本上不关心的东西吗?如果是这样,我还可以使用requireJS吗?在运行时期间动态加载资产的好方法是什么?

编辑:loadModule可以加载模块,这些模块在此库的构建时不存在。它们将由实现我的库的应用程序提供。

3 个答案:

答案 0 :(得分:14)

所以我发现我的要求是在运行时加载一些文件,只能在“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中没有。

事后我觉得在运行时加载第三方库加载文件是错误的。

答案 1 :(得分:9)

有一个名为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);
    })
});

但可能它不是你需要的 - 你将拥有大量的块而不是一个包含所有必需模块的块,并且可能它不是最佳的..

最好在配置文件中定义模块需求,并将其包含在您的构建中:

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

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

答案 2 :(得分:2)

您也可以尝试使用此类库:https://github.com/Venryx/webpack-runtime-require

免责声明:我是其开发人员。我写它是因为我对在运行时无法自由访问模块内容感到沮丧。 (就我而言,从控制台进行测试)