Webpack Scope Hoisting

Webpack 作用域提升的原理与配置

问题

介绍一下 Webpack Scope Hoisting(作用域提升)。

解答

什么是 Scope Hoisting

Scope Hoisting 是 Webpack 3 引入的优化特性,它将多个模块合并到一个函数作用域中,减少函数声明和闭包,从而减小打包体积、提升运行速度。

未开启 Scope Hoisting 的打包结果

// 每个模块被包裹在单独的函数中
(function(modules) {
  // webpack runtime
})([
  // 模块 0
  function(module, exports, __webpack_require__) {
    var a = __webpack_require__(1);
    console.log(a);
  },
  // 模块 1
  function(module, exports) {
    module.exports = 'hello';
  }
]);

开启 Scope Hoisting 后的打包结果

// 模块被合并到同一作用域
(function(modules) {
  // webpack runtime
})([
  function(module, exports) {
    // 模块 1 的内容直接内联
    var a = 'hello';
    console.log(a);
  }
]);

如何启用

Webpack 4+(production 模式自动开启):

// webpack.config.js
module.exports = {
  mode: 'production', // 自动启用
};

手动配置:

// webpack.config.js
const webpack = require('webpack');

module.exports = {
  optimization: {
    concatenateModules: true, // Webpack 4+
  },
  // 或使用插件
  plugins: [
    new webpack.optimize.ModuleConcatenationPlugin()
  ]
};

使用条件

Scope Hoisting 只对 ES Module 生效:

// ✅ 支持 - ES Module
import { foo } from './utils';
export const bar = foo;

// ❌ 不支持 - CommonJS
const { foo } = require('./utils');
module.exports = { bar: foo };

查看优化效果

// webpack.config.js
module.exports = {
  stats: {
    optimizationBailout: true, // 显示哪些模块无法被优化
  },
};

关键点

  • Scope Hoisting 将模块合并到同一作用域,减少闭包和函数声明
  • 只对 ES Module(import/export)生效,CommonJS 不支持
  • Webpack 4+ 的 production 模式自动开启
  • 可通过 optimization.concatenateModulesModuleConcatenationPlugin 手动配置
  • 减小打包体积,提升代码执行速度