【若川视野 x 源码共读】第20期 | Vue团队核心成员开发的39行小工具 install-pkg 安装包

93 阅读2分钟

学习链接:juejin.cn/post/703949…

源码:git clone github.com/antfu/insta…

1、install-pkg 是什么

npm i @antfu/install-pkg   //安装包
引用:
import { installPackage } from '@antfu/install-pkg'
await installPackage('vite', { silent: true })

2、源码

src
  - detect.ts
  - index.ts
- install

1、index.ts

export * from './detect'
export * from './install'
//导出所有

2、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')
  
  //execa 执行脚本 
  return execa(
    agent,
    [
      agent === 'yarn'
      ? 'add'
      : 'install',
      options.dev ? '-D' : '',
      ...args,
      ...names,
    ].filter(Boolean),
    {
      stdio: options.silent ? 'ignore' : 'inherit',
      cwd: options.cwd,
    },
  )
}
最后输出形式类似:pnpm install -D --prefer-offine release-it react antd

3、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 })
  //path.basename 返回 path 的最后一部分
  const agent = (result ? LOCKS[path.basename(result)] : null)
  return agent
}
import {findUp} from 'find-up';

console.log(await findUp('pnpm-lock.yaml'));
//=> '/Users/install-pkg/pnpm-lock.yaml'

4、package.json script 命令解析

"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"
  },

1、n //自动根据锁文件 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

2、esno 运行 ts

const spawn = require('cross-spawn') //跨平台
const spawnSync = spawn.sync
//使用 esbuild 即时传输 JSX、TypeScript 和 esnext 功能
const register = require.resolve('esbuild-register')

const argv = process.argv.slice(2)

process.exit(spawnSync('node', ['-r', register, ...argv], { stdio: 'inherit' }).status)

3、tsup 打包 ts 打包 TypeScript 库的最简单、最快的方法

4、bumpp 交互式提升版本号

5、eslint 预设

5. github action workflows

6、感谢

今天觉得有些扩展的包没听过 不太会 哎呀呀呀 冲