maishu-scripts 1.0.0 → 1.1.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.
Files changed (39) hide show
  1. package/out/index.d.ts +2 -0
  2. package/out/index.js +11 -0
  3. package/out/modules/compile/biel-compile.d.ts +7 -0
  4. package/out/modules/compile/biel-compile.js +131 -0
  5. package/out/modules/compile.d.ts +6 -0
  6. package/out/modules/compile.js +83 -0
  7. package/out/modules/errors.d.ts +9 -0
  8. package/out/modules/errors.js +27 -0
  9. package/out/modules/import-path-rewrite.d.ts +7 -0
  10. package/out/modules/import-path-rewrite.js +45 -0
  11. package/out/modules/project-compiler.d.ts +34 -0
  12. package/out/modules/project-compiler.js +229 -0
  13. package/out/modules/run.d.ts +1 -0
  14. package/out/modules/run.js +11 -0
  15. package/out/start.d.ts +1 -0
  16. package/out/start.js +9 -0
  17. package/package.json +8 -3
  18. package/{index.ts → src/index.ts} +1 -1
  19. package/{modules/compile.ts → src/modules/compile/biel-compile.ts} +7 -81
  20. package/{modules → src/modules}/compile.test.ts +1 -1
  21. package/src/modules/compile.ts +92 -0
  22. package/{modules → src/modules}/project-compiler.test.ts +2 -2
  23. package/{modules → src/modules}/project-compiler.ts +2 -0
  24. package/babel.config.js +0 -6
  25. package/test/package.json +0 -7
  26. package/test/src/app.controller.ts +0 -14
  27. package/test/src/app.module.ts +0 -17
  28. package/test/src/app.service.ts +0 -8
  29. package/test/src/config.ts +0 -16
  30. package/test/src/controllers/proxy.ts +0 -13
  31. package/test/src/main.ts +0 -8
  32. package/test/src/middleware/proxy.ts +0 -36
  33. package/test/src/static/babel.config.json +0 -6
  34. package/test/src/static/design/babel.config.js +0 -6
  35. package/test/tsconfig.json +0 -8
  36. /package/{modules → src/modules}/errors.ts +0 -0
  37. /package/{modules → src/modules}/import-path-rewrite.ts +0 -0
  38. /package/{modules → src/modules}/run.ts +0 -0
  39. /package/{start.ts → src/start.ts} +0 -0
