介绍
webpack 是一个现代 JavaScript 应用程序的静态模块打包器
webpack 将模块化开发方式编写的代码,编译为浏览器可识别的代码
当 webpack 处理应用程序时,它会递归地构建一个依赖关系图,其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle
核心概念
entry:指示 webpack 应该使用哪个模块,来作为构建其内部依赖图的开始
output:output 属性告诉 webpack 在哪里输出它所创建的 bundles,以及如何命名这些文件
loader:webpack 只能处理 JS 文件,loader 将非 JS 文件,编译为 JS 文件供 webpack 使用
plugins:loader 被用于转换某些类型的模块,而 plugins 则可以用于执行范围更广的任务,比如打包优化、压缩
流程概述
Loader
loader 可以理解为 webpack 的编译器,用于对模块的源代码进行转换。它使得 webpack 可以处理一些非 JS 文件,如 png、css、json
实现一个简单的 loader,功能是替换 console.log、去除换行符、在文件结尾处增加一行自定义内容
const loaderUtils = require('loader-utils')
/** 过滤console.log和换行符 */
module.exports = function (source) {
// 获取loader配置项
const options = loaderUtils.getOptions(this)
console.log('loader配置项:', options)
const result = source
.replace(/console.log\(.*\);?/g, "")
.replace(/\n/g, "")
.concat(`console.log("${options.message || '没有配置项'}");`)
return result
}
Tapable
tapable 和 EventEmitter 一样,是一系列事件的生成和管理工具,典型的发布订阅模式
tapable 实现了 webpack 的事件流机制,将各个插件串联起来
tapable 暴露出很多钩子类,这些类可以用来为插件创建钩子函数
以 SyncHook 为例,用法:
const { SyncHook } = require("tapable")
let queue = new SyncHook(['name']) //所有的构造函数都接收一个可选的参数,这个参数是一个字符串的数组。
// 订阅
queue.tap('1', function (name) { // tap 的第一个参数用来标识订阅的函数
console.log(name, name2, 1)
return '1'
})
queue.tap('2', function (name) {
console.log(name, 2);
})
queue.tap('3', function (name) {
console.log(name, 3);
})
// 发布
queue.call('webpack') // 发布的时候触发订阅的函数 同时传入参数
// 执行结果:
/*
webpack 1
webpack 2
webpack 3
*/
简化的原理:
class SyncHook{
constructor(){
this.hooks = [];
}
// 订阅事件
tap(name, fn){
this.hooks.push(fn);
}
// 发布
call(){
this.hooks.forEach(hook => hook(...arguments));
}
}
Plugin
plugin 是带有 apply 方法的 class
实现一个简单的 plugin
// 1、Plugin名称
const MY_PLUGIN_NAME = "MyBasicPlugin";
class MyBasicPlugin {
// 2、在构造函数中获取插件配置项
constructor(option) {
this.option = option;
}
// 3、在原型对象上定义一个 apply 函数供 webpack 注册
apply(compiler) {
// 4、注册 webpack 事件监听函数
compiler.hooks.emit.tapAsync(MY_PLUGIN_NAME, (compilation, asyncCallback) => {
// 5、操作 Or 改变 compilation 内部数据
console.log(compilation);
// 6、如果是异步钩子,结束后需要执行异步回调
asyncCallback();
});
}
}
// 7、模块导出
module.exports = MyBasicPlugin;
在webpack.config.js 中 require 并实例化进行使用
const MyPlugin = require('./plugins/myplugin.js')
module.exports = {
......,
plugins: [
new MyPlugin("Plugin is instancing.")
]
}
webpack 中注册插件的代码
lib/webpack.js
JavaScript
if (Array.isArray(options.plugins)) {
for (const plugin of options.plugins) {
if (typeof plugin === "function") {
plugin.call(compiler, compiler)
} else {
plugin.apply(compiler)
}
}
}
参考
webpack官方文档
Webpack漫谈
浅析webpack
Webpack揭秘——走向高阶前端的必经之路
Webpack源码解读:理清编译主流程
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!