【umi】01 从umi-scripts学创建cli

161 阅读2分钟

看到umi中有很多自定义命令,都是umi-scripts xx, 就好奇是怎么运行,翻了下源码看到

image.png

原来是在scripts文件创建了一个bin/umi-scripts.js,然后在package.json的bin下面创建一个命令,在安装node_modules的时候生成.bin可执行文件,最后执行执行自定义命令

image.png

image.png

image.png

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)
}