gpt4 book ai didi

javascript - 从 Webpack 1.x 迁移到 2.x

转载 作者:可可西里 更新时间:2023-11-01 01:19:29 24 4
gpt4 key购买 nike

在 Webpack 1.x 中,我曾经定期执行以下操作:

require.ensure([ './mod2.js' ], ( require ) => {
setTimeout(() => {
// some later point in time, most likely through any kind of event
var data = require( './mod2.js' ); // actual evaluating the code
},1100);
}, 'myModule2');

通过这种技术,我们能够通过网络传输 webpack-bundle,但会在稍后的某个时间点评估该包的实际内容(JavaScript 代码)。此外,使用 require.ensure 我们可以命名 bundle ,在本例中为 myModule2,因此我们可以在捆绑执行 webpack 时看到名称/别名>.

在 Webpack 2.x 中,新的方法是使用 System.import。虽然我现在喜欢接收 Promise 对象,但我对这种风格有两个问题。上面代码的等价物如下所示:

System.import( './mod2.js' ).then( MOD2 => {
// bundle was transferred AND evaluated at this point
});
  • 我们现在如何拆分传输和评估?
  • 我们如何仍然命名 bundle ?

Webpack documentation在 Github 上说如下:

Full dynamic requires now fail by default

A dependency with only an expression (i. e. require(expr)) will now create an empty context instead of an context of the complete directory.

Best refactor this code as it won't work with ES6 Modules. If this is not possible you can use the ContextReplacementPlugin to hint the compiler to the correct resolving.

我不确定这在本案中是否起作用。他们还在其中讨论了代码拆分,但非常简短,他们没有提到任何“问题”或如何解决。

最佳答案

长话短说: System.resolveSystem.register做你想做的大部分事情。这个答案的其余部分是为什么 require.ensure 不能以及 System.import 如何调用其他的。

认为 ES6 模块阻止了这种情况的良好运行,尽管通过相关规范来遵循它是很棘手的,所以我可能完全错了。

也就是说,让我们从一些引用开始:

  1. WhatWG module loader
  2. ES6 specification on modules (§15.2)
  3. CommonJS module specification
  4. fantastic 2ality article on ES6 modules

第一个引用解释了更多的行为,虽然我不完全确定它是如何规范化的。后者解释了JS端的实现细节。由于还没有平台实现这一点,我没有关于它在现实生活中如何实际工作的引用,我们将不得不依赖规范。

The require that has been available在 webpack 1.x 中是 CommonJS 和 AMD 要求的混搭。 CommonJS 方面在引用#3 中有所描述,特别是“模块上下文”部分。那里没有提到 require.ensure,也没有提到 AMD“规范”(实际上是这样),所以这纯粹是 webpack 的发明。也就是说,该功能从来都不是真实的,因为它被指定在某个官方的地方并且看起来很花哨。

也就是说,我认为 require.ensure 与 ES6 模块冲突。调用 System.import 应该调用 import method来自Loader object .引用#2 中的相关部分没有明确说明,但是 §10.1确实提到将加载程序附加到 System

Loader.prototype.import method并不十分复杂,我们唯一感兴趣的是第 4 步:

  1. Return the result of transforming Resolve(loader, name, referrer) with a fulfillment handler that, when called with argument key, runs the following steps:
    1. Let entry be EnsureRegistered(loader, key).
    2. Return the result of transforming LoadModule(entry, "instantiate") with a fulfillment handler that, when called, runs the following steps:
      1. Return EnsureEvaluated(entry).

流程是解析-注册-加载-评估,您想要在加载和评估之间中断。但是请注意,加载阶段调用 LoadModule stage 设置为 "instantiate"。这意味着并且可能需要该模块已经通过 RequestTranslate 进行了翻译。 ,它会在尝试查找模块的入口点等时进行大量繁重的解析。

这已经完成了比你想要的更多的工作,从它的声音来看。由于模块加载的基础知识需要一个已知的入口点,我认为没有办法避免使用从 System 公开的调用来解析和部分评估模块。你已经知道了。

问题是 System.import 不可能知道——直到解析之后——该模块是必须评估的 ES6 模块还是可以延迟的 webpack 包。必须进行解析才能确定我们是否需要解析,从而导致先有鸡还是先有蛋的问题。

到目前为止,我们一直遵循从 System.importLoader 的路径。 import 调用指示我们所处的导入阶段,假设您想要完成完整的端到端加载过程。底层调用,如 Loader.prototype.load , 提供对这些阶段的细粒度控制。

我不确定您将如何调用前两个阶段(获取和翻译),但如果您能够翻译和注册一个模块,后面的调用应该简单地评估并返回它。

如果规范准确无误,这应该通过 System.loader 属性公开(在支持实现中),并且会有您需要调用的方法。您无权访问大部分流程,因此我建议您不要这样做,而是设置您的代码,以便在加载模块时不会运行任何重要内容。如果那不可能,您需要通过注册重新创建流程,但不要回避评估。

关于javascript - 从 Webpack 1.x 迁移到 2.x,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40314627/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com