Quickly setup everything, or custom it in simple way
GIF made by VHS
❗ ESM
only, pnpm
only.
-
Simple: Use in simple way.
-
Simple: Build in simple way.
-
Simple: Custom in simple way.
Install
pnpm add @norah1to/setup-cli -g
Help
setup-cli help
Create a app
setup-cli create
Opt repo
# Recommend exec "setup-cli update" after do this
setup-cli repo <add|set|rm>
Show repo list
setup-cli repo list
Synchronize the local repo with the remote
setup-cli update
Inject anything into current project
setup-cli inject
Reset the CLI to the state it was first installed in
setup-cli reset
We provide the default templates.
You can build your own too.
Every template has files
,hook
two folder.
└───base-node
├───files
├───hook
└───...
index.js
in hook
must export a function by default, and must be an ESM
module.
It should be of type BaseHook
or InjectHook
, depending on the template type, so you should write hook like this.
// base-node/hook/index.js
/**
* @type {import("@norah1to/setup-cli").BaseHook}
*/
const hook = () => ({ ... });
export default hook;
Of course, you can also use third-party dependencies through packaging tools.
I provide a template base on rollup
that uses a third-party dependency.
Base templates must start with base-
like base-node
.
Its must contain metadata for Inject to use:
const hook = () => ({ ... });
// metadata
hook.meta = { ... }
export default hook;
Inject templates must start with inject-
like inject-lint
.
It does not need to additionally export metadata (temporarily)
Hooks is the core of custom templates, it provides many life cycle hooks.
You can customize the injection logic in it.
The following are described in order of execution.
All hooks are optional.
Will be executed at the beginning, usually used to collect requirements.
It will be executed when each file of the current template is about to be merged.
Used to make some preparations before merging a file.
Type: object
Type: DirInfo
A virtual file tree rooted in the files
folder in the template.
Type: DirInfo
Virtual file tree of target folder.
Type: FileInfo
The virtual file object to be merged into the current template.
Type: FileInfo
A virtual file object with the same name in the target directory.
Used to overwrite the merge logic for files with the same name.
By default, files with the same name in the target path will be overwritten, but sometimes they need to be merged instead of overwritten.
For example when you need to merge package.json
:
onMerging({ srcDir, destDir, src, dest }) {
if (src === srcDir.get('package.json'))
return JSON.stringify(
dpMergePackageJson(dest.getJson(), src.getJson())
);
return src.getContent();
},
Type: string
Required: true
Type: object
Type: DirInfo
Type: DirInfo
Type: FileInfo
Type: FileInfo
Execute after the current file is merged, the rest is the same as beforeMerge
Execute after the virtual file tree is generated.
Type: object
Type: DirInfo
Virtual file tree of target folder.
Execute after outputting the virtual file tree to disk with formatting.
Usually used to execute some installation scripts, for example you need to customize eslint
configuration:
async afterOutput() {
const cwd = process.cwd();
await $.cd(__dir_target_root__);
$.verbose = true;
await $`pnpm create @eslint/config`;
}
Used to store folder information, won't modify the original file or folder on disk.
Type: string
Folder name.
Type: string
The full absolute path of the folder.
Type: string
The folder's parent folder path.
Type: DirInfo
Parent folder information, null
if root.
Type: boolean
Whether it is a folder, used to determine the type when fuzzy searching in the tree.
Type: boolean
Does the folder exist.
Find if a file or folder exists in the tree.
/*
* └───foo
* ├───index.ts
* └───bar
* └───deep.ts
*/
const dir = new DirInfo({ pathname: '/foo' });
dir.has('/index.ts'); // true
dir.has('/bar'); // true
dir.has('/bar/deep.ts'); // true
dir.has('/bar/deep.ts', { type: 'dir' }); // false
Required: true
Relative path relative to folder.
Required: false
Type: "file"
,"dir"
Get item by path, it will return undefined
if not exist.
Same as above.
Same as above.
Get the child mapping table under the current folder, the key
is the file name or folder name.
Same as above.
Make sure a file or folder exists, create it if it does not exist.
Same as above.
Same as above, but Required.
Used to store file information, won't modify the original file on disk.
Type: string
The directory where the file is located
Type: string
Filename, including extension.
Type: string
The full absolute path of the file.
Type: string
File extension.
Type: boolean
Does the file exist.
Type: DirInfo
Parent folder information.
Type: boolean
Whether it is a folder, used to determine the type when fuzzy searching in the tree.
Set the content of the file.
Return the content of the file, return undefined
when the file does not exist and no content is added.
json
and yaml
files will parse their contents, and this method returns the parsed result object.
Returns undefined
if the file is empty, does not exist, or is malformed.