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:
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 theoclif.manifest.json
- Improved accuracy in the
DEBUG=perf
output. - Remove
ts-node
fromdependencies
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()