@modern-js/app-tools 2.49.0 → 2.49.1-alpha.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (32) hide show
  1. package/dist/cjs/builder/builder-webpack/index.js +1 -1
  2. package/dist/cjs/index.js +3 -1
  3. package/dist/cjs/plugins/deploy/dependencies.js +257 -0
  4. package/dist/cjs/plugins/deploy/entrys/netlify.js +95 -0
  5. package/dist/cjs/plugins/deploy/entrys/node.js +88 -0
  6. package/dist/cjs/plugins/deploy/entrys/vercel.js +95 -0
  7. package/dist/cjs/plugins/deploy/index.js +140 -0
  8. package/dist/cjs/plugins/deploy/utils.js +150 -0
  9. package/dist/esm/builder/builder-webpack/index.js +1 -1
  10. package/dist/esm/index.js +3 -1
  11. package/dist/esm/plugins/deploy/dependencies.js +726 -0
  12. package/dist/esm/plugins/deploy/entrys/netlify.js +41 -0
  13. package/dist/esm/plugins/deploy/entrys/node.js +39 -0
  14. package/dist/esm/plugins/deploy/entrys/vercel.js +41 -0
  15. package/dist/esm/plugins/deploy/index.js +219 -0
  16. package/dist/esm/plugins/deploy/utils.js +244 -0
  17. package/dist/esm-node/builder/builder-webpack/index.js +1 -1
  18. package/dist/esm-node/index.js +3 -1
  19. package/dist/esm-node/plugins/deploy/dependencies.js +223 -0
  20. package/dist/esm-node/plugins/deploy/entrys/netlify.js +71 -0
  21. package/dist/esm-node/plugins/deploy/entrys/node.js +64 -0
  22. package/dist/esm-node/plugins/deploy/entrys/vercel.js +71 -0
  23. package/dist/esm-node/plugins/deploy/index.js +110 -0
  24. package/dist/esm-node/plugins/deploy/utils.js +109 -0
  25. package/dist/types/plugins/deploy/dependencies.d.ts +1 -0
  26. package/dist/types/plugins/deploy/entrys/netlify.d.ts +5 -0
  27. package/dist/types/plugins/deploy/entrys/node.d.ts +5 -0
  28. package/dist/types/plugins/deploy/entrys/vercel.d.ts +5 -0
  29. package/dist/types/plugins/deploy/index.d.ts +4 -0
  30. package/dist/types/plugins/deploy/utils.d.ts +27 -0
  31. package/dist/types/types/config/tools.d.ts +1 -1
  32. package/package.json +16 -13
