Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(cli): use citty rewrite cli #1517

Draft
wants to merge 8 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/thin-donuts-drive.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@farmfe/cli": patch
---

Rewrite cli with citty
1 change: 1 addition & 0 deletions cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"canonicalize",
"changset",
"chpos",
"citty",
"clippy",
"clsx",
"codeframe",
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@
"node": ">= 16"
},
"dependencies": {
"cac": "^6.7.14",
"cross-spawn": "^7.0.3",
"citty": "^0.1.6",
"inquirer": "^9.1.4",
"walkdir": "^0.4.1"
},
Expand Down
73 changes: 73 additions & 0 deletions packages/cli/src/commands/build.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { defineCommand } from 'citty';
import { getOptionFromBuildOption } from '../config.js';
import {
FarmCLIBuildOptions,
FarmCLICommonOptions,
NormalizedFarmCLIBuildOptions
} from '../types.js';
import {
handleAsyncOperationErrors,
resolveCliConfig,
resolveCore
} from '../utils.js';

export default defineCommand({
meta: {
name: 'build',
description: 'compile the project in production mode'
},
args: {
root: {
type: 'positional',
description: 'root path',
required: false,
valueHint: 'path'
},
outDir: {
type: 'string',
alias: 'o',
description: 'output directory'
},
input: {
type: 'string',
alias: 'i',
description: 'input file path'
},
watch: { type: 'boolean', alias: 'w', description: 'watch file change' },
target: {
type: 'string',
description: 'transpile targetEnv node, browser'
},
format: {
type: 'string',
description: 'transpile format esm, commonjs'
},
sourcemap: {
type: 'boolean',
description: 'output source maps for build'
},
treeShaking: {
type: 'boolean',
description: 'Eliminate useless code without side effects'
},
minify: {
type: 'boolean',
description: 'code compression at build time'
}
},
async run({ args }: { args: FarmCLICommonOptions & FarmCLIBuildOptions }) {
const { root, configPath } = resolveCliConfig(
args.root,
args.config ?? args.c
);

const defaultOptions = {
root,
configPath,
...getOptionFromBuildOption(args as NormalizedFarmCLIBuildOptions)
};

const { build } = await resolveCore();
handleAsyncOperationErrors(build(defaultOptions), 'error during build');
}
});
37 changes: 37 additions & 0 deletions packages/cli/src/commands/clean.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { defineCommand } from 'citty';
import { FarmCLICommonOptions, ICleanOptions } from '../types.js';
import { resolveCliConfig, resolveCore } from '../utils.js';

export default defineCommand({
meta: {
name: 'clean',
description: 'Clean up the cache built incrementally'
},
args: {
root: {
type: 'positional',
description: 'root path',
required: false,
valueHint: 'path'
},
recursive: {
type: 'boolean',
alias: 'r',
description:
'Recursively search for node_modules directories and clean them'
}
},
async run({ args }: { args: FarmCLICommonOptions & ICleanOptions }) {
const { root } = resolveCliConfig(args.root, args.config);

const { clean } = await resolveCore();
try {
await clean(root, args.recursive);
} catch (e) {
const { Logger } = await import('@farmfe/core');
const logger = new Logger();
logger.error(`Failed to clean cache: \n ${e.stack}`);
process.exit(1);
}
}
});
55 changes: 55 additions & 0 deletions packages/cli/src/commands/dev.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { defineCommand } from 'citty';
import {
FarmCLICommonOptions,
FarmCLIServerOptions,
GlobalFarmCLIOptions
} from '../types.js';
import {
handleAsyncOperationErrors,
resolveCliConfig,
resolveCommandOptions,
resolveCore
} from '../utils.js';

export default defineCommand({
meta: {
name: 'dev',
description:
'Compile the project in dev mode and serve it with farm dev server'
},
args: {
root: {
type: 'positional',
description: 'root path',
required: false,
valueHint: 'path'
},
lazy: { type: 'boolean', alias: 'l', description: 'lazyCompilation' },
host: { type: 'string', description: 'specify host' },
port: { type: 'string', description: 'specify port' },
open: { type: 'boolean', description: 'open browser on server start' },
hmr: { type: 'boolean', description: 'enable hot module replacement' },
cors: { type: 'boolean', description: 'enable cors' },
strictPort: {
type: 'boolean',
description: 'specified port is already in use, exit with error'
}
},
async run({ args }: { args: FarmCLICommonOptions & FarmCLIServerOptions }) {
const { root, configPath } = resolveCliConfig(args.root, args.config);

const resolvedOptions = resolveCommandOptions(args as GlobalFarmCLIOptions);
const defaultOptions = {
root,
compilation: {
lazyCompilation: args.lazy
},
server: resolvedOptions,
clearScreen: args.clearScreen,
configPath,
mode: args.mode
};
const { start } = await resolveCore();
handleAsyncOperationErrors(start(defaultOptions), 'Failed to start server');
}
});
50 changes: 50 additions & 0 deletions packages/cli/src/commands/preview.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { defineCommand } from 'citty';
import {
FarmCLICommonOptions,
FarmCLIPreviewOptions,
GlobalFarmCLIOptions
} from '../types.js';
import {
handleAsyncOperationErrors,
resolveCliConfig,
resolveCommandOptions,
resolveCore
} from '../utils.js';

export default defineCommand({
meta: {
name: 'preview',
description: 'compile the project in watch mode'
},
args: {
root: {
type: 'positional',
description: 'root path',
required: false,
valueHint: 'path'
},
port: { type: 'string', description: 'specify port' },
open: {
type: 'boolean',
description: 'open browser on server preview start'
}
},
async run({ args }: { args: FarmCLICommonOptions & FarmCLIPreviewOptions }) {
const { root, configPath } = resolveCliConfig(args.root, args.config);

const resolvedOptions = resolveCommandOptions(args as GlobalFarmCLIOptions);
const defaultOptions = {
root,
mode: args.mode,
server: resolvedOptions,
configPath,
port: resolvedOptions.port
};

const { preview } = await resolveCore();
handleAsyncOperationErrors(
preview(defaultOptions),
'Failed to start preview server'
);
}
});
75 changes: 75 additions & 0 deletions packages/cli/src/commands/watch.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import { defineCommand } from 'citty';
import { getOptionFromBuildOption } from '../config.js';
import {
FarmCLIBuildOptions,
GlobalFarmCLIOptions,
NormalizedFarmCLIBuildOptions
} from '../types.js';
import {
handleAsyncOperationErrors,
resolveCliConfig,
resolveCore
} from '../utils.js';

export default defineCommand({
meta: {
name: 'watch',
description: 'watch file change'
},
args: {
root: {
type: 'positional',
description: 'root path',
required: false,
valueHint: 'path'
},
outDir: {
type: 'string',
alias: 'o',
description: 'output directory'
},
input: {
type: 'string',
alias: 'i',
description: 'input file path'
},
target: {
type: 'string',
description: 'transpile targetEnv node, browser'
},
format: {
type: 'string',
description: 'transpile format esm, commonjs'
},
sourcemap: {
type: 'boolean',
description: 'output source maps for build'
},
treeShaking: {
type: 'boolean',
description: 'Eliminate useless code without side effects'
},
minify: {
type: 'boolean',
description: 'code compression at build time'
}
},
async run({ args }: { args: FarmCLIBuildOptions & GlobalFarmCLIOptions }) {
const { root, configPath } = resolveCliConfig(
args.root,
args.config ?? args.c
);

const defaultOptions = {
root,
configPath,
...getOptionFromBuildOption(args as NormalizedFarmCLIBuildOptions)
};

const { watch } = await resolveCore();
handleAsyncOperationErrors(
watch(defaultOptions),
'error during watch project'
);
}
});
10 changes: 8 additions & 2 deletions packages/cli/src/config.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import { FarmCLIOptions, UserConfig } from '@farmfe/core';
import { FarmCLIBuildOptions, GlobalFarmCLIOptions } from './types.js';
import {
FarmCLIBuildOptions,
GlobalFarmCLIOptions,
NormalizedFarmCLIBuildOptions
} from './types.js';
import { resolveCommonOptions } from './utils.js';

export function getOptionFromBuildOption(
options: FarmCLIBuildOptions & GlobalFarmCLIOptions
Expand All @@ -14,7 +19,8 @@ export function getOptionFromBuildOption(
sourcemap,
treeShaking,
mode
} = options;
} = resolveCommonOptions(options) as NormalizedFarmCLIBuildOptions &
GlobalFarmCLIOptions;

const output: UserConfig['compilation']['output'] = {
...(outDir && { path: outDir }),
Expand Down
Loading
Loading