Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

webpack 的 scope hoisting #10

Open
mbaxszy7 opened this issue Jun 20, 2020 · 0 comments
Open

webpack 的 scope hoisting #10

mbaxszy7 opened this issue Jun 20, 2020 · 0 comments
Labels

Comments

@mbaxszy7
Copy link
Owner

下面比较简单的来总结一下webpack 的 scope hoisting

什么是scope hoisting

scope hoisting 翻译过来就是作用域提升。在webpack中,这个特性被用来检测引用链(import chaining)是否可以被内联,从而减少没有必要的module。

webpack中的scope hoisting

要了解webpack中的scope hoisting,首选需要知道webpack打包出来的代码。这一部分已经在我的前面一篇webpack是如何实现动态导入的中有详细的讲述,下面来简单提一下。webpack打包后的代码框架:

(function(modules) {
  . . .
  // cache
  var installedModules = {};

  function __webpack_require__(moduleId) {
     // check cache
    if (installedModules[id]) {
      return installedModules[id].exports;
    }

     // create new module and cache it
     var module = installedModules[id] = {
       id: id,
       exports: {}
     };

     // execute the module function
     modules[id].call(module.exports, module, module.exports, __webpack_require__);
  }

  // load entry module and return exports
   return __webpack_require__(0);
})({
  "hello.js": function() {},
  "app.js": function() {},
  0:  function() {}
});

可以看到匿名函数的参数modules对象是一个个我们项目中的模块。如果模块很多那modules将会很大,毫无疑问会有大量的函数声明和内存开销。所以webpack通过scope hoisting来检测模块间的引用链(import chaining),从而来展平引用链,并把他们内联到一个函数中,达到“压缩”modules的效果。

怎么开启scope hoisting

在webpack中开启ModuleConcatenationPlugin插件可以开启scope hoisting。此插件只在 production mode生产环境中默认开启。
new webpack.optimize.ModuleConcatenationPlugin();

一些不会产生scope hoisting的情况

webpack attempts to achieve partial scope hoisting. It will merge modules into a single scope but cannot do so in every case. If webpack cannot merge a module, the two alternatives are Prevent and Root. Prevent means the module must be in its own scope. Root means a new module group will be created. The following conditions determine the outcome

大致翻译如下: webpack尝试完成部分scope hoisting。也就是说webpack不会在每种情况下都把modules合并到同一个作用域。如果合并失败会有以下两种情况替代: Prevent and Root。

- Prevent: 模块必须待在自己的作用域中。比如非es6模块、使用eval()、export * from "cjs-module"
- Root:一个新的模块会被开启。比如动态import

具体情况如下,可以在官方文档中查阅。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant