webpack之打包工具原理以及自定义插件

380 阅读3分钟

打包原理无非就是读取配置文件,然后输出到指定的目录,接下来简单实现一个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了

image.png

npm run build

demo文件夹下面创建index.js文件

当我们执行npm run build发现控制台输出build success,并且在demo文件夹下生成一个dist文件夹,里面的文件就是我们在webpack配置的参数,文件内容就是我们自定义在demo文件夹下面创建index.js内容。

npm run clean(自定义)

demo文件夹下package.json

image.png

创建自定义创建插件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

简单点的打包工具并支持自定义插件就完成了。