深入理解webpack打包bundle.js的机制

本文通过实际打包查看bundle.js的源码的方式来理解webpack的打包输出。

项目目录如下:

+ index.js
+ package.json
+ webpack.config.js

其中webpack.config.js的配置如下

const path = require('path');
module.exports = {
  entry: './index.js',
  mode: 'development',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'bundle.js',
    library: 'demo',
    libraryTarget: 'umd'
  },
}

index.js来模拟一个需要导出的包。并使用了esmodule的方式导出。

function demo() {
  console.log('this is demo');
}

export default demo;

以上的配置是希望打包出一个支持umd模块规范的lib库。执行webpack打包出了./dist/bundle.js,最好配合node中commonjs的规范对比理解。

我这里先把commonjs执行的过程列一下,详细见这里

// 1. 检查 Module._cache,是否缓存之中有指定模块
// 2. 如果缓存之中没有,就创建一个新的Module实例
// 3. 将它保存到缓存
// 4. 使用 module.load() 加载指定的模块文件,
// 读取文件内容之后,使用 module.compile() 执行文件代码
// 5. 如果加载/解析过程报错,就从缓存删除该模块
// 6. 返回该模块的 module.exports

打包出的文件源码内容摘略如下,请仔细看注释。

// umd规范
(function webpackUniversalModuleDefinition(root, factory) {
	// commonjs2
	if(typeof exports === 'object' && typeof module === 'object')
		module.exports = factory();
	// amd
	else if(typeof define === 'function' && define.amd)
		define([], factory);
	// commonjs
	else if(typeof exports === 'object')
		exports["demo"] = factory();
	else
	// 注入到全局
		root["demo"] = factory();
})(self, function() {
return /******/ (() => { // webpackBootstrap
/******/ 	"use strict";
/******/ 	var __webpack_modules__ = ({
// index.js 即为需要导出的模块,可以看出这就是一个kv组成的模块的map
/***/ "./index.js":
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
		eval("...")
	  })
	  	});
	  	// 如同nodejs的commonjs,webpack也会缓存已经加载的模块。
	  	var __webpack_module_cache__ = {};
/******/ 	
/******/ 	// The require 函数
/******/ 	function __webpack_require__(moduleId) {
/******/ 		// 检查是否在缓存中
/******/ 		if(__webpack_module_cache__[moduleId]) {
/******/ 			return __webpack_module_cache__[moduleId].exports;
/******/ 		}
/******/ 		// 创建一个新的模块并放入到缓存,其实可以看出只是一个对象字面量
/******/ 		var module = __webpack_module_cache__[moduleId] = {
/******/ 			// no module.id needed
/******/ 			// no module.loaded needed
/******/ 			exports: {}
/******/ 		};
/******/ 	
/******/ 		// 执行Module中的代码
/******/ 		__webpack_modules__[moduleId](module, module.exports, __webpack_require__);
/******/ 	
/******/ 		// 导出模块。
/******/ 		return module.exports;
/******/ 	}
			// 运行入口文件,并导出
/******/ 	return __webpack_require__("./index.js");
/******/ })()
;
});

可以看出,几乎就是Node.js commonjs规范的浏览器实现。可参考阮一峰的模块加载机制进行对比。这样相互印证,更好去理解和记忆。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值