从Webpack 1.x迁移到2.x

詹迪:

在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捆绑包,但在稍后的某个时间点评估该捆绑包的实际内容(JavaScript代码)。另外,使用require.ensure我们可以命名该包,在本例中为myModule2,因此当执行webpack发生绑定时,我们可以看到名称/别名

在Webpack 2.x中,新方法是使用System.import虽然我现在喜欢接收Promise对象,但是该样式有两个问题。上面的代码等效于:

System.import( './mod2.js' ).then( MOD2 => {
    // bundle was transferred AND evaluated at this point   
});
  • 我们现在如何划分转让和评估?
  • 我们如何仍可以命名捆绑包?

Github上Webpack文档说:

全动态要求现在默认会失败

现在只有一个表达式(即require(expr))的依赖项将创建一个空上下文,而不是完整目录的上下文。

最好重构此代码,因为它不适用于ES6模块。如果这不可能,则可以使用ContextReplacementPlugin来提示编译器进行正确的解析。

我不确定在这种情况下是否起作用。他们还讨论了其中的代码拆分,但是只是很简短,他们没有提到任何“问题”或解决方法。

ssube:

tl; dr: System.resolve然后System.register执行您想要的大部分操作。该答案的其余部分是为什么require.ensure不能以及如何System.import称呼其他人。

认为 ES6模块阻止了此操作的顺利进行,尽管通过相关规范遵循它很棘手,所以我可能完全错了。

就是说,让我们从一些参考开始:

  1. WHATWG模块加载
  2. 模块上ES6规范(第15.2节)
  3. 所述CommonJS的模块规范
  4. 有关ES6模块精彩2ality文章

第一个参考资料解释了更多的行为,尽管我不完全确定它是如何规范化的。后者在JS端解释了实现细节。由于尚无平台实现此功能,因此我没有引用说明其在现实生活中的实际工作方式,我们将不得不依赖该规范。

require已提供的的WebPack 1.x中是CommonJS的的混搭和AMD需要。ref#3(特别是“模块上下文”部分)中介绍了CommonJS方面。没有任何地方提及require.ensureAMD,也没有提及AMD的“规格”,因此这纯粹是webpack的发明。就是说,该功能从不正式,从某种意义上说是正式的且看起来很奇特。

也就是说,我认为require.ensure与ES6模块存在冲突。调用System.import应从一个对象调用该import方法ref#2中的相关部分未明确列出,但§10.1确实提到了将loader附加到LoaderSystem

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

  1. 返回使用实现处理程序转换Resolve(loader,name,referrer)的结果,该处理程序在使用参数键调用时运行以下步骤:
    1. 让entry为EnsureRegistered(loader,key)。
    2. 返回使用实现处理程序转换LoadModule(entry,“ instantiate”)的结果,该处理程序在调用时将运行以下步骤:
      1. 返回EnsureEvaluated(entry)。

该流程为resolve-register-load-evaluate,您想在负载和评估之间进行切换。但是请注意,负载阶段要求LoadModulestage设置为"instantiate"这意味着并且可能要求模块已经通过进行了翻译RequestTranslate,该过程在尝试查找模块的入口点时进行了大量繁琐的分析,依此类推。

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

问题是,System.import直到解析后才能知道该模块是必须评估的ES6模块还是可以推迟的Webpack捆绑包。必须进行解析以弄清楚是否需要解析,从而导致鸡和蛋的问题。

到目前为止,我们一直在跟踪从System.import到的路径Loaderimport呼叫发号施令什么阶段进口的我们在,假设你想通过满端至端的加载过程。像这样的基础调用Loader.prototype.load提供了对那些阶段的细粒度控制。

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

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

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章