Webpack 处理 ES Module 的 import 和 export

101 阅读1分钟

image.png

关键运行时的方法

webpack 注入的运行时包含一下核心方法

  • _webpack_require_(moduleId): 加载模块的入口函数
  • _webpack_exports_:每个模块的导出对象,类似(module.exports)
  • _webpack_require_.d():定义属性的快捷方法(用于兼容性)
  • _webpack_require_.r(): 标记模块为ES Module(通过Symbol.toStringTag)

不同导出方式的处理

具名导出

    export const foo = 123;
    export function bar(){}
    //转换后
    __webpack_exports__["foo"] = 123
    __webpack_exports__["bar:] = function(){}

默认导出

export default 42;
__webpack_exports__["default"] = 42;

混合导出

export const a = 1;
export default {b: 2}

__webpack_exports__["a"] = 1;
__webpack_exports_["default"] = {b: 2}

不同的导入方式

默认导入

import foo from './module'

var foo = __webpack_require__("./module.js"]["default"]

具名导入

// 源码
import { add } from './math';

// 转换后
var _math__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./math.js");
_math__WEBPACK_IMPORTED_MODULE_0__["add"];

命名空间导入

// 源码
import * as math from './math';

// 转换后
var math = __webpack_require__.n(__webpack_require__("./math.js"));

动态导入

import ('./module').then(module => {})

__webpack_require__.e(/* chunkId *).then(__webpack_require__.bind(__webpack_require__, "./module.js"));

总结:webpack的处理流程

  1. 解析:将import/export转换为__webpack_require__和__webpack_exports__调用
  2. 封装:每个模块被包裹为函数,隔离作用域
  3. 标记:通过__webpack_require__.r()区分ES Module
  4. 运行:按依赖顺序执行模块函数,维护缓存机制

标记:通过__webpack_require__.r()区分ES Module 是什么意思?

在webpack 打包的代码中,webpack_require.r() 是一个运行时辅助函数,用于标记某个模块为 ES Module,它的核心作用时通过修改模块的导出对象(webpack_exports)的属性,确保其符合ES Module的规范,从而在运行时与其他模块系统(如 CommonJS)区分开来