/
index.ts
121 lines (102 loc) · 3.91 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
import path from 'path';
import {promises as fs} from 'fs';
import pLimit from 'p-limit';
import {highlight} from 'cli-highlight';
import {transformFileAsync, TransformOptions} from '@babel/core';
import {logger} from '@reskript/core';
import {getTransformBabelConfig, BabelConfigOptions} from '@reskript/config-babel';
import {BabelCommandLineArgs} from './interface.js';
export {BabelCommandLineArgs};
const changeExtension = (file: string, extension: string) => {
const normalized = path.normalize(file);
const parsed = path.parse(normalized);
const changed = {...parsed, base: undefined, ext: extension};
return path.format(changed);
};
const writeFile = async (file: string, content: string) => {
await fs.mkdir(path.dirname(file), {recursive: true});
await fs.writeFile(file, content);
};
const transformFile = async (file: string, baseIn: string, baseOut: string, options: TransformOptions) => {
// 定义文件不处理
if (file.endsWith('.d.ts')) {
return;
}
const result = await transformFileAsync(file, options);
if (!result || result.code == null || result.map == null) {
logger.error(`Failed to transform ${file}`);
process.exit(20);
}
const relative = path.relative(baseIn, file);
const destination = path.join(baseOut, changeExtension(relative, '.js'));
const writingFiles = [
writeFile(destination, result.code + `\n//# sourceMappingURL=${destination}.map`),
writeFile(`${destination}.map`, JSON.stringify(result.map)),
];
await Promise.all(writingFiles);
};
const transformDirectory = async (dir: string, out: string, options: TransformOptions) => {
const {globby} = await import('globby');
const files = await globby(`${dir.replace(/\/$/, '')}/**/*.{js,jsx,ts,tsx}`);
await Promise.all(files.map(f => transformFile(f, dir, out, options)));
};
const copyFile = async (file: string, baseIn: string, baseOut: string) => {
const relative = path.relative(baseIn, file);
const out = path.join(baseOut, relative);
await fs.mkdir(path.dirname(out), {recursive: true});
return fs.copyFile(file, out);
};
const printInConsole = (code: string | null | undefined) => {
if (code == null) {
logger.error('Transform failed');
process.exit(20);
}
// eslint-disable-next-line no-console
console.log(highlight(code, {language: 'javascript'}));
};
export const run = async (cmd: BabelCommandLineArgs, file: string): Promise<void> => {
const {globby} = await import('globby');
if (!file) {
return;
}
const {outDirectory, clean, copy, mode, polyfill} = cmd;
if (outDirectory) {
if (clean) {
await fs.rm(outDirectory, {recursive: true, force: true});
}
await fs.mkdir(outDirectory, {recursive: true});
}
const babelConfigOptions: BabelConfigOptions = {
mode,
polyfill,
hot: false,
hostType: 'application',
modules: false,
};
const babelConfig: TransformOptions = {
...getTransformBabelConfig(babelConfigOptions),
sourceMaps: !!outDirectory,
babelrc: false,
};
if (path.extname(file)) {
if (outDirectory) {
await transformFile(file, path.dirname(file), outDirectory, babelConfig);
}
else {
const result = await transformFileAsync(file, babelConfig);
printInConsole(result?.code);
}
}
else {
if (!outDirectory) {
logger.error('Cannot output to terminal with directory input, specify a single file or use --out-dir.');
process.exit(21);
}
await transformDirectory(file, outDirectory, babelConfig);
if (copy) {
const files = await globby([`${file}/**`, `!${file}/**/*.{ts,js,tsx,jsx}`]);
const limit = pLimit(2);
await Promise.all(files.map(v => limit(copyFile, v, file, outDirectory)));
}
}
};