maishu-scripts 1.4.0 → 1.4.2

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.
@@ -1,3 +1,3 @@
1
1
  import * as babel from "@babel/core";
2
- import { FileAction } from "../../types";
3
- export declare function create(babelOptions?: babel.TransformOptions): FileAction;
2
+ import { FileAction, JavaScriptExtension } from "../../types";
3
+ export declare function create(defaultBabelOptions?: babel.TransformOptions, outExit?: JavaScriptExtension): FileAction;
@@ -39,26 +39,30 @@ const fs = __importStar(require("fs"));
39
39
  const path = __importStar(require("path"));
40
40
  const errors_1 = require("../errors");
41
41
  const project_compiler_1 = require("../project-compiler");
42
- const outExt = project_compiler_1.ProjectCompiler.tsOutExt;
43
- function create(babelOptions) {
42
+ // const outExt = ProjectCompiler.tsOutExt;
43
+ function create(defaultBabelOptions, outExit) {
44
44
  const action = (sourcePath, outputPath, projectPath) => {
45
- if (!babelOptions) {
46
- let bablePath;
47
- let sourceDir = path.dirname(sourcePath);
48
- if (projectPath) {
49
- let c = project_compiler_1.ProjectCompiler.getBabelConfig(projectPath, sourceDir);
50
- bablePath = c.path;
51
- babelOptions = c.options;
52
- }
53
- else {
54
- babelOptions = project_compiler_1.ProjectCompiler.getDefaultBabelConfig();
55
- bablePath = '';
56
- }
57
- babelOptions.filename = sourcePath;
58
- babelOptions.code = false;
59
- babelOptions.ast = true;
45
+ outExit = outExit || ".js";
46
+ if (defaultBabelOptions) {
47
+ return compileFile(sourcePath, outputPath, projectPath, defaultBabelOptions, outExit);
60
48
  }
61
- return compileFile(sourcePath, outputPath, projectPath, babelOptions);
49
+ // 如果没有 babelOptions,则尝试从项目目录查找 babel 配置文件,如果没有,则使用默认配置。
50
+ let babelOptions;
51
+ let bablePath;
52
+ let sourceDir = path.dirname(sourcePath);
53
+ if (projectPath) {
54
+ let c = project_compiler_1.ProjectCompiler.getBabelConfig(projectPath, sourceDir);
55
+ bablePath = c.path;
56
+ babelOptions = c.options;
57
+ }
58
+ else {
59
+ babelOptions = project_compiler_1.ProjectCompiler.getDefaultBabelConfig();
60
+ bablePath = '';
61
+ }
62
+ babelOptions.filename = sourcePath;
63
+ babelOptions.code = false;
64
+ babelOptions.ast = true;
65
+ return compileFile(sourcePath, outputPath, projectPath, babelOptions, outExit);
62
66
  };
63
67
  return action;
64
68
  }
@@ -68,7 +72,7 @@ function create(babelOptions) {
68
72
  * @param outputPath 输出目录
69
73
  * @param projectPath 项目路径
70
74
  * */
71
- async function compileFile(sourcePath, outputPath, projectPath, babelOptions) {
75
+ async function compileFile(sourcePath, outputPath, projectPath, babelOptions, outExt) {
72
76
  if (!sourcePath)
73
77
  throw errors_1.errors.argumentNull("sourcePath");
74
78
  if (!outputPath)
@@ -107,7 +111,7 @@ async function compileFile(sourcePath, outputPath, projectPath, babelOptions) {
107
111
  let ast = fileResult.ast;
108
112
  if (!ast)
109
113
  throw errors_1.errors.compileError(sourcePath);
110
- new ImportPathRewrite(sourcePath, ast);
114
+ new ImportPathRewrite(sourcePath, ast, outExt);
111
115
  let r = babel.transformFromAstSync(ast, undefined, {
112
116
  filename: sourcePath, plugins: babelOptions.plugins,
113
117
  presets: babelOptions.presets, sourceMaps: babelOptions.sourceMaps
@@ -115,7 +119,7 @@ async function compileFile(sourcePath, outputPath, projectPath, babelOptions) {
115
119
  if (!r || r.code == null)
116
120
  throw errors_1.errors.compileError(sourcePath);
117
121
  let ext = extname(sourcePath);
118
- let outExt = fileOutExt(sourcePath);
122
+ //let outExt = fileOutExt(sourcePath);
119
123
  let targetPath = path.join(outputPath, path.basename(sourcePath).replace(ext, outExt)); //sourcePath.replace(new RegExp(ext + "$"), outExt).replace(path.dirname(sourcePath), outDir);
120
124
  let outDirPath = path.resolve(targetPath, "..");
121
125
  let mapPath = targetPath + ".map";
@@ -144,18 +148,20 @@ function extname(file) {
144
148
  * 获取源文件所对应生成文件的扩展名
145
149
  * @param file 源文件名
146
150
  * */
147
- function fileOutExt(file) {
148
- let ext = extname(file);
149
- if (ext === ".ts")
150
- return outExt;
151
- if (ext === ".tsx")
152
- return outExt;
153
- return ext;
154
- }
151
+ // function fileOutExt(file: string) {
152
+ // let ext = extname(file);
153
+ // if (ext === ".ts")
154
+ // return outExt;
155
+ // if (ext === ".tsx")
156
+ // return outExt;
157
+ // return ext;
158
+ // }
155
159
  class ImportPathRewrite {
156
160
  filePath;
157
- constructor(filePath, node) {
161
+ outExt;
162
+ constructor(filePath, node, outExt) {
158
163
  this.filePath = filePath;
164
+ this.outExt = outExt;
159
165
  this.traverse(node);
160
166
  }
161
167
  traverse(node) {
@@ -169,14 +175,14 @@ class ImportPathRewrite {
169
175
  case "ImportDeclaration":
170
176
  if (node.source.type === "StringLiteral" && node.source.value.startsWith(".")) {
171
177
  let ext = extname(node.source.value);
172
- if (ext != outExt) {
178
+ if (ext != this.outExt) {
173
179
  let dir = path.dirname(this.filePath);
174
180
  let fullPath = path.join(dir, node.source.value);
175
181
  console.log(`ImportDeclaration: ${fullPath} -> ${ext}`);
176
182
  if (fs.existsSync(fullPath) && fs.statSync(fullPath).isDirectory()) {
177
183
  node.source.value = node.source.value + "/index";
178
184
  }
179
- node.source.value += outExt;
185
+ node.source.value += this.outExt;
180
186
  }
181
187
  }
182
188
  break;
@@ -1,5 +1,5 @@
1
1
  import * as ts from 'typescript';
2
- import { FileAction } from '../../types';
3
- export declare function create(compilerOptions?: ts.CompilerOptions): FileAction;
2
+ import { FileAction, JavaScriptExtension } from '../../types';
3
+ export declare function create(defaultCompilerOptions?: ts.CompilerOptions, outExt?: JavaScriptExtension): FileAction;
4
4
  export declare function getTypescriptConfig(projectPath: string, directoryPath: string): ts.CompilerOptions;
5
5
  export declare function findTypeScriptConfigPath(projectPath: string, directoryPath: string): string | null;
@@ -40,14 +40,16 @@ const ts = __importStar(require("typescript"));
40
40
  const errors_1 = require("../errors");
41
41
  const fs = __importStar(require("fs"));
42
42
  const path = __importStar(require("path"));
43
- const project_compiler_1 = require("../project-compiler");
44
43
  const TS_CONFIG_FILE = 'tsconfig.json';
45
- function create(compilerOptions) {
44
+ function create(defaultCompilerOptions, outExt) {
45
+ outExt = outExt || ".js";
46
46
  const action = async (filePath, outDir, projectPath) => {
47
- if (!compilerOptions) {
48
- compilerOptions = getTypescriptConfig(projectPath, path.dirname(filePath));
47
+ if (defaultCompilerOptions) {
48
+ return compileFile(filePath, outDir, projectPath, defaultCompilerOptions, outExt);
49
49
  }
50
- return compileFile(filePath, outDir, projectPath, compilerOptions);
50
+ // 如果没有指定默认编译选项,则尝试从项目目录查找 tsconfig.json 文件,并使用其中的配置进行编译
51
+ const compilerOptions = getTypescriptConfig(projectPath, path.dirname(filePath));
52
+ return compileFile(filePath, outDir, projectPath, compilerOptions, outExt);
51
53
  };
52
54
  return action;
53
55
  }
@@ -57,7 +59,7 @@ function create(compilerOptions) {
57
59
  * @param outDir 输出目录,相对于项目路径
58
60
  * @param projectPath 项目路径,绝对路径
59
61
  * */
60
- async function compileFile(filePath, outDir, projectPath, compilerOptions) {
62
+ async function compileFile(filePath, outDir, projectPath, compilerOptions, outExt) {
61
63
  if (!filePath)
62
64
  throw errors_1.errors.argumentNull('sourcePath');
63
65
  if (!outDir)
@@ -68,7 +70,6 @@ async function compileFile(filePath, outDir, projectPath, compilerOptions) {
68
70
  // let compilerOptions = getTypescriptConfig(projectPath, path.dirname(filePath));
69
71
  let result = ts.transpileModule(content, { compilerOptions });
70
72
  let ext = path.extname(filePath);
71
- let outExt = project_compiler_1.ProjectCompiler.tsOutExt;
72
73
  let targetPath = path.join(projectPath, outDir, path.basename(filePath).replace(ext, outExt));
73
74
  let outDirPath = path.resolve(targetPath, "..");
74
75
  if (!fs.existsSync(outDirPath))
@@ -14,5 +14,6 @@ type Options = {
14
14
  skipFiles?: RegExp[];
15
15
  fileAction?: (fileName: string) => FileAction | undefined;
16
16
  callback?: Callback;
17
+ defaultAction?: FileAction;
17
18
  };
18
19
  export {};
@@ -104,7 +104,9 @@ function extname(file) {
104
104
  return ext;
105
105
  }
106
106
  function generateCodeByOptions(options) {
107
- let { sourceDir, outDir, projectPath, skipFiles, fileAction: fileActions, callback } = options;
107
+ let { sourceDir, outDir, projectPath, skipFiles, fileAction: fileActions, callback, defaultAction } = options;
108
+ if (!defaultAction)
109
+ defaultAction = copy_file_1.default;
108
110
  if (!sourceDir)
109
111
  throw errors_1.errors.argumentNull("sourceDir");
110
112
  if (!outDir)
@@ -126,11 +128,7 @@ function generateCodeByOptions(options) {
126
128
  console.log(`Skip ${filePath}`);
127
129
  continue;
128
130
  }
129
- fileActions = fileActions || function (fileName) {
130
- const ext = path.extname(fileName);
131
- return configs_1.default.fileActions[ext];
132
- };
133
- let action = fileActions(filePath);
131
+ let action = fileActions?.(filePath) || configs_1.default.fileActions[ext] || defaultAction;
134
132
  if (action) {
135
133
  action(filePath, outDir, projectPath);
136
134
  if (callback) {
@@ -143,14 +141,18 @@ function generateCodeByOptions(options) {
143
141
  let fullPath = path.join(sourceDir, dir);
144
142
  let outDirPath = path.join(outDir, dir);
145
143
  if (fs.statSync(fullPath).isDirectory()) {
146
- generateCodeByOptions({ sourceDir: fullPath, outDir: outDirPath, projectPath: projectPath, skipFiles, fileAction: fileActions, callback });
144
+ generateCodeByOptions({ sourceDir: fullPath, outDir: outDirPath, projectPath: projectPath, skipFiles, fileAction: fileActions, callback, defaultAction });
147
145
  }
148
146
  }
149
147
  }
150
148
  function watchDirectoryByOptions(options) {
151
- let { sourceDir, outDir, projectPath, skipFiles, fileAction: fileActions, callback } = options;
149
+ let { sourceDir, outDir, projectPath, skipFiles, fileAction: fileActions, callback, defaultAction } = options;
150
+ if (!defaultAction)
151
+ defaultAction = copy_file_1.default;
152
152
  (0, node_watch_1.default)(sourceDir, { recursive: true }, async (evt, name) => {
153
- const filePath = name;
153
+ const filePath = name.replace(/\\/g, "/");
154
+ sourceDir = sourceDir.replace(/\\/g, "/");
155
+ outDir = outDir.replace(/\\/g, "/");
154
156
  const ext = extname(filePath);
155
157
  skipFiles = skipFiles || configs_1.default.skipFiles[ext] || [];
156
158
  let isSkip = skipFiles.some(pattern => pattern.test(filePath)); //isIgnoredFile(filePath);//skipFiles.some(pattern => new RegExp(pattern).test(filePath));
@@ -161,15 +163,15 @@ function watchDirectoryByOptions(options) {
161
163
  if (evt === "remove") {
162
164
  return;
163
165
  }
164
- let action = fileActions?.(filePath) || configs_1.default.fileActions[ext];
166
+ let action = fileActions?.(filePath) || configs_1.default.fileActions[ext] || defaultAction;
165
167
  if (!action) {
166
168
  return;
167
169
  }
168
170
  try {
169
- let outPath = path.dirname(name).replace(sourceDir, outDir);
170
- action(name, outPath, projectPath);
171
+ let outPath = path.dirname(filePath).replace(sourceDir, outDir);
172
+ action(filePath, outPath, projectPath);
171
173
  if (callback)
172
- callback(name, outPath, projectPath);
174
+ callback(filePath, outPath, projectPath);
173
175
  }
174
176
  catch (e) {
175
177
  console.error(e);
package/out/types.d.ts CHANGED
@@ -1 +1,2 @@
1
1
  export type FileAction = (filePath: string, outPath: string, projectPath: string) => void;
2
+ export type JavaScriptExtension = ".js" | ".mjs" | ".cjs";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "maishu-scripts",
3
- "version": "1.4.0",
3
+ "version": "1.4.2",
4
4
  "description": "用于对 node 项目进行代码生成,打包,运行",
5
5
  "dependencies": {
6
6
  "@babel/core": "^7.24.3",
@@ -31,6 +31,7 @@
31
31
  "src"
32
32
  ],
33
33
  "scripts": {
34
- "build": "tsc"
34
+ "build": "tsc -p tsconfig.build.json",
35
+ "test": "jest"
35
36
  }
36
- }
37
+ }
@@ -4,31 +4,37 @@ import * as fs from "fs";
4
4
  import * as path from "path";
5
5
  import { errors } from "../errors";
6
6
  import { ProjectCompiler } from "../project-compiler";
7
- import { FileAction } from "../../types";
7
+ import { FileAction, JavaScriptExtension } from "../../types";
8
8
 
9
- const outExt = ProjectCompiler.tsOutExt;
9
+ // const outExt = ProjectCompiler.tsOutExt;
10
10
 
11
11
 
12
- export function create(babelOptions?: babel.TransformOptions): FileAction {
12
+ export function create(defaultBabelOptions?: babel.TransformOptions, outExit?: JavaScriptExtension): FileAction {
13
13
  const action: FileAction = (sourcePath: string, outputPath: string, projectPath: string) => {
14
- if (!babelOptions) {
15
- let bablePath: string;
16
- let sourceDir = path.dirname(sourcePath);
17
- if (projectPath) {
18
- let c = ProjectCompiler.getBabelConfig(projectPath, sourceDir);
19
- bablePath = c.path;
20
- babelOptions = c.options;
21
- }
22
- else {
23
- babelOptions = ProjectCompiler.getDefaultBabelConfig();
24
- bablePath = '';
25
- }
26
- babelOptions.filename = sourcePath;
27
- babelOptions.code = false;
28
- babelOptions.ast = true;
14
+ outExit = outExit || ".js";
15
+ if (defaultBabelOptions) {
16
+ return compileFile(sourcePath, outputPath, projectPath, defaultBabelOptions, outExit);
29
17
  }
30
18
 
31
- return compileFile(sourcePath, outputPath, projectPath, babelOptions);
19
+ // 如果没有 babelOptions,则尝试从项目目录查找 babel 配置文件,如果没有,则使用默认配置。
20
+ let babelOptions: babel.TransformOptions;
21
+ let bablePath: string;
22
+ let sourceDir = path.dirname(sourcePath);
23
+ if (projectPath) {
24
+ let c = ProjectCompiler.getBabelConfig(projectPath, sourceDir);
25
+ bablePath = c.path;
26
+ babelOptions = c.options;
27
+ }
28
+ else {
29
+ babelOptions = ProjectCompiler.getDefaultBabelConfig();
30
+ bablePath = '';
31
+ }
32
+
33
+ babelOptions.filename = sourcePath;
34
+ babelOptions.code = false;
35
+ babelOptions.ast = true;
36
+
37
+ return compileFile(sourcePath, outputPath, projectPath, babelOptions, outExit);
32
38
  }
33
39
  return action;
34
40
  }
@@ -39,7 +45,7 @@ export function create(babelOptions?: babel.TransformOptions): FileAction {
39
45
  * @param outputPath 输出目录
40
46
  * @param projectPath 项目路径
41
47
  * */
42
- async function compileFile(sourcePath: string, outputPath: string, projectPath: string, babelOptions: babel.TransformOptions) {
48
+ async function compileFile(sourcePath: string, outputPath: string, projectPath: string, babelOptions: babel.TransformOptions, outExt: JavaScriptExtension) {
43
49
  if (!sourcePath) throw errors.argumentNull("sourcePath");
44
50
  if (!outputPath) throw errors.argumentNull("outputPath");
45
51
  if (!projectPath) throw errors.argumentNull("projectPath");
@@ -82,7 +88,7 @@ async function compileFile(sourcePath: string, outputPath: string, projectPath:
82
88
  if (!ast)
83
89
  throw errors.compileError(sourcePath);
84
90
 
85
- new ImportPathRewrite(sourcePath, ast);
91
+ new ImportPathRewrite(sourcePath, ast, outExt);
86
92
  let r = babel.transformFromAstSync(ast, undefined, {
87
93
  filename: sourcePath, plugins: babelOptions.plugins,
88
94
  presets: babelOptions.presets, sourceMaps: babelOptions.sourceMaps
@@ -91,7 +97,7 @@ async function compileFile(sourcePath: string, outputPath: string, projectPath:
91
97
  throw errors.compileError(sourcePath);
92
98
 
93
99
  let ext = extname(sourcePath);
94
- let outExt = fileOutExt(sourcePath);
100
+ //let outExt = fileOutExt(sourcePath);
95
101
  let targetPath = path.join(outputPath, path.basename(sourcePath).replace(ext, outExt));//sourcePath.replace(new RegExp(ext + "$"), outExt).replace(path.dirname(sourcePath), outDir);
96
102
  let outDirPath = path.resolve(targetPath, "..");
97
103
 
@@ -128,20 +134,20 @@ function extname(file: string) {
128
134
  * 获取源文件所对应生成文件的扩展名
129
135
  * @param file 源文件名
130
136
  * */
131
- function fileOutExt(file: string) {
132
- let ext = extname(file);
133
- if (ext === ".ts")
134
- return outExt;
137
+ // function fileOutExt(file: string) {
138
+ // let ext = extname(file);
139
+ // if (ext === ".ts")
140
+ // return outExt;
135
141
 
136
- if (ext === ".tsx")
137
- return outExt;
142
+ // if (ext === ".tsx")
143
+ // return outExt;
138
144
 
139
- return ext;
140
- }
145
+ // return ext;
146
+ // }
141
147
 
142
148
 
143
149
  class ImportPathRewrite {
144
- constructor(private filePath: string, node: babel.types.File) {
150
+ constructor(private filePath: string, node: babel.types.File, private outExt: JavaScriptExtension) {
145
151
  this.traverse(node);
146
152
  }
147
153
 
@@ -156,14 +162,14 @@ class ImportPathRewrite {
156
162
  case "ImportDeclaration":
157
163
  if (node.source.type === "StringLiteral" && node.source.value.startsWith(".")) {
158
164
  let ext = extname(node.source.value);
159
- if (ext != outExt) {
165
+ if (ext != this.outExt) {
160
166
  let dir = path.dirname(this.filePath);
161
167
  let fullPath = path.join(dir, node.source.value);
162
168
  console.log(`ImportDeclaration: ${fullPath} -> ${ext}`)
163
169
  if (fs.existsSync(fullPath) && fs.statSync(fullPath).isDirectory()) {
164
170
  node.source.value = node.source.value + "/index";
165
171
  }
166
- node.source.value += outExt;
172
+ node.source.value += this.outExt;
167
173
  }
168
174
  }
169
175
  break;
@@ -3,7 +3,7 @@ import { errors } from '../errors';
3
3
  import * as fs from 'fs';
4
4
  import * as path from 'path';
5
5
  import { ProjectCompiler } from '../project-compiler';
6
- import { FileAction } from '../../types';
6
+ import { FileAction, JavaScriptExtension } from '../../types';
7
7
 
8
8
  const TS_CONFIG_FILE = 'tsconfig.json';
9
9
 
@@ -11,12 +11,16 @@ type TypeScriptProjectConfig = {
11
11
  compilerOptions: ts.CompilerOptions;
12
12
  }
13
13
 
14
- export function create(compilerOptions?: ts.CompilerOptions): FileAction {
14
+ export function create(defaultCompilerOptions?: ts.CompilerOptions, outExt?: JavaScriptExtension): FileAction {
15
+ outExt = outExt || ".js";
15
16
  const action: FileAction = async (filePath: string, outDir: string, projectPath: string) => {
16
- if (!compilerOptions) {
17
- compilerOptions = getTypescriptConfig(projectPath, path.dirname(filePath));
17
+ if (defaultCompilerOptions) {
18
+ return compileFile(filePath, outDir, projectPath, defaultCompilerOptions, outExt);
18
19
  }
19
- return compileFile(filePath, outDir, projectPath, compilerOptions)
20
+
21
+ // 如果没有指定默认编译选项,则尝试从项目目录查找 tsconfig.json 文件,并使用其中的配置进行编译
22
+ const compilerOptions = getTypescriptConfig(projectPath, path.dirname(filePath));
23
+ return compileFile(filePath, outDir, projectPath, compilerOptions, outExt);
20
24
  }
21
25
 
22
26
  return action;
@@ -28,7 +32,7 @@ export function create(compilerOptions?: ts.CompilerOptions): FileAction {
28
32
  * @param outDir 输出目录,相对于项目路径
29
33
  * @param projectPath 项目路径,绝对路径
30
34
  * */
31
- async function compileFile(filePath: string, outDir: string, projectPath: string, compilerOptions: ts.CompilerOptions) {
35
+ async function compileFile(filePath: string, outDir: string, projectPath: string, compilerOptions: ts.CompilerOptions, outExt: JavaScriptExtension) {
32
36
  if (!filePath)
33
37
  throw errors.argumentNull('sourcePath');
34
38
  if (!outDir)
@@ -42,7 +46,6 @@ async function compileFile(filePath: string, outDir: string, projectPath: string
42
46
  let result = ts.transpileModule(content, { compilerOptions });
43
47
 
44
48
  let ext = path.extname(filePath);
45
- let outExt = ProjectCompiler.tsOutExt;
46
49
  let targetPath = path.join(projectPath, outDir, path.basename(filePath).replace(ext, outExt));
47
50
  let outDirPath = path.resolve(targetPath, "..");
48
51
 
@@ -1,188 +1,236 @@
1
- import { generateCode, isIgnoredFile, watchDirectory } from "./compile";
2
- import * as path from "path";
3
- import * as fs from "fs";
4
- import { create as createTsCompiler } from "../modules/actions/ts-compile";
5
- import ts from "typescript";
6
- import { FileAction } from "../types";
7
-
8
- describe("Compile Test", function () {
9
-
10
- test("copyFile test", function () {
11
-
12
- let srcPath = "test/src";
13
- let srcExists = fs.existsSync(srcPath);
14
- expect(srcExists).toBe(true);
15
- })
16
-
17
- test("generateCode test", function () {
18
-
19
- let srcPath = "test/src";
20
- let destPath = "test/out";
21
- if (fs.existsSync(destPath)) {
22
- fs.rmdirSync(destPath, { recursive: true });
23
- }
24
-
25
- let projectPath = path.join(__dirname, "..", "..");
26
- generateCode(srcPath, destPath, projectPath);
27
- })
28
-
29
- test("generateCode with callback test", function () {
30
-
31
- let srcPath = "test/src";
32
- let destPath = "test/out";
33
- if (fs.existsSync(destPath)) {
34
- fs.rmdirSync(destPath, { recursive: true });
35
- }
36
-
37
- let projectPath = path.join(__dirname, "..", "..");
38
- const callback = jest.fn();
39
- generateCode(srcPath, destPath, projectPath, callback);
40
- expect(callback.mock.calls.length).toBeGreaterThan(0);
41
- })
42
-
43
- test("generateCode with skipFiles test", function () {
44
-
45
- let srcPath = "test/src";
46
- let destPath = "test/out";
47
- if (fs.existsSync(destPath)) {
48
- fs.rmdirSync(destPath, { recursive: true });
49
- }
50
-
51
- let projectPath = path.join(__dirname, "..", "..");
52
- let executedPaths: string[] = [];
53
- generateCode(srcPath, destPath, projectPath, (filePath: string) => {
54
- executedPaths.push(filePath);
55
- });
56
-
57
- // 'test\\src\\controllers\\proxy.ts'
58
- expect(executedPaths.some(p => p.includes("controllers")));
59
-
60
- // 忽略掉 controllers 目录
61
- const skipFiles = [new RegExp("controllers")];
62
- executedPaths = [];
63
- generateCode({
64
- sourceDir: srcPath, outDir: destPath, projectPath, skipFiles,
65
- callback(filePath: string) {
66
- executedPaths.push(filePath);
67
- }
68
- })
69
- expect(executedPaths.some(p => p.includes("controllers"))).toBe(false);
70
- })
71
-
72
- test("generateCode 根据文件夹使用不同的 TS 编译器", function () {
73
-
74
- let srcPath = "test/src";
75
- let destPath = "test/out";
76
- if (fs.existsSync(destPath)) {
77
- fs.rmdirSync(destPath, { recursive: true });
78
- }
79
-
80
- const srcCompiler = createTsCompiler({
81
- target: ts.ScriptTarget.ES2015,
82
- module: ts.ModuleKind.CommonJS,
83
- declaration: true,
84
- });
85
-
86
- const staticCompiler = createTsCompiler({
87
- target: ts.ScriptTarget.ES5,
88
- module: ts.ModuleKind.AMD,
89
- declaration: false,
90
- });
91
-
92
- let projectPath = path.join(__dirname, "..", "..");
93
- const mainFile = "main.ts";
94
- const staticFile = "static/index.ts";
95
- const mainFilePath = path.resolve(srcPath, mainFile);
96
- expect(fs.existsSync(mainFilePath)).toBeTruthy();
97
- const staticFilePath = path.resolve(srcPath, staticFile);
98
- expect(fs.existsSync(staticFilePath)).toBeTruthy();
99
-
100
-
101
- generateCode({
102
- sourceDir: srcPath, outDir: destPath, projectPath,
103
- fileAction(filePath: string) {
104
- const ext = path.extname(filePath);
105
- if (ext !== ".ts" && ext !== ".tsx") {
106
- return undefined;
107
- }
108
- filePath = filePath.replace(/\\/g, "/");
109
- if (filePath.startsWith("test/src/static/")) {
110
- return staticCompiler;
111
- }
112
- return srcCompiler;
113
- },
114
- callback(filePath: string) {
115
- }
116
- })
117
-
118
- const mainOutFile = "main.js";
119
- const staticOutFile = "static/index.js";
120
- const mainOutFilePath = path.resolve(destPath, mainOutFile);
121
- const staticOutFilePath = path.resolve(destPath, staticOutFile);
122
- expect(fs.existsSync(mainOutFilePath)).toBeTruthy();
123
- expect(fs.existsSync(staticOutFilePath)).toBeTruthy();
124
-
125
- const mainFileContent = fs.readFileSync(mainOutFilePath, "utf-8");
126
- const staticFileContent = fs.readFileSync(staticOutFilePath, "utf-8");
127
-
128
- expect(mainFileContent.includes("Object.defineProperty(exports, \"__esModule\"")).toBe(true);
129
- expect(staticFileContent.includes("define([")).toBe(true);
130
-
131
- })
132
-
133
- test("isIgnored test", function () {
134
- let filePath = "D:\\startdard-process\\plm-projects\\tc-api-proxy\\src\\app.controller.spec.ts";
135
- let ignored = isIgnoredFile(filePath);
136
- expect(ignored).toBe(true);
137
- })
138
-
139
- test("watchDirectory test, 修改文件应该触发回调, 删除文不应该触发回调", async function () {
140
-
141
- let srcPath = "test/src";
142
- let destPath = "test/out";
143
-
144
- // srcPath 中创建文件
145
- let filePath = path.join(srcPath, "test.txt");
146
- fs.writeFileSync(filePath, "test");
147
- const fileAction = jest.fn();
148
-
149
- setTimeout(() => {
150
- // 监听 srcPath
151
- let projectPath = path.join(__dirname, "..", "..");
152
- let executedPaths: string[] = [];
153
- // watchDirectory(srcPath, destPath, projectPath, (filePath: string) => {
154
- // executedPaths.push(filePath);
155
- // });
156
- watchDirectory({
157
- sourceDir: srcPath, outDir: destPath, projectPath,
158
- fileAction: () => {
159
- return fileAction;
160
- },
161
- callback(filePath: string) {
162
- executedPaths.push(filePath);
163
- }
164
- })
165
- }, 0);
166
-
167
- await new Promise(resolve => setTimeout(resolve, 1000 * 1));
168
- // 修改文件
169
- fs.writeFileSync(filePath, "test2");
170
-
171
- await new Promise(resolve => setTimeout(resolve, 1000 * 1));
172
- expect(fileAction.mock.calls.length).toBe(1);
173
- expect(fileAction.mock.calls[0][0]).toBe(filePath);
174
-
175
-
176
- const calltimes = fileAction.mock.calls.length;
177
- setTimeout(() => {
178
- // 删除文件
179
- fs.unlinkSync(filePath);
180
- }, 1000 * 1);
181
-
182
- await new Promise(resolve => setTimeout(resolve, 1000 * 1));
183
- expect(fileAction.mock.calls.length).toBe(calltimes);
184
-
185
-
186
- })
187
-
188
- })
1
+ import { generateCode, isIgnoredFile, watchDirectory } from "./compile";
2
+ import * as path from "path";
3
+ import * as fs from "fs";
4
+ import { create as createTsCompiler } from "./actions/ts-compile";
5
+ import ts from "typescript";
6
+ import copyFile from "./actions/copy-file";
7
+ import { errors } from "./errors";
8
+
9
+ // 公共常量
10
+ const SRC_PATH = "test/src";
11
+ const DEST_PATH = "test/out";
12
+ const PROJECT_PATH = path.join(__dirname, "..", "..");
13
+
14
+ // 清理输出目录的工具函数
15
+ function cleanDir(dir: string) {
16
+ if (fs.existsSync(dir)) {
17
+ fs.rmSync(dir, { recursive: true });
18
+ }
19
+ }
20
+
21
+ describe("Compile Test", function () {
22
+
23
+ test("copyFile test", function () {
24
+ let srcExists = fs.existsSync(SRC_PATH);
25
+ expect(srcExists).toBe(true);
26
+ })
27
+
28
+ test("generateCode test", function () {
29
+ cleanDir(DEST_PATH);
30
+ generateCode(SRC_PATH, DEST_PATH, PROJECT_PATH);
31
+ })
32
+
33
+ test("generateCode with callback test", function () {
34
+ cleanDir(DEST_PATH);
35
+ const callback = jest.fn();
36
+ generateCode(SRC_PATH, DEST_PATH, PROJECT_PATH, callback);
37
+ expect(callback.mock.calls.length).toBeGreaterThan(0);
38
+ })
39
+
40
+ test("generateCode with skipFiles test", function () {
41
+ cleanDir(DEST_PATH);
42
+
43
+ let executedPaths: string[] = [];
44
+ generateCode(SRC_PATH, DEST_PATH, PROJECT_PATH, (filePath: string) => {
45
+ executedPaths.push(filePath);
46
+ });
47
+
48
+ expect(executedPaths.some(p => p.includes("controllers"))).toBe(true);
49
+
50
+ // 忽略掉 controllers 目录
51
+ const skipFiles = [new RegExp("controllers")];
52
+ executedPaths = [];
53
+ generateCode({
54
+ sourceDir: SRC_PATH, outDir: DEST_PATH, projectPath: PROJECT_PATH, skipFiles,
55
+ callback(filePath: string) {
56
+ executedPaths.push(filePath);
57
+ }
58
+ })
59
+ expect(executedPaths.some(p => p.includes("controllers"))).toBe(false);
60
+ })
61
+
62
+ test("generateCode 根据文件夹使用不同的 TS 编译器", async function () {
63
+ cleanDir(DEST_PATH);
64
+
65
+ const srcCompiler = createTsCompiler({
66
+ target: ts.ScriptTarget.ES2015,
67
+ module: ts.ModuleKind.CommonJS,
68
+ declaration: true,
69
+ });
70
+
71
+ const staticCompiler = createTsCompiler({
72
+ target: ts.ScriptTarget.ES5,
73
+ module: ts.ModuleKind.AMD,
74
+ declaration: false,
75
+ });
76
+
77
+ const mainFile = "main.ts";
78
+ const staticFile = "static/index.ts";
79
+ const mainFilePath = path.resolve(SRC_PATH, mainFile);
80
+ expect(fs.existsSync(mainFilePath)).toBeTruthy();
81
+ const staticFilePath = path.resolve(SRC_PATH, staticFile);
82
+ expect(fs.existsSync(staticFilePath)).toBeTruthy();
83
+
84
+ generateCode({
85
+ sourceDir: SRC_PATH, outDir: DEST_PATH, projectPath: PROJECT_PATH,
86
+ fileAction(filePath: string) {
87
+ const ext = path.extname(filePath);
88
+ if (ext !== ".ts" && ext !== ".tsx") {
89
+ return undefined;
90
+ }
91
+ filePath = filePath.replace(/\\/g, "/");
92
+ if (filePath.startsWith("test/src/static/")) {
93
+ return staticCompiler;
94
+ }
95
+ return srcCompiler;
96
+ },
97
+ callback(_filePath: string) {
98
+ }
99
+ })
100
+
101
+ // 等待异步编译完成
102
+ await new Promise(resolve => setTimeout(resolve, 1000));
103
+
104
+ const mainOutFile = "main.js";
105
+ const staticOutFile = "static/index.js";
106
+ const mainOutFilePath = path.resolve(DEST_PATH, mainOutFile);
107
+ const staticOutFilePath = path.resolve(DEST_PATH, staticOutFile);
108
+ expect(fs.existsSync(mainOutFilePath)).toBeTruthy();
109
+ expect(fs.existsSync(staticOutFilePath)).toBeTruthy();
110
+
111
+ const mainFileContent = fs.readFileSync(mainOutFilePath, "utf-8");
112
+ const staticFileContent = fs.readFileSync(staticOutFilePath, "utf-8");
113
+
114
+ expect(mainFileContent.includes("Object.defineProperty(exports, \"__esModule\"")).toBe(true);
115
+ expect(staticFileContent.includes("define([")).toBe(true);
116
+ })
117
+
118
+ test("generateCode 参数校验", function () {
119
+ expect(() => generateCode("", DEST_PATH, PROJECT_PATH)).toThrow();
120
+ expect(() => generateCode(SRC_PATH, "", PROJECT_PATH)).toThrow();
121
+ expect(() => generateCode(SRC_PATH, DEST_PATH, "")).toThrow();
122
+ expect(() => generateCode("/nonexistent/path", DEST_PATH, PROJECT_PATH)).toThrow();
123
+ })
124
+
125
+ test("generateCode with defaultAction", function () {
126
+ cleanDir(DEST_PATH);
127
+
128
+ const customAction = jest.fn();
129
+ generateCode({
130
+ sourceDir: SRC_PATH, outDir: DEST_PATH, projectPath: PROJECT_PATH,
131
+ fileAction() {
132
+ return undefined; // fileAction 始终返回 undefined
133
+ },
134
+ defaultAction: customAction as any,
135
+ })
136
+
137
+ // defaultAction 应该被调用
138
+ expect(customAction.mock.calls.length).toBeGreaterThan(0);
139
+ })
140
+
141
+ test("generateCode defaultAction 默认为 copyFile", function () {
142
+ cleanDir(DEST_PATH);
143
+
144
+ // 不指定 fileAction 和 defaultAction,未知扩展名应使用 copyFile 作为兜底
145
+ const jsFile = path.join(SRC_PATH, "test-default-action.js");
146
+ fs.writeFileSync(jsFile, "console.log('test');");
147
+
148
+ try {
149
+ generateCode({
150
+ sourceDir: SRC_PATH, outDir: DEST_PATH, projectPath: PROJECT_PATH,
151
+ fileAction() {
152
+ return undefined; // 不提供任何 action
153
+ },
154
+ })
155
+
156
+ // copyFile 应该将 .js 文件复制到输出目录
157
+ const outFile = path.resolve(DEST_PATH, "test-default-action.js");
158
+ expect(fs.existsSync(outFile)).toBe(true);
159
+ } finally {
160
+ // 清理临时文件
161
+ if (fs.existsSync(jsFile)) fs.unlinkSync(jsFile);
162
+ const outFile = path.resolve(DEST_PATH, "test-default-action.js");
163
+ if (fs.existsSync(outFile)) fs.unlinkSync(outFile);
164
+ }
165
+ })
166
+
167
+ describe("isIgnoredFile", function () {
168
+
169
+ test(".spec.ts 文件应该被忽略", function () {
170
+ let filePath = "D:\\project\\src\\app.controller.spec.ts";
171
+ let ignored = isIgnoredFile(filePath);
172
+ expect(ignored).toBe(true);
173
+ })
174
+
175
+ test(".test.ts 文件应该被忽略", function () {
176
+ let filePath = "D:\\project\\src\\app.controller.test.ts";
177
+ let ignored = isIgnoredFile(filePath);
178
+ expect(ignored).toBe(true);
179
+ })
180
+
181
+ test(".d.ts 文件应该被忽略", function () {
182
+ let filePath = "D:\\project\\src\\app.d.ts";
183
+ let ignored = isIgnoredFile(filePath);
184
+ expect(ignored).toBe(true);
185
+ })
186
+
187
+ test("普通 .ts 文件不应被忽略", function () {
188
+ let filePath = "D:\\project\\src\\app.controller.ts";
189
+ let ignored = isIgnoredFile(filePath);
190
+ expect(ignored).toBe(false);
191
+ })
192
+
193
+ test("空参数应抛出异常", function () {
194
+ expect(() => isIgnoredFile("")).toThrow();
195
+ })
196
+
197
+ })
198
+
199
+ test("watchDirectory test, 修改文件应该触发回调, 删除文件不应该触发回调", async function () {
200
+ let filePath = path.join(SRC_PATH, "test.txt");
201
+ filePath = filePath.replace(/\\/g, "/");
202
+ fs.writeFileSync(filePath, "test");
203
+ const fileAction = jest.fn();
204
+
205
+ setTimeout(() => {
206
+ let executedPaths: string[] = [];
207
+ watchDirectory({
208
+ sourceDir: SRC_PATH, outDir: DEST_PATH, projectPath: PROJECT_PATH,
209
+ fileAction: () => {
210
+ return fileAction;
211
+ },
212
+ callback(filePath: string) {
213
+ executedPaths.push(filePath);
214
+ }
215
+ })
216
+ }, 0);
217
+
218
+ await new Promise(resolve => setTimeout(resolve, 1000));
219
+ // 修改文件
220
+ fs.writeFileSync(filePath, "test2");
221
+
222
+ await new Promise(resolve => setTimeout(resolve, 1000));
223
+ expect(fileAction.mock.calls.length).toBe(1);
224
+ expect(fileAction.mock.calls[0][0]).toBe(filePath);
225
+
226
+ const calltimes = fileAction.mock.calls.length;
227
+ setTimeout(() => {
228
+ // 删除文件
229
+ fs.unlinkSync(filePath);
230
+ }, 1000);
231
+
232
+ await new Promise(resolve => setTimeout(resolve, 1000));
233
+ expect(fileAction.mock.calls.length).toBe(calltimes);
234
+ })
235
+
236
+ })
@@ -84,11 +84,15 @@ type Options = {
84
84
  sourceDir: string, outDir: string, projectPath: string,
85
85
  skipFiles?: RegExp[],
86
86
  fileAction?: (fileName: string) => FileAction | undefined,
87
- callback?: Callback
87
+ callback?: Callback,
88
+ defaultAction?: FileAction
88
89
  }
89
90
  function generateCodeByOptions(options: Options) {
90
91
 
91
- let { sourceDir, outDir, projectPath, skipFiles, fileAction: fileActions, callback } = options;
92
+ let { sourceDir, outDir, projectPath, skipFiles, fileAction: fileActions, callback, defaultAction } = options;
93
+
94
+ if (!defaultAction)
95
+ defaultAction = copyFile;
92
96
 
93
97
 
94
98
  if (!sourceDir) throw errors.argumentNull("sourceDir");
@@ -116,11 +120,7 @@ function generateCodeByOptions(options: Options) {
116
120
  continue;
117
121
  }
118
122
 
119
- fileActions = fileActions || function (fileName: string) {
120
- const ext = path.extname(fileName);
121
- return configs.fileActions[ext];
122
- };
123
- let action = fileActions(filePath);
123
+ let action = fileActions?.(filePath) || configs.fileActions[ext] || defaultAction;
124
124
  if (action) {
125
125
  action(filePath, outDir, projectPath);
126
126
  if (callback) {
@@ -134,16 +134,22 @@ function generateCodeByOptions(options: Options) {
134
134
  let fullPath = path.join(sourceDir, dir);
135
135
  let outDirPath = path.join(outDir, dir);
136
136
  if (fs.statSync(fullPath).isDirectory()) {
137
- generateCodeByOptions({ sourceDir: fullPath, outDir: outDirPath, projectPath: projectPath, skipFiles, fileAction: fileActions, callback });
137
+ generateCodeByOptions({ sourceDir: fullPath, outDir: outDirPath, projectPath: projectPath, skipFiles, fileAction: fileActions, callback, defaultAction });
138
138
  }
139
139
  }
140
140
  }
141
141
 
142
142
  function watchDirectoryByOptions(options: Options) {
143
- let { sourceDir, outDir, projectPath, skipFiles, fileAction: fileActions, callback } = options;
143
+ let { sourceDir, outDir, projectPath, skipFiles, fileAction: fileActions, callback, defaultAction } = options;
144
+
145
+ if (!defaultAction)
146
+ defaultAction = copyFile;
147
+
148
+ watch(sourceDir, { recursive: true }, async (evt: "update" | "remove", name: string) => {
149
+ const filePath = name.replace(/\\/g, "/");
150
+ sourceDir = sourceDir.replace(/\\/g, "/");
151
+ outDir = outDir.replace(/\\/g, "/");
144
152
 
145
- watch(sourceDir, { recursive: true }, async (evt, name) => {
146
- const filePath = name;
147
153
  const ext = extname(filePath);
148
154
  skipFiles = skipFiles || configs.skipFiles[ext] || [];
149
155
  let isSkip = skipFiles.some(pattern => pattern.test(filePath));//isIgnoredFile(filePath);//skipFiles.some(pattern => new RegExp(pattern).test(filePath));
@@ -156,16 +162,16 @@ function watchDirectoryByOptions(options: Options) {
156
162
  return;
157
163
  }
158
164
 
159
- let action = fileActions?.(filePath) || configs.fileActions[ext];
165
+ let action = fileActions?.(filePath) || configs.fileActions[ext] || defaultAction;
160
166
  if (!action) {
161
167
  return;
162
168
  }
163
169
 
164
170
  try {
165
- let outPath = path.dirname(name).replace(sourceDir, outDir);
166
- action(name, outPath, projectPath);
171
+ let outPath = path.dirname(filePath).replace(sourceDir, outDir);
172
+ action(filePath, outPath, projectPath);
167
173
  if (callback)
168
- callback(name, outPath, projectPath);
174
+ callback(filePath, outPath, projectPath);
169
175
  }
170
176
  catch (e) {
171
177
  console.error(e);
package/src/types.ts CHANGED
@@ -1 +1,2 @@
1
- export type FileAction = (filePath: string, outPath: string, projectPath: string) => void;
1
+ export type FileAction = (filePath: string, outPath: string, projectPath: string) => void;
2
+ export type JavaScriptExtension = ".js" | ".mjs" | ".cjs";
@@ -1,7 +0,0 @@
1
- /**
2
- * 编译特定文件,并生成到制定目录
3
- * @param sourcePath 源文件路径
4
- * @param outputPath 输出目录
5
- * @param projectPath 项目路径
6
- * */
7
- export declare function compileFile(sourcePath: string, outputPath: string, projectPath: string): Promise<void>;
@@ -1,153 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || function (mod) {
19
- if (mod && mod.__esModule) return mod;
20
- var result = {};
21
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
- __setModuleDefault(result, mod);
23
- return result;
24
- };
25
- Object.defineProperty(exports, "__esModule", { value: true });
26
- exports.compileFile = compileFile;
27
- const babel = __importStar(require("@babel/core"));
28
- const fs = __importStar(require("fs"));
29
- const path = __importStar(require("path"));
30
- const errors_1 = require("../errors");
31
- const project_compiler_1 = require("../project-compiler");
32
- const outExt = project_compiler_1.ProjectCompiler.tsOutExt;
33
- /**
34
- * 编译特定文件,并生成到制定目录
35
- * @param sourcePath 源文件路径
36
- * @param outputPath 输出目录
37
- * @param projectPath 项目路径
38
- * */
39
- async function compileFile(sourcePath, outputPath, projectPath) {
40
- if (!sourcePath)
41
- throw errors_1.errors.argumentNull("sourcePath");
42
- if (!outputPath)
43
- throw errors_1.errors.argumentNull("outputPath");
44
- if (!projectPath)
45
- throw errors_1.errors.argumentNull("projectPath");
46
- // if (!fs.existsSync(sourcePath)) throw errors.pathNotExists(sourcePath);
47
- if (!fs.existsSync(sourcePath)) {
48
- console.warn(`Path not exists: ${sourcePath}`);
49
- return;
50
- }
51
- let sourceDir = path.dirname(sourcePath);
52
- let babelOptions;
53
- let bablePath;
54
- //= projectPath ?
55
- // ProjectCompiler.getBabelConfig(projectPath, sourceDir) : ProjectCompiler.getDefaultBabelConfig();
56
- if (projectPath) {
57
- let c = project_compiler_1.ProjectCompiler.getBabelConfig(projectPath, sourceDir);
58
- bablePath = c.path;
59
- babelOptions = c.options;
60
- }
61
- else {
62
- babelOptions = project_compiler_1.ProjectCompiler.getDefaultBabelConfig();
63
- bablePath = '';
64
- }
65
- babelOptions.filename = sourcePath;
66
- babelOptions.code = false;
67
- babelOptions.ast = true;
68
- // let fileResult = babel.transformFileSync(sourcePath, {
69
- // filename: sourcePath, code: false, ast: true, plugins,
70
- // presets
71
- // });
72
- let fileResult = babel.transformFileSync(sourcePath, babelOptions);
73
- if (!fileResult)
74
- throw errors_1.errors.compileError(sourcePath);
75
- let ast = fileResult.ast;
76
- if (!ast)
77
- throw errors_1.errors.compileError(sourcePath);
78
- new ImportPathRewrite(sourcePath, ast);
79
- let r = babel.transformFromAstSync(ast, undefined, {
80
- filename: sourcePath, plugins: babelOptions.plugins,
81
- presets: babelOptions.presets, sourceMaps: babelOptions.sourceMaps
82
- });
83
- if (!r || r.code == null)
84
- throw errors_1.errors.compileError(sourcePath);
85
- let ext = extname(sourcePath);
86
- let outExt = fileOutExt(sourcePath);
87
- let targetPath = path.join(outputPath, path.basename(sourcePath).replace(ext, outExt)); //sourcePath.replace(new RegExp(ext + "$"), outExt).replace(path.dirname(sourcePath), outDir);
88
- let outDirPath = path.resolve(targetPath, "..");
89
- let mapPath = targetPath + ".map";
90
- if (r.map) {
91
- r.map.file = path.basename(targetPath);
92
- r.map.sources = [path.relative(outputPath, sourcePath)];
93
- if (!fs.existsSync(outDirPath))
94
- fs.mkdirSync(outDirPath, { recursive: true });
95
- fs.writeFileSync(mapPath, JSON.stringify(r.map));
96
- r.code += `\n//babel file path = ${bablePath}`;
97
- r.code += "\n//# sourceMappingURL=" + path.basename(mapPath);
98
- }
99
- else if (fs.existsSync(mapPath)) {
100
- fs.rmSync(targetPath);
101
- }
102
- if (!fs.existsSync(outDirPath))
103
- fs.mkdirSync(outDirPath, { recursive: true });
104
- fs.writeFileSync(targetPath, r.code);
105
- }
106
- function extname(file) {
107
- // let ext = /\.[a-zA-Z]+/.exec(file)?.[0] || '';
108
- let ext = path.extname(file);
109
- return ext;
110
- }
111
- /**
112
- * 获取源文件所对应生成文件的扩展名
113
- * @param file 源文件名
114
- * */
115
- function fileOutExt(file) {
116
- let ext = extname(file);
117
- if (ext === ".ts")
118
- return outExt;
119
- if (ext === ".tsx")
120
- return outExt;
121
- return ext;
122
- }
123
- class ImportPathRewrite {
124
- filePath;
125
- constructor(filePath, node) {
126
- this.filePath = filePath;
127
- this.traverse(node);
128
- }
129
- traverse(node) {
130
- switch (node.type) {
131
- case "Program":
132
- node.body.forEach(c => this.traverse(c));
133
- break;
134
- case "File":
135
- this.traverse(node.program);
136
- break;
137
- case "ImportDeclaration":
138
- if (node.source.type === "StringLiteral" && node.source.value.startsWith(".")) {
139
- let ext = extname(node.source.value);
140
- if (ext != outExt) {
141
- let dir = path.dirname(this.filePath);
142
- let fullPath = path.join(dir, node.source.value);
143
- console.log(`ImportDeclaration: ${fullPath} -> ${ext}`);
144
- if (fs.existsSync(fullPath) && fs.statSync(fullPath).isDirectory()) {
145
- node.source.value = node.source.value + "/index";
146
- }
147
- node.source.value += outExt;
148
- }
149
- }
150
- break;
151
- }
152
- }
153
- }