pkg-install
以编程方式安装包。自动检测包管理器(npm、yarn 和 pnpm)
这个包不大,知识点扩展开来涉及不少。
自动检测包管理器(npm、yarn 和 pnpm)
import { installPackage } from '@antfu/install-pkg'
await installPackage('vite', { silent: true })
原理就是通过锁文件自动检测使用何种包管理器(npm、yarn、pnpm),最终用 execa
执行类似如下的命令。
pnpm install -D --prefer-offine release-it react antd
index.ts 入口文件
export * from './detect'
export * from './install'
detect.ts 探测包管理器
import path from 'path'
import findUp from 'find-up'
export type PackageManager = 'pnpm' | 'yarn' | 'npm'
const LOCKS: Record<string, PackageManager> = {
'pnpm-lock.yaml': 'pnpm',
'yarn.lock': 'yarn',
'package-lock.json': 'npm',
}
export async function detectPackageManager(cwd = process.cwd()) {
const result = await findUp(Object.keys(LOCKS), { cwd })
const agent = (result ? LOCKS[path.basename(result)] : null)
return agent
}
install.ts
支持安装多个,也支持指定包管理器,支持额外的参数。
import execa from 'execa'
import { detectPackageManager } from '.'
export interface InstallPackageOptions {
cwd?: string
dev?: boolean
silent?: boolean
packageManager?: string
preferOffline?: boolean
additionalArgs?: string[]
}
export async function installPackage(names: string | string[], options: InstallPackageOptions = {}) {
const agent = options.packageManager || await detectPackageManager(options.cwd) || 'npm'
if (!Array.isArray(names))
names = [names]
const args = options.additionalArgs || []
if (options.preferOffline)
args.unshift('--prefer-offline')
return execa(
agent,
[
agent === 'yarn'
? 'add'
: 'install',
options.dev ? '-D' : '',
...args,
...names,
].filter(Boolean),
{
stdio: options.silent ? 'ignore' : 'inherit',
cwd: options.cwd,
},
)
}
依赖包 find-up
用于查找路径
import { findUp } from 'find-up';
console.log(await findUp('pnpm-lock.yaml'));
//=> '/Users/install-pkg/pnpm-lock.yaml'
path.basename('/Users/install-pkg/pnpm-lock.yaml') // 则是 pnpm-lock.yaml
package.json scripts
解析"scripts": {
"prepublishOnly": "nr build",
"dev": "nr build --watch",
"start": "esno src/index.ts",
"build": "tsup src/index.ts --format cjs,esm --dts --no-splitting",
"release": "bumpp --commit --push --tag && pnpm publish",
"lint": "eslint \"{src,test}/**/*.ts\"",
"lint:fix": "nr lint -- --fix"
},
ni
神器自动根据锁文件 yarn.lock / pnpm-lock.yaml / package-lock.json 检测使用 yarn / pnpm / npm 的包管理器。
nr dev --port=3000
# npm run dev -- --port=3000
# yarn run dev --port=3000
# pnpm run dev -- --port=3000
nr
# 交互式选择脚本
# interactively select the script to run
# supports https://www.npmjs.com/package/npm-scripts-info convention
nci - clean install
nci
# npm ci
# 简单说就是不更新锁文件
# yarn install --frozen-lockfile
# pnpm install --frozen-lockfile
esno
运行 ts#!/usr/bin/env node
const spawn = require('cross-spawn')
const spawnSync = spawn.sync
const register = require.resolve('esbuild-register')
const argv = process.argv.slice(2)
process.exit(spawnSync('node', ['-r', register, ...argv], { stdio: 'inherit' }).status)
tsup
打包 ts打包 TypeScript 库的最简单、最快的方法。
bumpp
交互式提升版本号bumpp
Forked from version-bump-prompt
交互式 CLI 可增加您的版本号等
pnpm add -D eslint @antfu/eslint-config
// .eslintrc
{
"extends": ["@antfu"],
"rules": {}
}
path.basename
execa
执行脚本
stdio
cwd
find-up
查找路径.npmrc
ignore-workspace-root-check=true
即 -W
Yarn Workspaces
并且它管理所有项目(工作区)的依赖项,您应该将每个项目的依赖项添加到自己的 package.json
,而不是工作区根。nr
交互式选择脚本esno
package.json exports
github action