# 钩子
const {
SyncHook,//同步串行钩子 不关系函数的返回值
SyncBailHook,//同步串行钩子 上一个返回值不为null 跳过剩下的逻辑
SyncWaterfallHook,//同步串行 上一个监听函数的返回值可以传递给下一个函数
SyncLoopHook,//同步循环 如果这个函数返回true反复执行 undefined退出
AsyncParallelHook,//异步并发 不关心每个返回值
AsyncParallelBailHook,//异步兵法 上一个返回值不为null 跳过剩下的逻辑
AsyncSeriesHook,//异步串行 不关系callback的参数
AsyncSeriesBailHook,//callback的参数不为null
AsyncSeriesWaterfallHook //异步串行上一个监听函数的返回值可以传递给下一个函数
} = require("tapable");
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
https://alienzhou.github.io/webpack-internal-plugin-relation/
# dist文件分析
npm run dev 打包出dist 文件 main.js整理
(function (modules) {
// webpack文件进行缓存
var installedModules = {};
function __webpack_require__(moduleId) {
// 判断缓存情况
if (installedModules[moduleId]) {
return installedModules[moduleId].exports;
}
var module = installedModules[moduleId] = {
exports: {}
};
// 执行key对应的匿名函数
modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
return module.exports;
}
// Load entry module and return exports
// 执行入口函数 把export导出
return __webpack_require__("./src/index.js");
})
({
"./src/index.js": (function (module, exports) {
console.log('🍎🍎🍎xiaoming!');
})
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
实现了common.js规范,不发网络请求,把包打包到了自己身上 eval编译快执行快
新建src/data.js
//data.js
const data = 'webpack源码分析';
export default data;
//index.js
import data from './data';
console.log(data);
console.log('🍎🍎🍎xiaoming!');
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
//抽离出的main.js
(function (modules) {
// webpack文件进行缓存
var installedModules = {};
function __webpack_require__(moduleId) {
// 判断缓存情况
if (installedModules[moduleId]) {
return installedModules[moduleId].exports;
}
var module = installedModules[moduleId] = {
exports: {}
};
// 执行key对应的匿名函数
modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
return module.exports;
}
// Load entry module and return exports
// 执行入口函数 把export导出
return __webpack_require__("./src/index.js");
})
({
//__webpack_require__ => module.exports
"./src/data.js": (function (module, __webpack_exports__, __webpack_require__) {
const data = 'webpack源码分析';
/*
module.exports = {
default:data
}
*/
__webpack_exports__["default"] = (data);
}),
"./src/index.js": (function (module, __webpack_exports__, __webpack_require__) {
var _data__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./src/data.js");
console.log(_data__WEBPACK_IMPORTED_MODULE_0__["default"]);
console.log('🍎🍎🍎xiaoming!');
})
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# 与webpack5对比
mkdir webpack5Demo npm install webpack@next --save npm install webpack-cli --save
发现打包出来的dist/main.js 与我们上面删减版本差不多 体积减少了很多
# 异步操作下dist
src/async1.js
const async1 = 'webpack源码分析async1';
export default async1;
1
2
2
src/data.js
const data = 'webpack源码分析data';
export default data;
1
2
2
src/index.js
import('./async1').then(res=>{
console.log(res);
})
import('./data').then(res=>{
console.log(res);
})
console.log('🍎🍎🍎xiaoming!');
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
dist/main.js下面多了webpackJsonpCallback操作
存在问题 async1.js ---> dist/0.js data.js ---> dist/1.js
// import('./async1').then(res=>{
// console.log(res);
// })
import('./data').then(res=>{
console.log(res);
})
console.log('🍎🍎🍎xiaoming!');
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
data.js ---> dist/0.js 这样如果我们之前缓存了0.js 那么就需要用户重新再访问然后才能进行缓存
webpack5已经解决了这个问题 开发环境 dist打包出来用文件名称 dist/async__xxxxx.js 生产环境 dist打包出来用hash dist/854.js
webpack4解决方法 魔法注释
import(/*webpackChunkName*/'./data').then(res=>{
console.log(res);
})
1
2
3
2
3
# 实现一个简单webpack
const data = require("./data.js");
console.log(data);
console.log('hello world 😊xianming!');
1
2
3
2
3
const fs = require("fs");
let input = "./index.js";
let output = "./dist/index.js";
const ejs = require("ejs");
const getEntry = fs.readFileSync(input, "utf-8");
//后面的文件依赖
let contAry = [];
const dealEntry = getEntry.replace(/(require)\(['"](.+?)["']\)/g, ($1, $2, $3, $4) => {
let cont = fs.readFileSync($3, "utf-8");
contAry.push(cont);
// console.log($2)
return $2 = `__webpack_require__(${contAry.length})`
})
let template = `
(function (modules) {
// 对webpack文件进行缓存
var installedModules = {};
function __webpack_require__(moduleId) {
//判断缓存情况
if (installedModules[moduleId]) {
return installedModules[moduleId].exports;
}
var module = installedModules[moduleId] = {
exports: {}
};
//执行key对应的匿名函数
modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
// Return the exports of the module
return module.exports;
}
//执行我们的入口函数 把export导出
return __webpack_require__(0);
})([
(function (module, exports,__webpack_require__) {
<%- dealEntry %>
})
<% for(var i=0;i<contAry.length;i++){ %>
(function (module, exports) {
<%- contAry[i] %>
})
<% } %>
]);`
let result = ejs.render(template, {
dealEntry,
contAry
})
fs.writeFileSync(output, result);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48