From c8a20ab19ebee1cf31b06149bbdc32cbe7da17f0 Mon Sep 17 00:00:00 2001 From: seho Date: Sun, 2 Apr 2023 22:19:30 +0800 Subject: [PATCH] feat(cli): support config set autoImport and generateTypeDeclarationsFile #22 --- packages/cli/package.json | 3 ++- packages/cli/src/core/autoImport.ts | 38 ++++++++++++++++++++++------- packages/cli/src/core/config.ts | 7 ++++++ packages/cli/src/dev.ts | 3 ++- packages/cli/src/index.ts | 37 ++++++++++++++++++++-------- packages/cli/typings/config.d.ts | 7 +++++- util/constants.ts | 2 ++ 7 files changed, 75 insertions(+), 22 deletions(-) diff --git a/packages/cli/package.json b/packages/cli/package.json index 893c55c..3d2be9a 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -38,7 +38,8 @@ "@types/mv": "^2.1.2", "openapi-types": "^11.0.0", "typescript": "^4.3.5", - "unbuild": "^0.6.9" + "unbuild": "^0.6.9", + "unplugin": "^1.3.1" }, "dependencies": { "@swordjs/esbuild-plugin-condition-comment-macro": "^1.0.1", diff --git a/packages/cli/src/core/autoImport.ts b/packages/cli/src/core/autoImport.ts index acfb5d7..f3badad 100644 --- a/packages/cli/src/core/autoImport.ts +++ b/packages/cli/src/core/autoImport.ts @@ -1,20 +1,23 @@ -import { createUnimport } from 'unimport'; +import { resolve } from 'path'; +import { createUnimport, TypeDeclarationOptions } from 'unimport'; import Unimport from 'unimport/unplugin'; +import { APP_SRC_DIR, AUTO_IMPORT_TYPE_DECLARATION_FILE } from '~util/constants'; +import { writeFileRecursive } from '~util/file'; +import { configData } from '../core/config'; +import type { Preset } from 'unimport'; +import type { EsbuildPlugin } from 'unplugin'; -const autoImportsPresets = [ +const autoImportsPresets: Preset[] = [ { from: '@swordjs/sword-framework', imports: ['useApi', 'useApp', 'usePipeline', 'usePlugin', 'useGetApiMap', 'usePlatform', 'usePlatformHook', 'useIsDev', 'useIsProd'] } ]; -const { toExports } = createUnimport({ - presets: autoImportsPresets -}); - -const esbuildPluginAutoImport = Unimport.esbuild({ presets: autoImportsPresets }); - let importCode: string; +let toExports: (filepath?: string | undefined) => Promise; +let generateTypeDeclarations: (options?: TypeDeclarationOptions | undefined) => Promise; +let esbuildPluginAutoImport: EsbuildPlugin | undefined; const getImportCode = async () => { if (importCode) return importCode; @@ -26,4 +29,21 @@ const getImportCode = async () => { return importCode; }; -export { getImportCode, esbuildPluginAutoImport }; +const generateTypeDeclarationsFile = async () => { + const typeDeclarationsCode = await generateTypeDeclarations(); + // typeDeclarationsCode is the automatically imported type declarations + writeFileRecursive(resolve(process.cwd(), APP_SRC_DIR, AUTO_IMPORT_TYPE_DECLARATION_FILE), typeDeclarationsCode); +}; + +export default () => { + const options = { + presets: autoImportsPresets.concat(configData.autoImport?.presets || []), + imports: configData.autoImport?.imports || [] + }; + const unimport = createUnimport(options); + toExports = unimport.toExports; + generateTypeDeclarations = unimport.generateTypeDeclarations; + esbuildPluginAutoImport = Unimport.esbuild(options); +}; + +export { getImportCode, generateTypeDeclarationsFile, esbuildPluginAutoImport }; diff --git a/packages/cli/src/core/config.ts b/packages/cli/src/core/config.ts index 5d9a2cb..aac411b 100644 --- a/packages/cli/src/core/config.ts +++ b/packages/cli/src/core/config.ts @@ -1,6 +1,7 @@ import { cwd } from 'process'; import { loadConfig } from 'unconfig'; import { getPackageJson } from '~util/package'; +import autoImport from '../core/autoImport'; import type { Config } from '../../typings/config'; export let configData: Required; @@ -44,6 +45,7 @@ export const initConfig = async () => { }); if (typeof config === 'undefined') return defaultConfig; configData = mergeConfig(config, defaultConfig) as any; + await afterInitConfig(); return configData; }; @@ -61,4 +63,9 @@ const mergeConfig = (config: Config, defaultConfig: Config) => { return config; }; +const afterInitConfig = async () => { + // The automatically imported configuration items are initialized in autoImport + await autoImport(); +}; + export type { Config } from '../../typings/config'; diff --git a/packages/cli/src/dev.ts b/packages/cli/src/dev.ts index 7b2224c..4fe8e7d 100644 --- a/packages/cli/src/dev.ts +++ b/packages/cli/src/dev.ts @@ -7,7 +7,7 @@ import { generateSchema } from './core/api'; import { devUnicloudApp } from './platform/unicloud'; import { presetApi } from './util/presetApi'; import log from './core/log'; -import { getImportCode } from './core/autoImport'; +import { getImportCode, generateTypeDeclarationsFile } from './core/autoImport'; import type { Argv } from 'mri'; import type { CommandConfig } from '~types/config'; @@ -51,6 +51,7 @@ const start = async (args: Argv) => { stdio: 'inherit' } ); + generateTypeDeclarationsFile(); // 运行成功 log.info(`启动入口文件: src/index.ts`); } else if (args.platform === 'unicloud') devUnicloudApp(args); diff --git a/packages/cli/src/index.ts b/packages/cli/src/index.ts index abad453..0b4fb76 100644 --- a/packages/cli/src/index.ts +++ b/packages/cli/src/index.ts @@ -1,6 +1,6 @@ #! /usr/bin/env node -import * as esbuildRegister from 'esbuild-register/dist/node'; +import { register } from 'esbuild-register/dist/node'; import dev from './dev'; import build from './build'; import init from './init'; @@ -8,30 +8,35 @@ import doc from './doc'; import util from './util'; import share from './share'; import packageJSON from './../package.json'; +import { getImportCode } from './core/autoImport'; import { processShim } from './core/shim'; import { initConfig } from './core/config'; import { commandArgs as args } from '~util/config'; import { resolve } from 'path'; -esbuildRegister.register(); +import { PRIVATE_CACHE_DIR, PRIVATE_SHIM_DIR, SHIM_PROCESS_FILE } from '~util/constants'; type commands = 'dev' | 'build' | 'init' | 'doc' | 'share' | 'util'; -async function main() { +const main = async () => { + // parse config params + const config = await initConfig(); + // The cli compiler may execute some ts files at runtime, + // especially the program runtime logic in the dev environment + await registerTsRuntimeByEsbuild(); + // check version if (args['v']) { console.log(`cli version: ${packageJSON.version}`); return; } - // 解析config参数 - const config = await initConfig(); if (['dev', 'build'].includes(args._[0])) { - // 创建shim + // create shim when dev or build processShim(args._[0] as 'dev' | 'build', args.platform, config); } - // 加载可能已经预定义的shim + // Load the shim that may have been predefined try { - await import(resolve(process.cwd(), './.sword/shim/process.js')); + await import(resolve(process.cwd(), PRIVATE_CACHE_DIR, PRIVATE_SHIM_DIR, SHIM_PROCESS_FILE)); } catch (error) {} - // 解析命令行参数 + // Parsing command line parameters const cliHandler = { dev, build, @@ -43,7 +48,19 @@ async function main() { if (args._[0]) { cliHandler[args._[0] as commands](args); } -} +}; + +/** + * + * @description When using cli to compile api to api.json, the dev environment needs to run the ts file directly to get the information of each api + */ +const registerTsRuntimeByEsbuild = async () => { + // get auto import code + const code = await getImportCode(); + register({ + banner: code + }); +}; main().catch((err) => { console.error(err); diff --git a/packages/cli/typings/config.d.ts b/packages/cli/typings/config.d.ts index e1e2bbf..075375e 100644 --- a/packages/cli/typings/config.d.ts +++ b/packages/cli/typings/config.d.ts @@ -1,7 +1,7 @@ import { PackageJson } from '~types/package'; import type { TransProtoReturn } from '../src/doc'; import type { Map } from '@runtime/core/map'; -import type {} from 'wrangler'; +import type { Import, Preset } from 'unimport'; export interface Config { server?: { @@ -32,5 +32,10 @@ export interface Config { output: (markdownMap: Record) => void; }; }; + // AutoImport + autoImport?: { + imports?: Import[]; + presets?: Preset[]; + }; language?: 'CN' | 'EN'; } diff --git a/util/constants.ts b/util/constants.ts index 1ca8170..2decdfe 100644 --- a/util/constants.ts +++ b/util/constants.ts @@ -12,3 +12,5 @@ export const PRIVATE_DEV_DIR = 'dev'; export const PRIVATE_SHIM_DIR = 'shim'; export const SHIM_PROCESS_FILE = 'process.js'; + +export const AUTO_IMPORT_TYPE_DECLARATION_FILE = 'auto-import.d.ts';