@bleedingdev/modern-js-server-utils 3.2.0-ultramodern.99 → 3.4.0-ultramodern.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/common/index.js +9 -5
- package/dist/cjs/compilers/typescript/importRewriter.js +242 -0
- package/dist/cjs/compilers/typescript/index.js +109 -39
- package/dist/cjs/compilers/typescript/tsconfigPathsPlugin.js +9 -5
- package/dist/cjs/index.js +9 -5
- package/dist/esm/compilers/typescript/importRewriter.mjs +204 -0
- package/dist/esm/compilers/typescript/index.mjs +90 -33
- package/dist/esm-node/compilers/typescript/importRewriter.mjs +205 -0
- package/dist/esm-node/compilers/typescript/index.mjs +93 -33
- package/dist/types/compilers/typescript/importRewriter.d.ts +12 -0
- package/dist/types/compilers/typescript/index.d.ts +20 -0
- package/dist/types/compilers/typescript/tsconfigPathsPlugin.d.ts +1 -1
- package/package.json +15 -7
|
@@ -3,8 +3,11 @@ const require = /*#__PURE__*/ __rslib_shim_module__.createRequire(/*#__PURE__*/
|
|
|
3
3
|
import { fs, getAliasConfig, logger } from "@modern-js/utils";
|
|
4
4
|
import { spawn } from "child_process";
|
|
5
5
|
import path from "path";
|
|
6
|
+
import { rewriteImportSpecifiers } from "./importRewriter.mjs";
|
|
6
7
|
import { createTsconfigPathsMatcher, getNotAliasedPath } from "./tsconfigPathsPlugin.mjs";
|
|
7
|
-
|
|
8
|
+
import { fileURLToPath as __rspack_fileURLToPath } from "node:url";
|
|
9
|
+
import { dirname as __rspack_dirname } from "node:path";
|
|
10
|
+
var typescript_dirname = __rspack_dirname(__rspack_fileURLToPath(import.meta.url));
|
|
8
11
|
const copyFiles = async (from, to, appDirectory)=>{
|
|
9
12
|
if (await fs.pathExists(from)) {
|
|
10
13
|
const relativePath = path.relative(appDirectory, from);
|
|
@@ -17,42 +20,58 @@ const copyFiles = async (from, to, appDirectory)=>{
|
|
|
17
20
|
});
|
|
18
21
|
}
|
|
19
22
|
};
|
|
20
|
-
|
|
21
|
-
|
|
23
|
+
let resolvedConfigCount = 0;
|
|
24
|
+
const createResolvedTsgoConfig = async (appDirectory, tsconfigPath, distDir, sourceDirs, moduleType, tsgoBinPath)=>{
|
|
25
|
+
const tsconfigDir = path.dirname(tsconfigPath);
|
|
26
|
+
const output = await runTsgo(tsgoBinPath, [
|
|
22
27
|
'--showConfig',
|
|
23
28
|
'-p',
|
|
24
29
|
tsconfigPath
|
|
25
30
|
], {
|
|
26
|
-
cwd:
|
|
31
|
+
cwd: tsconfigDir
|
|
27
32
|
});
|
|
28
33
|
const config = JSON.parse(output.stdout);
|
|
29
34
|
config.compilerOptions ??= {};
|
|
30
35
|
config.compilerOptions.rootDir = appDirectory;
|
|
31
36
|
config.compilerOptions.outDir = distDir;
|
|
32
|
-
config.files = filterSourceFiles(
|
|
37
|
+
config.files = filterSourceFiles(tsconfigDir, sourceDirs, config.files);
|
|
33
38
|
delete config.include;
|
|
34
39
|
delete config.compilerOptions.baseUrl;
|
|
35
40
|
if ([
|
|
36
41
|
'node',
|
|
37
42
|
'node10'
|
|
38
43
|
].includes(String(config.compilerOptions.moduleResolution).toLowerCase())) delete config.compilerOptions.moduleResolution;
|
|
39
|
-
|
|
44
|
+
if ('module' !== moduleType) {
|
|
45
|
+
if ([
|
|
46
|
+
'preserve',
|
|
47
|
+
'esnext',
|
|
48
|
+
'es2015',
|
|
49
|
+
'es2020',
|
|
50
|
+
'es2022',
|
|
51
|
+
'es6'
|
|
52
|
+
].includes(String(config.compilerOptions.module).toLowerCase())) {
|
|
53
|
+
config.compilerOptions.module = 'commonjs';
|
|
54
|
+
delete config.compilerOptions.moduleResolution;
|
|
55
|
+
}
|
|
56
|
+
config.compilerOptions.verbatimModuleSyntax = false;
|
|
57
|
+
}
|
|
58
|
+
const resolvedConfigPath = path.join(tsconfigDir, `.tsgo.${process.pid}.${resolvedConfigCount++}.resolved.json`);
|
|
40
59
|
await fs.writeFile(resolvedConfigPath, JSON.stringify(config, null, 2));
|
|
41
60
|
return {
|
|
42
61
|
config,
|
|
43
62
|
resolvedConfigPath
|
|
44
63
|
};
|
|
45
64
|
};
|
|
46
|
-
const filterSourceFiles = (
|
|
65
|
+
const filterSourceFiles = (tsconfigDir, sourceDirs, files = [])=>{
|
|
47
66
|
const sourcePosixPaths = sourceDirs.map((sourceDir)=>sourceDir.split(path.sep).join(path.posix.sep));
|
|
48
67
|
return files.filter((fileName)=>{
|
|
49
|
-
const absoluteFileName = path.resolve(
|
|
68
|
+
const absoluteFileName = path.resolve(tsconfigDir, fileName).split(path.sep).join(path.posix.sep);
|
|
50
69
|
return fileName.endsWith('.d.ts') || sourcePosixPaths.some((sourceDir)=>absoluteFileName.includes(sourceDir));
|
|
51
70
|
});
|
|
52
71
|
};
|
|
53
|
-
const runTsgo = (args, options)=>new Promise((resolve, reject)=>{
|
|
72
|
+
const runTsgo = (tsgoBinPath, args, options)=>new Promise((resolve, reject)=>{
|
|
54
73
|
const child = spawn(process.execPath, [
|
|
55
|
-
|
|
74
|
+
tsgoBinPath,
|
|
56
75
|
...args
|
|
57
76
|
], {
|
|
58
77
|
cwd: options.cwd,
|
|
@@ -81,14 +100,51 @@ const runTsgo = (args, options)=>new Promise((resolve, reject)=>{
|
|
|
81
100
|
resolve(result);
|
|
82
101
|
});
|
|
83
102
|
});
|
|
84
|
-
const getTsgoBinPath = (
|
|
103
|
+
const getTsgoBinPath = (appDirectory, resolvePaths = [
|
|
104
|
+
appDirectory,
|
|
105
|
+
typescript_dirname
|
|
106
|
+
])=>{
|
|
107
|
+
try {
|
|
108
|
+
const pkgPath = require.resolve("@typescript/native-preview/package.json", {
|
|
109
|
+
paths: resolvePaths
|
|
110
|
+
});
|
|
111
|
+
return path.join(path.dirname(pkgPath), 'bin/tsgo.js');
|
|
112
|
+
} catch {
|
|
113
|
+
throw new Error('tsgo could not be found! Please install "@typescript/native-preview" in your project to compile BFF/server code.');
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
const OUTPUT_SOURCE_EXTENSIONS = {
|
|
117
|
+
'.js': [
|
|
118
|
+
'.ts',
|
|
119
|
+
'.tsx',
|
|
120
|
+
'.js',
|
|
121
|
+
'.jsx'
|
|
122
|
+
],
|
|
123
|
+
'.mjs': [
|
|
124
|
+
'.mts',
|
|
125
|
+
'.mjs'
|
|
126
|
+
],
|
|
127
|
+
'.cjs': [
|
|
128
|
+
'.cts',
|
|
129
|
+
'.cjs'
|
|
130
|
+
]
|
|
131
|
+
};
|
|
85
132
|
const getSourceFileForOutput = (appDirectory, distDir, outputFile)=>{
|
|
86
133
|
const relativeOutput = path.relative(distDir, outputFile);
|
|
87
134
|
const parsed = path.parse(relativeOutput);
|
|
88
135
|
const sourceBase = path.join(appDirectory, parsed.dir, parsed.name);
|
|
89
|
-
|
|
136
|
+
const extensions = OUTPUT_SOURCE_EXTENSIONS[parsed.ext] ?? OUTPUT_SOURCE_EXTENSIONS['.js'];
|
|
137
|
+
for (const extension of extensions){
|
|
138
|
+
const candidate = `${sourceBase}${extension}`;
|
|
139
|
+
if (fs.existsSync(candidate)) return candidate;
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
const sourceMappingUrlRE = /^\/\/[#@] sourceMappingURL=.*$/gm;
|
|
143
|
+
const dropStaleSourceMap = async (outputFile, content)=>{
|
|
144
|
+
const mapFile = `${outputFile}.map`;
|
|
145
|
+
if (await fs.pathExists(mapFile)) await fs.remove(mapFile);
|
|
146
|
+
return content.replace(sourceMappingUrlRE, '');
|
|
90
147
|
};
|
|
91
|
-
const findExistingSource = (filePath)=>fs.existsSync(filePath) ? filePath : void 0;
|
|
92
148
|
const rewriteOutputSpecifiers = async (appDirectory, distDir, baseUrl, paths, moduleType)=>{
|
|
93
149
|
if (0 === Object.keys(paths).length || !await fs.pathExists(distDir)) return;
|
|
94
150
|
const matcher = createTsconfigPathsMatcher(baseUrl, paths);
|
|
@@ -98,14 +154,8 @@ const rewriteOutputSpecifiers = async (appDirectory, distDir, baseUrl, paths, mo
|
|
|
98
154
|
const sourceFile = getSourceFileForOutput(appDirectory, distDir, file);
|
|
99
155
|
if (!sourceFile) return;
|
|
100
156
|
const content = await fs.readFile(file, 'utf8');
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
const nextSpecifier = getNotAliasedPath(sourceFile, matcher, specifier, moduleType);
|
|
104
|
-
if (!nextSpecifier || nextSpecifier === specifier) return match;
|
|
105
|
-
changed = true;
|
|
106
|
-
return `${prefix}${nextSpecifier}${suffix}`;
|
|
107
|
-
});
|
|
108
|
-
if (changed) await fs.writeFile(file, rewritten);
|
|
157
|
+
const { content: rewritten, changed } = rewriteImportSpecifiers(content, (specifier)=>getNotAliasedPath(sourceFile, matcher, specifier, moduleType));
|
|
158
|
+
if (changed) await fs.writeFile(file, await dropStaleSourceMap(file, rewritten));
|
|
109
159
|
}));
|
|
110
160
|
};
|
|
111
161
|
const collectOutputFiles = async (dir)=>{
|
|
@@ -131,24 +181,34 @@ const compileByTs = async (appDirectory, config, compileOptions)=>{
|
|
|
131
181
|
tsconfigPath
|
|
132
182
|
});
|
|
133
183
|
const { paths = {}, absoluteBaseUrl = './' } = aliasOption;
|
|
134
|
-
const
|
|
135
|
-
const
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
184
|
+
const tsgoBinPath = getTsgoBinPath(appDirectory);
|
|
185
|
+
const { config: tsgoConfig, resolvedConfigPath } = await createResolvedTsgoConfig(appDirectory, tsconfigPath, distDir, sourceDirs, compileOptions.moduleType, tsgoBinPath);
|
|
186
|
+
let result;
|
|
187
|
+
try {
|
|
188
|
+
result = await runTsgo(tsgoBinPath, [
|
|
189
|
+
'-p',
|
|
190
|
+
resolvedConfigPath
|
|
191
|
+
], {
|
|
192
|
+
cwd: appDirectory,
|
|
193
|
+
reject: false
|
|
194
|
+
});
|
|
195
|
+
} finally{
|
|
196
|
+
await fs.remove(resolvedConfigPath);
|
|
197
|
+
}
|
|
143
198
|
if (result.stderr) logger.error(result.stderr);
|
|
144
199
|
if (result.stdout) logger.info(result.stdout);
|
|
145
200
|
if (0 !== result.code) {
|
|
146
201
|
const noEmitOnError = tsgoConfig.compilerOptions?.noEmitOnError;
|
|
147
|
-
if (void 0 === noEmitOnError || true === noEmitOnError) if (compileOptions.throwErrorInsteadOfExit)
|
|
148
|
-
|
|
202
|
+
if (void 0 === noEmitOnError || true === noEmitOnError) if (compileOptions.throwErrorInsteadOfExit) {
|
|
203
|
+
logger.error('TS-Go compilation failed');
|
|
204
|
+
throw new Error([
|
|
205
|
+
`TS-Go compilation failed with exit code ${result.code}.`,
|
|
206
|
+
result.stderr.trim() || result.stdout.trim()
|
|
207
|
+
].filter(Boolean).join('\n'));
|
|
208
|
+
} else process.exit(1);
|
|
149
209
|
}
|
|
150
210
|
await rewriteOutputSpecifiers(appDirectory, distDir, absoluteBaseUrl, paths, compileOptions.moduleType);
|
|
151
211
|
for (const source of sourceDirs)await copyFiles(source, distDir, appDirectory);
|
|
152
212
|
logger.info("TS-Go compile succeed");
|
|
153
213
|
};
|
|
154
|
-
export { compileByTs };
|
|
214
|
+
export { compileByTs, createResolvedTsgoConfig, getTsgoBinPath, rewriteOutputSpecifiers };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export type SpecifierRewrite = (specifier: string) => string | undefined;
|
|
2
|
+
/**
|
|
3
|
+
* Rewrite the import/export/require specifiers of emitted JavaScript.
|
|
4
|
+
*
|
|
5
|
+
* Specifiers whose contents contain escape sequences are left untouched (the
|
|
6
|
+
* raw source slice would not round-trip), which never happens for the
|
|
7
|
+
* compiler-emitted relative/alias specifiers this is used on.
|
|
8
|
+
*/
|
|
9
|
+
export declare const rewriteImportSpecifiers: (content: string, rewrite: SpecifierRewrite) => {
|
|
10
|
+
content: string;
|
|
11
|
+
changed: boolean;
|
|
12
|
+
};
|
|
@@ -1,2 +1,22 @@
|
|
|
1
1
|
import type { CompileFunc } from '../../common';
|
|
2
|
+
type TsgoConfig = {
|
|
3
|
+
compilerOptions?: {
|
|
4
|
+
baseUrl?: unknown;
|
|
5
|
+
module?: string;
|
|
6
|
+
moduleResolution?: string;
|
|
7
|
+
noEmitOnError?: boolean;
|
|
8
|
+
outDir?: string;
|
|
9
|
+
rootDir?: string;
|
|
10
|
+
verbatimModuleSyntax?: boolean;
|
|
11
|
+
};
|
|
12
|
+
files?: string[];
|
|
13
|
+
include?: string[];
|
|
14
|
+
};
|
|
15
|
+
export declare const createResolvedTsgoConfig: (appDirectory: string, tsconfigPath: string, distDir: string, sourceDirs: string[], moduleType: 'module' | 'commonjs' | undefined, tsgoBinPath: string) => Promise<{
|
|
16
|
+
config: TsgoConfig;
|
|
17
|
+
resolvedConfigPath: string;
|
|
18
|
+
}>;
|
|
19
|
+
export declare const getTsgoBinPath: (appDirectory: string, resolvePaths?: string[]) => string;
|
|
20
|
+
export declare const rewriteOutputSpecifiers: (appDirectory: string, distDir: string, baseUrl: string, paths: Record<string, string[] | string>, moduleType?: 'module' | 'commonjs') => Promise<void>;
|
|
2
21
|
export declare const compileByTs: CompileFunc;
|
|
22
|
+
export {};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { MatchPath } from '@modern-js/utils/tsconfig-paths';
|
|
2
2
|
export declare const createTsconfigPathsMatcher: (baseUrl: string, paths: Record<string, string[] | string>) => MatchPath | undefined;
|
|
3
|
-
export declare function getNotAliasedPath(sourceFile: string, matcher: MatchPath, text: string, moduleType?: 'module' | 'commonjs'):
|
|
3
|
+
export declare function getNotAliasedPath(sourceFile: string, matcher: MatchPath, text: string, moduleType?: 'module' | 'commonjs'): string | undefined;
|
package/package.json
CHANGED
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"modern",
|
|
18
18
|
"modern.js"
|
|
19
19
|
],
|
|
20
|
-
"version": "3.
|
|
20
|
+
"version": "3.4.0-ultramodern.1",
|
|
21
21
|
"types": "./dist/types/index.d.ts",
|
|
22
22
|
"main": "./dist/cjs/index.js",
|
|
23
23
|
"exports": {
|
|
@@ -40,14 +40,22 @@
|
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
42
|
"@swc/helpers": "^0.5.23",
|
|
43
|
-
"@modern-js/utils": "npm:@bleedingdev/modern-js-utils@3.
|
|
43
|
+
"@modern-js/utils": "npm:@bleedingdev/modern-js-utils@3.4.0-ultramodern.1"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
|
-
"@rslib/core": "0.
|
|
47
|
-
"@types/node": "^
|
|
48
|
-
"@typescript/native-preview": "7.0.0-dev.
|
|
49
|
-
"@
|
|
50
|
-
"@
|
|
46
|
+
"@rslib/core": "0.23.0",
|
|
47
|
+
"@types/node": "^26.0.0",
|
|
48
|
+
"@typescript/native-preview": "7.0.0-dev.20260624.1",
|
|
49
|
+
"@modern-js/server-core": "npm:@bleedingdev/modern-js-server-core@3.4.0-ultramodern.1",
|
|
50
|
+
"@scripts/rstest-config": "2.66.0"
|
|
51
|
+
},
|
|
52
|
+
"peerDependencies": {
|
|
53
|
+
"@typescript/native-preview": ">=7.0.0-dev.20260624.1"
|
|
54
|
+
},
|
|
55
|
+
"peerDependenciesMeta": {
|
|
56
|
+
"@typescript/native-preview": {
|
|
57
|
+
"optional": true
|
|
58
|
+
}
|
|
51
59
|
},
|
|
52
60
|
"sideEffects": false,
|
|
53
61
|
"publishConfig": {
|