@modern-js/app-tools 2.0.0-beta.2 → 2.0.0-beta.3
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/CHANGELOG.md +251 -0
- package/bin/modern.js +10 -1
- package/dist/js/modern/analyze/constants.js +2 -0
- package/dist/js/modern/analyze/generateCode.js +38 -18
- package/dist/js/modern/analyze/getServerRoutes.js +3 -3
- package/dist/js/modern/analyze/nestedRoutes.js +17 -6
- package/dist/js/modern/analyze/templates.js +59 -27
- package/dist/js/modern/analyze/utils.js +30 -4
- package/dist/js/modern/builder/builderPlugins/compatModern.js +6 -1
- package/dist/js/modern/builder/index.js +3 -5
- package/dist/js/modern/builder/loaders/routerLoader.js +20 -0
- package/dist/js/modern/builder/loaders/serverModuleLoader.js +4 -0
- package/dist/js/modern/commands/dev.js +23 -27
- package/dist/js/modern/commands/start.js +0 -1
- package/dist/js/modern/config/default.js +0 -1
- package/dist/js/modern/config/initial/createOutputConfig.js +3 -0
- package/dist/js/modern/utils/createFileWatcher.js +1 -1
- package/dist/js/modern/utils/restart.js +1 -1
- package/dist/js/node/analyze/constants.js +5 -1
- package/dist/js/node/analyze/generateCode.js +36 -16
- package/dist/js/node/analyze/getServerRoutes.js +3 -3
- package/dist/js/node/analyze/nestedRoutes.js +15 -4
- package/dist/js/node/analyze/templates.js +60 -27
- package/dist/js/node/analyze/utils.js +31 -3
- package/dist/js/node/builder/builderPlugins/compatModern.js +6 -1
- package/dist/js/node/builder/index.js +3 -5
- package/dist/js/node/builder/loaders/routerLoader.js +27 -0
- package/dist/js/node/builder/loaders/serverModuleLoader.js +11 -0
- package/dist/js/node/commands/dev.js +23 -27
- package/dist/js/node/commands/start.js +0 -1
- package/dist/js/node/config/default.js +0 -1
- package/dist/js/node/config/initial/createOutputConfig.js +3 -0
- package/dist/js/node/utils/createFileWatcher.js +2 -1
- package/dist/js/node/utils/restart.js +1 -1
- package/dist/js/treeshaking/analyze/constants.js +2 -0
- package/dist/js/treeshaking/analyze/generateCode.js +137 -81
- package/dist/js/treeshaking/analyze/getServerRoutes.js +4 -3
- package/dist/js/treeshaking/analyze/nestedRoutes.js +98 -55
- package/dist/js/treeshaking/analyze/templates.js +175 -101
- package/dist/js/treeshaking/analyze/utils.js +80 -4
- package/dist/js/treeshaking/builder/builderPlugins/compatModern.js +6 -1
- package/dist/js/treeshaking/builder/index.js +3 -5
- package/dist/js/treeshaking/builder/loaders/routerLoader.js +14 -0
- package/dist/js/treeshaking/builder/loaders/serverModuleLoader.js +4 -0
- package/dist/js/treeshaking/commands/dev.js +37 -38
- package/dist/js/treeshaking/commands/start.js +0 -1
- package/dist/js/treeshaking/config/default.js +0 -1
- package/dist/js/treeshaking/config/initial/createOutputConfig.js +3 -0
- package/dist/js/treeshaking/utils/createFileWatcher.js +1 -1
- package/dist/js/treeshaking/utils/restart.js +1 -1
- package/dist/types/analyze/constants.d.ts +2 -0
- package/dist/types/analyze/templates.d.ts +8 -7
- package/dist/types/analyze/utils.d.ts +9 -1
- package/dist/types/builder/loaders/routerLoader.d.ts +3 -0
- package/dist/types/builder/loaders/serverModuleLoader.d.ts +3 -0
- package/dist/types/types/config/tools.d.ts +8 -1
- package/dist/types/types/hooks.d.ts +2 -1
- package/dist/types/utils/createFileWatcher.d.ts +2 -1
- package/lib/types.d.ts +1 -1
- package/package.json +25 -22
|
@@ -78,6 +78,11 @@ export const PluginCompatModern = (appContext, modernConfig, options) => ({
|
|
|
78
78
|
chain.plugin('route-plugin').use(RouterPlugin, [{
|
|
79
79
|
existNestedRoutes
|
|
80
80
|
}]);
|
|
81
|
+
if (target !== 'node') {
|
|
82
|
+
const bareServerModuleReg = /\.(server|node)\.[tj]sx?$/;
|
|
83
|
+
chain.module.rule(CHAIN_ID.RULE.JS).exclude.add(bareServerModuleReg);
|
|
84
|
+
chain.module.rule('bare-server-module').test(bareServerModuleReg).use('server-module-loader').loader(require.resolve("../loaders/serverModuleLoader"));
|
|
85
|
+
}
|
|
81
86
|
function isHtmlEnabled(config, target) {
|
|
82
87
|
var _config$tools;
|
|
83
88
|
return ((_config$tools = config.tools) === null || _config$tools === void 0 ? void 0 : _config$tools.htmlPlugin) !== false && target !== 'node' && target !== 'web-worker';
|
|
@@ -108,7 +113,7 @@ function applyCallbacks(api, options) {
|
|
|
108
113
|
*/
|
|
109
114
|
function applyNodeCompat(chain, modernConfig, isProd) {
|
|
110
115
|
// apply node resolve extensions
|
|
111
|
-
for (const ext of ['.node.js', '.node.jsx', '.node.ts', '.node.tsx']) {
|
|
116
|
+
for (const ext of ['.node.js', '.node.jsx', '.node.ts', '.node.tsx', '.server.js', '.server.ts', '.server.ts', '.server.tsx']) {
|
|
112
117
|
chain.resolve.extensions.prepend(ext);
|
|
113
118
|
}
|
|
114
119
|
|
|
@@ -33,6 +33,7 @@ export async function createBuilderForEdenX({
|
|
|
33
33
|
return builder;
|
|
34
34
|
}
|
|
35
35
|
export function createBuilderProviderConfig(normalizedConfig, appContext) {
|
|
36
|
+
var _normalizedConfig$ser;
|
|
36
37
|
const output = createOutputConfig(normalizedConfig, appContext);
|
|
37
38
|
return _objectSpread(_objectSpread({}, normalizedConfig), {}, {
|
|
38
39
|
source: _objectSpread(_objectSpread({}, normalizedConfig.source), {}, {
|
|
@@ -40,6 +41,7 @@ export function createBuilderProviderConfig(normalizedConfig, appContext) {
|
|
|
40
41
|
}),
|
|
41
42
|
output,
|
|
42
43
|
dev: {
|
|
44
|
+
port: (_normalizedConfig$ser = normalizedConfig.server) === null || _normalizedConfig$ser === void 0 ? void 0 : _normalizedConfig$ser.port,
|
|
43
45
|
https: normalizedConfig.dev.https,
|
|
44
46
|
assetPrefix: normalizedConfig.dev.assetPrefix
|
|
45
47
|
},
|
|
@@ -61,11 +63,7 @@ export function createBuilderProviderConfig(normalizedConfig, appContext) {
|
|
|
61
63
|
return _objectSpread(_objectSpread({}, config.output), {}, {
|
|
62
64
|
copy: builderCopy,
|
|
63
65
|
// We need to do this in the app-tools prepare hook because some files will be generated into the dist directory in the analyze process
|
|
64
|
-
cleanDistPath: false
|
|
65
|
-
// `@modern-js/webpack` used to generate asset manifest by default
|
|
66
|
-
enableAssetManifest: true,
|
|
67
|
-
// compatible the modern-js with fallback behavior
|
|
68
|
-
enableAssetFallback: true
|
|
66
|
+
cleanDistPath: false
|
|
69
67
|
});
|
|
70
68
|
}
|
|
71
69
|
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
function loader(source) {
|
|
2
|
+
// eslint-disable-next-line @babel/no-invalid-this
|
|
3
|
+
this.cacheable();
|
|
4
|
+
// eslint-disable-next-line @babel/no-invalid-this
|
|
5
|
+
const {
|
|
6
|
+
target
|
|
7
|
+
} = this._compiler.options;
|
|
8
|
+
if (target === 'node' || Array.isArray(target) && target.includes('node')) {
|
|
9
|
+
return source;
|
|
10
|
+
}
|
|
11
|
+
// eslint-disable-next-line @babel/no-invalid-this
|
|
12
|
+
const {
|
|
13
|
+
resourcePath
|
|
14
|
+
} = this;
|
|
15
|
+
const code = `
|
|
16
|
+
export { default } from "${resourcePath}";
|
|
17
|
+
`;
|
|
18
|
+
return code;
|
|
19
|
+
}
|
|
20
|
+
export default loader;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
|
2
2
|
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
|
|
3
3
|
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
4
|
-
import { logger } from '@modern-js/utils';
|
|
5
4
|
import { ResolvedConfigContext } from '@modern-js/core';
|
|
6
5
|
import { createFileWatcher } from "../utils/createFileWatcher";
|
|
7
6
|
import { printInstructions } from "../utils/printInstructions";
|
|
@@ -47,42 +46,39 @@ export const dev = async (api, options) => {
|
|
|
47
46
|
}
|
|
48
47
|
});
|
|
49
48
|
await hookRunners.beforeDev();
|
|
50
|
-
let compiler
|
|
49
|
+
let compiler;
|
|
50
|
+
if (!appContext.builder && !apiOnly) {
|
|
51
|
+
throw new Error('Expect the Builder to have been initialized, But the appContext.builder received `undefined`');
|
|
52
|
+
}
|
|
51
53
|
if (!apiOnly) {
|
|
52
|
-
if (!appContext.builder) {
|
|
53
|
-
throw new Error('Expect the Builder to have been initialized, But the appContext.builder received `undefined`');
|
|
54
|
-
}
|
|
55
54
|
compiler = await appContext.builder.createCompiler();
|
|
56
55
|
}
|
|
57
56
|
await generateRoutes(appContext);
|
|
58
|
-
const
|
|
59
|
-
dev: _objectSpread(
|
|
60
|
-
client: {
|
|
61
|
-
port: port.toString()
|
|
62
|
-
},
|
|
63
|
-
devMiddleware: {
|
|
64
|
-
writeToDisk: file => !file.includes('.hot-update.')
|
|
65
|
-
},
|
|
66
|
-
hot: true,
|
|
67
|
-
liveReload: true,
|
|
57
|
+
const serverOptions = {
|
|
58
|
+
dev: _objectSpread({
|
|
68
59
|
port,
|
|
69
60
|
https: normalizedConfig.dev.https
|
|
70
|
-
}
|
|
71
|
-
compiler,
|
|
61
|
+
}, (_normalizedConfig$too = normalizedConfig.tools) === null || _normalizedConfig$too === void 0 ? void 0 : _normalizedConfig$too.devServer),
|
|
62
|
+
compiler: compiler || null,
|
|
72
63
|
pwd: appDirectory,
|
|
73
64
|
config: normalizedConfig,
|
|
74
65
|
serverConfigFile,
|
|
75
66
|
internalPlugins: injectDataLoaderPlugin(serverInternalPlugins)
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
} else {
|
|
67
|
+
};
|
|
68
|
+
if (apiOnly) {
|
|
69
|
+
const app = await createServer(serverOptions);
|
|
70
|
+
app.listen(port, async err => {
|
|
71
|
+
if (err) {
|
|
72
|
+
throw err;
|
|
73
|
+
}
|
|
84
74
|
printInstructions(hookRunners, appContext, normalizedConfig);
|
|
85
|
-
}
|
|
86
|
-
}
|
|
75
|
+
});
|
|
76
|
+
} else {
|
|
77
|
+
await appContext.builder.startDevServer({
|
|
78
|
+
compiler,
|
|
79
|
+
printURLs: false,
|
|
80
|
+
serverOptions
|
|
81
|
+
});
|
|
82
|
+
}
|
|
87
83
|
await createFileWatcher(appContext, normalizedConfig.source.configDir, hookRunners);
|
|
88
84
|
};
|
|
@@ -16,7 +16,6 @@ export const start = async api => {
|
|
|
16
16
|
const apiOnly = await isApiOnly(appContext.appDirectory, userConfig === null || userConfig === void 0 ? void 0 : (_userConfig$source = userConfig.source) === null || _userConfig$source === void 0 ? void 0 : _userConfig$source.entriesDir);
|
|
17
17
|
const app = await server({
|
|
18
18
|
pwd: appDirectory,
|
|
19
|
-
// FIXME: remove the `any` type
|
|
20
19
|
config: userConfig,
|
|
21
20
|
serverConfigFile,
|
|
22
21
|
internalPlugins: injectDataLoaderPlugin(appContext.serverInternalPlugins),
|
|
@@ -13,7 +13,7 @@ const getPackageConfig = (appDirectory, packageJsonConfig) => {
|
|
|
13
13
|
const json = JSON.parse(fs.readFileSync(path.resolve(appDirectory, './package.json'), 'utf8'));
|
|
14
14
|
return json[packageJsonConfig !== null && packageJsonConfig !== void 0 ? packageJsonConfig : PACKAGE_JSON_CONFIG_NAME];
|
|
15
15
|
};
|
|
16
|
-
const addServerConfigToDeps = async (dependencies, appDirectory, serverConfigFile) => {
|
|
16
|
+
export const addServerConfigToDeps = async (dependencies, appDirectory, serverConfigFile) => {
|
|
17
17
|
const serverConfig = await getServerConfig(appDirectory, serverConfigFile);
|
|
18
18
|
if (serverConfig) {
|
|
19
19
|
dependencies.push(serverConfig);
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.PAGES_DIR_NAME = exports.NESTED_ROUTES_DIR = exports.JS_EXTENSIONS = exports.INDEX_FILE_NAME = exports.HTML_PARTIALS_FOLDER = exports.HTML_PARTIALS_EXTENSIONS = exports.FILE_SYSTEM_ROUTES_LAYOUT = exports.FILE_SYSTEM_ROUTES_INDEX = exports.FILE_SYSTEM_ROUTES_IGNORED_REGEX = exports.FILE_SYSTEM_ROUTES_GLOBAL_LAYOUT = exports.FILE_SYSTEM_ROUTES_FILE_NAME = exports.FILE_SYSTEM_ROUTES_DYNAMIC_REGEXP = exports.FILE_SYSTEM_ROUTES_COMPONENTS_DIR = exports.ENTRY_POINT_FILE_NAME = exports.ENTRY_BOOTSTRAP_FILE_NAME = exports.APP_FILE_NAME = void 0;
|
|
6
|
+
exports.TEMP_LOADERS_DIR = exports.PAGES_DIR_NAME = exports.NESTED_ROUTES_DIR = exports.LOADER_EXPORT_NAME = exports.JS_EXTENSIONS = exports.INDEX_FILE_NAME = exports.HTML_PARTIALS_FOLDER = exports.HTML_PARTIALS_EXTENSIONS = exports.FILE_SYSTEM_ROUTES_LAYOUT = exports.FILE_SYSTEM_ROUTES_INDEX = exports.FILE_SYSTEM_ROUTES_IGNORED_REGEX = exports.FILE_SYSTEM_ROUTES_GLOBAL_LAYOUT = exports.FILE_SYSTEM_ROUTES_FILE_NAME = exports.FILE_SYSTEM_ROUTES_DYNAMIC_REGEXP = exports.FILE_SYSTEM_ROUTES_COMPONENTS_DIR = exports.ENTRY_POINT_FILE_NAME = exports.ENTRY_BOOTSTRAP_FILE_NAME = exports.APP_FILE_NAME = void 0;
|
|
7
7
|
const JS_EXTENSIONS = ['.js', '.ts', '.jsx', '.tsx'];
|
|
8
8
|
exports.JS_EXTENSIONS = JS_EXTENSIONS;
|
|
9
9
|
const INDEX_FILE_NAME = 'index';
|
|
@@ -16,6 +16,10 @@ const NESTED_ROUTES_DIR = 'routes';
|
|
|
16
16
|
exports.NESTED_ROUTES_DIR = NESTED_ROUTES_DIR;
|
|
17
17
|
const FILE_SYSTEM_ROUTES_FILE_NAME = 'routes.js';
|
|
18
18
|
exports.FILE_SYSTEM_ROUTES_FILE_NAME = FILE_SYSTEM_ROUTES_FILE_NAME;
|
|
19
|
+
const LOADER_EXPORT_NAME = 'loader';
|
|
20
|
+
exports.LOADER_EXPORT_NAME = LOADER_EXPORT_NAME;
|
|
21
|
+
const TEMP_LOADERS_DIR = '__loaders__';
|
|
22
|
+
exports.TEMP_LOADERS_DIR = TEMP_LOADERS_DIR;
|
|
19
23
|
const ENTRY_POINT_FILE_NAME = 'index.js';
|
|
20
24
|
exports.ENTRY_POINT_FILE_NAME = ENTRY_POINT_FILE_NAME;
|
|
21
25
|
const ENTRY_BOOTSTRAP_FILE_NAME = 'bootstrap.js';
|
|
@@ -17,6 +17,11 @@ var _nestedRoutes = require("./nestedRoutes");
|
|
|
17
17
|
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
18
18
|
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
19
19
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
20
|
+
const loader = {
|
|
21
|
+
'.js': 'jsx',
|
|
22
|
+
'.ts': 'tsx'
|
|
23
|
+
};
|
|
24
|
+
const EXTERNAL_REGEXP = /^[^./]|^\.[^./]|^\.\.[^/]/;
|
|
20
25
|
const createImportSpecifier = specifiers => {
|
|
21
26
|
let defaults = '';
|
|
22
27
|
const named = [];
|
|
@@ -73,15 +78,10 @@ const createImportStatements = statements => {
|
|
|
73
78
|
};
|
|
74
79
|
exports.createImportStatements = createImportStatements;
|
|
75
80
|
const buildLoader = async (entry, outfile) => {
|
|
76
|
-
const loader = {
|
|
77
|
-
'.js': 'jsx',
|
|
78
|
-
'.ts': 'tsx'
|
|
79
|
-
};
|
|
80
|
-
const EXTERNAL_REGEXP = /^[^./]|^\.[^./]|^\.\.[^/]/;
|
|
81
81
|
const command = (0, _commands.getCommand)();
|
|
82
82
|
await _esbuild.default.build({
|
|
83
|
-
format: '
|
|
84
|
-
platform: '
|
|
83
|
+
format: 'esm',
|
|
84
|
+
platform: 'browser',
|
|
85
85
|
target: 'esnext',
|
|
86
86
|
loader,
|
|
87
87
|
watch: command === 'dev' && {},
|
|
@@ -110,6 +110,20 @@ const buildLoader = async (entry, outfile) => {
|
|
|
110
110
|
}]
|
|
111
111
|
});
|
|
112
112
|
};
|
|
113
|
+
const buildServerLoader = async (entry, outfile) => {
|
|
114
|
+
const command = (0, _commands.getCommand)();
|
|
115
|
+
await _esbuild.default.build({
|
|
116
|
+
format: 'cjs',
|
|
117
|
+
platform: 'node',
|
|
118
|
+
target: 'esnext',
|
|
119
|
+
loader,
|
|
120
|
+
watch: command === 'dev' && {},
|
|
121
|
+
bundle: true,
|
|
122
|
+
logLevel: 'error',
|
|
123
|
+
entryPoints: [entry],
|
|
124
|
+
outfile
|
|
125
|
+
});
|
|
126
|
+
};
|
|
113
127
|
const generateCode = async (appContext, config, entrypoints, api) => {
|
|
114
128
|
var _config$runtime, _config$runtime$route;
|
|
115
129
|
const {
|
|
@@ -188,28 +202,34 @@ const generateCode = async (appContext, config, entrypoints, api) => {
|
|
|
188
202
|
code
|
|
189
203
|
} = await hookRunners.beforeGenerateRoutes({
|
|
190
204
|
entrypoint,
|
|
191
|
-
code: templates.fileSystemRoutes({
|
|
205
|
+
code: await templates.fileSystemRoutes({
|
|
192
206
|
routes,
|
|
193
207
|
ssrMode: mode,
|
|
194
208
|
nestedRoutesEntry: entrypoint.nestedRoutesEntry,
|
|
195
|
-
entryName: entrypoint.entryName
|
|
209
|
+
entryName: entrypoint.entryName,
|
|
210
|
+
internalDirectory
|
|
196
211
|
})
|
|
197
212
|
});
|
|
198
213
|
|
|
199
214
|
// extract nested router loaders
|
|
200
215
|
if (entrypoint.nestedRoutesEntry) {
|
|
201
|
-
const routesServerFile = _path.default.join(internalDirectory, entryName, '
|
|
202
|
-
const outputRoutesServerFile = _path.default.join(distDirectory,
|
|
216
|
+
const routesServerFile = _path.default.join(internalDirectory, entryName, 'route-server-loaders.js');
|
|
217
|
+
const outputRoutesServerFile = _path.default.join(distDirectory, _utils.LOADER_ROUTES_DIR, entryName, 'index.js');
|
|
203
218
|
const code = templates.routesForServer({
|
|
204
219
|
routes: routes,
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
basename: srcDirectory
|
|
208
|
-
}
|
|
220
|
+
internalDirectory,
|
|
221
|
+
entryName
|
|
209
222
|
});
|
|
210
223
|
await _utils.fs.ensureFile(routesServerFile);
|
|
211
224
|
await _utils.fs.writeFile(routesServerFile, code);
|
|
212
|
-
|
|
225
|
+
const loaderEntryFile = _path.default.join(internalDirectory, entryName, _constants.TEMP_LOADERS_DIR, 'entry.js');
|
|
226
|
+
const loaderIndexFile = _path.default.join(internalDirectory, entryName, _constants.TEMP_LOADERS_DIR, 'index.js');
|
|
227
|
+
if (await _utils.fs.pathExists(loaderEntryFile)) {
|
|
228
|
+
await buildLoader(loaderEntryFile, loaderIndexFile);
|
|
229
|
+
}
|
|
230
|
+
if (await _utils.fs.pathExists(routesServerFile)) {
|
|
231
|
+
await buildServerLoader(routesServerFile, outputRoutesServerFile);
|
|
232
|
+
}
|
|
213
233
|
}
|
|
214
234
|
_utils.fs.outputFileSync(_path.default.resolve(internalDirectory, `./${entryName}/${_constants.FILE_SYSTEM_ROUTES_FILE_NAME}`), code, 'utf8');
|
|
215
235
|
}
|
|
@@ -106,7 +106,8 @@ const collectHtmlRoutes = (entrypoints, appContext, config) => {
|
|
|
106
106
|
output: {
|
|
107
107
|
distPath: {
|
|
108
108
|
html: htmlPath
|
|
109
|
-
} = {}
|
|
109
|
+
} = {},
|
|
110
|
+
enableModernMode
|
|
110
111
|
},
|
|
111
112
|
server: {
|
|
112
113
|
baseUrl,
|
|
@@ -133,8 +134,7 @@ const collectHtmlRoutes = (entrypoints, appContext, config) => {
|
|
|
133
134
|
isSPA: true,
|
|
134
135
|
isSSR,
|
|
135
136
|
responseHeaders: resHeaders,
|
|
136
|
-
|
|
137
|
-
// enableModernMode: Boolean(enableModernMode),
|
|
137
|
+
enableModernMode: Boolean(enableModernMode),
|
|
138
138
|
bundle: isSSR ? `${_utils.SERVER_BUNDLE_DIRECTORY}/${entryName}.js` : undefined
|
|
139
139
|
};
|
|
140
140
|
if (routes !== null && routes !== void 0 && routes.hasOwnProperty(entryName)) {
|
|
@@ -19,6 +19,12 @@ const LOADING_FILE = 'loading';
|
|
|
19
19
|
const ERROR_FILE = 'error';
|
|
20
20
|
const LOADER_FILE = 'loader';
|
|
21
21
|
const conventionNames = [LAYOUT_FILE, PAGE_FILE, LOADING_FILE, ERROR_FILE, LOADER_FILE];
|
|
22
|
+
const getLoaderPath = async filename => {
|
|
23
|
+
if (await (0, _utils2.hasLoader)(filename)) {
|
|
24
|
+
return (0, _utils.normalizeToPosixPath)(filename);
|
|
25
|
+
}
|
|
26
|
+
return undefined;
|
|
27
|
+
};
|
|
22
28
|
const replaceDynamicPath = routePath => {
|
|
23
29
|
return routePath.replace(/\[(.*?)\]/g, ':$1');
|
|
24
30
|
};
|
|
@@ -56,7 +62,8 @@ const walk = async (dirname, rootDir, alias, entryName) => {
|
|
|
56
62
|
routePath = replaceDynamicPath(routePath);
|
|
57
63
|
const route = {
|
|
58
64
|
path: routePath,
|
|
59
|
-
children: []
|
|
65
|
+
children: [],
|
|
66
|
+
isRoot
|
|
60
67
|
};
|
|
61
68
|
const items = await _utils.fs.readdir(dirname);
|
|
62
69
|
for (const item of items) {
|
|
@@ -76,17 +83,21 @@ const walk = async (dirname, rootDir, alias, entryName) => {
|
|
|
76
83
|
}
|
|
77
84
|
if (itemWithoutExt === LAYOUT_FILE) {
|
|
78
85
|
route._component = (0, _utils2.replaceWithAlias)(alias.basename, itemPath, alias.name);
|
|
86
|
+
route.loader = await getLoaderPath(itemPath);
|
|
79
87
|
}
|
|
80
88
|
if (itemWithoutExt === PAGE_FILE) {
|
|
81
89
|
var _route$children2;
|
|
82
90
|
const childRoute = createIndexRoute({
|
|
83
91
|
_component: (0, _utils2.replaceWithAlias)(alias.basename, itemPath, alias.name)
|
|
84
92
|
}, rootDir, itemPath, entryName);
|
|
93
|
+
childRoute.loader = await getLoaderPath(itemPath);
|
|
85
94
|
(_route$children2 = route.children) === null || _route$children2 === void 0 ? void 0 : _route$children2.push(childRoute);
|
|
86
95
|
}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
96
|
+
|
|
97
|
+
// if (itemWithoutExt === LOADER_FILE) {
|
|
98
|
+
// route.loader = replaceWithAlias(alias.basename, itemPath, alias.name);
|
|
99
|
+
// }
|
|
100
|
+
|
|
90
101
|
if (itemWithoutExt === LOADING_FILE) {
|
|
91
102
|
route.loading = (0, _utils2.replaceWithAlias)(alias.basename, itemPath, alias.name);
|
|
92
103
|
}
|
|
@@ -4,6 +4,10 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.routesForServer = exports.renderFunction = exports.index = exports.html = exports.fileSystemRoutes = void 0;
|
|
7
|
+
var _path = _interopRequireDefault(require("path"));
|
|
8
|
+
var _utils = require("@modern-js/utils");
|
|
9
|
+
var _constants = require("./constants");
|
|
10
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
7
11
|
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
|
8
12
|
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
|
|
9
13
|
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
@@ -87,13 +91,11 @@ const html = partials => `
|
|
|
87
91
|
exports.html = html;
|
|
88
92
|
const routesForServer = ({
|
|
89
93
|
routes,
|
|
90
|
-
|
|
94
|
+
internalDirectory,
|
|
95
|
+
entryName
|
|
91
96
|
}) => {
|
|
92
|
-
const {
|
|
93
|
-
name,
|
|
94
|
-
basename
|
|
95
|
-
} = alias;
|
|
96
97
|
const loaders = [];
|
|
98
|
+
const loaderIndexFile = _path.default.join(internalDirectory, entryName, _constants.TEMP_LOADERS_DIR, 'index.js');
|
|
97
99
|
const traverseRouteTree = route => {
|
|
98
100
|
let children;
|
|
99
101
|
if ('children' in route && route.children) {
|
|
@@ -125,39 +127,44 @@ const routesForServer = ({
|
|
|
125
127
|
}
|
|
126
128
|
}
|
|
127
129
|
routesCode += `\n];`;
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
130
|
+
let importLoadersCode = '';
|
|
131
|
+
if (loaders.length > 0) {
|
|
132
|
+
importLoadersCode = `
|
|
133
|
+
import { ${loaders.map((loader, index) => `loader_${index}`)} } from "${loaderIndexFile}"`;
|
|
134
|
+
}
|
|
132
135
|
return `
|
|
133
136
|
${importLoadersCode}
|
|
134
137
|
${routesCode}
|
|
135
138
|
`;
|
|
136
139
|
};
|
|
137
140
|
exports.routesForServer = routesForServer;
|
|
138
|
-
const fileSystemRoutes = ({
|
|
141
|
+
const fileSystemRoutes = async ({
|
|
139
142
|
routes,
|
|
140
143
|
ssrMode,
|
|
141
144
|
nestedRoutesEntry,
|
|
142
|
-
entryName
|
|
145
|
+
entryName,
|
|
146
|
+
internalDirectory
|
|
143
147
|
}) => {
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
148
|
+
const loadings = [];
|
|
149
|
+
const errors = [];
|
|
150
|
+
const loaders = [];
|
|
151
|
+
const loadersMap = {};
|
|
152
|
+
const loadersIndexFile = _path.default.join('@_modern_js_internal', entryName, _constants.TEMP_LOADERS_DIR, 'index.js');
|
|
153
|
+
const loadersMapFile = _path.default.join(internalDirectory, entryName, _constants.TEMP_LOADERS_DIR, 'map.json');
|
|
147
154
|
const importLazyCode = `
|
|
148
155
|
import { lazy } from "react";
|
|
149
156
|
import loadable, { lazy as loadableLazy } from "@modern-js/runtime/loadable"
|
|
150
157
|
`;
|
|
158
|
+
let rootLayoutCode = ``;
|
|
151
159
|
let dataLoaderPath = '';
|
|
160
|
+
let componentLoaderPath = '';
|
|
152
161
|
if (ssrMode) {
|
|
153
162
|
dataLoaderPath = require.resolve(`@modern-js/plugin-data-loader/loader`);
|
|
154
163
|
if (nestedRoutesEntry) {
|
|
155
|
-
dataLoaderPath = `${dataLoaderPath}?routesDir=${nestedRoutesEntry}&
|
|
164
|
+
dataLoaderPath = `${dataLoaderPath}?routesDir=${nestedRoutesEntry}&mapFile=${loadersMapFile}!`;
|
|
156
165
|
}
|
|
166
|
+
componentLoaderPath = `${_path.default.join(__dirname, '../builder/loaders/routerLoader')}!`;
|
|
157
167
|
}
|
|
158
|
-
const loadings = [];
|
|
159
|
-
const errors = [];
|
|
160
|
-
const loaders = [];
|
|
161
168
|
const traverseRouteTree = route => {
|
|
162
169
|
let children;
|
|
163
170
|
if ('children' in route && route.children) {
|
|
@@ -179,13 +186,19 @@ const fileSystemRoutes = ({
|
|
|
179
186
|
}
|
|
180
187
|
if (route.loader) {
|
|
181
188
|
loaders.push(route.loader);
|
|
182
|
-
|
|
189
|
+
const loaderId = loaders.length - 1;
|
|
190
|
+
loader = `loader_${loaderId}`;
|
|
191
|
+
loadersMap[loader] = route.id;
|
|
183
192
|
}
|
|
184
193
|
if (route._component) {
|
|
185
|
-
if (
|
|
186
|
-
|
|
194
|
+
if (route.isRoot) {
|
|
195
|
+
rootLayoutCode = `import RootLayout from '${route._component}'`;
|
|
196
|
+
component = `RootLayout`;
|
|
197
|
+
} else if (ssrMode === 'string') {
|
|
198
|
+
component = `loadable(() => import(/* webpackChunkName: "${route.id}" */ '${componentLoaderPath}${route._component}'))`;
|
|
187
199
|
} else {
|
|
188
|
-
|
|
200
|
+
// csr and streaming
|
|
201
|
+
component = `lazy(() => import(/* webpackChunkName: "${route.id}" */ '${componentLoaderPath}${route._component}'))`;
|
|
189
202
|
}
|
|
190
203
|
}
|
|
191
204
|
} else if (route._component) {
|
|
@@ -208,7 +221,7 @@ const fileSystemRoutes = ({
|
|
|
208
221
|
for (const route of routes) {
|
|
209
222
|
if ('type' in route) {
|
|
210
223
|
const newRoute = traverseRouteTree(route);
|
|
211
|
-
routeComponentsCode += `${JSON.stringify(newRoute, null, 2).replace(/"(loadable.*\))"/g, '$1').replace(/"(loadableLazy.*\))"/g, '$1').replace(/"(lazy.*\))"/g, '$1').replace(/"(loading_[^"])"/g, '$1').replace(/"(loader_[^"])"/g, '$1').replace(/"(error_[^"])"/g, '$1').replace(/\\"/g, '"')},`;
|
|
224
|
+
routeComponentsCode += `${JSON.stringify(newRoute, null, 2).replace(/"(loadable.*\))"/g, '$1').replace(/"(loadableLazy.*\))"/g, '$1').replace(/"(lazy.*\))"/g, '$1').replace(/"(loading_[^"])"/g, '$1').replace(/"(loader_[^"])"/g, '$1').replace(/"(RootLayout)"/g, '$1').replace(/"(error_[^"])"/g, '$1').replace(/\\"/g, '"')},`;
|
|
212
225
|
} else {
|
|
213
226
|
const component = `loadable(() => import('${route._component}'))`;
|
|
214
227
|
const finalRoute = _objectSpread(_objectSpread({}, route), {}, {
|
|
@@ -224,14 +237,34 @@ const fileSystemRoutes = ({
|
|
|
224
237
|
const importErrorComponentsCode = errors.map((error, index) => {
|
|
225
238
|
return `import error_${index} from '${error}';\n`;
|
|
226
239
|
}).join('');
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
240
|
+
let importLoadersCode = '';
|
|
241
|
+
if (loaders.length > 0) {
|
|
242
|
+
importLoadersCode = `
|
|
243
|
+
import { ${loaders.map((loader, index) => `loader_${index}`)} } from "${dataLoaderPath}${loadersIndexFile}"
|
|
244
|
+
`;
|
|
245
|
+
const loaderEntryCode = loaders.map((loader, index) => {
|
|
246
|
+
return `export * from './loader_${index}.js';`;
|
|
247
|
+
}).join('\n');
|
|
248
|
+
const loaderEntryFile = _path.default.join(internalDirectory, entryName, _constants.TEMP_LOADERS_DIR, 'entry.js');
|
|
249
|
+
await _utils.fs.ensureFile(loaderEntryFile);
|
|
250
|
+
await _utils.fs.writeFile(loaderEntryFile, loaderEntryCode);
|
|
251
|
+
await _utils.fs.writeJSON(loadersMapFile, loadersMap);
|
|
252
|
+
await Promise.all(loaders.map(async (loader, index) => {
|
|
253
|
+
const name = `loader_${index}`;
|
|
254
|
+
const filename = _path.default.join(internalDirectory, entryName, _constants.TEMP_LOADERS_DIR, `${name}.js`);
|
|
255
|
+
const code = `
|
|
256
|
+
export { loader as ${name} } from '${loader}'
|
|
257
|
+
`;
|
|
258
|
+
await _utils.fs.ensureFile(filename);
|
|
259
|
+
await _utils.fs.writeFile(filename, code);
|
|
260
|
+
}));
|
|
261
|
+
}
|
|
230
262
|
return `
|
|
231
263
|
${importLazyCode}
|
|
264
|
+
${rootLayoutCode}
|
|
232
265
|
${importLoadingCode}
|
|
233
266
|
${importErrorComponentsCode}
|
|
234
|
-
${
|
|
267
|
+
${importLoadersCode}
|
|
235
268
|
${routeComponentsCode}
|
|
236
269
|
`;
|
|
237
270
|
};
|
|
@@ -3,10 +3,12 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.walkDirectory = exports.replaceWithAlias = exports.isRouteComponentFile = exports.getDefaultImports = void 0;
|
|
6
|
+
exports.walkDirectory = exports.replaceWithAlias = exports.parseModule = exports.isRouteComponentFile = exports.hasLoader = exports.getDefaultImports = void 0;
|
|
7
7
|
var _fs = _interopRequireDefault(require("fs"));
|
|
8
8
|
var _path = _interopRequireDefault(require("path"));
|
|
9
9
|
var _utils = require("@modern-js/utils");
|
|
10
|
+
var _esbuild = require("esbuild");
|
|
11
|
+
var _esModuleLexer = require("es-module-lexer");
|
|
10
12
|
var _constants = require("./constants");
|
|
11
13
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
12
14
|
const walkDirectory = dir => _fs.default.readdirSync(dir).reduce((previous, filename) => {
|
|
@@ -59,7 +61,7 @@ const getDefaultImports = ({
|
|
|
59
61
|
specifiers: [{
|
|
60
62
|
imported: 'routes'
|
|
61
63
|
}],
|
|
62
|
-
value: (0, _utils.normalizeToPosixPath)(`${internalDirAlias}/${entryName}/${_constants.FILE_SYSTEM_ROUTES_FILE_NAME}`)
|
|
64
|
+
value: (0, _utils.normalizeToPosixPath)(`${internalDirAlias}/${entryName}/${_constants.FILE_SYSTEM_ROUTES_FILE_NAME.replace('.js', '')}`)
|
|
63
65
|
};
|
|
64
66
|
if (fileSystemRoutes.globalApp) {
|
|
65
67
|
imports.push({
|
|
@@ -94,4 +96,30 @@ const isRouteComponentFile = filePath => {
|
|
|
94
96
|
};
|
|
95
97
|
exports.isRouteComponentFile = isRouteComponentFile;
|
|
96
98
|
const replaceWithAlias = (base, filePath, alias) => (0, _utils.normalizeToPosixPath)(_path.default.join(alias, _path.default.relative(base, filePath)));
|
|
97
|
-
exports.replaceWithAlias = replaceWithAlias;
|
|
99
|
+
exports.replaceWithAlias = replaceWithAlias;
|
|
100
|
+
const parseModule = async ({
|
|
101
|
+
source,
|
|
102
|
+
filename
|
|
103
|
+
}) => {
|
|
104
|
+
let content = source;
|
|
105
|
+
if (filename.endsWith('.tsx') || filename.endsWith('.jsx')) {
|
|
106
|
+
const result = await (0, _esbuild.transform)(content, {
|
|
107
|
+
loader: _path.default.extname(filename).slice(1),
|
|
108
|
+
format: 'esm'
|
|
109
|
+
});
|
|
110
|
+
content = result.code;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// eslint-disable-next-line @typescript-eslint/await-thenable
|
|
114
|
+
return await (0, _esModuleLexer.parse)(content);
|
|
115
|
+
};
|
|
116
|
+
exports.parseModule = parseModule;
|
|
117
|
+
const hasLoader = async filename => {
|
|
118
|
+
const source = await _utils.fs.readFile(filename);
|
|
119
|
+
const [, moduleExports] = await parseModule({
|
|
120
|
+
source: source.toString(),
|
|
121
|
+
filename
|
|
122
|
+
});
|
|
123
|
+
return moduleExports.some(e => e.n === _constants.LOADER_EXPORT_NAME);
|
|
124
|
+
};
|
|
125
|
+
exports.hasLoader = hasLoader;
|
|
@@ -85,6 +85,11 @@ const PluginCompatModern = (appContext, modernConfig, options) => ({
|
|
|
85
85
|
chain.plugin('route-plugin').use(_routerPlugin.default, [{
|
|
86
86
|
existNestedRoutes
|
|
87
87
|
}]);
|
|
88
|
+
if (target !== 'node') {
|
|
89
|
+
const bareServerModuleReg = /\.(server|node)\.[tj]sx?$/;
|
|
90
|
+
chain.module.rule(CHAIN_ID.RULE.JS).exclude.add(bareServerModuleReg);
|
|
91
|
+
chain.module.rule('bare-server-module').test(bareServerModuleReg).use('server-module-loader').loader(require.resolve("../loaders/serverModuleLoader"));
|
|
92
|
+
}
|
|
88
93
|
function isHtmlEnabled(config, target) {
|
|
89
94
|
var _config$tools;
|
|
90
95
|
return ((_config$tools = config.tools) === null || _config$tools === void 0 ? void 0 : _config$tools.htmlPlugin) !== false && target !== 'node' && target !== 'web-worker';
|
|
@@ -116,7 +121,7 @@ function applyCallbacks(api, options) {
|
|
|
116
121
|
*/
|
|
117
122
|
function applyNodeCompat(chain, modernConfig, isProd) {
|
|
118
123
|
// apply node resolve extensions
|
|
119
|
-
for (const ext of ['.node.js', '.node.jsx', '.node.ts', '.node.tsx']) {
|
|
124
|
+
for (const ext of ['.node.js', '.node.jsx', '.node.ts', '.node.tsx', '.server.js', '.server.ts', '.server.ts', '.server.tsx']) {
|
|
120
125
|
chain.resolve.extensions.prepend(ext);
|
|
121
126
|
}
|
|
122
127
|
|
|
@@ -43,6 +43,7 @@ async function createBuilderForEdenX({
|
|
|
43
43
|
return builder;
|
|
44
44
|
}
|
|
45
45
|
function createBuilderProviderConfig(normalizedConfig, appContext) {
|
|
46
|
+
var _normalizedConfig$ser;
|
|
46
47
|
const output = createOutputConfig(normalizedConfig, appContext);
|
|
47
48
|
return _objectSpread(_objectSpread({}, normalizedConfig), {}, {
|
|
48
49
|
source: _objectSpread(_objectSpread({}, normalizedConfig.source), {}, {
|
|
@@ -50,6 +51,7 @@ function createBuilderProviderConfig(normalizedConfig, appContext) {
|
|
|
50
51
|
}),
|
|
51
52
|
output,
|
|
52
53
|
dev: {
|
|
54
|
+
port: (_normalizedConfig$ser = normalizedConfig.server) === null || _normalizedConfig$ser === void 0 ? void 0 : _normalizedConfig$ser.port,
|
|
53
55
|
https: normalizedConfig.dev.https,
|
|
54
56
|
assetPrefix: normalizedConfig.dev.assetPrefix
|
|
55
57
|
},
|
|
@@ -71,11 +73,7 @@ function createBuilderProviderConfig(normalizedConfig, appContext) {
|
|
|
71
73
|
return _objectSpread(_objectSpread({}, config.output), {}, {
|
|
72
74
|
copy: builderCopy,
|
|
73
75
|
// We need to do this in the app-tools prepare hook because some files will be generated into the dist directory in the analyze process
|
|
74
|
-
cleanDistPath: false
|
|
75
|
-
// `@modern-js/webpack` used to generate asset manifest by default
|
|
76
|
-
enableAssetManifest: true,
|
|
77
|
-
// compatible the modern-js with fallback behavior
|
|
78
|
-
enableAssetFallback: true
|
|
76
|
+
cleanDistPath: false
|
|
79
77
|
});
|
|
80
78
|
}
|
|
81
79
|
}
|