1. Introduction

Hi, I’m Wakawa. In order to help more interested in the source code, want to learn to read the source code, enhance their front-end technology ability of the students. I have organized source code reading activities with all my efforts, and those who are interested can join in with my wechat account RuoChuan12. Welcome to follow my official account Ruochuan Vision. Every week we learn about 200 lines of source code, common progress, has been carried out for 4 months, many people said that the harvest is quite abundant.

If you want to learn source code, Highly recommend to pay attention to my column (currently 1.9K people concerned) “learning source code overall architecture series” Includes jQuery, underscore, Lodash, vuex, Sentry, AXIos, Redux, KOA, VUE-devtools, vuex4, koa-compose, vue 3.2 Release, VUE-this, CREate-Vue, toy Vite and other more than 20 source code articles.

This paper warehouse, https://github.com/lxchuan12/install-pkg-analysis.git, and a star ^_^

Source code reading activities a week, has been carried out to 16 issues. The install-pkg widget developed by Anthony Fu, a core member of the Vue team, has only 39 lines of main file source code, which is worth learning.

Reading this article, you will learn:

How to learn to debug source code 2. How to develop and build a TS NPM package 3. How to configure Github Actions 4. Configure your own ESLint default, promoted version number, etc. 5. Learn to execute commands using execA. 6. EtcCopy the code

2. What is install-pkg

Install package programmatically. Detect package managers automatically (npm, yarn and pnpm).

Install packages programmatically. Automatic detection of package managers (NPM, YARN, and PNPM).

npm i @antfu/install-pkg
Copy the code
import { installPackage } from '@antfu/install-pkg'
await installPackage('vite', { silent: true })
Copy the code

npm @antfu/install-pkg

At present, only the following two projects are used. unplugin-icons @chenyueban/lint

3 Cloning Project

# Recommend cloning my project to ensure synchronization with the article
git clone https://github.com/lxchuan12/install-pkg-analysis.git
# npm i -g pnpm
cd install-pkg-analysis/install-pkg && pnpm i
# VSCode opens the current project directly
# code .

# or clone official projects
git clone https://github.com/antfu/install-pkg.git
# npm i -g pnpm
cd install-pkg && pnpm i
# VSCode opens the current project directly
# code .
Copy the code

Json, then script.

{
    "name": "@antfu/install-pkg"."version": "0.1.0 from"."scripts": {
      "start": "esno src/index.ts"}},Copy the code

For more information on debugging, see this article: Beginners to: Front-end programmers must learn basic skills – debugging JS code, I won’t go into details here.

We can tell that the entry file is SRC /index.ts

There are three files in the SRC folder

src
- detect.ts
- index.ts
- install
Copy the code

Then we look at the source of these files.

4. The source code

4.1 the index. Js

Export all

// src/install.ts
export * from './detect'
export * from './install'
Copy the code

4.2 installPackage Installation package

// src/install.ts
import execa from 'execa'
import { detectPackageManager } from '. '

exportinterface 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,
    },
  )
}
Copy the code

Support for multiple installations, also support for specifying package managers, support for additional parameters.

Execa executes the script

Process execution for humans

github execa

pnpm install -D --prefer-offine release-it react antd
Copy the code

Let’s look at how the detectPackageManager function, the package manager, is implemented.

4.3 detectPackageManager detectPackageManager

Probes the package manager based on the current directory lock file.

// src/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
}
Copy the code

Find-up searches the path.

/ └── ├─ package.txtCopy the code
import {findUp} from 'find-up';

console.log(await findUp('package.json'));
//=> '/Users/ruochuan/package.json'
Copy the code

In a word, the principle is: automatically detect which package manager (NPM, YARN, PNPM) to use by locking files, and finally use execa to execute commands like the following.

After reviewing the source code, let’s go on to explain the scripts command in package.json.

Package. json script Command parsing

{
    "name": "@antfu/install-pkg"."version": "0.1.0 from"."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"}},Copy the code

5.1 ni artifact

ithub ni

I’ve written source code articles before.

Can you replace NPM/YARN/PNPM? Easy to use! Source code revealed!