package/out/index.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export { generateCode, watchDirectory } from "./modules/compile";
2
+ export { run } from "./modules/run";
package/out/index.js ADDED
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.run = exports.watchDirectory = exports.generateCode = void 0;
4
+ var compile_1 = require("./modules/compile");
5
+ Object.defineProperty(exports, "generateCode", { enumerable: true, get: function () { return compile_1.generateCode; } });
6
+ Object.defineProperty(exports, "watchDirectory", { enumerable: true, get: function () { return compile_1.watchDirectory; } });
7
+ var run_1 = require("./modules/run");
8
+ Object.defineProperty(exports, "run", { enumerable: true, get: function () { return run_1.run; } });
9
+ // let sourceDir = "src";
10
+ // let outDir = "out";
11
+ // generateCode(sourceDir, outDir);
@@ -0,0 +1,7 @@
1
+ /**
2
+ * 编译特定文件,并生成到制定目录
3
+ * @param sourcePath 源文件路径
4
+ * @param outDir 输出目录
5
+ * @param projectPath 项目路径
6
+ * */
7
+ export declare function compileFile(sourcePath: string, outDir: string, projectPath?: string): Promise<void>;
@@ -0,0 +1,131 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.compileFile = void 0;
4
+ const babel = require("@babel/core");
5
+ const fs = require("fs");
6
+ const path = require("path");
7
+ const errors_1 = require("../errors");
8
+ const project_compiler_1 = require("../project-compiler");
9
+ const outExt = project_compiler_1.ProjectCompiler.tsOutExt;
10
+ /**
11
+ * 编译特定文件,并生成到制定目录
12
+ * @param sourcePath 源文件路径
13
+ * @param outDir 输出目录
14
+ * @param projectPath 项目路径
15
+ * */
16
+ async function compileFile(sourcePath, outDir, projectPath) {
17
+ if (!sourcePath)
18
+ throw errors_1.errors.argumentNull("sourcePath");
19
+ if (!outDir)
20
+ throw errors_1.errors.argumentNull("outDir");
21
+ // if (!fs.existsSync(sourcePath)) throw errors.pathNotExists(sourcePath);
22
+ if (!fs.existsSync(sourcePath)) {
23
+ console.warn(`Path not exists: ${sourcePath}`);
24
+ return;
25
+ }
26
+ let sourceDir = path.dirname(sourcePath);
27
+ let babelOptions;
28
+ let bablePath;
29
+ //= projectPath ?
30
+ // ProjectCompiler.getBabelConfig(projectPath, sourceDir) : ProjectCompiler.getDefaultBabelConfig();
31
+ if (projectPath) {
32
+ let c = project_compiler_1.ProjectCompiler.getBabelConfig(projectPath, sourceDir);
33
+ bablePath = c.path;
34
+ babelOptions = c.options;
35
+ }
36
+ else {
37
+ babelOptions = project_compiler_1.ProjectCompiler.getDefaultBabelConfig();
38
+ bablePath = '';
39
+ }
40
+ babelOptions.filename = sourcePath;
41
+ babelOptions.code = false;
42
+ babelOptions.ast = true;
43
+ // let fileResult = babel.transformFileSync(sourcePath, {
44
+ // filename: sourcePath, code: false, ast: true, plugins,
45
+ // presets
46
+ // });
47
+ let fileResult = babel.transformFileSync(sourcePath, babelOptions);
48
+ if (!fileResult)
49
+ throw errors_1.errors.compileError(sourcePath);
50
+ let ast = fileResult.ast;
51
+ if (!ast)
52
+ throw errors_1.errors.compileError(sourcePath);
53
+ new ImportPathRewrite(sourcePath, ast);
54
+ let r = babel.transformFromAstSync(ast, undefined, {
55
+ filename: sourcePath, plugins: babelOptions.plugins,
56
+ presets: babelOptions.presets, sourceMaps: true
57
+ });
58
+ if (!r || r.code == null)
59
+ throw errors_1.errors.compileError(sourcePath);
60
+ let ext = extname(sourcePath);
61
+ let outExt = fileOutExt(sourcePath);
62
+ let targetPath = path.join(outDir, path.basename(sourcePath).replace(ext, outExt)); //sourcePath.replace(new RegExp(ext + "$"), outExt).replace(path.dirname(sourcePath), outDir);
63
+ let outDirPath = path.resolve(targetPath, "..");
64
+ if (r.map) {
65
+ r.map.file = path.basename(targetPath);
66
+ let sources = r.map.sources || [];
67
+ let sourceDir = path.dirname(sourcePath);
68
+ sources.forEach((s, i) => {
69
+ sources[i] = path.relative(outDirPath, path.join(sourceDir, s));
70
+ });
71
+ r.map.sources = sources;
72
+ let mapPath = targetPath + ".map";
73
+ if (!fs.existsSync(outDirPath))
74
+ fs.mkdirSync(outDirPath, { recursive: true });
75
+ fs.writeFileSync(mapPath, JSON.stringify(r.map));
76
+ r.code += `\n//babel file path = ${bablePath}`;
77
+ r.code += "\n//# sourceMappingURL=" + path.basename(mapPath);
78
+ }
79
+ if (!fs.existsSync(outDirPath))
80
+ fs.mkdirSync(outDirPath, { recursive: true });
81
+ fs.writeFileSync(targetPath, r.code);
82
+ }
83
+ exports.compileFile = compileFile;
84
+ function extname(file) {
85
+ // let ext = /\.[a-zA-Z]+/.exec(file)?.[0] || '';
86
+ let ext = path.extname(file);
87
+ return ext;
88
+ }
89
+ /**
90
+ * 获取源文件所对应生成文件的扩展名
91
+ * @param file 源文件名
92
+ * */
93
+ function fileOutExt(file) {
94
+ let ext = extname(file);
95
+ if (ext === ".ts")
96
+ return outExt;
97
+ if (ext === ".tsx")
98
+ return outExt;
99
+ return ext;
100
+ }
101
+ class ImportPathRewrite {
102
+ filePath;
103
+ constructor(filePath, node) {
104
+ this.filePath = filePath;
105
+ this.traverse(node);
106
+ }
107
+ traverse(node) {
108
+ switch (node.type) {
109
+ case "Program":
110
+ node.body.forEach(c => this.traverse(c));
111
+ break;
112
+ case "File":
113
+ this.traverse(node.program);
114
+ break;
115
+ case "ImportDeclaration":
116
+ if (node.source.type === "StringLiteral" && node.source.value.startsWith(".")) {
117
+ let ext = extname(node.source.value);
118
+ if (ext != outExt) {
119
+ let dir = path.dirname(this.filePath);
120
+ let fullPath = path.join(dir, node.source.value);
121
+ console.log(`ImportDeclaration: ${fullPath} -> ${ext}`);
122
+ if (fs.existsSync(fullPath) && fs.statSync(fullPath).isDirectory()) {
123
+ node.source.value = node.source.value + "/index";
124
+ }
125
+ node.source.value += outExt;
126
+ }
127
+ }
128
+ break;
129
+ }
130
+ }
131
+ }
@@ -0,0 +1,6 @@
1
+ /** 将 sourceDir 目录下所有文件生成到 outDir */
2
+ export declare function generateCode(sourceDir: string, outDir: string, projectPath?: string): void;
3
+ /** 监听 sourceRoot 目录下所有文件变化,并生成到 outRoot */
4
+ export declare function watchDirectory(sourceRoot: string, outRoot: string, projectPath?: string): void;
5
+ export declare function copyFile(filePath: string, outDir: string): void;
6
+ export declare function isIgnoredFile(filePath: string): boolean;
@@ -0,0 +1,83 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isIgnoredFile = exports.copyFile = exports.watchDirectory = exports.generateCode = void 0;
4
+ const fs = require("fs");
5
+ const node_watch_1 = require("node-watch");
6
+ const path = require("path");
7
+ const errors_1 = require("./errors");
8
+ const biel_compile_1 = require("./compile/biel-compile");
9
+ const skipFiles = ["\\S+\\.d\\.tsx?$", "\\S+\\.test\\.tsx?$", "\\S+\\.spec\\.tsx?$"];
10
+ const outExt = ".js";
11
+ let fileActions = {
12
+ ".ts": biel_compile_1.compileFile,
13
+ ".tsx": biel_compile_1.compileFile,
14
+ };
15
+ /** 将 sourceDir 目录下所有文件生成到 outDir */
16
+ function generateCode(sourceDir, outDir, projectPath) {
17
+ if (!sourceDir)
18
+ throw errors_1.errors.argumentNull("sourceDir");
19
+ if (!outDir)
20
+ throw errors_1.errors.argumentNull("outDir");
21
+ if (!fs.existsSync(sourceDir))
22
+ throw errors_1.errors.pathNotExists(sourceDir);
23
+ let files = fs.readdirSync(sourceDir);
24
+ for (let file of files) {
25
+ let filePath = path.join(sourceDir, file);
26
+ if (!fs.statSync(filePath).isFile()) {
27
+ continue;
28
+ }
29
+ let isSkip = isIgnoredFile(filePath); //skipFiles.some(pattern => new RegExp(pattern).test(filePath));
30
+ if (isSkip) {
31
+ console.log(`Skip ${filePath}`);
32
+ continue;
33
+ }
34
+ let ext = extname(file);
35
+ let action = fileActions[ext];
36
+ if (action) {
37
+ action(filePath, outDir, projectPath);
38
+ }
39
+ }
40
+ let dirs = fs.readdirSync(sourceDir);
41
+ for (let dir of dirs) {
42
+ let fullPath = path.join(sourceDir, dir);
43
+ let outDirPath = path.join(outDir, dir);
44
+ if (fs.statSync(fullPath).isDirectory()) {
45
+ generateCode(fullPath, outDirPath, projectPath);
46
+ }
47
+ }
48
+ }
49
+ exports.generateCode = generateCode;
50
+ /** 监听 sourceRoot 目录下所有文件变化,并生成到 outRoot */
51
+ function watchDirectory(sourceRoot, outRoot, projectPath) {
52
+ (0, node_watch_1.default)(sourceRoot, { recursive: true }, async (evt, name) => {
53
+ let action = fileActions[extname(name)];
54
+ let outPath = path.dirname(name).replace(sourceRoot, outRoot);
55
+ if (action) {
56
+ action(name, outPath, projectPath);
57
+ }
58
+ });
59
+ }
60
+ exports.watchDirectory = watchDirectory;
61
+ function copyFile(filePath, outDir) {
62
+ if (!filePath)
63
+ throw errors_1.errors.argumentNull("filePath");
64
+ if (!outDir)
65
+ throw errors_1.errors.argumentNull("outDir");
66
+ let out = filePath.replace(path.dirname(filePath), outDir);
67
+ let outDirPath = path.resolve(out, "..");
68
+ fs.mkdirSync(outDirPath, { recursive: true });
69
+ fs.copyFileSync(filePath, out);
70
+ }
71
+ exports.copyFile = copyFile;
72
+ function isIgnoredFile(filePath) {
73
+ if (!filePath)
74
+ throw errors_1.errors.argumentNull("filePath");
75
+ let isSkip = skipFiles.some(pattern => new RegExp(pattern).test(filePath));
76
+ return isSkip;
77
+ }
78
+ exports.isIgnoredFile = isIgnoredFile;
79
+ function extname(file) {
80
+ // let ext = /\.[a-zA-Z]+/.exec(file)?.[0] || '';
81
+ let ext = path.extname(file);
82
+ return ext;
83
+ }
@@ -0,0 +1,9 @@
1
+ import { Errors as BaseErrors } from "maishu-toolkit/out/errors";
2
+ declare class Errors extends BaseErrors {
3
+ compileError(filePath: string): Error;
4
+ pathNotExists(path: string): Error;
5
+ notAbsolutePath(path: string): Error;
6
+ invalidBabelConfigExtension(extension: string, configPath: string): Error;
7
+ }
8
+ export declare const errors: Errors;
9
+ export {};
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.errors = void 0;
4
+ const errors_1 = require("maishu-toolkit/out/errors");
5
+ class Errors extends errors_1.Errors {
6
+ compileError(filePath) {
7
+ let error = new Error(`Compile error in file: ${filePath}`);
8
+ error.name = Errors.prototype.compileError.name;
9
+ return error;
10
+ }
11
+ pathNotExists(path) {
12
+ let error = new Error(`Path not exists: ${path}`);
13
+ error.name = Errors.prototype.pathNotExists.name;
14
+ return error;
15
+ }
16
+ notAbsolutePath(path) {
17
+ let error = new Error(`Path is not absolute: ${path}`);
18
+ error.name = Errors.prototype.notAbsolutePath.name;
19
+ return error;
20
+ }
21
+ invalidBabelConfigExtension(extension, configPath) {
22
+ let error = new Error(`Invalid babel config file extension: ${extension}, babel config file path: ${configPath}.`);
23
+ error.name = Errors.prototype.invalidBabelConfigExtension.name;
24
+ return error;
25
+ }
26
+ }
27
+ exports.errors = new Errors();
@@ -0,0 +1,7 @@
1
+ export declare class ImportPathRewrite {
2
+ private filePath;
3
+ private outExt;
4
+ constructor(filePath: string, node: babel.types.File, outExt: string);
5
+ private traverse;
6
+ private extname;
7
+ }
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ImportPathRewrite = void 0;
4
+ const path = require("path");
5
+ const fs = require("fs");
6
+ // const outExt = ".js";
7
+ class ImportPathRewrite {
8
+ filePath;
9
+ outExt;
10
+ constructor(filePath, node, outExt) {
11
+ this.filePath = filePath;
12
+ this.outExt = outExt;
13
+ this.traverse(node);
14
+ }
15
+ traverse(node) {
16
+ switch (node.type) {
17
+ case "Program":
18
+ node.body.forEach(c => this.traverse(c));
19
+ break;
20
+ case "File":
21
+ this.traverse(node.program);
22
+ break;
23
+ case "ImportDeclaration":
24
+ if (node.source.type === "StringLiteral" && node.source.value.startsWith(".")) {
25
+ let ext = this.extname(node.source.value);
26
+ if (ext != this.outExt) {
27
+ let dir = path.dirname(this.filePath);
28
+ let fullPath = path.join(dir, node.source.value);
29
+ console.log(`ImportDeclaration: ${fullPath} -> ${ext}`);
30
+ if (fs.existsSync(fullPath) && fs.statSync(fullPath).isDirectory()) {
31
+ node.source.value = node.source.value + "/index";
32
+ }
33
+ node.source.value += this.outExt;
34
+ }
35
+ }
36
+ break;
37
+ }
38
+ }
39
+ extname(file) {
40
+ // let ext = /\.[a-zA-Z]+/.exec(file)?.[0] || '';
41
+ let ext = path.extname(file);
42
+ return ext;
43
+ }
44
+ }
45
+ exports.ImportPathRewrite = ImportPathRewrite;
@@ -0,0 +1,34 @@
1
+ import * as babel from "@babel/core";
2
+ export declare class ProjectCompiler {
3
+ private projectPath;
4
+ private sourceDirectoryNanme;
5
+ private outputDirectoryName;
6
+ private fileActions;
7
+ private skipFiles;
8
+ static tsOutExt: string;
9
+ constructor(projectPath: string, sourceDirectoryNanme: string, outputDirectoryName: string);
10
+ /**
11
+ * 编译特定文件,并生成到制定目录
12
+ * @param sourcePath 源文件路径
13
+ * @param outDir 输出目录
14
+ * */
15
+ compileFile(filePath: string, outDir: string): Promise<void>;
16
+ private compileTypeScriptFileByBabel;
17
+ static loadBabelConfig(configPath: string): babel.TransformOptions;
18
+ static findBabelConfigPath(projectPath: string, directoryPath: string): string | null;
19
+ static getBabelConfig(projectPath: string, directoryPath: string): {
20
+ options: babel.TransformOptions;
21
+ path: string;
22
+ };
23
+ static getDefaultBabelConfig(): babel.TransformOptions;
24
+ /**
25
+ * 获取源文件所对应生成文件的扩展名
26
+ * @param file 源文件名
27
+ * */
28
+ private fileOutExt;
29
+ private isIgnoredFile;
30
+ generateCode(): void;
31
+ generateCode(sourceDir: string, outDir: string): void;
32
+ watchDirectory(): void;
33
+ run(): void;
34
+ }
@@ -0,0 +1,229 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ProjectCompiler = void 0;
4
+ const nodemon = require("nodemon");
5
+ const errors_1 = require("./errors");
6
+ const fs = require("fs");
7
+ const path = require("path");
8
+ const babel = require("@babel/core");
9
+ const import_path_rewrite_1 = require("./import-path-rewrite");
10
+ const node_watch_1 = require("node-watch");
11
+ const tsOutExt = ".js";
12
+ class ProjectCompiler {
13
+ projectPath;
14
+ sourceDirectoryNanme;
15
+ outputDirectoryName;
16
+ fileActions;
17
+ skipFiles = ["\\S+\\.d\\.tsx?$", "\\S+\\.test\\.tsx?$", "\\S+\\.spec\\.tsx?$"];
18
+ static tsOutExt = tsOutExt;
19
+ constructor(projectPath, sourceDirectoryNanme, outputDirectoryName) {
20
+ this.projectPath = projectPath;
21
+ this.sourceDirectoryNanme = sourceDirectoryNanme;
22
+ this.outputDirectoryName = outputDirectoryName;
23
+ if (!projectPath)
24
+ throw errors_1.errors.argumentNull("projectPath");
25
+ if (!sourceDirectoryNanme)
26
+ throw errors_1.errors.argumentNull("sourceDirectoryNanme");
27
+ if (!outputDirectoryName)
28
+ throw errors_1.errors.argumentNull("outputDirectoryName");
29
+ if (!path.isAbsolute(projectPath))
30
+ throw errors_1.errors.notAbsolutePath(projectPath);
31
+ let sourcePath = path.join(projectPath, sourceDirectoryNanme);
32
+ if (!fs.existsSync(sourcePath))
33
+ throw errors_1.errors.pathNotExists(sourcePath);
34
+ this.fileActions = {
35
+ ".ts": this.compileFile.bind(this),
36
+ ".tsx": this.compileFile.bind(this),
37
+ };
38
+ }
39
+ /**
40
+ * 编译特定文件,并生成到制定目录
41
+ * @param sourcePath 源文件路径
42
+ * @param outDir 输出目录
43
+ * */
44
+ async compileFile(filePath, outDir) {
45
+ this.compileTypeScriptFileByBabel(filePath, outDir);
46
+ }
47
+ async compileTypeScriptFileByBabel(sourcePath, outDir) {
48
+ if (!sourcePath)
49
+ throw errors_1.errors.argumentNull("sourcePath");
50
+ if (!outDir)
51
+ throw errors_1.errors.argumentNull("outDir");
52
+ if (!fs.existsSync(sourcePath))
53
+ throw errors_1.errors.pathNotExists(sourcePath);
54
+ let sourceDir = path.dirname(sourcePath);
55
+ let babelConfig = ProjectCompiler.getBabelConfig(this.projectPath, sourceDir);
56
+ let babelOptions = babelConfig.options;
57
+ let babelPath = babelConfig.path;
58
+ babelOptions.filename = sourcePath;
59
+ babelOptions.code = false;
60
+ babelOptions.ast = true;
61
+ let fileResult = babel.transformFileSync(sourcePath, babelOptions);
62
+ if (!fileResult)
63
+ throw errors_1.errors.compileError(sourcePath);
64
+ let ast = fileResult.ast;
65
+ if (!ast)
66
+ throw errors_1.errors.compileError(sourcePath);
67
+ new import_path_rewrite_1.ImportPathRewrite(sourcePath, ast, tsOutExt);
68
+ let r = babel.transformFromAstSync(ast, undefined, {
69
+ filename: sourcePath, plugins: babelOptions.plugins,
70
+ presets: babelOptions.presets, sourceMaps: true
71
+ });
72
+ if (!r || r.code == null)
73
+ throw errors_1.errors.compileError(sourcePath);
74
+ let ext = path.extname(sourcePath);
75
+ let outExt = this.fileOutExt(sourcePath);
76
+ let targetPath = path.join(outDir, path.basename(sourcePath).replace(ext, outExt));
77
+ let outDirPath = path.resolve(targetPath, "..");
78
+ if (r.map) {
79
+ r.map.file = path.basename(targetPath);
80
+ let sources = r.map.sources || [];
81
+ let sourceDir = path.dirname(sourcePath);
82
+ sources.forEach((s, i) => {
83
+ sources[i] = path.relative(outDirPath, path.join(sourceDir, s));
84
+ });
85
+ r.map.sources = sources;
86
+ let mapPath = targetPath + ".map";
87
+ if (!fs.existsSync(outDirPath))
88
+ fs.mkdirSync(outDirPath, { recursive: true });
89
+ fs.writeFileSync(mapPath, JSON.stringify(r.map));
90
+ r.code += `\n//babelPath:${babelPath}`;
91
+ r.code += "\n//# sourceMappingURL=" + path.basename(mapPath);
92
+ }
93
+ if (!fs.existsSync(outDirPath))
94
+ fs.mkdirSync(outDirPath, { recursive: true });
95
+ fs.writeFileSync(targetPath, r.code);
96
+ }
97
+ static loadBabelConfig(configPath) {
98
+ if (!configPath)
99
+ throw errors_1.errors.argumentNull("configPath");
100
+ if (!fs.existsSync(configPath))
101
+ throw errors_1.errors.pathNotExists(configPath);
102
+ let ext = path.extname(configPath);
103
+ if (ext === ".json") {
104
+ let content = fs.readFileSync(configPath, "utf-8");
105
+ return JSON.parse(content);
106
+ }
107
+ if (ext === ".js") {
108
+ let module = require(configPath);
109
+ let config = Object.assign({}, module.default || module);
110
+ return config;
111
+ }
112
+ throw errors_1.errors.invalidBabelConfigExtension(ext, configPath);
113
+ }
114
+ static findBabelConfigPath(projectPath, directoryPath) {
115
+ if (!path.isAbsolute(directoryPath)) {
116
+ directoryPath = path.join(projectPath, directoryPath);
117
+ }
118
+ console.assert(path.isAbsolute(projectPath), `projectPath ${projectPath} is not absolute`);
119
+ console.assert(path.isAbsolute(directoryPath), `directoryPath ${directoryPath} is not absolute`);
120
+ let jsonConfigPath = path.join(directoryPath, "babel.config.json");
121
+ let jsConfigPath = path.join(directoryPath, "babel.config.js");
122
+ if (fs.existsSync(jsConfigPath)) {
123
+ return jsConfigPath;
124
+ }
125
+ if (fs.existsSync(jsonConfigPath)) {
126
+ return jsonConfigPath;
127
+ }
128
+ if (projectPath == directoryPath)
129
+ return null;
130
+ let parentPath = path.resolve(directoryPath, "..");
131
+ return this.findBabelConfigPath(projectPath, parentPath);
132
+ }
133
+ static getBabelConfig(projectPath, directoryPath) {
134
+ let configPath = this.findBabelConfigPath(projectPath, directoryPath);
135
+ let babelOptions;
136
+ if (configPath) {
137
+ babelOptions = this.loadBabelConfig(configPath);
138
+ }
139
+ else {
140
+ babelOptions = this.getDefaultBabelConfig();
141
+ }
142
+ babelOptions.ast = true;
143
+ babelOptions.code = false;
144
+ return { options: babelOptions, path: configPath || '' };
145
+ }
146
+ static getDefaultBabelConfig() {
147
+ let plugins = [
148
+ "babel-plugin-transform-typescript-metadata",
149
+ ["@babel/plugin-proposal-decorators", { legacy: true }],
150
+ ["@babel/plugin-transform-typescript", { isTSX: true }],
151
+ ["@babel/plugin-transform-react-jsx", { "pragma": "React.createElement", "pragmaFrag": "React.Fragment" }],
152
+ ];
153
+ let presets = [
154
+ ['@babel/preset-env', { targets: { node: 'current' } }],
155
+ ];
156
+ let babelOptions = { plugins, presets };
157
+ return babelOptions;
158
+ }
159
+ /**
160
+ * 获取源文件所对应生成文件的扩展名
161
+ * @param file 源文件名
162
+ * */
163
+ fileOutExt(file) {
164
+ let ext = path.extname(file);
165
+ if (ext === ".ts")
166
+ return tsOutExt;
167
+ if (ext === ".tsx")
168
+ return tsOutExt;
169
+ return ext;
170
+ }
171
+ isIgnoredFile(filePath) {
172
+ if (!filePath)
173
+ throw errors_1.errors.argumentNull("filePath");
174
+ let isSkip = this.skipFiles.some(pattern => new RegExp(pattern).test(filePath));
175
+ return isSkip;
176
+ }
177
+ generateCode(sourceDir, outDir) {
178
+ // if (!sourceDir) throw errors.argumentNull("sourceDir");
179
+ // if (!outDir) throw errors.argumentNull("outDir");
180
+ if (!sourceDir)
181
+ sourceDir = path.join(this.projectPath, this.sourceDirectoryNanme);
182
+ if (!outDir)
183
+ outDir = path.join(this.projectPath, this.outputDirectoryName);
184
+ let fileActions = this.fileActions;
185
+ if (!fs.existsSync(sourceDir))
186
+ throw errors_1.errors.pathNotExists(sourceDir);
187
+ let files = fs.readdirSync(sourceDir);
188
+ for (let file of files) {
189
+ let filePath = path.join(sourceDir, file);
190
+ if (!fs.statSync(filePath).isFile()) {
191
+ continue;
192
+ }
193
+ let isSkip = this.isIgnoredFile(filePath); //skipFiles.some(pattern => new RegExp(pattern).test(filePath));
194
+ if (isSkip) {
195
+ console.log(`Skip ${filePath}`);
196
+ continue;
197
+ }
198
+ let ext = path.extname(file);
199
+ let action = fileActions[ext];
200
+ if (action) {
201
+ action(filePath, outDir);
202
+ }
203
+ }
204
+ let dirs = fs.readdirSync(sourceDir);
205
+ for (let dir of dirs) {
206
+ let fullPath = path.join(sourceDir, dir);
207
+ let outDirPath = path.join(outDir, dir);
208
+ if (fs.statSync(fullPath).isDirectory()) {
209
+ this.generateCode(fullPath, outDirPath);
210
+ }
211
+ }
212
+ }
213
+ watchDirectory() {
214
+ (0, node_watch_1.default)(this.sourceDirectoryNanme, { recursive: true }, async (evt, name) => {
215
+ let action = this.fileActions[path.extname(name)];
216
+ let outPath = path.dirname(name).replace(this.sourceDirectoryNanme, this.outputDirectoryName);
217
+ if (action) {
218
+ action(name, outPath);
219
+ }
220
+ });
221
+ }
222
+ run() {
223
+ nodemon({
224
+ script: `./${this.outputDirectoryName}/main.js`,
225
+ watch: [`./${this.outputDirectoryName}/`],
226
+ });
227
+ }
228
+ }
229
+ exports.ProjectCompiler = ProjectCompiler;
@@ -0,0 +1 @@
1
+ export declare function run(): void;
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.run = void 0;
4
+ const nodemon = require("nodemon");
5
+ function run() {
6
+ nodemon({
7
+ script: "./out/main.js",
8
+ watch: ["./out/"],
9
+ });
10
+ }
11
+ exports.run = run;
package/out/start.d.ts ADDED
@@ -0,0 +1 @@
1
+ export {};
package/out/start.js ADDED
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const compile_1 = require("./modules/compile");
4
+ const run_1 = require("./modules/run");
5
+ let sourceDir = "src";
6
+ let outDir = "out";
7
+ (0, compile_1.generateCode)(sourceDir, outDir);
8
+ (0, compile_1.watchDirectory)(sourceDir, outDir);
9
+ (0, run_1.run)();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "maishu-scripts",
3
- "version": "1.0.0",
3
+ "version": "1.1.2",
4
4
  "description": "用于对 node 项目进行代码生成,打包,运行",
