打包原理无非就是读取配置文件,然后输出到指定的目录,接下来简单实现一个webpack打包工具。
自定义插件原理就是创建一个插件集合,并提供一个自定义插件的接口,如果用户提供了自定义方法,就添加到插件集合中,否则执行默认的工具函数。
//新建文件夹dd
//创建配置文件
npm init
// 安装依赖
npm install webpack minimist -D
webpack: 静态模块打包工具webpack
minimist: 轻量级的命令行参数解析引擎minimist
创建打包所需的配置webpack.config.js
module.exports ={
entry:'./index.js',
output:{
filename:'bundle.js'
}
}
创建打包和自定义插件代码文件:index.js
#!/usr/bin/env node
const webpack = require('webpack')
const minimist = require('minimist')
const path = require('path')
//将内置的webpack文件引入进来,获取内置配置
const builtInWebpackConfig = require('../webpack.config.js')
//命令行遇到"-"就会被解析成对象.例子: -a 1 -b 2 => {a:1,b:2},获取命令参数
const args = minimist(process.argv.slice(2))
// 生命用户的配置文件,用户进行配置
const fname = 'dd.config.js'
// 存命令,包括用户自定义的命令
const __commands = {}
// 用户怎么自定义插件
const api = {
// 提供给用户这样的api:自定义接口
registerCommands(name, impl) { //impl 就是用户要执行的命令
const command = __commands[name]
// 将用户想要执行的命令存起来
if (!command) {
__commands[name] = impl
}
},
chainWebpack() { }//自定义webpack 插件
}
// 比如我们设置一个打包的工具
const runWebpackBuild = () => {
// 加载内置配置
webpack(builtInWebpackConfig, (err, stats) => {
// log(err)
// 报错,输出
if (err || stats.hasErrors()) {
return console.log('build error')
}
// 成功,输出
console.log('build success')
})
}
// 支持用户根目录下面配置一个文件
// 读去用户的配置文件
const readLocalOption = () => new Promise((resolve) => {
//process.cwd() 获取当前路径
const config = require(path.join(process.cwd(), fname)) || {}
const {plugins:{commands=[]}} = config;
if(commands.length){ //用户配置文件中是是够有自定义插件
commands.forEach(command=>{
// 循环执行自行插件registerCommands
command(api)
})
}
// 向下传递自定义插件集合
resolve(__commands)
})
// 如果什么参数都没有,默认执行打包
readLocalOption().then((commands)=>{
// 获取执行命令的第一个值
const command = args._[0]
console.log(command)
// 去存储命令的集合中找时候有当前命令
if(commands[command]){
commands[command]()
}else{
//执行默认的打包工具函数
runWebpackBuild()
}
})
// npm link 在当前根目录dd下执行,会根据package.json上的配置module会被连接到全局上
npm link
在需要时候的地方执行
//在demo文件下执行,dd会被链接过来一个快捷方式
npm link dd
发现dd被连接过来,我们就可以在使用dd了
npm run build
demo文件夹下面创建index.js文件
当我们执行npm run build发现控制台输出build success,并且在demo文件夹下生成一个dist文件夹,里面的文件就是我们在webpack配置的参数,文件内容就是我们自定义在demo文件夹下面创建index.js内容。
npm run clean(自定义)
demo文件夹下package.json
创建自定义创建插件clean.js
// 第一层函数支持传入一自定义参数,返回一个函数,这里是的api即使,传进来的自定义插件对象
// 支持自定义方法
module.exports = (options) => (api)=>{
api.registerCommands('clean',()=>{
console.log(options)
})
}
demo自定义配置文件dd.config.js
const cleanPluginForCommand = require('./plugin/clean')
module.exports = {
plugins:{
commands:[
cleanPluginForCommand('clean something')
]
}
}
最后执行npm run clean
简单点的打包工具并支持自定义插件就完成了。