@modern-js/server-utils 2.69.4 → 3.0.0-alpha.0
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 +58 -62
- package/dist/cjs/compilers/babel/index.js +145 -101
- package/dist/cjs/compilers/babel/preset/alias.js +123 -105
- package/dist/cjs/compilers/babel/preset/index.js +102 -68
- package/dist/cjs/compilers/babel/preset/types.js +17 -15
- package/dist/cjs/compilers/typescript/index.js +112 -119
- package/dist/cjs/compilers/typescript/tsconfigPathsPlugin.js +157 -191
- package/dist/cjs/compilers/typescript/typescriptLoader.js +47 -41
- package/dist/cjs/index.js +68 -28
- package/dist/esm/common/index.mjs +29 -0
- package/dist/esm/compilers/babel/index.mjs +57 -0
- package/dist/esm/compilers/babel/preset/alias.mjs +84 -0
- package/dist/esm/compilers/babel/preset/index.mjs +29 -0
- package/dist/esm/compilers/typescript/index.mjs +76 -0
- package/dist/esm/compilers/typescript/tsconfigPathsPlugin.mjs +126 -0
- package/dist/esm/compilers/typescript/typescriptLoader.mjs +20 -0
- package/dist/{esm-node/index.js → esm/index.mjs} +2 -4
- package/dist/esm-node/common/index.mjs +29 -0
- package/dist/esm-node/compilers/babel/index.mjs +57 -0
- package/dist/esm-node/compilers/babel/preset/alias.mjs +84 -0
- package/dist/esm-node/compilers/babel/preset/index.mjs +29 -0
- package/dist/esm-node/compilers/typescript/index.mjs +76 -0
- package/dist/esm-node/compilers/typescript/tsconfigPathsPlugin.mjs +126 -0
- package/dist/esm-node/compilers/typescript/typescriptLoader.mjs +20 -0
- package/dist/esm-node/index.mjs +3 -0
- package/package.json +33 -25
- package/rslib.config.mts +4 -0
- package/dist/esm/common/index.js +0 -97
- package/dist/esm/compilers/babel/index.js +0 -119
- package/dist/esm/compilers/babel/preset/alias.js +0 -70
- package/dist/esm/compilers/babel/preset/index.js +0 -36
- package/dist/esm/compilers/typescript/index.js +0 -202
- package/dist/esm/compilers/typescript/tsconfigPathsPlugin.js +0 -188
- package/dist/esm/compilers/typescript/typescriptLoader.js +0 -30
- package/dist/esm/index.js +0 -5
- package/dist/esm-node/common/index.js +0 -35
- package/dist/esm-node/compilers/babel/index.js +0 -66
- package/dist/esm-node/compilers/babel/preset/alias.js +0 -76
- package/dist/esm-node/compilers/babel/preset/index.js +0 -36
- package/dist/esm-node/compilers/typescript/index.js +0 -93
- package/dist/esm-node/compilers/typescript/tsconfigPathsPlugin.js +0 -170
- package/dist/esm-node/compilers/typescript/typescriptLoader.js +0 -24
- /package/dist/esm/compilers/babel/preset/{types.js → types.mjs} +0 -0
- /package/dist/esm-node/compilers/babel/preset/{types.js → types.mjs} +0 -0
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import * as __rspack_external__modern_js_babel_plugin_module_resolver_fc5e2536 from "@modern-js/babel-plugin-module-resolver";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import { getUserAlias } from "@modern-js/utils";
|
|
4
|
+
import { createMatchPath } from "@modern-js/utils/tsconfig-paths";
|
|
5
|
+
var __webpack_modules__ = {
|
|
6
|
+
"@modern-js/babel-plugin-module-resolver" (module) {
|
|
7
|
+
module.exports = __rspack_external__modern_js_babel_plugin_module_resolver_fc5e2536;
|
|
8
|
+
}
|
|
9
|
+
};
|
|
10
|
+
var __webpack_module_cache__ = {};
|
|
11
|
+
function __webpack_require__(moduleId) {
|
|
12
|
+
var cachedModule = __webpack_module_cache__[moduleId];
|
|
13
|
+
if (void 0 !== cachedModule) return cachedModule.exports;
|
|
14
|
+
var module = __webpack_module_cache__[moduleId] = {
|
|
15
|
+
exports: {}
|
|
16
|
+
};
|
|
17
|
+
__webpack_modules__[moduleId](module, module.exports, __webpack_require__);
|
|
18
|
+
return module.exports;
|
|
19
|
+
}
|
|
20
|
+
const { resolvePath } = __webpack_require__("@modern-js/babel-plugin-module-resolver");
|
|
21
|
+
const defaultPaths = {
|
|
22
|
+
'@': [
|
|
23
|
+
'./src'
|
|
24
|
+
]
|
|
25
|
+
};
|
|
26
|
+
const aliasPlugin = (alias)=>{
|
|
27
|
+
const { absoluteBaseUrl, isTsPath, isTsProject = false } = alias;
|
|
28
|
+
const mergedPaths = isTsPath ? alias.paths || {} : {
|
|
29
|
+
...defaultPaths,
|
|
30
|
+
...alias.paths || {}
|
|
31
|
+
};
|
|
32
|
+
let tsPaths = {};
|
|
33
|
+
if (isTsProject) tsPaths = getUserAlias(mergedPaths);
|
|
34
|
+
tsPaths = Object.keys(tsPaths).reduce((o, key)=>{
|
|
35
|
+
if ('string' == typeof tsPaths[key]) return {
|
|
36
|
+
...o,
|
|
37
|
+
[`${key}`]: [
|
|
38
|
+
tsPaths[key]
|
|
39
|
+
]
|
|
40
|
+
};
|
|
41
|
+
return {
|
|
42
|
+
...o,
|
|
43
|
+
[`${key}`]: tsPaths[key]
|
|
44
|
+
};
|
|
45
|
+
}, {});
|
|
46
|
+
const resolvePathFn = (sourcePath, currentFile, opts)=>{
|
|
47
|
+
if ('.' === sourcePath || './' === sourcePath) return sourcePath;
|
|
48
|
+
const matchPath = createMatchPath(absoluteBaseUrl, tsPaths, [
|
|
49
|
+
'index'
|
|
50
|
+
]);
|
|
51
|
+
const result = matchPath(sourcePath, void 0, void 0, [
|
|
52
|
+
'.js',
|
|
53
|
+
'.jsx',
|
|
54
|
+
'.ts',
|
|
55
|
+
'.tsx'
|
|
56
|
+
]);
|
|
57
|
+
if (result) {
|
|
58
|
+
const relativePath = path.relative(path.dirname(currentFile), path.dirname(result));
|
|
59
|
+
const fileName = path.basename(result);
|
|
60
|
+
const filePath = path.normalize(`${0 === relativePath.length ? '.' : relativePath}/${fileName}`).replace(/\\/, '/');
|
|
61
|
+
return filePath.startsWith('.') ? filePath : `./${filePath}`;
|
|
62
|
+
}
|
|
63
|
+
return resolvePath(sourcePath, currentFile, opts);
|
|
64
|
+
};
|
|
65
|
+
const typescriptExts = [
|
|
66
|
+
'.ts',
|
|
67
|
+
'.tsx',
|
|
68
|
+
'.js',
|
|
69
|
+
'.jsx',
|
|
70
|
+
'.es',
|
|
71
|
+
'.es6',
|
|
72
|
+
'.mjs'
|
|
73
|
+
];
|
|
74
|
+
return [
|
|
75
|
+
require.resolve('@modern-js/babel-plugin-module-resolver'),
|
|
76
|
+
{
|
|
77
|
+
root: absoluteBaseUrl,
|
|
78
|
+
alias: mergedPaths,
|
|
79
|
+
resolvePath: isTsPath ? resolvePathFn : void 0,
|
|
80
|
+
extensions: isTsProject ? typescriptExts : void 0
|
|
81
|
+
}
|
|
82
|
+
];
|
|
83
|
+
};
|
|
84
|
+
export { aliasPlugin };
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { getBabelConfigForNode } from "@modern-js/babel-preset/node";
|
|
2
|
+
import { aliasPlugin } from "./alias";
|
|
3
|
+
import { applyUserBabelConfig } from "@modern-js/utils";
|
|
4
|
+
export * from "./types";
|
|
5
|
+
const getBabelConfig = (libPresetOption)=>{
|
|
6
|
+
const { isEsm } = libPresetOption;
|
|
7
|
+
const config = getBabelConfigForNode({
|
|
8
|
+
presetEnv: {
|
|
9
|
+
loose: true,
|
|
10
|
+
modules: isEsm ? false : 'commonjs',
|
|
11
|
+
targets: [
|
|
12
|
+
'node >= 14'
|
|
13
|
+
]
|
|
14
|
+
},
|
|
15
|
+
pluginDecorators: {
|
|
16
|
+
version: 'legacy'
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
config.presets?.push([
|
|
20
|
+
require.resolve('@babel/preset-react'),
|
|
21
|
+
{
|
|
22
|
+
runtime: 'automatic'
|
|
23
|
+
}
|
|
24
|
+
]);
|
|
25
|
+
if (libPresetOption.alias) config.plugins?.push(aliasPlugin(libPresetOption.alias));
|
|
26
|
+
config.plugins?.push(require.resolve("babel-plugin-transform-typescript-metadata"));
|
|
27
|
+
return config;
|
|
28
|
+
};
|
|
29
|
+
export { applyUserBabelConfig, getBabelConfig };
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import path_0 from "path";
|
|
2
|
+
import { fs, getAliasConfig, logger } from "@modern-js/utils";
|
|
3
|
+
import { tsconfigPathsBeforeHookFactory } from "./tsconfigPathsPlugin";
|
|
4
|
+
import { TypescriptLoader } from "./typescriptLoader";
|
|
5
|
+
const readTsConfigByFile = (tsConfigFile, tsInstance)=>{
|
|
6
|
+
const parsedCmd = tsInstance.getParsedCommandLineOfConfigFile(tsConfigFile, void 0, tsInstance.sys);
|
|
7
|
+
const { options, fileNames, projectReferences } = parsedCmd;
|
|
8
|
+
return {
|
|
9
|
+
options,
|
|
10
|
+
fileNames,
|
|
11
|
+
projectReferences
|
|
12
|
+
};
|
|
13
|
+
};
|
|
14
|
+
const copyFiles = async (from, to, appDirectory)=>{
|
|
15
|
+
if (await fs.pathExists(from)) {
|
|
16
|
+
const relativePath = path_0.relative(appDirectory, from);
|
|
17
|
+
const targetDir = path_0.join(to, relativePath);
|
|
18
|
+
await fs.copy(from, targetDir, {
|
|
19
|
+
filter: (src)=>![
|
|
20
|
+
'.ts',
|
|
21
|
+
'.js'
|
|
22
|
+
].includes(path_0.extname(src)) && !src.endsWith('tsconfig.json')
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
const compileByTs = async (appDirectory, config, compileOptions)=>{
|
|
27
|
+
logger.info("Running ts compile...");
|
|
28
|
+
const { sourceDirs, distDir, tsconfigPath } = compileOptions;
|
|
29
|
+
if (!tsconfigPath) return;
|
|
30
|
+
const ts = new TypescriptLoader({
|
|
31
|
+
appDirectory
|
|
32
|
+
}).load();
|
|
33
|
+
const createProgram = ts.createIncrementalProgram || ts.createProgram;
|
|
34
|
+
const formatHost = getFormatHost(ts);
|
|
35
|
+
const { alias } = config;
|
|
36
|
+
const aliasOption = getAliasConfig(alias, {
|
|
37
|
+
appDirectory,
|
|
38
|
+
tsconfigPath
|
|
39
|
+
});
|
|
40
|
+
const { paths = {}, absoluteBaseUrl = './' } = aliasOption;
|
|
41
|
+
const { options, fileNames, projectReferences } = readTsConfigByFile(tsconfigPath, ts);
|
|
42
|
+
const sourcePosixPaths = sourceDirs.map((sourceDir)=>sourceDir.split(path_0.sep).join(path_0.posix.sep));
|
|
43
|
+
const rootNames = fileNames.filter((fileName)=>fileName.endsWith('.d.ts') || sourcePosixPaths.some((sourceDir)=>fileName.includes(sourceDir)));
|
|
44
|
+
const program = createProgram.call(ts, {
|
|
45
|
+
rootNames,
|
|
46
|
+
projectReferences,
|
|
47
|
+
options: {
|
|
48
|
+
rootDir: appDirectory,
|
|
49
|
+
outDir: distDir,
|
|
50
|
+
...options
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
const tsconfigPathsPlugin = tsconfigPathsBeforeHookFactory(ts, absoluteBaseUrl, paths);
|
|
54
|
+
const emitResult = program.emit(void 0, void 0, void 0, void 0, {
|
|
55
|
+
before: [
|
|
56
|
+
tsconfigPathsPlugin
|
|
57
|
+
]
|
|
58
|
+
});
|
|
59
|
+
const allDiagnostics = ts.getPreEmitDiagnostics(program).concat(emitResult.diagnostics);
|
|
60
|
+
const { noEmitOnError } = options;
|
|
61
|
+
if (allDiagnostics.length > 0) {
|
|
62
|
+
logger.error(ts.formatDiagnosticsWithColorAndContext([
|
|
63
|
+
...new Set(allDiagnostics)
|
|
64
|
+
], formatHost));
|
|
65
|
+
if (void 0 === noEmitOnError || true === noEmitOnError) if (compileOptions.throwErrorInsteadOfExit) logger.error('TypeScript compilation failed');
|
|
66
|
+
else process.exit(1);
|
|
67
|
+
}
|
|
68
|
+
for (const source of sourceDirs)await copyFiles(source, distDir, appDirectory);
|
|
69
|
+
logger.info("Ts compile succeed");
|
|
70
|
+
};
|
|
71
|
+
const getFormatHost = (ts)=>({
|
|
72
|
+
getCanonicalFileName: (path)=>path,
|
|
73
|
+
getCurrentDirectory: ts.sys.getCurrentDirectory,
|
|
74
|
+
getNewLine: ()=>ts.sys.newLine
|
|
75
|
+
});
|
|
76
|
+
export { compileByTs };
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { platform } from "os";
|
|
2
|
+
import path, { dirname, posix } from "path";
|
|
3
|
+
import { createMatchPath } from "@modern-js/utils/tsconfig-paths";
|
|
4
|
+
import { SyntaxKind } from "typescript";
|
|
5
|
+
const isRegExpKey = (str)=>str.startsWith('^') || str.endsWith('$');
|
|
6
|
+
const resolveAliasPath = (baseUrl, filePath)=>{
|
|
7
|
+
if (filePath.startsWith('.') || filePath.startsWith('..')) return path.resolve(baseUrl, filePath);
|
|
8
|
+
return filePath;
|
|
9
|
+
};
|
|
10
|
+
const createAliasMatcher = (baseUrl, alias)=>{
|
|
11
|
+
const aliasPairs = Object.keys(alias).reduce((o, key)=>{
|
|
12
|
+
if (isRegExpKey(key)) {
|
|
13
|
+
const regexp = new RegExp(key);
|
|
14
|
+
const aliasPath = resolveAliasPath(baseUrl, alias[key]);
|
|
15
|
+
o.push([
|
|
16
|
+
regexp,
|
|
17
|
+
aliasPath
|
|
18
|
+
]);
|
|
19
|
+
} else {
|
|
20
|
+
const aliasPath = resolveAliasPath(baseUrl, alias[key]);
|
|
21
|
+
o.push([
|
|
22
|
+
key,
|
|
23
|
+
aliasPath
|
|
24
|
+
]);
|
|
25
|
+
}
|
|
26
|
+
return o;
|
|
27
|
+
}, []);
|
|
28
|
+
const cacheMap = new Map();
|
|
29
|
+
return (requestedModule)=>{
|
|
30
|
+
if (cacheMap.has(requestedModule)) return cacheMap.get(requestedModule);
|
|
31
|
+
for (const [key, value] of aliasPairs){
|
|
32
|
+
if (key instanceof RegExp) {
|
|
33
|
+
if (key.test(requestedModule)) {
|
|
34
|
+
cacheMap.set(requestedModule, value);
|
|
35
|
+
return value;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
if (requestedModule === key) {
|
|
39
|
+
cacheMap.set(requestedModule, value);
|
|
40
|
+
return value;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
};
|
|
45
|
+
const isDynamicImport = (tsBinary, node)=>tsBinary.isCallExpression(node) && node.expression.kind === SyntaxKind.ImportKeyword;
|
|
46
|
+
function tsconfigPathsBeforeHookFactory(tsBinary, baseUrl, paths) {
|
|
47
|
+
const tsPaths = {};
|
|
48
|
+
const alias = {};
|
|
49
|
+
Object.keys(paths).forEach((key)=>{
|
|
50
|
+
if (Array.isArray(paths[key])) tsPaths[key] = paths[key];
|
|
51
|
+
else alias[key] = paths[key];
|
|
52
|
+
});
|
|
53
|
+
const matchAliasPath = createAliasMatcher(baseUrl, alias);
|
|
54
|
+
const matchTsPath = createMatchPath(baseUrl, tsPaths, [
|
|
55
|
+
'main'
|
|
56
|
+
]);
|
|
57
|
+
const matchPath = (requestedModule, readJSONSync, fileExists, extensions)=>{
|
|
58
|
+
const result = matchTsPath(requestedModule, readJSONSync, fileExists, extensions);
|
|
59
|
+
if (result) return result;
|
|
60
|
+
return matchAliasPath(requestedModule);
|
|
61
|
+
};
|
|
62
|
+
if (0 === Object.keys(paths).length) return;
|
|
63
|
+
return (ctx)=>(sf)=>{
|
|
64
|
+
const visitNode = (node)=>{
|
|
65
|
+
if (isDynamicImport(tsBinary, node)) {
|
|
66
|
+
const importPathWithQuotes = node.arguments[0].getText(sf);
|
|
67
|
+
const text = importPathWithQuotes.slice(1, importPathWithQuotes.length - 1);
|
|
68
|
+
const result = getNotAliasedPath(sf, matchPath, text);
|
|
69
|
+
if (!result) return node;
|
|
70
|
+
return tsBinary.factory.updateCallExpression(node, node.expression, node.typeArguments, tsBinary.factory.createNodeArray([
|
|
71
|
+
tsBinary.factory.createStringLiteral(result)
|
|
72
|
+
]));
|
|
73
|
+
}
|
|
74
|
+
if (tsBinary.isImportDeclaration(node) || tsBinary.isExportDeclaration(node) && node.moduleSpecifier) try {
|
|
75
|
+
const importPathWithQuotes = node?.moduleSpecifier?.getText();
|
|
76
|
+
if (!importPathWithQuotes) return node;
|
|
77
|
+
const text = importPathWithQuotes.substring(1, importPathWithQuotes.length - 1);
|
|
78
|
+
const result = getNotAliasedPath(sf, matchPath, text);
|
|
79
|
+
if (!result) return node;
|
|
80
|
+
const moduleSpecifier = tsBinary.factory.createStringLiteral(result);
|
|
81
|
+
moduleSpecifier.parent = node.moduleSpecifier.parent;
|
|
82
|
+
let newNode;
|
|
83
|
+
newNode = tsBinary.isImportDeclaration(node) ? tsBinary.factory.updateImportDeclaration(node, node.modifiers, node.importClause, moduleSpecifier, node.assertClause) : tsBinary.factory.updateExportDeclaration(node, node.modifiers, node.isTypeOnly, node.exportClause, moduleSpecifier, node.assertClause);
|
|
84
|
+
newNode.flags = node.flags;
|
|
85
|
+
return newNode;
|
|
86
|
+
} catch {
|
|
87
|
+
return node;
|
|
88
|
+
}
|
|
89
|
+
return tsBinary.visitEachChild(node, visitNode, ctx);
|
|
90
|
+
};
|
|
91
|
+
return tsBinary.visitNode(sf, visitNode);
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
function getNotAliasedPath(sf, matcher, text) {
|
|
95
|
+
let result = matcher(text, void 0, void 0, [
|
|
96
|
+
'.ts',
|
|
97
|
+
'.tsx',
|
|
98
|
+
'.js',
|
|
99
|
+
'.jsx'
|
|
100
|
+
]);
|
|
101
|
+
if (!result) return;
|
|
102
|
+
if ('win32' === platform()) result = result.replace(/\\/g, '/');
|
|
103
|
+
if (!path.isAbsolute(result)) {
|
|
104
|
+
if (!result.startsWith('.') && !result.startsWith('..')) try {
|
|
105
|
+
const packagePath = require.resolve(result, {
|
|
106
|
+
paths: [
|
|
107
|
+
process.cwd(),
|
|
108
|
+
...module.paths
|
|
109
|
+
]
|
|
110
|
+
});
|
|
111
|
+
if (packagePath) return result;
|
|
112
|
+
} catch {}
|
|
113
|
+
try {
|
|
114
|
+
const packagePath = require.resolve(text, {
|
|
115
|
+
paths: [
|
|
116
|
+
process.cwd(),
|
|
117
|
+
...module.paths
|
|
118
|
+
]
|
|
119
|
+
});
|
|
120
|
+
if (packagePath) return text;
|
|
121
|
+
} catch {}
|
|
122
|
+
}
|
|
123
|
+
const resolvedPath = posix.relative(dirname(sf.fileName), result) || './';
|
|
124
|
+
return '.' === resolvedPath[0] ? resolvedPath : `./${resolvedPath}`;
|
|
125
|
+
}
|
|
126
|
+
export { tsconfigPathsBeforeHookFactory };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
class TypescriptLoader {
|
|
2
|
+
load() {
|
|
3
|
+
if (this.tsBinary) return this.tsBinary;
|
|
4
|
+
try {
|
|
5
|
+
const tsPath = require.resolve("typescript", {
|
|
6
|
+
paths: [
|
|
7
|
+
this.appDirectory || process.cwd()
|
|
8
|
+
]
|
|
9
|
+
});
|
|
10
|
+
const ts = require(tsPath);
|
|
11
|
+
return ts;
|
|
12
|
+
} catch (error) {
|
|
13
|
+
throw new Error('TypeScript could not be found! Please, install "typescript" package.');
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
constructor({ appDirectory }){
|
|
17
|
+
this.appDirectory = appDirectory;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
export { TypescriptLoader };
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { isAbsolute } from "path";
|
|
2
|
+
import { fs } from "@modern-js/utils";
|
|
3
|
+
const FILE_EXTENSIONS = [
|
|
4
|
+
'.js',
|
|
5
|
+
'.ts',
|
|
6
|
+
'.mjs',
|
|
7
|
+
'.ejs'
|
|
8
|
+
];
|
|
9
|
+
const validateAbsolutePath = (filename, message)=>{
|
|
10
|
+
if (!isAbsolute(filename)) throw new Error(message);
|
|
11
|
+
};
|
|
12
|
+
const validateAbsolutePaths = (filenames, messageFunc)=>{
|
|
13
|
+
filenames.forEach((filename)=>validateAbsolutePath(filename, messageFunc(filename)));
|
|
14
|
+
};
|
|
15
|
+
const compile = async (appDirectory, modernConfig, compileOptions)=>{
|
|
16
|
+
const { sourceDirs, distDir, tsconfigPath } = compileOptions;
|
|
17
|
+
validateAbsolutePaths(sourceDirs, (dir)=>`source dir ${dir} is not an absolute path.`);
|
|
18
|
+
validateAbsolutePath(distDir, `dist dir ${distDir} is not an absolute path.`);
|
|
19
|
+
const compiler = modernConfig?.server?.compiler;
|
|
20
|
+
const isTsProject = tsconfigPath && await fs.pathExists(tsconfigPath);
|
|
21
|
+
if (isTsProject && 'babel' !== compiler) {
|
|
22
|
+
const { compileByTs } = await import("../compilers/typescript/index.mjs");
|
|
23
|
+
await compileByTs(appDirectory, modernConfig, compileOptions);
|
|
24
|
+
} else {
|
|
25
|
+
const { compileByBabel } = await import("../compilers/babel/index.mjs");
|
|
26
|
+
await compileByBabel(appDirectory, modernConfig, compileOptions);
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
export { FILE_EXTENSIONS, compile };
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { basename as external_path_basename, extname, join } from "path";
|
|
2
|
+
import { compiler } from "@modern-js/babel-compiler";
|
|
3
|
+
import { fs, getAliasConfig, json5 } from "@modern-js/utils";
|
|
4
|
+
import { FILE_EXTENSIONS } from "../../common/index.mjs";
|
|
5
|
+
import { applyUserBabelConfig, getBabelConfig } from "./preset/index.mjs";
|
|
6
|
+
export * from "@babel/core";
|
|
7
|
+
const readTsConfig = (tsconfigPath, noExistReturn = null)=>{
|
|
8
|
+
if (!fs.existsSync(tsconfigPath)) return noExistReturn;
|
|
9
|
+
const content = fs.readFileSync(tsconfigPath, 'utf-8');
|
|
10
|
+
return json5.parse(content);
|
|
11
|
+
};
|
|
12
|
+
const existTsConfigFile = (tsconfigAbsolutePath)=>{
|
|
13
|
+
const tsconfig = readTsConfig(tsconfigAbsolutePath);
|
|
14
|
+
return Boolean(tsconfig);
|
|
15
|
+
};
|
|
16
|
+
const resolveBabelConfig = (appDirectory, config, option, isEsm)=>{
|
|
17
|
+
const { alias, babelConfig } = config;
|
|
18
|
+
const aliasConfig = getAliasConfig(alias, {
|
|
19
|
+
appDirectory,
|
|
20
|
+
...option
|
|
21
|
+
});
|
|
22
|
+
const defaultBabelConfig = getBabelConfig({
|
|
23
|
+
appDirectory,
|
|
24
|
+
alias: aliasConfig,
|
|
25
|
+
isEsm
|
|
26
|
+
});
|
|
27
|
+
return applyUserBabelConfig(defaultBabelConfig, babelConfig);
|
|
28
|
+
};
|
|
29
|
+
const compileByBabel = async (appDirectory, config, compileOptions)=>{
|
|
30
|
+
const { sourceDirs, distDir, tsconfigPath, moduleType } = compileOptions;
|
|
31
|
+
const isEsm = 'module' === moduleType;
|
|
32
|
+
const results = await Promise.all(sourceDirs.map(async (sourceDir)=>{
|
|
33
|
+
const babelConfig = resolveBabelConfig(appDirectory, config, {
|
|
34
|
+
tsconfigPath: tsconfigPath ? tsconfigPath : ''
|
|
35
|
+
}, isEsm);
|
|
36
|
+
if (await fs.pathExists(sourceDir)) {
|
|
37
|
+
const basename = external_path_basename(sourceDir);
|
|
38
|
+
const targetDir = join(distDir, basename);
|
|
39
|
+
await fs.copy(sourceDir, targetDir, {
|
|
40
|
+
filter: (src)=>![
|
|
41
|
+
'.ts',
|
|
42
|
+
'.js'
|
|
43
|
+
].includes(extname(src)) && src !== tsconfigPath
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
return compiler({
|
|
47
|
+
rootDir: appDirectory,
|
|
48
|
+
distDir,
|
|
49
|
+
sourceDir,
|
|
50
|
+
extensions: FILE_EXTENSIONS
|
|
51
|
+
}, babelConfig);
|
|
52
|
+
}));
|
|
53
|
+
results.forEach((result)=>{
|
|
54
|
+
if (1 === result.code) throw new Error(result.message);
|
|
55
|
+
});
|
|
56
|
+
};
|
|
57
|
+
export { compileByBabel, existTsConfigFile, readTsConfig, resolveBabelConfig };
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import * as __rspack_external__modern_js_babel_plugin_module_resolver_fc5e2536 from "@modern-js/babel-plugin-module-resolver";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import { getUserAlias } from "@modern-js/utils";
|
|
4
|
+
import { createMatchPath } from "@modern-js/utils/tsconfig-paths";
|
|
5
|
+
var __webpack_modules__ = {
|
|
6
|
+
"@modern-js/babel-plugin-module-resolver" (module) {
|
|
7
|
+
module.exports = __rspack_external__modern_js_babel_plugin_module_resolver_fc5e2536;
|
|
8
|
+
}
|
|
9
|
+
};
|
|
10
|
+
var __webpack_module_cache__ = {};
|
|
11
|
+
function __webpack_require__(moduleId) {
|
|
12
|
+
var cachedModule = __webpack_module_cache__[moduleId];
|
|
13
|
+
if (void 0 !== cachedModule) return cachedModule.exports;
|
|
14
|
+
var module = __webpack_module_cache__[moduleId] = {
|
|
15
|
+
exports: {}
|
|
16
|
+
};
|
|
17
|
+
__webpack_modules__[moduleId](module, module.exports, __webpack_require__);
|
|
18
|
+
return module.exports;
|
|
19
|
+
}
|
|
20
|
+
const { resolvePath } = __webpack_require__("@modern-js/babel-plugin-module-resolver");
|
|
21
|
+
const defaultPaths = {
|
|
22
|
+
'@': [
|
|
23
|
+
'./src'
|
|
24
|
+
]
|
|
25
|
+
};
|
|
26
|
+
const aliasPlugin = (alias)=>{
|
|
27
|
+
const { absoluteBaseUrl, isTsPath, isTsProject = false } = alias;
|
|
28
|
+
const mergedPaths = isTsPath ? alias.paths || {} : {
|
|
29
|
+
...defaultPaths,
|
|
30
|
+
...alias.paths || {}
|
|
31
|
+
};
|
|
32
|
+
let tsPaths = {};
|
|
33
|
+
if (isTsProject) tsPaths = getUserAlias(mergedPaths);
|
|
34
|
+
tsPaths = Object.keys(tsPaths).reduce((o, key)=>{
|
|
35
|
+
if ('string' == typeof tsPaths[key]) return {
|
|
36
|
+
...o,
|
|
37
|
+
[`${key}`]: [
|
|
38
|
+
tsPaths[key]
|
|
39
|
+
]
|
|
40
|
+
};
|
|
41
|
+
return {
|
|
42
|
+
...o,
|
|
43
|
+
[`${key}`]: tsPaths[key]
|
|
44
|
+
};
|
|
45
|
+
}, {});
|
|
46
|
+
const resolvePathFn = (sourcePath, currentFile, opts)=>{
|
|
47
|
+
if ('.' === sourcePath || './' === sourcePath) return sourcePath;
|
|
48
|
+
const matchPath = createMatchPath(absoluteBaseUrl, tsPaths, [
|
|
49
|
+
'index'
|
|
50
|
+
]);
|
|
51
|
+
const result = matchPath(sourcePath, void 0, void 0, [
|
|
52
|
+
'.js',
|
|
53
|
+
'.jsx',
|
|
54
|
+
'.ts',
|
|
55
|
+
'.tsx'
|
|
56
|
+
]);
|
|
57
|
+
if (result) {
|
|
58
|
+
const relativePath = path.relative(path.dirname(currentFile), path.dirname(result));
|
|
59
|
+
const fileName = path.basename(result);
|
|
60
|
+
const filePath = path.normalize(`${0 === relativePath.length ? '.' : relativePath}/${fileName}`).replace(/\\/, '/');
|
|
61
|
+
return filePath.startsWith('.') ? filePath : `./${filePath}`;
|
|
62
|
+
}
|
|
63
|
+
return resolvePath(sourcePath, currentFile, opts);
|
|
64
|
+
};
|
|
65
|
+
const typescriptExts = [
|
|
66
|
+
'.ts',
|
|
67
|
+
'.tsx',
|
|
68
|
+
'.js',
|
|
69
|
+
'.jsx',
|
|
70
|
+
'.es',
|
|
71
|
+
'.es6',
|
|
72
|
+
'.mjs'
|
|
73
|
+
];
|
|
74
|
+
return [
|
|
75
|
+
require.resolve('@modern-js/babel-plugin-module-resolver'),
|
|
76
|
+
{
|
|
77
|
+
root: absoluteBaseUrl,
|
|
78
|
+
alias: mergedPaths,
|
|
79
|
+
resolvePath: isTsPath ? resolvePathFn : void 0,
|
|
80
|
+
extensions: isTsProject ? typescriptExts : void 0
|
|
81
|
+
}
|
|
82
|
+
];
|
|
83
|
+
};
|
|
84
|
+
export { aliasPlugin };
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { getBabelConfigForNode } from "@modern-js/babel-preset/node";
|
|
2
|
+
import { aliasPlugin } from "./alias.mjs";
|
|
3
|
+
import { applyUserBabelConfig } from "@modern-js/utils";
|
|
4
|
+
export * from "./types.mjs";
|
|
5
|
+
const getBabelConfig = (libPresetOption)=>{
|
|
6
|
+
const { isEsm } = libPresetOption;
|
|
7
|
+
const config = getBabelConfigForNode({
|
|
8
|
+
presetEnv: {
|
|
9
|
+
loose: true,
|
|
10
|
+
modules: isEsm ? false : 'commonjs',
|
|
11
|
+
targets: [
|
|
12
|
+
'node >= 14'
|
|
13
|
+
]
|
|
14
|
+
},
|
|
15
|
+
pluginDecorators: {
|
|
16
|
+
version: 'legacy'
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
config.presets?.push([
|
|
20
|
+
require.resolve('@babel/preset-react'),
|
|
21
|
+
{
|
|
22
|
+
runtime: 'automatic'
|
|
23
|
+
}
|
|
24
|
+
]);
|
|
25
|
+
if (libPresetOption.alias) config.plugins?.push(aliasPlugin(libPresetOption.alias));
|
|
26
|
+
config.plugins?.push(require.resolve("babel-plugin-transform-typescript-metadata"));
|
|
27
|
+
return config;
|
|
28
|
+
};
|
|
29
|
+
export { applyUserBabelConfig, getBabelConfig };
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import path_0 from "path";
|
|
2
|
+
import { fs, getAliasConfig, logger } from "@modern-js/utils";
|
|
3
|
+
import { tsconfigPathsBeforeHookFactory } from "./tsconfigPathsPlugin.mjs";
|
|
4
|
+
import { TypescriptLoader } from "./typescriptLoader.mjs";
|
|
5
|
+
const readTsConfigByFile = (tsConfigFile, tsInstance)=>{
|
|
6
|
+
const parsedCmd = tsInstance.getParsedCommandLineOfConfigFile(tsConfigFile, void 0, tsInstance.sys);
|
|
7
|
+
const { options, fileNames, projectReferences } = parsedCmd;
|
|
8
|
+
return {
|
|
9
|
+
options,
|
|
10
|
+
fileNames,
|
|
11
|
+
projectReferences
|
|
12
|
+
};
|
|
13
|
+
};
|
|
14
|
+
const copyFiles = async (from, to, appDirectory)=>{
|
|
15
|
+
if (await fs.pathExists(from)) {
|
|
16
|
+
const relativePath = path_0.relative(appDirectory, from);
|
|
17
|
+
const targetDir = path_0.join(to, relativePath);
|
|
18
|
+
await fs.copy(from, targetDir, {
|
|
19
|
+
filter: (src)=>![
|
|
20
|
+
'.ts',
|
|
21
|
+
'.js'
|
|
22
|
+
].includes(path_0.extname(src)) && !src.endsWith('tsconfig.json')
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
const compileByTs = async (appDirectory, config, compileOptions)=>{
|
|
27
|
+
logger.info("Running ts compile...");
|
|
28
|
+
const { sourceDirs, distDir, tsconfigPath } = compileOptions;
|
|
29
|
+
if (!tsconfigPath) return;
|
|
30
|
+
const ts = new TypescriptLoader({
|
|
31
|
+
appDirectory
|
|
32
|
+
}).load();
|
|
33
|
+
const createProgram = ts.createIncrementalProgram || ts.createProgram;
|
|
34
|
+
const formatHost = getFormatHost(ts);
|
|
35
|
+
const { alias } = config;
|
|
36
|
+
const aliasOption = getAliasConfig(alias, {
|
|
37
|
+
appDirectory,
|
|
38
|
+
tsconfigPath
|
|
39
|
+
});
|
|
40
|
+
const { paths = {}, absoluteBaseUrl = './' } = aliasOption;
|
|
41
|
+
const { options, fileNames, projectReferences } = readTsConfigByFile(tsconfigPath, ts);
|
|
42
|
+
const sourcePosixPaths = sourceDirs.map((sourceDir)=>sourceDir.split(path_0.sep).join(path_0.posix.sep));
|
|
43
|
+
const rootNames = fileNames.filter((fileName)=>fileName.endsWith('.d.ts') || sourcePosixPaths.some((sourceDir)=>fileName.includes(sourceDir)));
|
|
44
|
+
const program = createProgram.call(ts, {
|
|
45
|
+
rootNames,
|
|
46
|
+
projectReferences,
|
|
47
|
+
options: {
|
|
48
|
+
rootDir: appDirectory,
|
|
49
|
+
outDir: distDir,
|
|
50
|
+
...options
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
const tsconfigPathsPlugin = tsconfigPathsBeforeHookFactory(ts, absoluteBaseUrl, paths);
|
|
54
|
+
const emitResult = program.emit(void 0, void 0, void 0, void 0, {
|
|
55
|
+
before: [
|
|
56
|
+
tsconfigPathsPlugin
|
|
57
|
+
]
|
|
58
|
+
});
|
|
59
|
+
const allDiagnostics = ts.getPreEmitDiagnostics(program).concat(emitResult.diagnostics);
|
|
60
|
+
const { noEmitOnError } = options;
|
|
61
|
+
if (allDiagnostics.length > 0) {
|
|
62
|
+
logger.error(ts.formatDiagnosticsWithColorAndContext([
|
|
63
|
+
...new Set(allDiagnostics)
|
|
64
|
+
], formatHost));
|
|
65
|
+
if (void 0 === noEmitOnError || true === noEmitOnError) if (compileOptions.throwErrorInsteadOfExit) logger.error('TypeScript compilation failed');
|
|
66
|
+
else process.exit(1);
|
|
67
|
+
}
|
|
68
|
+
for (const source of sourceDirs)await copyFiles(source, distDir, appDirectory);
|
|
69
|
+
logger.info("Ts compile succeed");
|
|
70
|
+
};
|
|
71
|
+
const getFormatHost = (ts)=>({
|
|
72
|
+
getCanonicalFileName: (path)=>path,
|
|
73
|
+
getCurrentDirectory: ts.sys.getCurrentDirectory,
|
|
74
|
+
getNewLine: ()=>ts.sys.newLine
|
|
75
|
+
});
|
|
76
|
+
export { compileByTs };
|