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

Require JS files dynamically on runtime using webpack

我正在尝试将库从 grunt/requirejs 移植到 webpack 并偶然发现了一个问题,这可能会破坏这项工作。

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

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

这里的 require 需要在运行时调用并且表现得像 requireJS 一样。 Webpack 似乎只关心 "build-process".

中发生的事情

这是 webpack 根本不关心的事情吗?如果是这样,我还可以使用 requireJS 吗?在运行时动态加载资产有什么好的解决方案?

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

有一个名为 context (http://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);
})

所以我发现我要求在运行时加载一些文件,这些文件只能在“app-compile-time”上可用,而不能在“library-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 中无效。

事后看来,我觉得无论如何在运行时加载第 3 方库都是错误的。

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

免责声明:我是它的开发者。我写它是因为我也对无法在运行时自由访问模块内容感到沮丧。 (在我的例子中,用于从控制台进行测试)