webpack打包原理解析

webpack打包是如何运行的

  • 也可以称为,webpack是如何实现模块化的
  • CommonJS是同步加载模块,一般用于node。因为node应用程序运行在服务器上,程序通过文件系统可以直接读取到各个模块的文件,特点是响应快速,不会因为同步而阻塞了程序的运行;
  • AMD是异步加载模块,所以普遍用于前端。而前端项目运行在浏览器中,每个模块都要通过http请求加载js模块文件,受到网络等因素的影响如果同步的话就会使浏览器出现“假死”(卡死)的情况,影响到了用户体验。
  • ESModule 旨在实现前后端模块化的统一。而webpack就是把ES6的模块化代码转码成CommonJS的形式,从而兼容浏览器的。
  • 为什么webpack打包后的文件,可以用在浏览器:此时webpack会将所有的js模块打包到bundle.js中(异步加载的模块除外,异步模块后面会讲),读取到了内存里,就不会再分模块加载了。
  • webpack将代码打包成什么样子

webpack对CommonJS的模块化处理

  • 举例:
    • index.js文件,引入foo.js文件
    const foo = require('./foo');
    
    console.log(foo);
    console.log('我是高级前端工程师~');
    
    • foo.js文件
    module.exports = {
      name: 'quanquan',
      job: 'fe',
    };
    
  • 当我们执行webpack之后,打包完成,可以看到bundle.js内的代码
// modules 即为存放所有模块的数组,数组中的每一个元素都是一个函数
(function(modules) {
	// 安装过的模块都存放在这里面
    // 作用是把已经加载过的模块缓存在内存中,提升性能
	var installedModules = {};
	// 去数组中加载一个模块,moduleId 为要加载模块在数组中的 index
    // __webpack_require__作用和 Node.js 中 require 语句相似
	function __webpack_require__(moduleId) {
		// require 模块时先判断是否已经缓存, 已经缓存的模块直接返回
		if(installedModules[moduleId]) {
			return installedModules[moduleId].exports;
		}
		// 如果缓存中不存在需要加载的模块,就新建一个模块,并把它存在缓存中
		var module = installedModules[moduleId] = {
            // 模块在数组中的index
            i: moduleId,
            // 该模块是否已加载完毕
            l: false,
            // 该模块的导出值,也叫模块主体内容, 会被重写
			exports: {}
		};
		// 从 modules 中获取 index 为 moduleId 的模块对应的函数
        // 再调用这个函数,同时把函数需要的参数传入,this指向模块的主体内容
		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
		// 将模块标记为已加载
		module.l = true;
		// 返回模块的导出值,即模块主体内容
		return module.exports;
	}
    // 向外暴露所有的模块
	__webpack_require__.m = modules;
	// 向外暴露已缓存的模块
    __webpack_require__.c = installedModules;
	
	...
	...
	
    // Webpack 配置中的 publicPath,用于加载被分割出去的异步代码,这个暂时还没有用到
	__webpack_require__.p = "";
    // Load entry module and return exports
    // 准备工作做完了, require 一下入口模块, 让项目跑起来
    // 使用 __webpack_require__ 去加载 index 为 0 的模块,并且返回该模块导出的内容
    // index 为 0 的模块就是 index.js文件,也就是执行入口模块
    // __webpack_require__.s 的含义是启动模块对应的 index
	return __webpack_require__(__webpack_require__.s = 0);
})
/***** 华丽的分割线 上边时 webpack 初始化代码, 下边是我们写的模块代码 *******/
// 所有的模块都存放在了一个数组里,根据每个模块在数组的 index 来区分和定位模块
([
	/* 模块 0 对应 index.js */
	(function(module, exports, __webpack_require__) {
		// 通过 __webpack_require__ 规范导入 foo 函数,foo.js 对应的模块 index 为 1
		const foo = __webpack_require__(1);
		
		console.log(foo);
		console.log('我是高级前端工程师~');
	}),
	/* 模块 1 对应 foo.js *
  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值