@rife/cli 0.0.6-beta.13 → 0.0.6-beta.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/logger.cjs +2 -0
- package/dist/cjs/plugin/index.cjs +3 -12
- package/dist/cjs/runner.cjs +4 -1
- package/dist/esm/cli.mjs +1 -1
- package/dist/esm/index.mjs +1 -1
- package/dist/esm/logger.mjs +3 -1
- package/dist/esm/plugin/commander.mjs +1 -1
- package/dist/esm/plugin/config.mjs +2 -2
- package/dist/esm/plugin/index.mjs +1 -2
- package/dist/esm/plugin/package.mjs +2 -2
- package/dist/esm/plugin/release.mjs +1 -1
- package/dist/esm/runner.mjs +9 -6
- package/dist/esm/sync.mjs +1 -1
- package/dist/esm/util.mjs +3 -3
- package/package.json +7 -17
- package/src/index.ts +0 -6
- package/src/logger.ts +2 -1
- package/src/plugin/index.ts +0 -1
- package/src/runner.ts +5 -1
- package/dist/cjs/plugin/compiler/compiler.cjs +0 -207
- package/dist/cjs/plugin/compiler/index.cjs +0 -126
- package/dist/cjs/plugin/compiler/swc.cjs +0 -107
- package/dist/cjs/plugin/compiler/tsc.cjs +0 -115
- package/dist/esm/plugin/compiler/compiler.mjs +0 -160
- package/dist/esm/plugin/compiler/index.mjs +0 -94
- package/dist/esm/plugin/compiler/swc.mjs +0 -75
- package/dist/esm/plugin/compiler/tsc.mjs +0 -73
- package/src/plugin/compiler/compiler.ts +0 -198
- package/src/plugin/compiler/index.ts +0 -115
- package/src/plugin/compiler/swc.ts +0 -56
- package/src/plugin/compiler/tsc.ts +0 -101
|
@@ -1,198 +0,0 @@
|
|
|
1
|
-
import path from 'path';
|
|
2
|
-
|
|
3
|
-
import { colors } from 'consola/utils';
|
|
4
|
-
import type * as ts from 'typescript';
|
|
5
|
-
|
|
6
|
-
import { swc } from './swc';
|
|
7
|
-
import { tsc } from './tsc';
|
|
8
|
-
import { Runner } from '../../runner';
|
|
9
|
-
|
|
10
|
-
export interface TsxConfig {
|
|
11
|
-
/** 默认:swc */
|
|
12
|
-
type: 'tsc' | 'swc';
|
|
13
|
-
|
|
14
|
-
/** 默认:. */
|
|
15
|
-
rootDir: string;
|
|
16
|
-
|
|
17
|
-
/** 默认:./dist/ */
|
|
18
|
-
outDir: string;
|
|
19
|
-
|
|
20
|
-
/** 默认:true */
|
|
21
|
-
clean: boolean;
|
|
22
|
-
|
|
23
|
-
/** 编译后入口启动文件 */
|
|
24
|
-
main?: string;
|
|
25
|
-
|
|
26
|
-
options?: any;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
const clear = () => {
|
|
30
|
-
console.clear();
|
|
31
|
-
process.stdout.write('\x1b[3J');
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
export async function compileTs(
|
|
35
|
-
runner: Runner,
|
|
36
|
-
tsxConfig: TsxConfig,
|
|
37
|
-
{ dev, build }: { dev?: boolean; build?: boolean } = { dev: false, build: true },
|
|
38
|
-
) {
|
|
39
|
-
const { logger, fs } = runner;
|
|
40
|
-
const log = logger.withTag(compileTs.name);
|
|
41
|
-
log.debug('tsxConfig %j', tsxConfig);
|
|
42
|
-
if (tsxConfig.clean) {
|
|
43
|
-
log.info('清空目录 %s', tsxConfig.outDir);
|
|
44
|
-
await fs.emptyDir(tsxConfig.outDir);
|
|
45
|
-
}
|
|
46
|
-
const showProjectName = () => {
|
|
47
|
-
clear();
|
|
48
|
-
console.log(`${colors.bgBlue(' 项目名称 ')} ${runner.package.name} \n`);
|
|
49
|
-
};
|
|
50
|
-
if (tsxConfig.type === 'tsc') {
|
|
51
|
-
const diagnostics: ts.Diagnostic[] = [];
|
|
52
|
-
let perfStart = performance.now();
|
|
53
|
-
tsc({
|
|
54
|
-
...tsxConfig,
|
|
55
|
-
watch: dev,
|
|
56
|
-
onWatchStatusChanged: data => {
|
|
57
|
-
switch (data.status) {
|
|
58
|
-
case 'startWatch': {
|
|
59
|
-
diagnostics.length = 0;
|
|
60
|
-
perfStart = performance.now();
|
|
61
|
-
break;
|
|
62
|
-
}
|
|
63
|
-
case 'reCompile': {
|
|
64
|
-
diagnostics.length = 0;
|
|
65
|
-
perfStart = performance.now();
|
|
66
|
-
if (dev) {
|
|
67
|
-
// watch 模式下,第二次编译清空一下屏幕
|
|
68
|
-
showProjectName();
|
|
69
|
-
}
|
|
70
|
-
break;
|
|
71
|
-
}
|
|
72
|
-
case 'error': {
|
|
73
|
-
const duration = ((performance.now() - perfStart) / 1000).toFixed(3);
|
|
74
|
-
log.error(`类型检查失败,耗时 ${duration} s\n\n%s`, formatDiagnostic(diagnostics));
|
|
75
|
-
break;
|
|
76
|
-
}
|
|
77
|
-
case 'success': {
|
|
78
|
-
const duration = ((performance.now() - perfStart) / 1000).toFixed(3);
|
|
79
|
-
log.success(`编译成功,耗时 ${duration} s`);
|
|
80
|
-
break;
|
|
81
|
-
}
|
|
82
|
-
default: {
|
|
83
|
-
console.log(data);
|
|
84
|
-
process.exit(1);
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
},
|
|
88
|
-
onReportDiagnostic: ({ diagnostic }) => {
|
|
89
|
-
diagnostics.push(diagnostic);
|
|
90
|
-
},
|
|
91
|
-
onEmitDiagnostics: ({ diagnostics }) => {
|
|
92
|
-
const duration = ((performance.now() - perfStart) / 1000).toFixed(3);
|
|
93
|
-
if (diagnostics.length) {
|
|
94
|
-
log.error(`编译失败,耗时 ${duration} s\n\n%s`, formatDiagnostic(diagnostics));
|
|
95
|
-
runner.compiler.fail = true;
|
|
96
|
-
} else {
|
|
97
|
-
log.success(`编译成功,耗时 ${duration} s`);
|
|
98
|
-
}
|
|
99
|
-
},
|
|
100
|
-
});
|
|
101
|
-
return;
|
|
102
|
-
}
|
|
103
|
-
if (tsxConfig.type === 'swc') {
|
|
104
|
-
const { promise, resolve } = Promise.withResolvers<void>();
|
|
105
|
-
swc({
|
|
106
|
-
...tsxConfig,
|
|
107
|
-
watch: dev,
|
|
108
|
-
onSuccess: async ({ watch, first, duration }) => {
|
|
109
|
-
if (watch && !first) {
|
|
110
|
-
// watch 模式下,第二次编译清空一下屏幕
|
|
111
|
-
showProjectName();
|
|
112
|
-
}
|
|
113
|
-
log.success(`编译成功,耗时 ${(duration / 1000).toFixed(3)} s`);
|
|
114
|
-
if (dev) {
|
|
115
|
-
// 启动文件钩子
|
|
116
|
-
runner.compiler.hook.execMain.promise();
|
|
117
|
-
}
|
|
118
|
-
// 检查类型
|
|
119
|
-
await runner.compiler.hook.checkAndEmitType.promise();
|
|
120
|
-
resolve();
|
|
121
|
-
},
|
|
122
|
-
onFail: ({ watch, first, duration, reasons }) => {
|
|
123
|
-
if (watch && !first) {
|
|
124
|
-
// watch 模式下,第二次编译清空一下屏幕
|
|
125
|
-
showProjectName();
|
|
126
|
-
}
|
|
127
|
-
const message = [...reasons.entries()]
|
|
128
|
-
.map(([key, value]) => {
|
|
129
|
-
const index = value.indexOf(key);
|
|
130
|
-
if (index > -1) {
|
|
131
|
-
return value.replace(key, path.resolve(key));
|
|
132
|
-
}
|
|
133
|
-
return `${value}`;
|
|
134
|
-
})
|
|
135
|
-
.join('\n');
|
|
136
|
-
log.error(`编译失败,耗时 ${(duration / 1000).toFixed(3)} s\n\n%s`, message);
|
|
137
|
-
runner.compiler.fail = true;
|
|
138
|
-
resolve();
|
|
139
|
-
},
|
|
140
|
-
});
|
|
141
|
-
if (build) {
|
|
142
|
-
return promise;
|
|
143
|
-
}
|
|
144
|
-
return;
|
|
145
|
-
}
|
|
146
|
-
log.error(`compiler type '${tsxConfig.type}' 不存在`);
|
|
147
|
-
process.exit(1);
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
export function checkAndEmitType() {
|
|
151
|
-
const perfStart = performance.now();
|
|
152
|
-
const ts: typeof import('typescript') = require('typescript');
|
|
153
|
-
const tsConfigPath = path.resolve('tsconfig.json');
|
|
154
|
-
// 读取 tsconfig.json 文件
|
|
155
|
-
const configFile = ts.readConfigFile(tsConfigPath, ts.sys.readFile);
|
|
156
|
-
|
|
157
|
-
// 解析 tsconfig.json 文件
|
|
158
|
-
const compilerOptions = ts.parseJsonConfigFileContent(configFile.config, ts.sys, path.dirname(tsConfigPath), {
|
|
159
|
-
noEmit: true,
|
|
160
|
-
incremental: false,
|
|
161
|
-
});
|
|
162
|
-
if (compilerOptions.options.declaration === true) {
|
|
163
|
-
compilerOptions.options.noEmit = false;
|
|
164
|
-
compilerOptions.options.emitDeclarationOnly = true;
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
// 获取编译器实例
|
|
168
|
-
const host = ts.createCompilerHost(compilerOptions.options);
|
|
169
|
-
const program = ts.createProgram(compilerOptions.fileNames, compilerOptions.options, host);
|
|
170
|
-
|
|
171
|
-
// 执行编译
|
|
172
|
-
const emitResult = program.emit();
|
|
173
|
-
|
|
174
|
-
// 处理编译结果
|
|
175
|
-
const diagnostics = ts.getPreEmitDiagnostics(program).concat(emitResult.diagnostics);
|
|
176
|
-
|
|
177
|
-
const duration = ((performance.now() - perfStart) / 1000).toFixed(3);
|
|
178
|
-
|
|
179
|
-
return { diagnostics, duration };
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
export function formatDiagnostic(diagnostics: readonly ts.Diagnostic[]) {
|
|
183
|
-
const ts: typeof import('typescript') = require('typescript');
|
|
184
|
-
const { colors }: typeof import('consola/utils') = require('consola/utils');
|
|
185
|
-
|
|
186
|
-
return diagnostics
|
|
187
|
-
.map(diagnostic => {
|
|
188
|
-
const message = ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n');
|
|
189
|
-
if (diagnostic.file) {
|
|
190
|
-
const { line, character } = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start!);
|
|
191
|
-
return `${colors.gray(diagnostic.file.fileName)} ${colors.yellow(`(${line + 1},${character + 1})`)}: ${colors.white(
|
|
192
|
-
message,
|
|
193
|
-
)}`;
|
|
194
|
-
}
|
|
195
|
-
return message;
|
|
196
|
-
})
|
|
197
|
-
.join('\n');
|
|
198
|
-
}
|
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
import type { ChildProcess } from 'child_process';
|
|
2
|
-
|
|
3
|
-
import { AsyncSeriesHook } from 'tapable';
|
|
4
|
-
|
|
5
|
-
import { TsxConfig, checkAndEmitType, compileTs, formatDiagnostic } from './compiler';
|
|
6
|
-
import type { Plugin } from '../../runner';
|
|
7
|
-
import { getDuration } from '../../util';
|
|
8
|
-
|
|
9
|
-
declare module '../../runner' {
|
|
10
|
-
interface Runner {
|
|
11
|
-
compiler: {
|
|
12
|
-
fail: boolean;
|
|
13
|
-
process: ChildProcess | null;
|
|
14
|
-
hook: {
|
|
15
|
-
checkAndEmitType: AsyncSeriesHook<[]>;
|
|
16
|
-
execMain: AsyncSeriesHook<[]>;
|
|
17
|
-
};
|
|
18
|
-
tsx: TsxConfig;
|
|
19
|
-
};
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export interface pluginCompilerOptions {
|
|
24
|
-
tsx?: Partial<TsxConfig>;
|
|
25
|
-
less?: {};
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export function pluginCompiler(options?: pluginCompilerOptions) {
|
|
29
|
-
const plugin: Plugin = {
|
|
30
|
-
name: pluginCompiler.name,
|
|
31
|
-
apply: runner => {
|
|
32
|
-
const { hook, logger, z, fs } = runner;
|
|
33
|
-
const log = logger.withTag(pluginCompiler.name);
|
|
34
|
-
const validation = z
|
|
35
|
-
.object({
|
|
36
|
-
tsx: z
|
|
37
|
-
.object({
|
|
38
|
-
type: z.enum(['tsc', 'swc']).default('swc'),
|
|
39
|
-
rootDir: z.string().trim().min(1).default('.'),
|
|
40
|
-
outDir: z.string().trim().min(1).default('./dist/'),
|
|
41
|
-
clean: z.boolean().default(true),
|
|
42
|
-
main: z.string().trim().optional(),
|
|
43
|
-
options: z.object({}).passthrough().optional(),
|
|
44
|
-
})
|
|
45
|
-
.default({}),
|
|
46
|
-
})
|
|
47
|
-
.optional()
|
|
48
|
-
.default({})
|
|
49
|
-
.safeParse(options);
|
|
50
|
-
|
|
51
|
-
if (!validation.success) {
|
|
52
|
-
log.error('配置错误\n', validation.error.message);
|
|
53
|
-
process.exit(1);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
runner.compiler = {
|
|
57
|
-
fail: false,
|
|
58
|
-
process: null,
|
|
59
|
-
hook: {
|
|
60
|
-
checkAndEmitType: new AsyncSeriesHook(),
|
|
61
|
-
execMain: new AsyncSeriesHook(),
|
|
62
|
-
},
|
|
63
|
-
tsx: validation.data.tsx,
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
hook.dev.tapPromise(pluginCompiler.name, async () => {
|
|
67
|
-
const tsxConfig: TsxConfig = validation.data.tsx;
|
|
68
|
-
compileTs(runner, tsxConfig, { dev: true });
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
hook.build.tapPromise(pluginCompiler.name, async () => {
|
|
72
|
-
const perfStart = performance.now();
|
|
73
|
-
const tsxConfig: TsxConfig = validation.data.tsx;
|
|
74
|
-
await compileTs(runner, tsxConfig, { build: true });
|
|
75
|
-
if (runner.compiler.fail) {
|
|
76
|
-
log.fail(`构建失败,${getDuration(perfStart)}`);
|
|
77
|
-
process.exit(1);
|
|
78
|
-
} else {
|
|
79
|
-
log.success(`构建成功,${getDuration(perfStart)}`);
|
|
80
|
-
}
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
runner.compiler.hook.checkAndEmitType.tapPromise(pluginCompiler.name, async () => {
|
|
84
|
-
const { diagnostics, duration } = checkAndEmitType();
|
|
85
|
-
if (diagnostics.length) {
|
|
86
|
-
log.error(`类型检查失败,耗时 ${duration} s\n\n%s`, formatDiagnostic(diagnostics));
|
|
87
|
-
runner.compiler.fail = true;
|
|
88
|
-
} else {
|
|
89
|
-
log.success(`类型检查成功,耗时 ${duration} s`);
|
|
90
|
-
}
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
runner.compiler.hook.execMain.tapPromise(pluginCompiler.name, async () => {
|
|
94
|
-
const compiler = runner.compiler;
|
|
95
|
-
const { main } = compiler.tsx;
|
|
96
|
-
if (!main) {
|
|
97
|
-
log.debug('没有指定 main');
|
|
98
|
-
return;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
if (!(await fs.exists(main))) {
|
|
102
|
-
log.warn(`启动文件不存在 %s`, main);
|
|
103
|
-
return;
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
log.info(`启动文件 node %s`, main);
|
|
107
|
-
|
|
108
|
-
const { fork } = require('child_process') as typeof import('child_process');
|
|
109
|
-
compiler.process?.kill();
|
|
110
|
-
compiler.process = fork(main, { stdio: 'inherit' });
|
|
111
|
-
});
|
|
112
|
-
},
|
|
113
|
-
};
|
|
114
|
-
return plugin;
|
|
115
|
-
}
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
import type { TsxConfig } from './compiler';
|
|
2
|
-
|
|
3
|
-
export interface SwcConfig extends TsxConfig {
|
|
4
|
-
watch?: boolean;
|
|
5
|
-
options?: any;
|
|
6
|
-
onSuccess?: (data: { watch: boolean; first: boolean; duration: number }) => any;
|
|
7
|
-
onFail?: (data: { watch: boolean; first: boolean; duration: number; reasons: Map<string, string> }) => any;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export async function swc(options: SwcConfig) {
|
|
11
|
-
const { watch = false, outDir } = options;
|
|
12
|
-
const { swcDir } = require('@swc/cli');
|
|
13
|
-
|
|
14
|
-
// https://swc.rs/docs/configuration/swcrc
|
|
15
|
-
const swcOptions = {
|
|
16
|
-
jsc: {
|
|
17
|
-
parser: {
|
|
18
|
-
syntax: 'typescript',
|
|
19
|
-
},
|
|
20
|
-
target: 'esnext',
|
|
21
|
-
externalHelpers: true,
|
|
22
|
-
},
|
|
23
|
-
module: {
|
|
24
|
-
type: 'commonjs',
|
|
25
|
-
// type: 'es6',
|
|
26
|
-
ignoreDynamic: true,
|
|
27
|
-
},
|
|
28
|
-
sourceMaps: true,
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
let first = true;
|
|
32
|
-
|
|
33
|
-
await swcDir({
|
|
34
|
-
cliOptions: {
|
|
35
|
-
outDir,
|
|
36
|
-
watch,
|
|
37
|
-
filenames: ['./src'],
|
|
38
|
-
extensions: ['.ts', '.tsx', '.js', '.jsx'],
|
|
39
|
-
stripLeadingPaths: true,
|
|
40
|
-
copyFiles: true,
|
|
41
|
-
},
|
|
42
|
-
swcOptions,
|
|
43
|
-
callbacks: {
|
|
44
|
-
onSuccess: ({ duration }: any) => {
|
|
45
|
-
options?.onSuccess?.({ watch, first, duration });
|
|
46
|
-
first = false;
|
|
47
|
-
},
|
|
48
|
-
onFail: (e: any) => {
|
|
49
|
-
options?.onFail?.({ ...e, watch, first });
|
|
50
|
-
// 不退出,下次修复报错后清空屏幕
|
|
51
|
-
first = false;
|
|
52
|
-
},
|
|
53
|
-
onWatchReady: () => {},
|
|
54
|
-
},
|
|
55
|
-
});
|
|
56
|
-
}
|
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
import type { ChildProcess } from 'child_process';
|
|
2
|
-
import path from 'path';
|
|
3
|
-
|
|
4
|
-
import type * as ts from 'typescript';
|
|
5
|
-
|
|
6
|
-
import type { TsxConfig } from './compiler';
|
|
7
|
-
|
|
8
|
-
type Status = 'startWatch' | 'reCompile' | 'error' | 'success' | '';
|
|
9
|
-
export interface TscConfig extends TsxConfig {
|
|
10
|
-
watch?: boolean;
|
|
11
|
-
options?: ts.CompilerOptions;
|
|
12
|
-
onWatchStatusChanged?: (data: { status: Status; message: string }) => any;
|
|
13
|
-
onReportDiagnostic?: (data: { diagnostic: ts.Diagnostic }) => any;
|
|
14
|
-
onEmitDiagnostics?: (data: { diagnostics: ts.Diagnostic[] }) => any;
|
|
15
|
-
}
|
|
16
|
-
export function tsc(config: TscConfig) {
|
|
17
|
-
const logger = console;
|
|
18
|
-
const ts: typeof import('typescript') = require('typescript');
|
|
19
|
-
// https://github.com/microsoft/TypeScript/wiki/Using-the-Compiler-API#writing-an-incremental-program-watcher
|
|
20
|
-
|
|
21
|
-
const rootDir = config.rootDir || '.';
|
|
22
|
-
|
|
23
|
-
const formatHost: ts.FormatDiagnosticsHost = {
|
|
24
|
-
getCanonicalFileName: path => path,
|
|
25
|
-
getCurrentDirectory: ts.sys.getCurrentDirectory,
|
|
26
|
-
getNewLine: () => ts.sys.newLine,
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
function reportDiagnostic(diagnostic: ts.Diagnostic) {
|
|
30
|
-
config.onReportDiagnostic?.({ diagnostic });
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Prints a diagnostic every time the watch status changes.
|
|
35
|
-
* This is mainly for messages like "Starting compilation" or "Compilation completed".
|
|
36
|
-
*/
|
|
37
|
-
let a: ChildProcess | any;
|
|
38
|
-
function reportWatchStatusChanged(diagnostic: ts.Diagnostic) {
|
|
39
|
-
const message = `${ts.formatDiagnostic(diagnostic, formatHost)}`.trimEnd();
|
|
40
|
-
let status: Status = '';
|
|
41
|
-
if (message.includes('message TS6031: Starting compilation in watch mode')) {
|
|
42
|
-
status = 'startWatch';
|
|
43
|
-
} else if (message.includes('message TS6032: File change detected')) {
|
|
44
|
-
status = 'reCompile';
|
|
45
|
-
} else if (message.includes('Found 0 errors')) {
|
|
46
|
-
status = 'success';
|
|
47
|
-
} else if (/Found \d+ error/.test(message)) {
|
|
48
|
-
status = 'error';
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
config.onWatchStatusChanged?.({ status, message });
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
const configPath = ts.findConfigFile(rootDir, ts.sys.fileExists, 'tsconfig.json');
|
|
55
|
-
if (!configPath) {
|
|
56
|
-
throw new Error('找不到tsconfig.json');
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
const createProgram = ts.createSemanticDiagnosticsBuilderProgram;
|
|
60
|
-
|
|
61
|
-
if (config.watch) {
|
|
62
|
-
const host = ts.createWatchCompilerHost(
|
|
63
|
-
configPath,
|
|
64
|
-
{
|
|
65
|
-
...config.options,
|
|
66
|
-
outDir: config.outDir,
|
|
67
|
-
noEmit: false,
|
|
68
|
-
incremental: true,
|
|
69
|
-
},
|
|
70
|
-
ts.sys,
|
|
71
|
-
createProgram,
|
|
72
|
-
reportDiagnostic,
|
|
73
|
-
reportWatchStatusChanged,
|
|
74
|
-
);
|
|
75
|
-
|
|
76
|
-
ts.createWatchProgram(host);
|
|
77
|
-
} else {
|
|
78
|
-
// 读取 tsconfig.json 文件
|
|
79
|
-
const configFile = ts.readConfigFile(configPath, ts.sys.readFile);
|
|
80
|
-
|
|
81
|
-
// 解析 tsconfig.json 文件
|
|
82
|
-
const compilerOptions = ts.parseJsonConfigFileContent(configFile.config, ts.sys, path.dirname(configPath), {
|
|
83
|
-
...config.options,
|
|
84
|
-
outDir: config.outDir,
|
|
85
|
-
noEmit: false,
|
|
86
|
-
incremental: false,
|
|
87
|
-
});
|
|
88
|
-
|
|
89
|
-
// 获取编译器实例
|
|
90
|
-
const host = ts.createCompilerHost(compilerOptions.options);
|
|
91
|
-
const program = ts.createProgram(compilerOptions.fileNames, compilerOptions.options, host);
|
|
92
|
-
|
|
93
|
-
// 执行编译
|
|
94
|
-
const emitResult = program.emit();
|
|
95
|
-
|
|
96
|
-
// 处理编译结果
|
|
97
|
-
const diagnostics = ts.getPreEmitDiagnostics(program).concat(emitResult.diagnostics);
|
|
98
|
-
|
|
99
|
-
config.onEmitDiagnostics?.({ diagnostics });
|
|
100
|
-
}
|
|
101
|
-
}
|