浅谈webpack编译原理
前言
想在小程序编译时做一些个性化的处理,必须要了解webpack,翻了下资料,在此浅谈webpack编译原理,对小程序的APP()和Page()函数的扩展或许有些帮助
测试的目录结构
- src目录下index.js文件
const a = require('./a.js') console.log(a)
- src目录下a.js文件
console.log("我是a模块,我的返回结果是 'a.js模块'") module.exports = 'a.js模块'
- dist目录下 index.html引入
<script src="./my-main.js" />
模仿webpack编译文件my_main.js
// 1. 把src目录下所有js文件模块的路径作为键(路径id),内容作为函数执行体(因为内容中需要外部参数,如 module.exports, exports ,require),加入到modules对象中
var modules = {
"./index.js" : function(module, exports ,require ){
//这里是index.js文件内容
const a = require('./a.js')
console.log(a)
},
"./a.js":function(module, exports ,require){
//这里是a.js文件内容
console.log("我是a模块,我的返回结果是 'a.js模块'")
module.exports = 'a.js模块'
}
}
// 2. 模块的结果缓存 防止模块函数多次运行
var installedModules={}
// 3. 执行每个模块的代码就是运行require函数(传参为模块路径id)
function require(moduleId){
// 检测缓存中是否有结果了,有就直接返回了
if(installedModules[moduleId]){
return installedModules[moduleId]
}
//定义参数,给模块内部使用
var module = {
exports:{}
}
// 运行js模块,如果里面有require就是递归,如果里面有module.exports或exports就是设置变量module对象
modules[module_id)(module,module.exports,require)
// 函数返回结果module.exports( 赋值表达式返回结果是值)
return installedModules[moduleId] = module.exports
}
// 4. 执行入口js文件默认是src下的index.js 引用中还有引用就是递归了require
require('./index.js')
webpack编译main.js
//webpack用了一个大闭包 防止变量污染,直接把modules通过传参的形式传入闭包内部,把js文件放入eval中可以在报错时候指定文件路径,还有些兼容处理,这里就不赋值代码了,想看的可以自己用webpack编译看下。