maishu-scripts 1.4.1 → 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.
@@ -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,7 +128,7 @@ function generateCodeByOptions(options) {
126
128
  console.log(`Skip ${filePath}`);
127
129
  continue;
128
130
  }
129
- let action = fileActions?.(filePath) || configs_1.default.fileActions[ext];
131
+ let action = fileActions?.(filePath) || configs_1.default.fileActions[ext] || defaultAction;
130
132
  if (action) {
131
133
  action(filePath, outDir, projectPath);
132
134
  if (callback) {
@@ -139,12 +141,14 @@ function generateCodeByOptions(options) {
139
141
  let fullPath = path.join(sourceDir, dir);
140
142
  let outDirPath = path.join(outDir, dir);
141
143
  if (fs.statSync(fullPath).isDirectory()) {
142
- generateCodeByOptions({ sourceDir: fullPath, outDir: outDirPath, projectPath: projectPath, skipFiles, fileAction: fileActions, callback });
144
+ generateCodeByOptions({ sourceDir: fullPath, outDir: outDirPath, projectPath: projectPath, skipFiles, fileAction: fileActions, callback, defaultAction });
143
145
  }
144
146
  }
145
147
  }
146
148
  function watchDirectoryByOptions(options) {
147
- 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;
148
152
  (0, node_watch_1.default)(sourceDir, { recursive: true }, async (evt, name) => {
149
153
  const filePath = name.replace(/\\/g, "/");
150
154
  sourceDir = sourceDir.replace(/\\/g, "/");
@@ -159,7 +163,7 @@ function watchDirectoryByOptions(options) {
159
163
  if (evt === "remove") {
160
164
  return;
161
165
  }
162
- let action = fileActions?.(filePath) || configs_1.default.fileActions[ext];
166
+ let action = fileActions?.(filePath) || configs_1.default.fileActions[ext] || defaultAction;
163
167
  if (!action) {
164
168
  return;
165
169
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "maishu-scripts",
3
- "version": "1.4.1",
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
+ }
@@ -1,189 +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
- filePath = filePath.replace(/\\/g, "/");
147
- fs.writeFileSync(filePath, "test");
148
- const fileAction = jest.fn();
149
-
150
- setTimeout(() => {
151
- // 监听 srcPath
152
- let projectPath = path.join(__dirname, "..", "..");
153
- let executedPaths: string[] = [];
154
- // watchDirectory(srcPath, destPath, projectPath, (filePath: string) => {
155
- // executedPaths.push(filePath);
156
- // });
157
- watchDirectory({
158
- sourceDir: srcPath, outDir: destPath, projectPath,
159
- fileAction: () => {
160
- return fileAction;
161
- },
162
- callback(filePath: string) {
163
- executedPaths.push(filePath);
164
- }
165
- })
166
- }, 0);
167
-
168
- await new Promise(resolve => setTimeout(resolve, 1000 * 1));
169
- // 修改文件
170
- fs.writeFileSync(filePath, "test2");
171
-
172
- await new Promise(resolve => setTimeout(resolve, 1000 * 1));
173
- expect(fileAction.mock.calls.length).toBe(1);
174
- expect(fileAction.mock.calls[0][0]).toBe(filePath);
175
-
176
-
177
- const calltimes = fileAction.mock.calls.length;
178
- setTimeout(() => {
179
- // 删除文件
180
- fs.unlinkSync(filePath);
181
- }, 1000 * 1);
182
-
183
- await new Promise(resolve => setTimeout(resolve, 1000 * 1));
184
- expect(fileAction.mock.calls.length).toBe(calltimes);
185
-
186
-
187
- })
188
-
189
- })
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,7 +120,7 @@ function generateCodeByOptions(options: Options) {
116
120
  continue;
117
121
  }
118
122
 
119
- let action = fileActions?.(filePath) || configs.fileActions[ext];
123
+ let action = fileActions?.(filePath) || configs.fileActions[ext] || defaultAction;
120
124
  if (action) {
121
125
  action(filePath, outDir, projectPath);
122
126
  if (callback) {
@@ -130,15 +134,18 @@ function generateCodeByOptions(options: Options) {
130
134
  let fullPath = path.join(sourceDir, dir);
131
135
  let outDirPath = path.join(outDir, dir);
132
136
  if (fs.statSync(fullPath).isDirectory()) {
133
- generateCodeByOptions({ sourceDir: fullPath, outDir: outDirPath, projectPath: projectPath, skipFiles, fileAction: fileActions, callback });
137
+ generateCodeByOptions({ sourceDir: fullPath, outDir: outDirPath, projectPath: projectPath, skipFiles, fileAction: fileActions, callback, defaultAction });
134
138
  }
135
139
  }
136
140
  }
137
141
 
138
142
  function watchDirectoryByOptions(options: Options) {
139
- 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;
140
147
 
141
- watch(sourceDir, { recursive: true }, async (evt, name) => {
148
+ watch(sourceDir, { recursive: true }, async (evt: "update" | "remove", name: string) => {
142
149
  const filePath = name.replace(/\\/g, "/");
143
150
  sourceDir = sourceDir.replace(/\\/g, "/");
144
151
  outDir = outDir.replace(/\\/g, "/");
@@ -155,7 +162,7 @@ function watchDirectoryByOptions(options: Options) {
155
162
  return;
156
163
  }
157
164
 
158
- let action = fileActions?.(filePath) || configs.fileActions[ext];
165
+ let action = fileActions?.(filePath) || configs.fileActions[ext] || defaultAction;
159
166
  if (!action) {
160
167
  return;
161
168
  }
@@ -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
- }