看到umi中有很多自定义命令,都是umi-scripts xx, 就好奇是怎么运行,翻了下源码看到
原来是在scripts文件创建了一个bin/umi-scripts.js,然后在package.json的bin下面创建一个命令,在安装node_modules的时候生成.bin可执行文件,最后执行执行自定义命令
package.json 的 bin
bin 其实使用的时候非常简单
// package.json
{
"name": "my-cli", // 注意这个name
"version": "1.2.5",
"test": "my-cli"
"bin": { "my-cli": "./scripts/my-cli.js" }
}
// my-cli.js
#!/usr/bin/env node
console.log("This is my custom script!");
调试
如果是本地调试的话,在my-cli 中使用npm link创建一个符号链接到my-cli
然后在要使用的项目中使用npm link my-cli导航到你的项目目录 ,就可以执行pnpm test了
总结创建cli的步骤
1、首先创建一个my-cli.js的文件
// !/usr/bin/env node
console.log("hello world")
2、然后在package.json中创建cli命令
"bin": {
"my-cli": "bin/my-cli.js"
}
3、本地调试
使用npm link或者yarn link
- 在
my-cli中使用npm link创建一个符号链接到my-cli - 要在使用的项目中使用
npm link my-cli导航到你的项目目录 - 注意
my-cli.js的权限,通过chmod +x cli.js来确保它是可执行的
使用pnpm link
不需要在my-cli中使用pnpm link, 而是直接在使用的项目中pnpm link path/to/my-cli,比如pnpm link ../my-cli
使用pnpm monorepo 自动 link
手动link非常不方便,有时会忘记,而且多人协作的时候也不方便。使用monorepo可以自动link,在测试的包的package.json中
"dependencies": {
"my-cli": "workspace:*"
},
然后从根目录中pnpm install 下就行
附:umi-scripts具体的内容
#!/usr/bin/env node
const { join } = require('path')
const { existsSync } = require('fs')
const { sync } = require('../compiled/cross-spawn')
const chalk = require('../compiled/chalk').default
const assert = require('assert')
const argv = process.argv.slice(2)
const [name, ...throughArgs] = argv
const scriptsPath = join(__dirname, `../${name}.ts`)
assert(
existsSync(scriptsPath) && !name.startsWith('.'),
`Executed script '${chalk.red(name)}' does not exist`
)
console.log(chalk.cyan(`umi-scripts: ${name}\n`))
// current dir path may contain spaces
// https://github.com/umijs/umi/issues/9865
const scriptPathAsStr = JSON.stringify(scriptsPath)
const spawn = sync(
'tsx',
[scriptPathAsStr, ...throughArgs],
{
env: process.env,
cwd: process.cwd(),
stdio: 'inherit',
shell: true
}
)
if (spawn.status !== 0) {
console.log(chalk.red(`umi-scripts: ${name} execute fail`))
process.exit(1)
}