阅读 116

插件机制是如何工作的

前言

作为解决扩展性的普遍方案,很多工具都支持引入插件来应对个性化场景的需求。比如现在已经离不开的webpack, babel. 冉冉升起的vite. 还有我们伴随我们青春的老大哥jquery. 下面我将尝试用两条叙事线来说明,一条是CLI,另一条是使用CLI的项目。

1. 初始化一个极简CLI

初始化一个项目

npm init -y 复制代码

简单装两个依赖,意思一下

npm i webpack minimist -D // minimist这个库是解析命令行参数用的 复制代码

在根目录创建这个CLI打包时要用的webpack的配置文件

// ./webpack.config.js module.exports = {   entry: './index.js',   output: {     filename: 'bandle.js'   } } 复制代码

package.json里加入bin字段

// ./package.json "bin":{    "snowpack":"./bin/index.js" }, 复制代码

创建bin文件夹,里面创建index.js, 我们开始写内容

#!/usr/bin/env node // ./bin/.index.js const { join } = require('path') const webpack = require('webpack') // 假设这个`CLI`用`snowpack.config.js`作为配置文件。 const snowpackConfig = 'snowpack.config.js' // 读取webpack配置 const webpackConfig = require('../webpack.config.js') // 命令和函数的映射 const __commands = {} // 这个对象会传给用户传入的函数里 const api = {   // 在插件作者传入的函数里会调用registeCommand注册命令   registeCommand: (command, func) => {     if(!__commands[command]){       __commands[command] = func     }   } } ... 复制代码

先写到这里,我们切换故事线,切换之前回顾一下snowpack的目录结构。

. |-snowpack   |-bin   |  |-index.js   |-node_modules      |...   |-package-lock.json   |-package.json 复制代码

2. 创建一个要使用 "snowpack" 的项目

同样先npm init一下

npm init -y 复制代码

在根目录创建一个index.js, 并随便写一写代码

// ./index.js console.log('im test project') 复制代码

在根目录创建一个snowpack的配置文件

// ./snowpack.config.js const { clean } = require('./plugins.js') module.exports = {   plugins:{     commands: [clean('cleaned')]   } } 复制代码

再把plugins.js写一写

// ./plugins.js module.exports = {   clean: (str) => (api) => {   // 这里接收api对象     api.registeCommand('clean', () => {       console.log('exec plugin', str)     })   } } 复制代码

最后看一下目录结构

. |-testProject   |-index.js   |-package.json   |-plugins.js   |-snowpack.config.js 复制代码

3. 补上 ./bin/index.js 剩余部分

第一节我们写到这里,通过第二节我们知道了snowpack.config.js的内容,和api对象会被传到哪里。

// ./bin/.index.js const { join } = require('path') const webpack = require('webpack') // 假设这个`CLI`用`snowpack.config.js`作为配置文件。 const snowpackConfig = 'snowpack.config.js' // 读取webpack配置 const webpackConfig = require('../webpack.config.js') // 命令和函数的映射 const __commands = {} // 这个对象会传给用户传入的函数里 const api = {   // 在插件作者传入的函数里会调用registeCommand注册命令   registeCommand: (command, func) => {     if(!__commands[command]){       __commands[command] = func     }   } } ... 复制代码

好,接着往下写

// ./bin/.index.js ... // 封装一个执行webpack打包的函数 const runWebpackBuild = () => {   webpack(webpackConfig, (err, status) => {     if(err || status.hasErrors()){       console.log('build failed')     }     console.log('build success')   }) } // 读取用户项目的配置文件 const readLocalOptions = () => {   return new Promise((resolve, reject) => {     const options = require(join(process.cwd(), snowpackConfig)) || {}     // commands 就是用户传入的函数数组     const { plugins: {commands = []} = {}} = options     if(commands.length > 0){       for(command of commands){         // 调用用户传入的函数时把api暴露出去         command(api)       }     }     resolve(__commands)   }) } // 使用minimist把cli命令的参数提取出来 const minimist = require('minimist') const args = minimist(process.argv.slice(2)) // 调用readLocalOptions,执行传入的命令参数 readLocalOptions().then((__commands)=>{   const arg = args._[0]   const func = __commands[arg]   // 传入的参数如果存在就执行   if(func){     func()   }else{ // 没有就走默认打包逻辑     runWebpackBuild()   } }) 复制代码

3. 让我们康康效果

敲到这里就差不多了,先到snowpack目录下执行npm link

npm link 复制代码

再到testProject目录npm link snowpack, 建立软连接

npm link snowpack 复制代码

此时的目录

. |-testProject   |-node_modules   |  |-.bin   |  |-snowpack   |-index.js   |-package-lock.json   |-package.json   |-plugins.js   |-snowpack.config.js 复制代码

在命令行输入snowpack

xuxuefeng@xuxuefengdeMacBook-Pro-2 testProject % snowpack build success 复制代码

在命令行输入snowpack clean

xuxuefeng@xuxuefengdeMacBook-Pro-2 testProject % snowpack clean exec plugin cleaned 复制代码

嗯,运行正常


作者:snowPeak
链接:https://juejin.cn/post/7021067291852800013


文章分类
后端
文章标签
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