If chuan source code interpretation source address: juejin.cn/post/699794…

Thank you if chuan elder brother organization read source code activities, harvest is very big, want to join the small partners look over: announcement

1. Related dependency packages

const args = require('minimist')(process.argv.slice(2))
const fs = require('fs')
const path = require('path')
const chalk = require('chalk')
const semver = require('semver')
const currentVersion = require('.. /package.json').version
const { prompt } = require('enquirer')
const execa = require('execa')
Copy the code

minimist

Minimist lightweight command line argument parsing engine

During the parsing process, minimist matches each pattern in turn, from long options to short Options, and then performs the corresponding parsing.

The first and second elements of process.argv are the fully qualified file system paths for the Node executable and the JavaScript files being executed, whether or not you enter them as such.

$ node example/parse.js -a beep -b boop
{ _: [], a: 'beep', b: 'boop' }

$ node example/parse.js -x 3 -y 4 -n5 -abc --beep=boop foo bar baz
{ _: [ 'foo', 'bar', 'baz' ],
  x: 3,
  y: 4,
  n: 5,
  a: true,
  b: true,
  c: true,
  beep: 'boop' }
Copy the code

chalk

The Chalk package modifies the style of strings in the console, including:

  1. Font styles (bold, hidden, etc.)
  2. The font color
  3. The background color

semver

Nodejs implementation of semantic version, used for version verification comparison, etc.

Semver defines two concepts:

  • Version is a string representing a particular version of the package, such as 0.4.1, 1.2.7, 1.2.4-beta.0.
  • A range is a representation of versions that satisfy a particular rule, such as 1.2.3-2.3.4, 1.x, ^0.2, >1.4.

A variety of calculations can be performed on these two concepts, such as comparing the size of two versions, determining whether a version fits a range, determining whether a version is larger than any version in the range, and so on.

Version format: Major version number. Minor version number. Revision number, the increment rules for the version number are as follows: major version number: when you make incompatible API changes, minor version number: when you make a backward-compatible functional addition, revision number: when you make a backward-compatible problem fix. The prior version number and version build information can be added to the major version number. Second version number. Revision number “is followed as an extension.

enquirer

Command line interaction tools, such as selecting relevant version numbers when publishing

execa

Execa is a javascript wrapper that can call shells and local external programs. The child process is started to execute. Supports multiple operating systems, including Windows. If the parent exits, all generated child processes are killed.

2. Main process interpretation

Run the following command yarn Release –dry, and the console will display the entire publishing process

// Run tests... To be skipped // Updating cross dependencies... // Building all packages... // Generate the description of the Changelog. md file$ conventional-changelog -p angular -i CHANGELOG.md -sCommit code research changes... // Publishing packages... Publishing compiler-core... Pushing to github...Copy the code

3. The main function

Take the version number

Yarn Run release 3.2.4
// Take the 3.2.4 parameter
let targetVersion = args._[0]

// Manually select the version if no version number exists
if(! targetVersion) {// no explicit version, offer suggestions
  const { release } = await prompt({
    type: 'select'.name: 'release'.message: 'Select release type'.choices: versionIncrements.map(i= > `${i} (${inc(i)}) `).concat(['custom'])})if (release === 'custom') {
    targetVersion = (
      await prompt({
        type: 'input'.name: 'version'.message: 'Input custom version'.initial: currentVersion
      })
    ).version
  } else {
    targetVersion = release.match(/ / ((. *))) [1]}}// Verify that the version conforms to the specification
if(! semver.valid(targetVersion)) {throw new Error(`invalid target version: ${targetVersion}`)}// Confirm to release
const { yes } = await prompt({
  type: 'confirm'.name: 'yes'.message: `Releasing v${targetVersion}. Confirm? `
})
Copy the code

Run the test case

// run tests before release
  step('\nRunning tests... ')
  if(! skipTests && ! isDryRun) {await run(bin('jest'),'--clearCache'])
    await run('yarn'['test'.'--bail'])}else {
    console.log(`(skipped)`)}Copy the code

Update the dependent version number

Process:

  1. The version number of your own package.json
  2. Modified dependencies related to vUE in Dependencies in Packes. json
  3. Modified dependencies related to vUE in peerDependencies in Packes. json
step('\nUpdating cross dependencies... ') updateVersions(targetVersion) function updateVersions(version) {// 1 package.json updatePackage(path.resolve(__dirname, '.. '), version) // 2. update all packages packages.forEach(p => updatePackage(getPkgRoot(p), Function updatePackage(pkgRoot, version) {const pkgPath = path.resolve(pkgRoot, version) 'package.json') const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8')) pkg.version = version updateDeps(pkg, 'dependencies', version) updateDeps(pkg, 'peerDependencies', version) fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + '\n') }Copy the code

Package and compile

// build all packages with types
step('\nBuilding all packages... ')
if(! skipBuild && ! isDryRun) {await run('yarn'['build'.'--release'])
  // test generated dts files
  step('\nVerifying type declarations... ')
  await run('yarn'['test-dts-only'])}else {
  console.log(`(skipped)`)}Copy the code

The last process

// Generate changelog await run(' yarn ', ['changelog']) Commit const {stdout} = await run('git', ['diff'], {stdio: 'pipe'}) if (stdout) {step('\ nresearch changes... ') await runIfNotDry('git', ['add', '-A']) await runIfNotDry('git', ['commit', '-m', `release: v${targetVersion}`]) } else { console.log('No changes to commit.') } // publish packages step('\nPublishing packages... ') for (const pkg of packages) { await publishPackage(pkg, targetVersion, RunIfNotDry)} step('\nPushing to github... ') await runIfNotDry('git', ['tag', `v${targetVersion}`]) await runIfNotDry('git', ['push', 'origin', `refs/tags/v${targetVersion}`]) await runIfNotDry('git', // const isDryRun = args.dry if (isDryRun) {console.log(' \nDry run finished -run git diff to see package changes. ')} But there are no packages in 'skippedPackages'. // So this code will not execute either. // We like to write arr. Length! == 0, 0 is false. I don't have to write it. if (skippedPackages.length) { console.log( chalk.yellow( `The following packages are skipped and NOT published:\n- ${skippedPackages.join( '\n- ' )}` ) ) } console.log()Copy the code

conclusion

Through this study:

  1. Familiar with vUE releases
  2. Some nodes will be debugged
  3. Learn about the functions of some dependent libraries