开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第6天,点击查看活动详情
1. webpack介绍
webpack 我们常用的打包工具,需要通过webpack.config.js配置来实现js,sass,less,文件等的处理。webpack只能处理js和json,使用loader可以转换非js文件,如sass转成css。plugin是webpack实现一些特殊处理和优化的插件,在webpack的打包流程中,会抛出一些已经监听的事件,plugin内的钩子去处理,改变wepback的打包结果。
以下为常用的webpack loader和plugin
2. debugger方式介绍
- 通过执行命令调试
- 打开工程目录,点击调试按钮,再点击小齿轮的配置按钮系统就会生成
launch.json配置文件 - 修改好了以后直接点击 F5 就可以启动调试
- 打开工程目录,点击调试按钮,再点击小齿轮的配置按钮系统就会生成
{ "version": "0.2.0",
"configurations": [
{ "type": "node",
"request": "launch",
"name": "debug webpack",
"cwd": "${workspaceFolder}",
"program": "${workspaceFolder}/node_modules/webpack-cli/bin/cli.js" }
]
}
- 通过 chrome 调试 chrome://inspect
node --inspect-brk ./node_modules/webpack-cli/bin/cli.js,然后打开 Chrome 浏览器控制台就可以调试了
3. webpack打包流程
3.1 引入webpack和webpack.config.js, 调用webpack方法得到compiler,传入options配置,合并shell语句和配置文件的参数,得到最终的配置对象
const webpack = require('webpack');
const configFactory = require('../config/webpack.config');
3.2 用上一步得到的配置参数,初始化Compiler对象
const compiler = new Compiler(finalOptions);
3.3 加载配置里面的插件, 循环调用plugin的apply方法
const { plugins } = finalOptions;
for (let plugin of plugins) {
plugin.apply(compiler);
}
3.4 执行Compiler的run方法开始执行编译
compiler.run((err, stats) => {});
// Compiler 类
class Compiler{
constructor(options) {
this.options = options;
this.hooks = {
run: new SyncHook(),//在开始编译之前调用
done:new SyncHook() //在编译完成时执行
}
}
run(callback) {
// 在编译的开始调用开始钩子
this.hooks.run.call();
//在编译的过程中会收集所有的依赖的模块或者说文件
//stats指的是统计信息 modules chunks files=bundle assets指的是文件名和文件内容的映射关系
const onCompiled = (err, stats, fileDependencies) => {
/** 省略部分代码*/
//在编译完成时触发done钩子执行
this.hooks.done.call();
}
//调用compile方法进行编译
this.compile(onCompiled);
}
//开启一次新的编译
compile(callback) {
//每次编译 都会创建一个新的Compilation实例,
let compilation = new Compilation(this.options,this);
// compilation.build 内部实现:
// 读取入口文件
// 文件根据role匹配来使用对应的loader去处理文件
// 递归查找依赖,所有文件都经过编译后。组装成包含多个文件的chunk
// 根据对应关系输出文件列表, 在callback中写入文件
compilation.build(callback);
}
}
3.5 在Compiler里面onCompiled处理文件写入和依赖文件的监听, 最后调用完成钩子
const onCompiled = (err, stats, fileDependencies) => {
//在确定好输出内容后,根据配置确定输出的路径和文件名,把文件内容写入到文件系统
for (let filename in stats.assets) {
let filePath = path.join(this.options.output.path, filename);
fs.writeFileSync(filePath,stats.assets[filename],'utf8');
}
callback(err, { toJson: () => stats });//是这里面传给run方法的回调 compiler.run((err, stats) => {});
for (let fileDependency of fileDependencies) {
//监听依赖的文件变化,如果依赖的文件变化后会开始一次新的编译
fs.watch(fileDependency,()=>this.compile(onCompiled));
}
this.hooks.done.call();//在编译完成时触发done钩子执行
}
//调用compile方法进行编译
this.compile(onCompiled);
小结
整体介绍了webpack的debugger方式和打包流程,对webpack有了整体的印象,后面深入学习loader和plugin的使用和实现。