Yaml/package-lock.json automatically detects the package manager using YARN/PNPM/NPM based on the lock file yarn.lock/pnpm-lock. json.

nr dev --port=3000

# npm run dev -- --port=3000
# yarn run dev --port=3000
# pnpm run dev -- --port=3000
Copy the code
nr
# Interactively select scripts
# interactively select the script to run
# supports https://www.npmjs.com/package/npm-scripts-info convention
Copy the code

nci – clean install

nci
# npm ci
The lock file is not updated
# yarn install --frozen-lockfile
# pnpm install --frozen-lockfile
Copy the code

pnpm install –frozen-lockfile

5.2 ESNO Runs TS

esno

TypeScript / ESNext node runtime powered by esbuild

There is not much source code.

#! /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)
Copy the code

Esbuild-register simply put: Use ESbuild to instantly transfer JSX, TypeScript, and ESNext functionality

5.3 TSUP Packs TS

The easiest and fastest way to package TypeScript libraries.

tsup

5.4 Bumpp Interactive enhanced version number

bumpp

version-bump-prompt

Interactive CLI can add your version number, etc

5.5 eslint preset

Eslint preset

pnpm add -D eslint @antfu/eslint-config
Copy the code

Add the.eslintrc file

// .eslintrc
{
  "extends": ["@antfu"]."rules": {}}Copy the code

The esLint tool XO is also very useful

xo

JavaScript/TypeScript Linter (ESLint wrapper) with Great defaults JavaScript/TypeScript Linter (ESLint wrapper) has nice defaults

After scripts command parsing, let’s take a look at github Action configuration.

6. github action workflows

For those unfamiliar with Github Actions, please check out ruan Yifeng’s github Actions tutorial

Configuration file workflows/release

Build history Github Action Workflow

name: Release

on:
  push:
    tags:
      - 'v*'

jobs:
  release:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
        with:
          fetch-depth: 0
      - uses: actions/setup-node@v2
        with:
          node-version: '14'
          registry-url: https://registry.npmjs.org/
      - run: npm i -g pnpm @antfu/ni
      - run: nci
      - run: nr test --if-present
      - run: npx conventional-github-releaser -p angular
        env:
          CONVENTIONAL_GITHUB_RELEASER_TOKEN: ${{secrets.GITHUB_TOKEN}}
Copy the code

Execute according to each tags push.

Install PNPM and NI globally
npm i -g pnpm @antfu/ni
Copy the code
# How to run the test command
nr test --if-present
Copy the code

nci – clean install

nci
# npm ci
The lock file is not updated
# yarn install --frozen-lockfile
# pnpm install --frozen-lockfile
Copy the code

NPX xcom -github-releaser -p Angular xcom -github-releaser

Generate the changelog

This completes the install-pkg package.

7. To summarize

The overall code is relatively simple. The principle is to automatically detect which package manager (NPM, YARN, PNPM) is used by locking files, and finally execute commands like the following with execa.

pnpm install -D --prefer-offine release-it react antd
Copy the code

We learned:

How to learn to debug source code 2. How to develop and build a TS NPM package 3. How to configure Github Actions 4. Configure your own ESLint default, promoted version number, etc. 5. Learn to execute commands using execA. 6. EtcCopy the code

There are various dependency tools.

Suggest readers clone my warehouse hands-on debugging source code learning.

Finally, you can continue to pay attention to me @Ruogawa. Welcome to join us in ruochuan12 to learn about 200 lines of source code every week and make progress together.


About && source code to read communication group

Recently, I organized a reading activity for source code. If you are interested, you can join me in wechat ruochuan12 for long-term communication and learning.

Author: Often in the name of ruochuan mixed traces in rivers and lakes. Welcome to add my wechat account ruochuan12. Front road | know very little, only good study. Concern about the public number if chuan vision, every week to learn the source code, learn to see the source code, advanced advanced front end. Wakawa’s blog segmentfault wakawa’s view column, has opened a column on wakawa’s view, welcome to follow ~ dig gold column, welcome to follow ~ github blog, beg a star^_^~