@@ -0,0 +1,223 @@
1
+ import path, { isAbsolute } from "node:path";
2
+ import { nodeFileTrace, resolve } from "@vercel/nft";
3
+ import { fs as fse, pkgUp } from "@modern-js/utils";
4
+ import { readPackageJSON } from "pkg-types";
5
+ import { parseNodeModulePath } from "mlly";
6
+ import { linkPackage, writePackage } from "./utils";
7
+ const readDirRecursive = async (dir) => {
8
+ const files = await fse.readdir(dir, {
9
+ withFileTypes: true
10
+ });
11
+ const filesAndDirs = await Promise.all(files.map(async (file) => {
12
+ const resPath = path.resolve(dir, file.name);
13
+ return file.isDirectory() ? readDirRecursive(resPath) : resPath;
14
+ }));
15
+ return filesAndDirs.flat();
16
+ };
17
+ async function isFile(file) {
18
+ try {
19
+ const stat = await fse.stat(file);
20
+ return stat.isFile();
21
+ } catch (error) {
22
+ if (error.code === "ENOENT") {
23
+ return false;
24
+ }
25
+ throw error;
26
+ }
27
+ }
28
+ const findEntryFiles = async (rootDir) => {
29
+ const files = await readDirRecursive(rootDir);
30
+ return files;
31
+ };
32
+ const handleDependencies = async (appDir, serverRootDir, include) => {
33
+ const base = "/";
34
+ const entryFiles = await findEntryFiles(serverRootDir);
35
+ const includeEntries = include.map((item) => {
36
+ if (isAbsolute(item)) {
37
+ return item;
38
+ }
39
+ try {
40
+ return require.resolve(item);
41
+ } catch (error) {
42
+ }
43
+ return item;
44
+ });
45
+ const _fileTrace = await nodeFileTrace(entryFiles.concat(includeEntries), {
46
+ base,
47
+ processCwd: serverRootDir,
48
+ resolve: async (id, parent, job, isCjs) => {
49
+ if (id.startsWith("@modern-js/prod-server")) {
50
+ return require.resolve(id, {
51
+ paths: [
52
+ require.resolve("@modern-js/app-tools")
53
+ ]
54
+ });
55
+ } else {
56
+ return resolve(id, parent, job, isCjs);
57
+ }
58
+ }
59
+ });
60
+ const currentProjectModules = path.join(appDir, "node_modules");
61
+ const _resolveTracedPath = (p) => fse.realpath(path.resolve(base, p));
62
+ const tracedFiles = Object.fromEntries(await Promise.all([
63
+ ..._fileTrace.reasons.entries()
64
+ ].map(async ([_path, reasons]) => {
65
+ if (reasons.ignored) {
66
+ return;
67
+ }
68
+ const filePath = await _resolveTracedPath(_path);
69
+ if (filePath.startsWith(serverRootDir) || filePath.startsWith(appDir) && !filePath.startsWith(currentProjectModules)) {
70
+ return;
71
+ }
72
+ if (!await isFile(filePath)) {
73
+ return;
74
+ }
75
+ let baseDir;
76
+ let pkgName;
77
+ let subpath;
78
+ let pkgPath;
79
+ if (filePath.includes("node_modules")) {
80
+ const parsed = parseNodeModulePath(filePath);
81
+ baseDir = parsed.dir;
82
+ pkgName = parsed.name;
83
+ subpath = parsed.subpath;
84
+ pkgPath = path.join(baseDir, pkgName);
85
+ } else {
86
+ const MODERN_UTILS_PATH = "packages/toolkit/utils";
87
+ const MODERN_UTILS_PATH_REGEX = new RegExp(`(.*${MODERN_UTILS_PATH})`);
88
+ const match = filePath.match(MODERN_UTILS_PATH_REGEX);
89
+ const packageJsonPath = match ? path.join(match[0], "package.json") : await pkgUp({
90
+ cwd: path.dirname(filePath)
91
+ });
92
+ if (packageJsonPath) {
93
+ const packageJson = await fse.readJSON(packageJsonPath);
94
+ pkgPath = baseDir = path.dirname(packageJsonPath);
95
+ subpath = path.relative(baseDir, filePath);
96
+ pkgName = packageJson.name;
97
+ }
98
+ }
99
+ if (!baseDir) {
100
+ return;
101
+ }
102
+ const parents = await Promise.all([
103
+ ...reasons.parents
104
+ ].map((p) => _resolveTracedPath(p)));
105
+ const tracedFile = {
106
+ path: filePath,
107
+ parents,
108
+ subpath,
109
+ pkgName,
110
+ pkgPath
111
+ };
112
+ return [
113
+ filePath,
114
+ tracedFile
115
+ ];
116
+ })).then((r) => r.filter(Boolean)));
117
+ const tracedPackages = {};
118
+ for (const tracedFile of Object.values(tracedFiles)) {
119
+ const { pkgName } = tracedFile;
120
+ let tracedPackage = tracedPackages[pkgName];
121
+ let pkgJSON = await readPackageJSON(tracedFile.pkgPath, {
122
+ cache: true
123
+ }).catch(() => {
124
+ });
125
+ if (!pkgJSON) {
126
+ pkgJSON = {
127
+ name: pkgName,
128
+ version: "0.0.0"
129
+ };
130
+ }
131
+ if (!tracedPackage) {
132
+ tracedPackage = {
133
+ name: pkgName,
134
+ versions: {}
135
+ };
136
+ tracedPackages[pkgName] = tracedPackage;
137
+ }
138
+ let tracedPackageVersion = tracedPackage.versions[pkgJSON.version];
139
+ if (!tracedPackageVersion) {
140
+ tracedPackageVersion = {
141
+ path: tracedFile.pkgPath,
142
+ files: [],
143
+ pkgJSON
144
+ };
145
+ tracedPackage.versions[pkgJSON.version] = tracedPackageVersion;
146
+ }
147
+ tracedFile.path.startsWith(tracedFile.pkgPath) && tracedPackageVersion.path === tracedFile.pkgPath && tracedPackageVersion.files.push(tracedFile.path);
148
+ tracedFile.pkgName = pkgName;
149
+ tracedFile.pkgVersion = pkgJSON.version;
150
+ }
151
+ const findPackageParents = (pkg, version) => {
152
+ const versionFiles = pkg.versions[version].files.map((path2) => tracedFiles[path2]);
153
+ const parentPkgs = [
154
+ ...new Set(versionFiles.flatMap((file) => file.parents.map((parentPath) => {
155
+ const parentFile = tracedFiles[parentPath];
156
+ if (parentFile.pkgName === pkg.name) {
157
+ return null;
158
+ }
159
+ return `${parentFile.pkgName}@${parentFile.pkgVersion}`;
160
+ }).filter(Boolean)))
161
+ ];
162
+ return parentPkgs;
163
+ };
164
+ const multiVersionPkgs = {};
165
+ const singleVersionPackages = [];
166
+ for (const tracedPackage of Object.values(tracedPackages)) {
167
+ const versions = Object.keys(tracedPackage.versions);
168
+ if (versions.length === 1) {
169
+ singleVersionPackages.push(tracedPackage.name);
170
+ continue;
171
+ }
172
+ multiVersionPkgs[tracedPackage.name] = {};
173
+ for (const version of versions) {
174
+ multiVersionPkgs[tracedPackage.name][version] = findPackageParents(tracedPackage, version);
175
+ }
176
+ }
177
+ await Promise.all(singleVersionPackages.map((pkgName) => {
178
+ const pkg = tracedPackages[pkgName];
179
+ const version = Object.keys(pkg.versions)[0];
180
+ return writePackage(pkg, version, serverRootDir);
181
+ }));
182
+ console.log("multiVersionPkgs111111111", multiVersionPkgs);
183
+ for (const [pkgName, pkgVersions] of Object.entries(multiVersionPkgs)) {
184
+ const versionEntires = Object.entries(pkgVersions).sort(
185
+ // TODO: remove ts-ignore
186
+ // @ts-expect-error
187
+ ([v1, p1], [v2, p2]) => {
188
+ if (p1.length === 0) {
189
+ return -1;
190
+ }
191
+ if (p2.length === 0) {
192
+ return 1;
193
+ }
194
+ }
195
+ );
196
+ for (const [version, parentPkgs] of versionEntires) {
197
+ const pkg = tracedPackages[pkgName];
198
+ const pkgDestPath = `.modernjs/${pkgName}@${version}/node_modules/${pkgName}`;
199
+ await writePackage(pkg, version, serverRootDir, pkgDestPath);
200
+ await linkPackage(pkgDestPath, `${pkgName}`, serverRootDir);
201
+ for (const parentPkg of parentPkgs) {
202
+ const parentPkgName = parentPkg.replace(/@[^@]+$/, "");
203
+ await (multiVersionPkgs[parentPkgName] ? linkPackage(pkgDestPath, `.modernjs/${parentPkg}/node_modules/${pkgName}@${version}`, path.join(serverRootDir, "node_modules")) : linkPackage(pkgDestPath, `${parentPkgName}/node_modules/${pkgName}@${version}`, path.join(serverRootDir, "node_modules")));
204
+ }
205
+ }
206
+ }
207
+ const projectPkg = await readPackageJSON(serverRootDir).catch(() => ({}));
208
+ const outputPkgPath = path.join(serverRootDir, "package.json");
209
+ await fse.writeJSON(outputPkgPath, {
210
+ name: `${projectPkg.name || "modernjs-project"}-prod`,
211
+ version: projectPkg.version || "0.0.0",
212
+ private: true,
213
+ dependencies: Object.fromEntries([
214
+ ...Object.values(tracedPackages).map((pkg) => [
215
+ pkg.name,
216
+ Object.keys(pkg.versions)[0]
217
+ ])
218
+ ].sort(([a], [b]) => a.localeCompare(b)))
219
+ });
220
+ };
221
+ export {
222
+ handleDependencies
223
+ };
@@ -0,0 +1,71 @@
1
+ import { ROUTE_SPEC_FILE, DEFAULT_SERVER_CONFIG } from "@modern-js/utils";
2
+ import { genPluginImportsCode, getPluginsCode, severAppContextTemplate } from "../utils";
3
+ function genNetlifyEntry({ config, plugins, appContext } = {}) {
4
+ const defaultConfig = {
5
+ server: {
6
+ port: 8080
7
+ },
8
+ output: {
9
+ path: "."
10
+ }
11
+ };
12
+ return `
13
+
14
+ const fs = require('node:fs/promises');
15
+ const path = require('node:path');
16
+ const { createNetlifyFunction } = require('@modern-js/prod-server/netlify');
17
+ ${genPluginImportsCode(plugins || [])}
18
+
19
+ let requestHandler = null;
20
+
21
+ if(!process.env.NODE_ENV){
22
+ process.env.NODE_ENV = 'production';
23
+ }
24
+
25
+ async function createHandler() {
26
+ try {
27
+ let routes = [];
28
+ const routeFilepath = path.join(__dirname, "${ROUTE_SPEC_FILE}");
29
+ try {
30
+ await fs.access(routeFilepath);
31
+ const content = await fs.readFile(routeFilepath, "utf-8");
32
+ const routeSpec = JSON.parse(content);
33
+ routes = routeSpec.routes;
34
+ } catch (error) {
35
+ console.warn('route.json not found, continuing with empty routes.');
36
+ }
37
+
38
+ const prodServerOptions = {
39
+ pwd: __dirname,
40
+ routes,
41
+ config: ${JSON.stringify(config || defaultConfig)},
42
+ serverConfigFile: '${DEFAULT_SERVER_CONFIG}',
43
+ plugins: ${getPluginsCode(plugins || [])},
44
+ appContext: ${appContext ? severAppContextTemplate(appContext) : "undefined"},
45
+ disableCustomHook: true
46
+ }
47
+
48
+ requestHandler = await createNetlifyFunction(prodServerOptions)
49
+
50
+ return requestHandler
51
+ } catch(error) {
52
+ console.error(error);
53
+ process.exit(1);
54
+ }
55
+ }
56
+
57
+ createHandler();
58
+
59
+ const handleRequest = async(request, context) => {
60
+ if(typeof requestHandler !== 'function'){
61
+ await createHandler();
62
+ }
63
+ return requestHandler(request, context);
64
+ }
65
+
66
+ export default handleRequest;
67
+ `;
68
+ }
69
+ export {
70
+ genNetlifyEntry
71
+ };
@@ -0,0 +1,64 @@
1
+ import { ROUTE_SPEC_FILE, DEFAULT_SERVER_CONFIG } from "@modern-js/utils";
2
+ import { genPluginImportsCode, getPluginsCode, severAppContextTemplate } from "../utils";
3
+ function genNodeEntry({ config, plugins, appContext } = {}) {
4
+ const defaultConfig = {
5
+ server: {
6
+ port: 8080
7
+ },
8
+ output: {
9
+ path: "."
10
+ }
11
+ };
12
+ return `
13
+
14
+ const fs = require('node:fs/promises');
15
+ const path = require('node:path');
16
+ const { createProdServer } = require('@modern-js/prod-server');
17
+ ${genPluginImportsCode(plugins || [])}
18
+
19
+ if(!process.env.NODE_ENV){
20
+ process.env.NODE_ENV = 'production';
21
+ }
22
+
23
+ async function main() {
24
+ try {
25
+ let routes = [];
26
+ const routeFilepath = path.join(__dirname, "${ROUTE_SPEC_FILE}");
27
+ try {
28
+ await fs.access(routeFilepath);
29
+ const content = await fs.readFile(routeFilepath, "utf-8");
30
+ const routeSpec = JSON.parse(content);
31
+ routes = routeSpec.routes;
32
+ } catch (error) {
33
+ console.warn('route.json not found, continuing with empty routes.');
34
+ }
35
+
36
+ const prodServerOptions = {
37
+ pwd: __dirname,
38
+ routes,
39
+ config: ${JSON.stringify(config || defaultConfig)},
40
+ serverConfigFile: '${DEFAULT_SERVER_CONFIG}',
41
+ plugins: ${getPluginsCode(plugins || [])},
42
+ appContext: ${appContext ? severAppContextTemplate(appContext) : "undefined"},
43
+ disableCustomHook: true
44
+ }
45
+
46
+ const app = await createProdServer(prodServerOptions)
47
+
48
+ const port = process.env.PORT || 3000;
49
+
50
+ app.listen(port, () => {
51
+ console.log('\\x1b[32mServer is listening on port', port, '\\x1b[0m');
52
+ });
53
+ } catch(error) {
54
+ console.error(error);
55
+ process.exit(1);
56
+ }
57
+ }
58
+
59
+ main();
60
+ `;
61
+ }
62
+ export {
63
+ genNodeEntry
64
+ };
@@ -0,0 +1,71 @@
1
+ import { ROUTE_SPEC_FILE, DEFAULT_SERVER_CONFIG } from "@modern-js/utils";
2
+ import { genPluginImportsCode, getPluginsCode, severAppContextTemplate } from "../utils";
3
+ function genVercelEntry({ config, plugins, appContext } = {}) {
4
+ const defaultConfig = {
5
+ server: {
6
+ port: 8080
7
+ },
8
+ output: {
9
+ path: "."
10
+ }
11
+ };
12
+ return `
13
+
14
+ const fs = require('node:fs/promises');
15
+ const path = require('node:path');
16
+ const { createNetlifyFunction } = require('@modern-js/prod-server/netlify');
17
+ ${genPluginImportsCode(plugins || [])}
18
+
19
+ let requestHandler = null;
20
+
21
+ if(!process.env.NODE_ENV){
22
+ process.env.NODE_ENV = 'production';
23
+ }
24
+
25
+ async function createHandler() {
26
+ try {
27
+ let routes = [];
28
+ const routeFilepath = path.join(__dirname, "${ROUTE_SPEC_FILE}");
29
+ try {
30
+ await fs.access(routeFilepath);
31
+ const content = await fs.readFile(routeFilepath, "utf-8");
32
+ const routeSpec = JSON.parse(content);
33
+ routes = routeSpec.routes;
34
+ } catch (error) {
35
+ console.warn('route.json not found, continuing with empty routes.');
36
+ }
37
+
38
+ const prodServerOptions = {
39
+ pwd: __dirname,
40
+ routes,
41
+ config: ${JSON.stringify(config || defaultConfig)},
42
+ serverConfigFile: '${DEFAULT_SERVER_CONFIG}',
43
+ plugins: ${getPluginsCode(plugins || [])},
44
+ appContext: ${appContext ? severAppContextTemplate(appContext) : "undefined"},
45
+ disableCustomHook: true
46
+ }
47
+
48
+ requestHandler = await createNetlifyFunction(prodServerOptions)
49
+
50
+ return requestHandler
51
+ } catch(error) {
52
+ console.error(error);
53
+ process.exit(1);
54
+ }
55
+ }
56
+
57
+ createHandler();
58
+
59
+ const handleRequest = async(request, context) => {
60
+ if(typeof requestHandler !== 'function'){
61
+ await createHandler();
62
+ }
63
+ return requestHandler(request, context);
64
+ }
65
+
66
+ export default handleRequest;
67
+ `;
68
+ }
69
+ export {
70
+ genVercelEntry
71
+ };
@@ -0,0 +1,110 @@
1
+ import path from "path";
2
+ import { fs as fse, getInternalPlugins } from "@modern-js/utils";
3
+ import { getProjectUsage } from "./utils";
4
+ import { handleDependencies } from "./dependencies";
5
+ var deploy_default = () => ({
6
+ name: "@modern-js/plugin-deploy",
7
+ pre: [
8
+ "@modern-js/plugin-bff",
9
+ "@modern-js/plugin-server"
10
+ ],
11
+ setup: (api) => {
12
+ return {
13
+ async beforeDeploy() {
14
+ const deployTarget = process.env.MODERNJS_DEPLOY || "node";
15
+ const appContext = api.useAppContext();
16
+ const { appDirectory, distDirectory, serverInternalPlugins, sharedDirectory, apiDirectory, lambdaDirectory, metaName } = appContext;
17
+ const configContext = api.useResolvedConfigContext();
18
+ const outputDirectory = path.join(appDirectory, ".output");
19
+ let funcsDirectory = outputDirectory;
20
+ let staticDirectory = path.join(outputDirectory, "static");
21
+ await fse.remove(outputDirectory);
22
+ if (deployTarget === "node") {
23
+ await fse.copy(distDirectory, outputDirectory, {
24
+ filter: (src) => {
25
+ const distStaticDirectory = path.join(distDirectory, "static");
26
+ return !src.includes(distStaticDirectory);
27
+ }
28
+ });
29
+ }
30
+ if (deployTarget === "vercel") {
31
+ funcsDirectory = path.join(outputDirectory, "functions");
32
+ staticDirectory = path.join(outputDirectory, "static");
33
+ await fse.copy(distDirectory, funcsDirectory, {
34
+ filter: (src) => {
35
+ const distStaticDirectory = path.join(distDirectory, "static");
36
+ return !src.includes(distStaticDirectory);
37
+ }
38
+ });
39
+ await fse.copy(path.join(distDirectory, "static"), staticDirectory);
40
+ await fse.writeJSON(path.join(funcsDirectory, ".vc-config.json"), {
41
+ runtime: "nodejs16.x",
42
+ handler: "index.js",
43
+ launcherType: "Nodejs",
44
+ shouldAddHelpers: false,
45
+ supportsResponseStreaming: true
46
+ });
47
+ }
48
+ const { bff } = configContext;
49
+ const config = {
50
+ output: {
51
+ path: "."
52
+ },
53
+ bff
54
+ };
55
+ const plugins = getInternalPlugins(appDirectory, serverInternalPlugins);
56
+ const serverAppContext = {
57
+ sharedDirectory: `path.join(__dirname, "${path.relative(appDirectory, sharedDirectory)}")`,
58
+ apiDirectory: `path.join(__dirname, "${path.relative(appDirectory, apiDirectory)}")`,
59
+ lambdaDirectory: `path.join(__dirname, "${path.relative(appDirectory, lambdaDirectory)}")`,
60
+ metaName
61
+ };
62
+ let code = ``;
63
+ console.log("deployTarget111111111", deployTarget);
64
+ switch (deployTarget) {
65
+ case "node": {
66
+ const { genNodeEntry } = await import("./entrys/node");
67
+ code = genNodeEntry({
68
+ plugins,
69
+ config,
70
+ appContext: serverAppContext
71
+ });
72
+ break;
73
+ }
74
+ case "vercel": {
75
+ const { genVercelEntry } = await import("./entrys/vercel");
76
+ code = genVercelEntry({
77
+ plugins,
78
+ config,
79
+ appContext: serverAppContext
80
+ });
81
+ break;
82
+ }
83
+ case "netlify": {
84
+ const { genNetlifyEntry } = await import("./entrys/netlify");
85
+ code = genNetlifyEntry({
86
+ plugins,
87
+ config,
88
+ appContext: serverAppContext
89
+ });
90
+ break;
91
+ }
92
+ default: {
93
+ code = `throw new Error("unknown deploy target, MODERNJS_DEPLOY should be set");`;
94
+ }
95
+ }
96
+ const { useSSR, useAPI, useWebServer } = getProjectUsage(appDirectory, distDirectory);
97
+ const entryFilePath = path.join(funcsDirectory, "index.js");
98
+ if (useSSR || useAPI || useWebServer) {
99
+ await fse.writeFile(entryFilePath, code);
100
+ }
101
+ await handleDependencies(appDirectory, funcsDirectory, [
102
+ "@modern-js/prod-server"
103
+ ]);
104
+ }
105
+ };
106
+ }
107
+ });
108
+ export {
109
+ deploy_default as default
110
+ };
@@ -0,0 +1,109 @@
1
+ import path from "path";
2
+ import os from "node:os";
3
+ import { ROUTE_SPEC_FILE, fs as fse, isDepExists } from "@modern-js/utils";
4
+ import { parseNodeModulePath } from "mlly";
5
+ const severAppContextTemplate = (serverAppContext) => {
6
+ return `{
7
+ sharedDirectory: ${serverAppContext.sharedDirectory},
8
+ apiDirectory: ${serverAppContext.apiDirectory},
9
+ lambdaDirectory: ${serverAppContext.lambdaDirectory},
10
+ }`;
11
+ };
12
+ const getPluginsCode = (plugins) => `[${plugins.map((_, index) => `plugin_${index}()`).join(",")}]`;
13
+ const genPluginImportsCode = (plugins) => {
14
+ return plugins.map((plugin, index) => `
15
+ let plugin_${index} = require('${plugin}')
16
+ plugin_${index} = plugin_${index}.default || plugin_${index}
17
+ `).join(";\n");
18
+ };
19
+ const getProjectUsage = (appDirectory, distDirectory) => {
20
+ const routeJSON = path.join(distDirectory, ROUTE_SPEC_FILE);
21
+ const { routes } = fse.readJSONSync(routeJSON);
22
+ let useSSR = false;
23
+ let useAPI = false;
24
+ routes.forEach((route) => {
25
+ if (route.isSSR) {
26
+ useSSR = true;
27
+ }
28
+ if (route.isApi) {
29
+ useAPI = true;
30
+ }
31
+ });
32
+ const useWebServer = isDepExists(appDirectory, "@modern-js/plugin-server");
33
+ return {
34
+ useSSR,
35
+ useAPI,
36
+ useWebServer
37
+ };
38
+ };
39
+ function applyProductionCondition(exports) {
40
+ if (!exports || typeof exports === "string") {
41
+ return;
42
+ }
43
+ if (exports.production) {
44
+ if (typeof exports.production === "string") {
45
+ exports.default = exports.production;
46
+ } else {
47
+ Object.assign(exports, exports.production);
48
+ }
49
+ }
50
+ for (const key in exports) {
51
+ applyProductionCondition(exports[key]);
52
+ }
53
+ }
54
+ function applyPublicCondition(pkg) {
55
+ var _pkg_publishConfig;
56
+ if (pkg === null || pkg === void 0 ? void 0 : (_pkg_publishConfig = pkg.publishConfig) === null || _pkg_publishConfig === void 0 ? void 0 : _pkg_publishConfig.exports) {
57
+ var _pkg_publishConfig1;
58
+ pkg.exports = pkg === null || pkg === void 0 ? void 0 : (_pkg_publishConfig1 = pkg.publishConfig) === null || _pkg_publishConfig1 === void 0 ? void 0 : _pkg_publishConfig1.exports;
59
+ }
60
+ }
61
+ const writePackage = async (pkg, version, projectDir, _pkgPath) => {
62
+ const pkgPath = _pkgPath || pkg.name;
63
+ for (const src of pkg.versions[version].files) {
64
+ if (src.includes("node_modules")) {
65
+ const { subpath } = parseNodeModulePath(src);
66
+ const dest = path.join(projectDir, "node_modules", pkgPath, subpath);
67
+ const dirname = path.dirname(dest);
68
+ await fse.ensureDir(dirname);
69
+ await fse.copyFile(src, dest);
70
+ } else {
71
+ const subpath = path.relative(pkg.versions[version].path, src);
72
+ const dest = path.join(projectDir, "node_modules", pkgPath, subpath);
73
+ const dirname = path.dirname(dest);
74
+ await fse.ensureDir(dirname);
75
+ await fse.copyFile(src, dest);
76
+ }
77
+ }
78
+ const { pkgJSON } = pkg.versions[version];
79
+ applyPublicCondition(pkgJSON);
80
+ const packageJsonPath = path.join(projectDir, "node_modules", pkgPath, "package.json");
81
+ await fse.ensureDir(path.dirname(packageJsonPath));
82
+ await fse.writeFile(packageJsonPath, JSON.stringify(pkgJSON, null, 2));
83
+ };
84
+ const isWindows = os.platform() === "win32";
85
+ const linkPackage = async (from, to, projectRootDir) => {
86
+ const src = path.join(projectRootDir, "node_modules", from);
87
+ const dest = path.join(projectRootDir, "node_modules", to);
88
+ const dstStat = await fse.lstat(dest).catch(() => null);
89
+ const exists = dstStat === null || dstStat === void 0 ? void 0 : dstStat.isSymbolicLink();
90
+ if (exists) {
91
+ return;
92
+ }
93
+ await fse.mkdir(path.dirname(dest), {
94
+ recursive: true
95
+ });
96
+ await fse.symlink(path.relative(path.dirname(dest), src), dest, isWindows ? "junction" : "dir").catch((error) => {
97
+ console.error("Cannot link", from, "to", to, error);
98
+ });
99
+ };
100
+ export {
101
+ applyProductionCondition,
102
+ applyPublicCondition,
103
+ genPluginImportsCode,
104
+ getPluginsCode,
105
+ getProjectUsage,
106
+ linkPackage,
107
+ severAppContextTemplate,
108
+ writePackage
109
+ };
@@ -0,0 +1 @@
1
+ export declare const handleDependencies: (appDir: string, serverRootDir: string, include: string[]) => Promise<void>;
@@ -0,0 +1,5 @@
1
+ export declare function genNetlifyEntry({ config, plugins, appContext, }?: {
2
+ config?: Record<string, any>;
3
+ plugins?: string[];
4
+ appContext?: Record<string, any>;
5
+ }): string;
@@ -0,0 +1,5 @@
1
+ export declare function genNodeEntry({ config, plugins, appContext, }?: {
2
+ config?: Record<string, any>;
3
+ plugins?: string[];
4
+ appContext?: Record<string, any>;
5
+ }): string;
@@ -0,0 +1,5 @@
1
+ export declare function genVercelEntry({ config, plugins, appContext, }?: {
2
+ config?: Record<string, any>;
3
+ plugins?: string[];
4
+ appContext?: Record<string, any>;
5
+ }): string;
@@ -0,0 +1,4 @@
1
+ import { CliPlugin } from '@modern-js/core';
2
+ import { AppTools } from '../../types';
3
+ declare const _default: () => CliPlugin<AppTools>;
4
+ export default _default;