5
5
  "dependencies": {
6
6
  "@babel/core": "^7.24.3",
@@ -20,5 +20,10 @@
20
20
  "@types/babel__core": "^7.20.5",
21
21
  "@types/jest": "^29.5.12",
22
22
  "jest": "^29.7.0"
23
- }
24
- }
23
+ },
24
+ "main": "./out/index.js",
25
+ "files": [
26
+ "out",
27
+ "src"
28
+ ]
29
+ }
@@ -1,5 +1,5 @@
1
1
  export { generateCode, watchDirectory } from "./modules/compile";
2
-
2
+ export { run } from "./modules/run";
3
3
  // let sourceDir = "src";
4
4
  // let outDir = "out";
5
5
  // generateCode(sourceDir, outDir);
@@ -1,73 +1,17 @@
1
+
1
2
  import * as babel from "@babel/core";
2
3
  import * as fs from "fs";
3
- import watch from "node-watch";
4
4
  import * as path from "path";
5
- import { errors } from "./errors";
6
- import { ProjectCompiler } from "./project-compiler";
7
-
8
- const skipFiles = ["\\S+\\.d\\.tsx?$", "\\S+\\.test\\.tsx?$", "\\S+\\.spec\\.tsx?$"]
9
- const outExt = ".js";
10
-
11
- type FileAction = (filePath: string, outDir: string, projectPath?: string) => void;
12
- let fileActions: { [ext: string]: FileAction } = {
13
- ".ts": compileFile,
14
- ".tsx": compileFile,
15
- }
16
-
17
- /** 将 sourceDir 目录下所有文件生成到 outDir */
18
- export function generateCode(sourceDir: string, outDir: string, projectPath?: string) {
19
-
20
- if (!sourceDir) throw errors.argumentNull("sourceDir");
21
- if (!outDir) throw errors.argumentNull("outDir");
22
-
23
- if (!fs.existsSync(sourceDir))
24
- throw errors.pathNotExists(sourceDir);
25
-
26
- let files = fs.readdirSync(sourceDir);
27
- for (let file of files) {
28
- let filePath = path.join(sourceDir, file);
29
- if (!fs.statSync(filePath).isFile()) {
30
- continue;
31
- }
32
-
33
- let isSkip = isIgnoredFile(filePath);//skipFiles.some(pattern => new RegExp(pattern).test(filePath));
34
- if (isSkip) {
35
- console.log(`Skip ${filePath}`);
36
- continue;
37
- }
38
-
39
- let ext = extname(file);
40
- let action = fileActions[ext];
41
- if (action) {
42
- action(filePath, outDir, projectPath);
43
- }
44
- }
45
-
46
- let dirs = fs.readdirSync(sourceDir);
47
- for (let dir of dirs) {
48
- let fullPath = path.join(sourceDir, dir);
49
- let outDirPath = path.join(outDir, dir);
50
- if (fs.statSync(fullPath).isDirectory()) {
51
- generateCode(fullPath, outDirPath, projectPath);
52
- }
53
- }
54
- }
5
+ import { errors } from "../errors";
6
+ import { ProjectCompiler } from "../project-compiler";
55
7
 
