什么是cli工具?
- 基于
@vue/cli实现的交互式的项目脚手架 - 基于 webpack 构建,并带有一些默认配置并且可扩展
实现了什么?
- 定义自己的命令行
- 使用对应的命令行执行对应的插件脚本
- 尽量做到开箱即用,也就是独立性要高
开撸
1. 首先我们建一个自己的插件目录比如说叫 dd
2. 然后在bin/index.js中添加如下代码
#!/usr/bin/env node
// 上面这段的意思是让使用 node 进行脚本的解释程序,那下面的就可以使用 node 的语法了
const webpack = require('webpack');
const builtInWebpackConfig = require('../webpack.config');
webpack(builtInWebpackConfig, (err, stats) => {
if (err || stats.hasErrors()) {
return console.log('build failed.')
}
console.log('build success.');
})
并在package.json中添加上:"bin": "bin/index.js",就是添加可执行js文件,然后执行 npm link (将npm 模块链接到对应的运行项目中去,方便地对模块进行调试和测试)
然后我们建一个临时的测试项目demo,在demo项目下执行 npm link demo 将dd模块 链接到demo项目中,
会在demo项目的 node_modules 中复制一份dd模块的内容
并且在demo的package.json中添加自定义的 srcipts : { "build": "dd" },我们来执行 npm run build 打印结果符合我们的预期
3. 接下来搞一个自定义的插件,首先在demo中建一个插件配置文件 config.js
const CleanPluginForCommand = require('./plugins/clean');
module.exports = {
plugins: {
// hello options 相当于可预置的默认配置参数
commands: [ CleanPluginForCommand('hello options') ],
webpackPlugins: [],
webapckLoader: []
}
}
在/plugins中加一个 比如自定义的 clean.js
// 假设用户要支持自定义的 clean 的命令
// module.exports = (api) => {}
module.exports = (options) => (api) => {
// 打印一下预置的参数
console.log('options: ', options);
api.registerCommands('clean', (...args) => {
// 我们自定义的 clean 命令的逻辑
console.log('exec clean script success!');
})
}
在 scripts中添加一个命令 "clean": "dd clean",后面执行 npm run clean来执行我们的插件
4. 最后一步完善一下我们的 dd/bin/index.js,困了,直接上代码,兄弟们自己看🥱🥱😴😴
#!/usr/bin/env node
// 这段话的意思是让使用 node 进行脚本的解释程序,那下面的就可以使用 node 的语法了
const webpack = require('webpack');
const minimist = require('minimist');
const builtInWebpackConfig = require('../webpack.config');
const path = require('path');
const args = minimist(process.argv.slice(2)); // 获取命令行的参数
// class PluginManager extends Plugin {} <- 优雅的方式是 内聚到一个模块实现
const __commands = {};
// const __plugins = {};
const fname = 'config.js'; // 上面建好的插件配置文件
const runWebpackBuild = () => {
webpack(builtInWebpackConfig, (err, stats) => {
if (err || stats.hasErrors()) {
return console.log('build failed.')
}
console.log('build success.');
})
}
// 封装 api,这个是作为参数塞到自定义插件函数中的,通过这个 api 往外暴露能力
// 优雅的方式是要写一个 class Api extends BaseApi {}
const api = {
registerCommands(name, impl) {
const command = __commands[name];
if (!command) {
__commands[name] = impl
}
},
}
// 读取用户本地的配置文件 config.js
const readLocalOption = () => new Promise((resolve) => {
// 读取到配置文件 config.js 的内容
const config = require(path.join(process.cwd(), fname)) || {};
// 取出对应的配置参数
const { plugins: { commands = [] } = {} } = config;
if (commands.length) {
commands.forEach(command => {
command(api);
})
}
console.log('__commands', __commands)
resolve(__commands);
})
readLocalOption().then((commands) => {
const command = args._[0]; // 取执行命令 dd clean
console.log('command', command)
// 有对应的插件就直接执行
if (commands[command]) {
commands[command]();
}
else {
runWebpackBuild();
}
})
执行 npm run clean 看下执行结果
到这里我们就实现了一个最简单的 cli机制和 plugin, 是否对你有帮助呢
记得留个赞哦🤞🤞🤞