Skip to content

Latest commit

 

History

History
153 lines (106 loc) · 5.77 KB

V3_MIGRATION.md

File metadata and controls

153 lines (106 loc) · 5.77 KB

Migrating to @oclif/core@V3

BREAKING CHANGES ❗

Dropping node 14 and node 16 support

The end-of-life date for Node.js 14 was April 30, 2023.

The end-of-life date for Node.js 16 was September 11, 2023. This date is earlier than previously published. Node.js’s blog explains why they chose this earlier end-of-life date.

Bin Scripts for ESM/CJS Interoperability

In order to support ESM and CommonJS plugin interoperability you will need to update your bin scripts to match these:

CJS Template

ESM Template

You will also need to update any references to the bin scripts to include the .js extension.

If you'd like to migrate your plugin to ESM, please read our guide here

Dropped ts-node as a dependency

We removed ts-node as a dependency to reduce the package size. By doing this, it means that linked plugin must have ts-node as a devDependency in order for auto-transpilation to work.

Config.plugins

Config.plugins is now a Map where the keys are the plugin names and the values are the loaded Plugin instances. Previously it was an array of loaded Plugin instances.

By using a Map we can now do more efficient lookups during command execution. Config.getPluginsList was added in case you still would like a flat array of Plugin instances.

Readonly properties on Config

Various properties on Config are now readonly - name - version - channel - pjson - root - arch - bin - cacheDir - configDir - dataDir - dirname - errLog - home - platform - shell - userAgent - windows - debug - npmRegistry - userPJSON - plugins - binPath - binAliases - nsisCustomization - valid - flexibleTaxonomy - commands

Private methods on Plugin

The _manifest and warn methods on Plugin are now private

global['cli-ux'] -> global.ux

The global cli-ux object has been renamed to ux to be consistent with the module's name

handle

The exported handle function for handling errors in bin scripts is now asynchronous

noCacheDefault flag property replaces isWritingManifest

Version 2 allowed you to optionally return non-sensitive input if the default or defaultHelp flag/arg properties were called during manifest creation. This is helpful if you don't want sensitive data to be put into the oclif.manifest.json and then released to npm. To do this you had to handle the isWritingManifest parameter passed in to the default and defaultHelp callbacks.

export const mySensitiveFlag = Flags.string({
  default: async (context, isWritingManifest) => {
    if (isWritingManifest) {
      return undefined
    }

    return 'sensitive info'
  },
})

Version 3 removes the isWritingManifest parameter in favor of a flag and arg property, noCacheDefault. Setting it to true will automatically keep it from being cached in the manifest.

export const mySensitiveFlag = Flags.string({
  noCacheDefault: true,
  default: async (context) => {
    return 'sensitive info'
  },
})

Removed Unnecessary Exports

The following exports have been removed:

  • toCached
  • tsPath

Features 🎉

Performance Improvements

  • Cache command permutations for flexible taxonomy in the oclif.manifest.json
  • Cache additional command properties (isESM, relativePath) in the oclif.manifest.json
  • Improved accuracy in the DEBUG=perf output.
  • Remove ts-node from dependencies to reduce the package size.

charAliases Flag Property

You can now define single character flag aliases using the charAliases property.

Flags.option

There's a new flag type that infers the flag's type from the provided options.

In v2 you would have needed to do something like this,

type Options = 'foo' | 'bar'
export default class MyCommand extends Command {
  static flags = {
    name: Flags.custom<Options>({
      options: ['foo', 'bar'],
    })(),
  }
}

Now in v3 you can do this,

export default class MyCommand extends Command {
  static flags = {
    name: Flags.option({
      options: ['foo', 'bar'] as const,
    })(),
  }
}

Set spinner styles

You can now configure the style of the spinner when using ux.action.start. See spinners for all the different options.

ux.action.start('starting spinner', 'spinning', {style: 'arc'})
await ux.wait(2500)
ux.action.status = 'still going'
await ux.wait(2500)
ux.action.stop()