56
- /** 监听 sourceRoot 目录下所有文件变化,并生成到 outRoot */
57
- export function watchDirectory(sourceRoot: string, outRoot: string, projectPath?: string) {
58
- watch(sourceRoot, { recursive: true }, async (evt, name) => {
59
- let action = fileActions[extname(name)];
60
- let outPath = path.dirname(name).replace(sourceRoot, outRoot);
61
- if (action) {
62
- action(name, outPath, projectPath);
63
- }
64
- })
65
- }
8
+ const outExt = ProjectCompiler.tsOutExt;
66
9
 
67
10
  /**
68
11
  * 编译特定文件,并生成到制定目录
69
12
  * @param sourcePath 源文件路径
70
13
  * @param outDir 输出目录
14
+ * @param projectPath 项目路径
71
15
  * */
72
16
  export async function compileFile(sourcePath: string, outDir: string, projectPath?: string) {
73
17
  if (!sourcePath) throw errors.argumentNull("sourcePath");
@@ -147,25 +91,6 @@ export async function compileFile(sourcePath: string, outDir: string, projectPat
147
91
 
148
92
  }
149
93
 
150
- export function copyFile(filePath: string, outDir: string) {
151
- if (!filePath) throw errors.argumentNull("filePath");
152
- if (!outDir) throw errors.argumentNull("outDir");
153
-
154
- let out = filePath.replace(path.dirname(filePath), outDir);
155
- let outDirPath = path.resolve(out, "..");
156
-
157
- fs.mkdirSync(outDirPath, { recursive: true });
158
-
159
- fs.copyFileSync(filePath, out);
160
- }
161
-
162
- export function isIgnoredFile(filePath: string) {
163
- if (!filePath) throw errors.argumentNull("filePath");
164
-
165
- let isSkip = skipFiles.some(pattern => new RegExp(pattern).test(filePath));
166
- return isSkip;
167
- }
168
-
169
94
  function extname(file: string) {
170
95
  // let ext = /\.[a-zA-Z]+/.exec(file)?.[0] || '';
171
96
  let ext = path.extname(file);
@@ -187,6 +112,7 @@ function fileOutExt(file: string) {
187
112
  return ext;
188
113
  }
189
114
 
115
+
190
116
  class ImportPathRewrite {
191
117
  constructor(private filePath: string, node: babel.types.File) {
192
118
  this.traverse(node);
@@ -218,4 +144,4 @@ class ImportPathRewrite {
218
144
  }
219
145
  }
220
146
 
221
- }
147
+ }
@@ -1,7 +1,7 @@
1
1
  import { copyFile, generateCode, isIgnoredFile } from "./compile";
2
2
  import * as path from "path";
3
3
  import * as fs from "fs";
4
- import ts from "typescript";
4
+ import * as ts from "typescript";
5
5
 
6
6
  describe("Compile Test", function () {
7
7
 
@@ -0,0 +1,92 @@
1
+ import * as babel from "@babel/core";
2
+ import * as fs from "fs";
3
+ import watch from "node-watch";
4
+ import * as path from "path";
5
+ import { errors } from "./errors";
6
+ import { ProjectCompiler } from "./project-compiler";
7
+ import { compileFile as bielCompileFile } from "./compile/biel-compile";
8
+
9
+ const skipFiles = ["\\S+\\.d\\.tsx?$", "\\S+\\.test\\.tsx?$", "\\S+\\.spec\\.tsx?$"]
10
+ const outExt = ".js";
11
+
12
+ type FileAction = (filePath: string, outDir: string, projectPath?: string) => void;
13
+ let fileActions: { [ext: string]: FileAction } = {
14
+ ".ts": bielCompileFile,
15
+ ".tsx": bielCompileFile,
16
+ }
17
+
18
+ /** 将 sourceDir 目录下所有文件生成到 outDir */
19
+ export function generateCode(sourceDir: string, outDir: string, projectPath?: string) {
20
+
21
+ if (!sourceDir) throw errors.argumentNull("sourceDir");
22
+ if (!outDir) throw errors.argumentNull("outDir");
23
+
24
+ if (!fs.existsSync(sourceDir))
25
+ throw errors.pathNotExists(sourceDir);
26
+
27
+ let files = fs.readdirSync(sourceDir);
28
+ for (let file of files) {
29
+ let filePath = path.join(sourceDir, file);
30
+ if (!fs.statSync(filePath).isFile()) {
31
+ continue;
32
+ }
33
+
34
+ let isSkip = isIgnoredFile(filePath);//skipFiles.some(pattern => new RegExp(pattern).test(filePath));
35
+ if (isSkip) {
36
+ console.log(`Skip ${filePath}`);
37
+ continue;
38
+ }
39
+
40
+ let ext = extname(file);
41
+ let action = fileActions[ext];
42
+ if (action) {
43
+ action(filePath, outDir, projectPath);
44
+ }
45
+ }
46
+
47
+ let dirs = fs.readdirSync(sourceDir);
48
+ for (let dir of dirs) {
49
+ let fullPath = path.join(sourceDir, dir);
50
+ let outDirPath = path.join(outDir, dir);
51
+ if (fs.statSync(fullPath).isDirectory()) {
52
+ generateCode(fullPath, outDirPath, projectPath);
53
+ }
54
+ }
55
+ }
56
+
57
+ /** 监听 sourceRoot 目录下所有文件变化,并生成到 outRoot */
58
+ export function watchDirectory(sourceRoot: string, outRoot: string, projectPath?: string) {
59
+ watch(sourceRoot, { recursive: true }, async (evt, name) => {
60
+ let action = fileActions[extname(name)];
61
+ let outPath = path.dirname(name).replace(sourceRoot, outRoot);
62
+ if (action) {
63
+ action(name, outPath, projectPath);
64
+ }
65
+ })
66
+ }
67
+
68
+ export function copyFile(filePath: string, outDir: string) {
69
+ if (!filePath) throw errors.argumentNull("filePath");
70
+ if (!outDir) throw errors.argumentNull("outDir");
71
+
72
+ let out = filePath.replace(path.dirname(filePath), outDir);
73
+ let outDirPath = path.resolve(out, "..");
74
+
75
+ fs.mkdirSync(outDirPath, { recursive: true });
76
+
77
+ fs.copyFileSync(filePath, out);
78
+ }
79
+
80
+ export function isIgnoredFile(filePath: string) {
81
+ if (!filePath) throw errors.argumentNull("filePath");
82
+
83
+ let isSkip = skipFiles.some(pattern => new RegExp(pattern).test(filePath));
84
+ return isSkip;
85
+ }
86
+
87
+ function extname(file: string) {
88
+ // let ext = /\.[a-zA-Z]+/.exec(file)?.[0] || '';
89
+ let ext = path.extname(file);
90
+ return ext;
91
+ }
92
+
@@ -1,5 +1,5 @@
1
- import path from "path";
2
- import fs from "fs";
1
+ import * as path from "path";
2
+ import * as fs from "fs";
3
3
  import { ProjectCompiler } from "./project-compiler";
4
4
  describe('project-compiler test', function () {
5
5
 
@@ -15,6 +15,8 @@ export class ProjectCompiler {
15
15
  private fileActions: { [ext: string]: FileAction };
16
16
  private skipFiles = ["\\S+\\.d\\.tsx?$", "\\S+\\.test\\.tsx?$", "\\S+\\.spec\\.tsx?$"];
17
17
 
18
+ static tsOutExt = tsOutExt;
19
+
18
20
  constructor(private projectPath: string, private sourceDirectoryNanme: string, private outputDirectoryName: string) {
19
21
  if (!projectPath) throw errors.argumentNull("projectPath");
20
22
  if (!sourceDirectoryNanme) throw errors.argumentNull("sourceDirectoryNanme");
package/babel.config.js DELETED
@@ -1,6 +0,0 @@
1
- module.exports = {
2
- presets: [
3
- ['@babel/preset-env', { targets: { node: 'current' } }],
4
- '@babel/preset-typescript',
5
- ],
6
- };
package/test/package.json DELETED
@@ -1,7 +0,0 @@
1
- {
2
- "name": "test-src",
3
- "devDependencies": {
4
- "@nestjs/common": "^10.3.7",
5
- "express": "^4.19.2"
6
- }
7
- }
@@ -1,14 +0,0 @@
1
- import { Controller, Get } from '@nestjs/common';
2
- import { AppService } from './app.service';
3
-
4
- @Controller()
5
- export class AppController {
6
- constructor(private readonly appService: AppService) {}
7
-
8
- @Get()
9
- getHello(): string {
10
- return this.appService.getHello();
11
- }
12
-
13
-
14
- }
@@ -1,17 +0,0 @@
1
- import { MiddlewareConsumer, Module, NestModule, RequestMethod } from '@nestjs/common';
2
- import { AppController } from './app.controller';
3
- import { AppService } from './app.service';
4
- import { ProxyMiddleware } from './middleware/proxy';
5
- import { ProxyController } from './controllers/proxy';
6
-
7
- @Module({
8
- imports: [],
9
- controllers: [AppController],
10
- providers: [AppService],
11
- })
12
- export class AppModule implements NestModule {
13
- configure(consumer: MiddlewareConsumer) {
14
- consumer.apply(ProxyMiddleware)
15
- .forRoutes({ path: "proxy/*", method: RequestMethod.GET });
16
- }
17
- }
@@ -1,8 +0,0 @@
1
- import { Injectable } from '@nestjs/common';
2
-
3
- @Injectable()
4
- export class AppService {
5
- getHello(): string {
6
- return 'Hello World!';
7
- }
8
- }
@@ -1,16 +0,0 @@
1
- //const config = require("../config.js").default as Config;
2
- import config from "../config.mjs";
3
-
4
- export interface Config {
5
- plmUrl: string,
6
- }
7
-
8
- // TODO: 校验配置项是否正确
9
- if (!config || !config.plmUrl)
10
- throw new Error("plmUrl is required in config.js");
11
-
12
-
13
-
14
- export function getConfig(): Config {
15
- return config;
16
- }
@@ -1,13 +0,0 @@
1
- import { Controller, Get } from '@nestjs/common';
2
-
3
- @Controller("proxy")
4
- export class ProxyController {
5
- constructor() {
6
-
7
- }
8
-
9
- @Get("*")
10
- create(): string {
11
- return 'tc api proxy';
12
- }
13
- }
package/test/src/main.ts DELETED
@@ -1,8 +0,0 @@
1
- import { NestFactory } from '@nestjs/core';
2
- import { AppModule } from './app.module';
3
-
4
- async function bootstrap() {
5
- const app = await NestFactory.create(AppModule);
6
- await app.listen(3000);
7
- }
8
- bootstrap();
@@ -1,36 +0,0 @@
1
- import { Request, Response, NextFunction } from 'express';
2
- import { get, request } from 'http';
3
- import { getConfig } from '../config';
4
-
5
- let config = getConfig();
6
- export class ProxyMiddleware {
7
- constructor() { }
8
-
9
- static rootPath = '/proxy/';
10
-
11
- async use(req: Request, res: Response, next: NextFunction) {
12
- const { url, headers, method, body } = req;
13
-
14
- let targetUrl = url.replace(ProxyMiddleware.rootPath, '/');
15
- targetUrl = config.plmUrl + targetUrl;
16
- console.log('targetUrl', targetUrl);
17
-
18
- const options = {
19
- url: targetUrl,
20
- headers: headers,
21
- method: method,
22
- body: body
23
- };
24
-
25
- // url = url.replace(ProxyMiddleware.rootPath, '');
26
-
27
-
28
- const proxyReq = request(options, (proxyRes) => {
29
- res.writeHead(proxyRes.statusCode, proxyRes.headers);
30
- proxyRes.pipe(res);
31
- });
32
-
33
- req.pipe(proxyReq);
34
-
35
- }
36
- }
@@ -1,6 +0,0 @@
1
- {
2
- "presets": [],
3
- "plugins": [
4
- "@babel/plugin-transform-typescript"
5
- ]
6
- }
@@ -1,6 +0,0 @@
1
- module.exports = {
2
- presets: [
3
- ['@babel/preset-env', { targets: { node: 'current' } }],
4
- '@babel/preset-typescript',
5
- ],
6
- };
@@ -1,8 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "noEmit": true,
4
- "target": "ESNext",
5
- "module": "commonjs",
6
- "experimentalDecorators": true
7
- }
8
- }
File without changes
File without changes
File without changes
File without changes