@modern-js/utils 2.26.0 → 2.28.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/CHANGELOG.md +20 -0
- package/dist/cjs/cli/alias.js +3 -3
- package/dist/cjs/cli/constants/chainId.js +4 -0
- package/dist/cjs/cli/constants/index.js +0 -1
- package/dist/cjs/cli/is/config.js +11 -8
- package/dist/cjs/cli/prettyInstructions.js +3 -2
- package/dist/cjs/cli/require.js +2 -1
- package/dist/cjs/runtime/nestedRoutes.js +9 -5
- package/dist/cjs/runtime-browser/parsed.js +2 -1
- package/dist/cjs/universal/formatWebpack.js +55 -12
- package/dist/esm/cli/alias.js +27 -23
- package/dist/esm/cli/applyOptionsChain.js +8 -6
- package/dist/esm/cli/babel.js +50 -35
- package/dist/esm/cli/commands.js +7 -7
- package/dist/esm/cli/common.js +10 -5
- package/dist/esm/cli/constants/chainId.js +5 -1
- package/dist/esm/cli/constants/index.js +33 -38
- package/dist/esm/cli/ensure.js +4 -2
- package/dist/esm/cli/fs.js +56 -9
- package/dist/esm/cli/get/config.js +7 -7
- package/dist/esm/cli/get/data.js +102 -55
- package/dist/esm/cli/get/index.js +21 -6
- package/dist/esm/cli/is/config.js +43 -21
- package/dist/esm/cli/is/env.js +18 -6
- package/dist/esm/cli/is/platform.js +6 -2
- package/dist/esm/cli/is/project.js +73 -36
- package/dist/esm/cli/is/type.js +3 -1
- package/dist/esm/cli/logger.js +49 -38
- package/dist/esm/cli/monorepo.js +49 -36
- package/dist/esm/cli/package.js +156 -38
- package/dist/esm/cli/path.js +44 -20
- package/dist/esm/cli/pathSerializer.js +29 -15
- package/dist/esm/cli/port.js +89 -40
- package/dist/esm/cli/prettyInstructions.js +44 -32
- package/dist/esm/cli/require.js +22 -16
- package/dist/esm/cli/runtimeExports.js +21 -15
- package/dist/esm/cli/watch.js +94 -27
- package/dist/esm/compiled.js +3 -3
- package/dist/esm/import.js +4 -4
- package/dist/esm/runtime/nestedRoutes.js +49 -32
- package/dist/esm/runtime-browser/parsed.js +6 -5
- package/dist/esm/runtime-node/index.js +1 -1
- package/dist/esm/runtime-node/nestedRoutes.js +6 -4
- package/dist/esm/runtime-node/serialize.js +1 -1
- package/dist/esm/runtime-node/storage.js +12 -14
- package/dist/esm/universal/constants.js +3 -3
- package/dist/esm/universal/formatWebpack.js +54 -28
- package/dist/esm/universal/pluginDagSort.js +49 -26
- package/dist/esm-node/cli/alias.js +51 -0
- package/dist/esm-node/cli/applyOptionsChain.js +24 -0
- package/dist/esm-node/cli/babel.js +103 -0
- package/dist/esm-node/cli/commands.js +16 -0
- package/dist/esm-node/cli/common.js +10 -0
- package/dist/esm-node/cli/constants/chainId.js +184 -0
- package/dist/esm-node/cli/constants/index.js +102 -0
- package/dist/esm-node/cli/ensure.js +10 -0
- package/dist/esm-node/cli/fs.js +14 -0
- package/dist/esm-node/cli/get/config.js +16 -0
- package/dist/esm-node/cli/get/data.js +86 -0
- package/dist/esm-node/cli/get/index.js +13 -0
- package/dist/esm-node/cli/index.js +20 -0
- package/dist/esm-node/cli/is/config.js +43 -0
- package/dist/esm-node/cli/is/env.js +6 -0
- package/dist/esm-node/cli/is/index.js +5 -0
- package/dist/esm-node/cli/is/platform.js +2 -0
- package/dist/esm-node/cli/is/project.js +73 -0
- package/dist/esm-node/cli/is/type.js +25 -0
- package/dist/esm-node/cli/logger.js +103 -0
- package/dist/esm-node/cli/monorepo.js +70 -0
- package/dist/esm-node/cli/package.js +43 -0
- package/dist/esm-node/cli/path.js +49 -0
- package/dist/esm-node/cli/pathSerializer.js +46 -0
- package/dist/esm-node/cli/port.js +44 -0
- package/dist/esm-node/cli/prettyInstructions.js +78 -0
- package/dist/esm-node/cli/require.js +53 -0
- package/dist/esm-node/cli/runtimeExports.js +35 -0
- package/dist/esm-node/cli/watch.js +41 -0
- package/dist/esm-node/compiled.js +33 -0
- package/dist/esm-node/import.js +8 -0
- package/dist/esm-node/index.js +3 -0
- package/dist/esm-node/runtime/nestedRoutes.js +116 -0
- package/dist/esm-node/runtime/remixRouter.js +1 -0
- package/dist/esm-node/runtime/router.js +1 -0
- package/dist/esm-node/runtime-browser/index.js +1 -0
- package/dist/esm-node/runtime-browser/parsed.js +18 -0
- package/dist/esm-node/runtime-node/index.js +5 -0
- package/dist/esm-node/runtime-node/nestedRoutes.js +18 -0
- package/dist/esm-node/runtime-node/router.js +1 -0
- package/dist/esm-node/runtime-node/serialize.js +6 -0
- package/dist/esm-node/runtime-node/storage.js +38 -0
- package/dist/esm-node/universal/constants.js +3 -0
- package/dist/esm-node/universal/formatWebpack.js +99 -0
- package/dist/esm-node/universal/pluginDagSort.js +50 -0
- package/dist/types/cli/constants/chainId.d.ts +4 -0
- package/dist/types/universal/formatWebpack.d.ts +14 -1
- package/package.json +4 -4
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { isEmpty } from "./type";
|
|
2
|
+
export const isSSR = (config) => {
|
|
3
|
+
var _server, _server1;
|
|
4
|
+
const { server } = config;
|
|
5
|
+
if ((_server = server) === null || _server === void 0 ? void 0 : _server.ssr) {
|
|
6
|
+
return true;
|
|
7
|
+
}
|
|
8
|
+
if (((_server1 = server) === null || _server1 === void 0 ? void 0 : _server1.ssrByEntries) && !isEmpty(server.ssrByEntries)) {
|
|
9
|
+
for (const name of Object.keys(server.ssrByEntries)) {
|
|
10
|
+
if (server.ssrByEntries[name]) {
|
|
11
|
+
return true;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
return false;
|
|
16
|
+
};
|
|
17
|
+
export const isUseSSRBundle = (config) => {
|
|
18
|
+
var _output;
|
|
19
|
+
const { output } = config;
|
|
20
|
+
if ((_output = output) === null || _output === void 0 ? void 0 : _output.ssg) {
|
|
21
|
+
return true;
|
|
22
|
+
}
|
|
23
|
+
return isSSR(config);
|
|
24
|
+
};
|
|
25
|
+
export const isServiceWorker = (config) => {
|
|
26
|
+
var _deploy_worker, _deploy, _output;
|
|
27
|
+
const { output, deploy } = config;
|
|
28
|
+
if (((_deploy = deploy) === null || _deploy === void 0 ? void 0 : (_deploy_worker = _deploy.worker) === null || _deploy_worker === void 0 ? void 0 : _deploy_worker.ssr) && (((_output = output) === null || _output === void 0 ? void 0 : _output.ssg) || isSSR(config))) {
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
31
|
+
return false;
|
|
32
|
+
};
|
|
33
|
+
export const isRouterV5 = (config) => {
|
|
34
|
+
var _config_runtime, _config_runtime_router, _config_runtime1, _config;
|
|
35
|
+
return typeof ((_config_runtime = config.runtime) === null || _config_runtime === void 0 ? void 0 : _config_runtime.router) !== "boolean" && ((_config = config) === null || _config === void 0 ? void 0 : (_config_runtime1 = _config.runtime) === null || _config_runtime1 === void 0 ? void 0 : (_config_runtime_router = _config_runtime1.router) === null || _config_runtime_router === void 0 ? void 0 : _config_runtime_router.mode) === "react-router-5";
|
|
36
|
+
};
|
|
37
|
+
export const isSSGEntry = (config, entryName, entrypoints) => {
|
|
38
|
+
var _ssgConfig, _ssgConfig1;
|
|
39
|
+
const ssgConfig = config.output.ssg;
|
|
40
|
+
const useSSG = isSingleEntry(entrypoints) ? Boolean(ssgConfig) : ssgConfig === true || typeof ((_ssgConfig = ssgConfig) === null || _ssgConfig === void 0 ? void 0 : _ssgConfig[0]) === "function" || Boolean((_ssgConfig1 = ssgConfig) === null || _ssgConfig1 === void 0 ? void 0 : _ssgConfig1[entryName]);
|
|
41
|
+
return useSSG;
|
|
42
|
+
};
|
|
43
|
+
export const isSingleEntry = (entrypoints) => entrypoints.length === 1 && entrypoints[0].entryName === "main";
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export const getNodeEnv = () => process.env.NODE_ENV || "development";
|
|
2
|
+
export const isDev = () => getNodeEnv() === "development";
|
|
3
|
+
export const isProd = () => getNodeEnv() === "production";
|
|
4
|
+
export const isTest = () => getNodeEnv() === "test";
|
|
5
|
+
export const isProdProfile = () => isProd() && process.argv.includes("--profile");
|
|
6
|
+
export const isFastRefresh = () => isDev() && process.env.FAST_REFRESH !== "false";
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import path from "path";
|
|
2
|
+
import pkgUp from "../../../compiled/pkg-up";
|
|
3
|
+
import { getArgv } from "../commands";
|
|
4
|
+
import { fs, minimist, semver } from "../../compiled";
|
|
5
|
+
import { createDebugger } from "../common";
|
|
6
|
+
import { ensureArray } from "../ensure";
|
|
7
|
+
const debug = createDebugger("judge-depExists");
|
|
8
|
+
export const isDepExists = (appDirectory, name) => {
|
|
9
|
+
const pkgPath = path.resolve(appDirectory, "./package.json");
|
|
10
|
+
if (!fs.existsSync(pkgPath)) {
|
|
11
|
+
debug(`can't find package.json under: %s`, appDirectory);
|
|
12
|
+
return false;
|
|
13
|
+
}
|
|
14
|
+
const json = require(pkgPath);
|
|
15
|
+
const { dependencies = {}, devDependencies = {} } = json;
|
|
16
|
+
return dependencies.hasOwnProperty(name) || devDependencies.hasOwnProperty(name);
|
|
17
|
+
};
|
|
18
|
+
export const isPackageInstalled = (name, resolvePaths) => {
|
|
19
|
+
try {
|
|
20
|
+
require.resolve(name, {
|
|
21
|
+
paths: ensureArray(resolvePaths)
|
|
22
|
+
});
|
|
23
|
+
return true;
|
|
24
|
+
} catch (err) {
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
export const isApiOnly = async (appDirectory, entryDir, apiDir) => {
|
|
29
|
+
const existApi = await fs.pathExists(apiDir !== null && apiDir !== void 0 ? apiDir : path.join(appDirectory, "api"));
|
|
30
|
+
const existSrc = await fs.pathExists(path.join(appDirectory, entryDir !== null && entryDir !== void 0 ? entryDir : "src"));
|
|
31
|
+
const options = minimist(getArgv());
|
|
32
|
+
if (options["api-only"]) {
|
|
33
|
+
return true;
|
|
34
|
+
}
|
|
35
|
+
return existApi && !existSrc;
|
|
36
|
+
};
|
|
37
|
+
export const isWebOnly = async () => {
|
|
38
|
+
const options = minimist(getArgv());
|
|
39
|
+
return Boolean(options["web-only"]);
|
|
40
|
+
};
|
|
41
|
+
export const isBeyondReact17 = (cwd) => {
|
|
42
|
+
const pkgPath = pkgUp.sync({
|
|
43
|
+
cwd
|
|
44
|
+
});
|
|
45
|
+
if (!pkgPath) {
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
const pkgInfo = JSON.parse(fs.readFileSync(pkgPath, "utf8"));
|
|
49
|
+
const deps = {
|
|
50
|
+
...pkgInfo.devDependencies,
|
|
51
|
+
...pkgInfo.dependencies
|
|
52
|
+
};
|
|
53
|
+
if (typeof deps.react !== "string") {
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
return semver.satisfies(semver.minVersion(deps.react), ">=17.0.0");
|
|
57
|
+
};
|
|
58
|
+
export const isReact18 = (cwd) => {
|
|
59
|
+
const pkgPath = path.join(cwd, "package.json");
|
|
60
|
+
if (!fs.existsSync(pkgPath)) {
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
const pkgInfo = JSON.parse(fs.readFileSync(pkgPath, "utf8"));
|
|
64
|
+
const deps = {
|
|
65
|
+
...pkgInfo.devDependencies,
|
|
66
|
+
...pkgInfo.dependencies
|
|
67
|
+
};
|
|
68
|
+
if (typeof deps.react !== "string") {
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
return semver.satisfies(semver.minVersion(deps.react), ">=18.0.0");
|
|
72
|
+
};
|
|
73
|
+
export const isTypescript = (root) => fs.existsSync(path.resolve(root, "./tsconfig.json"));
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export function isString(str) {
|
|
2
|
+
return typeof str === "string";
|
|
3
|
+
}
|
|
4
|
+
export function isUndefined(obj) {
|
|
5
|
+
return typeof obj === "undefined";
|
|
6
|
+
}
|
|
7
|
+
export function isArray(obj) {
|
|
8
|
+
return Array.isArray(obj);
|
|
9
|
+
}
|
|
10
|
+
export function isFunction(func) {
|
|
11
|
+
return typeof func === "function";
|
|
12
|
+
}
|
|
13
|
+
export function isObject(obj) {
|
|
14
|
+
return obj !== null && typeof obj === "object";
|
|
15
|
+
}
|
|
16
|
+
export function isPlainObject(obj) {
|
|
17
|
+
return isObject(obj) && Object.prototype.toString.call(obj) === "[object Object]";
|
|
18
|
+
}
|
|
19
|
+
export function isPromise(obj) {
|
|
20
|
+
return Boolean(obj) && (typeof obj === "object" || typeof obj === "function") && typeof obj.then === "function";
|
|
21
|
+
}
|
|
22
|
+
export function isRegExp(obj) {
|
|
23
|
+
return Object.prototype.toString.call(obj) === "[object RegExp]";
|
|
24
|
+
}
|
|
25
|
+
export const isEmpty = (o) => Object.entries(o).length === 0 && o.constructor === Object;
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import chalk from "../../compiled/chalk";
|
|
2
|
+
const LOG_LEVEL = {
|
|
3
|
+
error: 0,
|
|
4
|
+
warn: 1,
|
|
5
|
+
info: 2,
|
|
6
|
+
debug: 3,
|
|
7
|
+
log: 4
|
|
8
|
+
};
|
|
9
|
+
const LOG_TYPES = {
|
|
10
|
+
error: {
|
|
11
|
+
color: "red",
|
|
12
|
+
label: "error",
|
|
13
|
+
level: "error"
|
|
14
|
+
},
|
|
15
|
+
info: {
|
|
16
|
+
color: "cyan",
|
|
17
|
+
label: "info",
|
|
18
|
+
level: "info"
|
|
19
|
+
},
|
|
20
|
+
success: {
|
|
21
|
+
color: "green",
|
|
22
|
+
label: "Success",
|
|
23
|
+
level: "info"
|
|
24
|
+
},
|
|
25
|
+
warn: {
|
|
26
|
+
color: "yellow",
|
|
27
|
+
label: "warn",
|
|
28
|
+
level: "warn"
|
|
29
|
+
},
|
|
30
|
+
debug: {
|
|
31
|
+
color: "red",
|
|
32
|
+
label: "debug",
|
|
33
|
+
level: "debug"
|
|
34
|
+
},
|
|
35
|
+
log: {
|
|
36
|
+
level: "log"
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
const DEFAULT_CONFIG = {
|
|
40
|
+
displayLabel: true,
|
|
41
|
+
uppercaseLabel: false
|
|
42
|
+
};
|
|
43
|
+
class Logger {
|
|
44
|
+
_log(type, message, ...args) {
|
|
45
|
+
if (message === void 0 || message === null) {
|
|
46
|
+
console.log();
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
if (LOG_LEVEL[type] > LOG_LEVEL[this.level]) {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
let label = "";
|
|
53
|
+
let text = "";
|
|
54
|
+
const logType = this.types[type];
|
|
55
|
+
if (this.config.displayLabel && logType.label) {
|
|
56
|
+
label = this.config.uppercaseLabel ? logType.label.toUpperCase() : logType.label;
|
|
57
|
+
label = label.padEnd(this.longestLabel.length);
|
|
58
|
+
label = chalk.bold(logType.color ? chalk[logType.color](label) : label);
|
|
59
|
+
}
|
|
60
|
+
if (message instanceof Error) {
|
|
61
|
+
if (message.stack) {
|
|
62
|
+
const [name, ...rest] = message.stack.split("\n");
|
|
63
|
+
text = `${name}
|
|
64
|
+
${chalk.grey(rest.join("\n"))}`;
|
|
65
|
+
} else {
|
|
66
|
+
text = message.message;
|
|
67
|
+
}
|
|
68
|
+
} else {
|
|
69
|
+
text = `${message}`;
|
|
70
|
+
}
|
|
71
|
+
const log = label.length > 0 ? `${label} ${text}` : text;
|
|
72
|
+
console.log(log, ...args);
|
|
73
|
+
}
|
|
74
|
+
getLongestLabel() {
|
|
75
|
+
let longestLabel = "";
|
|
76
|
+
Object.keys(this.types).forEach((type) => {
|
|
77
|
+
const { label = "" } = this.types[type];
|
|
78
|
+
if (label.length > longestLabel.length) {
|
|
79
|
+
longestLabel = label;
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
return longestLabel;
|
|
83
|
+
}
|
|
84
|
+
constructor(options = {}) {
|
|
85
|
+
this.level = options.level || LOG_TYPES.log.level;
|
|
86
|
+
this.config = {
|
|
87
|
+
...DEFAULT_CONFIG,
|
|
88
|
+
...options.config || {}
|
|
89
|
+
};
|
|
90
|
+
this.types = {
|
|
91
|
+
...LOG_TYPES,
|
|
92
|
+
...options.types || {}
|
|
93
|
+
};
|
|
94
|
+
this.longestLabel = this.getLongestLabel();
|
|
95
|
+
Object.keys(this.types).forEach((type) => {
|
|
96
|
+
this[type] = this._log.bind(this, type);
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
const logger = new Logger();
|
|
101
|
+
logger.Logger = Logger;
|
|
102
|
+
export { Logger };
|
|
103
|
+
export { logger };
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import { glob, yaml } from "../compiled";
|
|
4
|
+
const PACKAGE_MAX_DEPTH = 5;
|
|
5
|
+
const WORKSPACE_FILES = {
|
|
6
|
+
YARN: "package.json",
|
|
7
|
+
PNPM: "pnpm-workspace.yaml",
|
|
8
|
+
LERNA: "lerna.json"
|
|
9
|
+
};
|
|
10
|
+
export const isLerna = (root) => fs.existsSync(path.join(root, WORKSPACE_FILES.LERNA));
|
|
11
|
+
export const isYarnWorkspaces = (root) => {
|
|
12
|
+
var _json_workspaces;
|
|
13
|
+
const pkg = path.join(root, WORKSPACE_FILES.YARN);
|
|
14
|
+
if (!fs.existsSync(pkg)) {
|
|
15
|
+
return false;
|
|
16
|
+
}
|
|
17
|
+
const json = JSON.parse(fs.readFileSync(pkg, "utf8"));
|
|
18
|
+
return Boolean((_json_workspaces = json.workspaces) === null || _json_workspaces === void 0 ? void 0 : _json_workspaces.packages);
|
|
19
|
+
};
|
|
20
|
+
export const isPnpmWorkspaces = (root) => fs.existsSync(path.join(root, WORKSPACE_FILES.PNPM));
|
|
21
|
+
export const isMonorepo = (root) => isLerna(root) || isYarnWorkspaces(root) || isPnpmWorkspaces(root);
|
|
22
|
+
export const isModernjsMonorepo = (root) => {
|
|
23
|
+
const pkgJsonPath = path.join(root, "package.json");
|
|
24
|
+
if (!fs.existsSync(pkgJsonPath)) {
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
const json = JSON.parse(fs.readFileSync(pkgJsonPath, "utf8"));
|
|
28
|
+
const deps = {
|
|
29
|
+
...json.dependencies || {},
|
|
30
|
+
...json.devDependencies || {}
|
|
31
|
+
};
|
|
32
|
+
return Boolean(deps["@modern-js/monorepo-tools"]);
|
|
33
|
+
};
|
|
34
|
+
export const findMonorepoRoot = (appDirectory, maxDepth = PACKAGE_MAX_DEPTH) => {
|
|
35
|
+
let inMonorepo = false;
|
|
36
|
+
for (let depth = 0; depth < maxDepth; depth++) {
|
|
37
|
+
if (isMonorepo(appDirectory)) {
|
|
38
|
+
inMonorepo = true;
|
|
39
|
+
break;
|
|
40
|
+
}
|
|
41
|
+
appDirectory = path.dirname(appDirectory);
|
|
42
|
+
}
|
|
43
|
+
return inMonorepo ? appDirectory : void 0;
|
|
44
|
+
};
|
|
45
|
+
export const getMonorepoPackages = (root) => {
|
|
46
|
+
let packages = [];
|
|
47
|
+
if (isYarnWorkspaces(root)) {
|
|
48
|
+
const json = JSON.parse(fs.readFileSync(path.join(root, "package.json"), "utf8"));
|
|
49
|
+
({ packages } = json.workspaces);
|
|
50
|
+
} else if (isLerna(root)) {
|
|
51
|
+
const json = JSON.parse(fs.readFileSync(path.resolve(root, "lerna.json"), "utf8"));
|
|
52
|
+
({ packages } = json);
|
|
53
|
+
} else {
|
|
54
|
+
({ packages } = yaml.load(fs.readFileSync(path.join(root, WORKSPACE_FILES.PNPM), "utf8")));
|
|
55
|
+
}
|
|
56
|
+
if (packages) {
|
|
57
|
+
return packages.map((name) => (
|
|
58
|
+
// The trailing / ensures only dirs are picked up
|
|
59
|
+
glob.sync(path.join(root, `${name}/`), {
|
|
60
|
+
ignore: [
|
|
61
|
+
"**/node_modules/**"
|
|
62
|
+
]
|
|
63
|
+
})
|
|
64
|
+
)).reduce((acc, val) => acc.concat(val), []).filter((filepath) => fs.existsSync(path.resolve(filepath, "package.json"))).map((filepath) => ({
|
|
65
|
+
path: filepath,
|
|
66
|
+
name: JSON.parse(fs.readFileSync(path.resolve(filepath, "package.json"), "utf8")).name
|
|
67
|
+
}));
|
|
68
|
+
}
|
|
69
|
+
return [];
|
|
70
|
+
};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { execa } from "../compiled";
|
|
2
|
+
export async function getPnpmVersion() {
|
|
3
|
+
const { stdout } = await execa("pnpm", [
|
|
4
|
+
"--version"
|
|
5
|
+
]);
|
|
6
|
+
return stdout;
|
|
7
|
+
}
|
|
8
|
+
export async function canUseNpm() {
|
|
9
|
+
try {
|
|
10
|
+
await execa("npm", [
|
|
11
|
+
"--version"
|
|
12
|
+
], {
|
|
13
|
+
env: process.env
|
|
14
|
+
});
|
|
15
|
+
return true;
|
|
16
|
+
} catch (e) {
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
export async function canUseYarn() {
|
|
21
|
+
try {
|
|
22
|
+
await execa("yarn", [
|
|
23
|
+
"--version"
|
|
24
|
+
], {
|
|
25
|
+
env: process.env
|
|
26
|
+
});
|
|
27
|
+
return true;
|
|
28
|
+
} catch (e) {
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
export async function canUsePnpm() {
|
|
33
|
+
try {
|
|
34
|
+
await execa("pnpm", [
|
|
35
|
+
"--version"
|
|
36
|
+
], {
|
|
37
|
+
env: process.env
|
|
38
|
+
});
|
|
39
|
+
return true;
|
|
40
|
+
} catch (e) {
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import path from "path";
|
|
2
|
+
import os from "os";
|
|
3
|
+
import fs from "fs";
|
|
4
|
+
import { nanoid, upath, lodash as _ } from "../compiled";
|
|
5
|
+
export const isPathString = (test) => path.posix.basename(test) !== test || path.win32.basename(test) !== test;
|
|
6
|
+
export const isRelativePath = (test) => /^\.\.?($|[\\/])/.test(test);
|
|
7
|
+
export const normalizeOutputPath = (s) => s.replace(/\\/g, "\\\\");
|
|
8
|
+
export const normalizeToPosixPath = (p) => upath.normalizeSafe(path.normalize(p || "")).replace(/^([a-zA-Z]+):/, (_2, m) => `/${m.toLowerCase()}`);
|
|
9
|
+
export const getTemplatePath = (prefix) => {
|
|
10
|
+
const tmpRoot = fs.realpathSync(os.tmpdir());
|
|
11
|
+
const parts = [
|
|
12
|
+
tmpRoot
|
|
13
|
+
];
|
|
14
|
+
prefix && parts.push(prefix);
|
|
15
|
+
parts.push(nanoid());
|
|
16
|
+
return path.resolve(...parts);
|
|
17
|
+
};
|
|
18
|
+
export function compilePathMatcherRegExp(match) {
|
|
19
|
+
if (typeof match !== "string") {
|
|
20
|
+
return match;
|
|
21
|
+
}
|
|
22
|
+
const escaped = _.escapeRegExp(match);
|
|
23
|
+
return new RegExp(`(?<=\\W|^)${escaped}(?=\\W|$)`);
|
|
24
|
+
}
|
|
25
|
+
export const _joinPathParts = (_part, i, parts) => _(parts).filter((part) => ![
|
|
26
|
+
"/",
|
|
27
|
+
"\\"
|
|
28
|
+
].includes(part)).tap((parts2) => parts2.unshift("")).slice(0, i + 2).join("/");
|
|
29
|
+
export function upwardPaths(start) {
|
|
30
|
+
return _(start).split(/[/\\]/).filter(Boolean).map(_joinPathParts).reverse().push("/").value();
|
|
31
|
+
}
|
|
32
|
+
export function getRealTemporaryDirectory() {
|
|
33
|
+
let ret = null;
|
|
34
|
+
try {
|
|
35
|
+
ret = os.tmpdir();
|
|
36
|
+
ret = fs.realpathSync(ret);
|
|
37
|
+
} catch {
|
|
38
|
+
}
|
|
39
|
+
return ret;
|
|
40
|
+
}
|
|
41
|
+
export function splitPathString(str) {
|
|
42
|
+
return str.split(/[\\/]/);
|
|
43
|
+
}
|
|
44
|
+
export const removeLeadingSlash = (s) => s.replace(/^\/+/, "");
|
|
45
|
+
export const removeTailSlash = (s) => s.replace(/\/+$/, "");
|
|
46
|
+
export const removeSlash = (s) => removeLeadingSlash(removeTailSlash(s));
|
|
47
|
+
export const cutNameByHyphen = (s) => {
|
|
48
|
+
return s.split(/[-_]/)[0];
|
|
49
|
+
};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import os from "os";
|
|
2
|
+
import _ from "../../compiled/lodash";
|
|
3
|
+
import { compilePathMatcherRegExp, normalizeToPosixPath, getRealTemporaryDirectory, splitPathString, upwardPaths } from "./path";
|
|
4
|
+
export const matchUpwardPathsAsUnknown = (p) => _(upwardPaths(normalizeToPosixPath(p))).map((match) => ({
|
|
5
|
+
match,
|
|
6
|
+
mark: "unknown"
|
|
7
|
+
})).slice(1, -1).value();
|
|
8
|
+
export function applyPathMatcher(matcher, str, options = {}) {
|
|
9
|
+
const regex = compilePathMatcherRegExp(matcher.match);
|
|
10
|
+
const replacer = (substring, ...args) => {
|
|
11
|
+
if (options.minPartials && splitPathString(substring).length < options.minPartials) {
|
|
12
|
+
return substring;
|
|
13
|
+
}
|
|
14
|
+
const ret = typeof matcher.mark === "string" ? matcher.mark : matcher.mark(substring, ...args);
|
|
15
|
+
return `<${_.snakeCase(ret).toUpperCase()}>`;
|
|
16
|
+
};
|
|
17
|
+
return str.replace(regex, replacer);
|
|
18
|
+
}
|
|
19
|
+
export function applyMatcherReplacement(matchers, str, options = {}) {
|
|
20
|
+
return matchers.reduce((ret, matcher) => {
|
|
21
|
+
return applyPathMatcher(matcher, ret, options);
|
|
22
|
+
}, str);
|
|
23
|
+
}
|
|
24
|
+
export const createDefaultPathMatchers = (root) => {
|
|
25
|
+
const ret = [
|
|
26
|
+
{
|
|
27
|
+
match: RegExp("(?<=\\/)(\\.pnpm\\/.+?\\/node_modules)(?=\\/)"),
|
|
28
|
+
mark: "pnpmInner"
|
|
29
|
+
}
|
|
30
|
+
];
|
|
31
|
+
const tmpdir = getRealTemporaryDirectory();
|
|
32
|
+
tmpdir && ret.push({
|
|
33
|
+
match: tmpdir,
|
|
34
|
+
mark: "temp"
|
|
35
|
+
});
|
|
36
|
+
ret.push({
|
|
37
|
+
match: os.tmpdir(),
|
|
38
|
+
mark: "temp"
|
|
39
|
+
});
|
|
40
|
+
ret.push({
|
|
41
|
+
match: os.homedir(),
|
|
42
|
+
mark: "home"
|
|
43
|
+
});
|
|
44
|
+
ret.push(...matchUpwardPathsAsUnknown(root));
|
|
45
|
+
return ret;
|
|
46
|
+
};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import net from "net";
|
|
2
|
+
import { chalk } from "../compiled";
|
|
3
|
+
import { logger } from "./logger";
|
|
4
|
+
export const getPort = async (port, { tryLimits = 20, strictPort = false } = {}) => {
|
|
5
|
+
if (typeof port === "string") {
|
|
6
|
+
port = parseInt(port, 10);
|
|
7
|
+
}
|
|
8
|
+
if (strictPort) {
|
|
9
|
+
tryLimits = 1;
|
|
10
|
+
}
|
|
11
|
+
const original = port;
|
|
12
|
+
let found = false;
|
|
13
|
+
let attempts = 0;
|
|
14
|
+
while (!found && attempts <= tryLimits) {
|
|
15
|
+
try {
|
|
16
|
+
await new Promise((resolve, reject) => {
|
|
17
|
+
const server = net.createServer();
|
|
18
|
+
server.unref();
|
|
19
|
+
server.on("error", reject);
|
|
20
|
+
server.listen({
|
|
21
|
+
port,
|
|
22
|
+
host: "0.0.0.0"
|
|
23
|
+
}, () => {
|
|
24
|
+
found = true;
|
|
25
|
+
server.close(resolve);
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
} catch (e) {
|
|
29
|
+
if (e.code !== "EADDRINUSE") {
|
|
30
|
+
throw e;
|
|
31
|
+
}
|
|
32
|
+
port++;
|
|
33
|
+
attempts++;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
if (port !== original) {
|
|
37
|
+
if (strictPort) {
|
|
38
|
+
throw new Error(`Port "${original}" is occupied, please choose another one.`);
|
|
39
|
+
} else {
|
|
40
|
+
logger.info(`Something is already running on port ${original}. ${chalk.yellow(`Use port ${port} instead.`)}`);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return port;
|
|
44
|
+
};
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import os from "os";
|
|
2
|
+
import { chalk } from "../compiled";
|
|
3
|
+
import { isDev, isSingleEntry } from "./is";
|
|
4
|
+
import { DEFAULT_DEV_HOST } from "./constants";
|
|
5
|
+
const normalizeUrl = (url) => url.replace(/([^:]\/)\/+/g, "$1");
|
|
6
|
+
const getIpv4Interfaces = () => {
|
|
7
|
+
const interfaces = os.networkInterfaces();
|
|
8
|
+
const ipv4Interfaces = [];
|
|
9
|
+
Object.keys(interfaces).forEach((key) => {
|
|
10
|
+
interfaces[key].forEach((detail) => {
|
|
11
|
+
const familyV4Value = typeof detail.family === "string" ? "IPv4" : 4;
|
|
12
|
+
if (detail.family === familyV4Value) {
|
|
13
|
+
ipv4Interfaces.push(detail);
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
});
|
|
17
|
+
return ipv4Interfaces;
|
|
18
|
+
};
|
|
19
|
+
export const getAddressUrls = (protocol = "http", port, host) => {
|
|
20
|
+
const LOCAL_LABEL = "Local: ";
|
|
21
|
+
const NETWORK_LABEL = "Network: ";
|
|
22
|
+
const isLocalhost = (url) => {
|
|
23
|
+
var _url;
|
|
24
|
+
return (_url = url) === null || _url === void 0 ? void 0 : _url.includes("localhost");
|
|
25
|
+
};
|
|
26
|
+
if (host && host !== DEFAULT_DEV_HOST) {
|
|
27
|
+
return [
|
|
28
|
+
{
|
|
29
|
+
label: isLocalhost(host) ? LOCAL_LABEL : NETWORK_LABEL,
|
|
30
|
+
url: `${protocol}://${host}:${port}`
|
|
31
|
+
}
|
|
32
|
+
];
|
|
33
|
+
}
|
|
34
|
+
const ipv4Interfaces = getIpv4Interfaces();
|
|
35
|
+
return ipv4Interfaces.reduce((memo, detail) => {
|
|
36
|
+
if (isLocalhost(detail.address) || detail.internal) {
|
|
37
|
+
memo.push({
|
|
38
|
+
label: LOCAL_LABEL,
|
|
39
|
+
url: `${protocol}://localhost:${port}`
|
|
40
|
+
});
|
|
41
|
+
} else {
|
|
42
|
+
memo.push({
|
|
43
|
+
label: NETWORK_LABEL,
|
|
44
|
+
url: `${protocol}://${detail.address}:${port}`
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
return memo;
|
|
48
|
+
}, []);
|
|
49
|
+
};
|
|
50
|
+
export const prettyInstructions = (appContext, config) => {
|
|
51
|
+
var _appContext_builder_context_devServer, _appContext_builder, _config_dev;
|
|
52
|
+
const { entrypoints, serverRoutes, port, apiOnly, checkedEntries } = appContext;
|
|
53
|
+
const isHttps = isDev() && ((_appContext_builder = appContext.builder) === null || _appContext_builder === void 0 ? void 0 : (_appContext_builder_context_devServer = _appContext_builder.context.devServer) === null || _appContext_builder_context_devServer === void 0 ? void 0 : _appContext_builder_context_devServer.https);
|
|
54
|
+
const urls = getAddressUrls(isHttps ? "https" : "http", port, (_config_dev = config.dev) === null || _config_dev === void 0 ? void 0 : _config_dev.host);
|
|
55
|
+
const routes = !apiOnly ? serverRoutes.filter((route) => route.entryName) : serverRoutes;
|
|
56
|
+
let message = "App running at:\n\n";
|
|
57
|
+
if (isSingleEntry(entrypoints) || apiOnly) {
|
|
58
|
+
message += urls.map(({ label, url }) => ` ${chalk.bold(`> ${label.padEnd(10)}`)}${chalk.cyanBright(normalizeUrl(`${url}/${routes[0].urlPath}`))}
|
|
59
|
+
`).join("");
|
|
60
|
+
} else {
|
|
61
|
+
const maxNameLength = Math.max(...routes.map((r) => r.entryName.length));
|
|
62
|
+
urls.forEach(({ label, url }) => {
|
|
63
|
+
message += ` ${chalk.bold(`> ${label}`)}
|
|
64
|
+
`;
|
|
65
|
+
routes.forEach(({ entryName, urlPath, isSSR }) => {
|
|
66
|
+
if (!checkedEntries.includes(entryName)) {
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
message += ` ${chalk.yellowBright(isSSR ? "λ" : "○")} ${chalk.yellowBright(entryName.padEnd(maxNameLength + 8))}${chalk.cyanBright(normalizeUrl(`${url}/${urlPath}`))}
|
|
70
|
+
`;
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
message += "\n";
|
|
74
|
+
message += chalk.cyanBright(" λ (Server) server-side renders at runtime\n");
|
|
75
|
+
message += chalk.cyanBright(" ○ (Static) client-side renders as static HTML\n");
|
|
76
|
+
}
|
|
77
|
+
return message;
|
|
78
|
+
};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { findExists } from "./fs";
|
|
2
|
+
export const compatRequire = (filePath, interop = true) => {
|
|
3
|
+
var _mod;
|
|
4
|
+
const mod = require(filePath);
|
|
5
|
+
const rtnESMDefault = interop && ((_mod = mod) === null || _mod === void 0 ? void 0 : _mod.__esModule);
|
|
6
|
+
return rtnESMDefault ? mod.default : mod;
|
|
7
|
+
};
|
|
8
|
+
export const dynamicImport = new Function("modulePath", "return import(modulePath)");
|
|
9
|
+
export const requireExistModule = (filename, opt) => {
|
|
10
|
+
const final = {
|
|
11
|
+
extensions: [
|
|
12
|
+
".ts",
|
|
13
|
+
".js"
|
|
14
|
+
],
|
|
15
|
+
interop: true,
|
|
16
|
+
...opt
|
|
17
|
+
};
|
|
18
|
+
const exist = findExists(final.extensions.map((ext) => `${filename}${ext}`));
|
|
19
|
+
if (!exist) {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
return compatRequire(exist, final.interop);
|
|
23
|
+
};
|
|
24
|
+
export const cleanRequireCache = (filelist) => {
|
|
25
|
+
filelist.forEach((filepath) => {
|
|
26
|
+
delete require.cache[filepath];
|
|
27
|
+
});
|
|
28
|
+
};
|
|
29
|
+
export function deleteRequireCache(path) {
|
|
30
|
+
if (require.cache[path]) {
|
|
31
|
+
delete require.cache[path];
|
|
32
|
+
}
|
|
33
|
+
if (module.children) {
|
|
34
|
+
module.children = module.children.filter((item) => item.filename !== path);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
export const tryResolve = (name, resolvePath) => {
|
|
38
|
+
let filePath = "";
|
|
39
|
+
try {
|
|
40
|
+
filePath = require.resolve(name, {
|
|
41
|
+
paths: [
|
|
42
|
+
resolvePath
|
|
43
|
+
]
|
|
44
|
+
});
|
|
45
|
+
delete require.cache[filePath];
|
|
46
|
+
} catch (err) {
|
|
47
|
+
if (err.code === "MODULE_NOT_FOUND") {
|
|
48
|
+
throw new Error(`Can not find module ${name}.`);
|
|
49
|
+
}
|
|
50
|
+
throw err;
|
|
51
|
+
}
|
|
52
|
+
return filePath;
|
|
53
|
+
};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import path from "path";
|
|
2
|
+
import { fs } from "../compiled";
|
|
3
|
+
import { normalizeOutputPath } from "./path";
|
|
4
|
+
const memo = (fn) => {
|
|
5
|
+
const cache = /* @__PURE__ */ new Map();
|
|
6
|
+
return (...params) => {
|
|
7
|
+
const stringifiedParams = JSON.stringify(params);
|
|
8
|
+
const cachedResult = cache.get(stringifiedParams);
|
|
9
|
+
if (cachedResult) {
|
|
10
|
+
return cachedResult;
|
|
11
|
+
}
|
|
12
|
+
const res = fn(...params);
|
|
13
|
+
cache.set(stringifiedParams, res);
|
|
14
|
+
return res;
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
export const createRuntimeExportsUtils = memo((pwd = "", namespace = "index") => {
|
|
18
|
+
const entryExportFile = path.join(pwd, `.runtime-exports/${namespace}.js`);
|
|
19
|
+
const addExport = (statement) => {
|
|
20
|
+
statement = normalizeOutputPath(statement);
|
|
21
|
+
try {
|
|
22
|
+
fs.ensureFileSync(entryExportFile);
|
|
23
|
+
if (!fs.readFileSync(entryExportFile, "utf8").includes(statement)) {
|
|
24
|
+
fs.appendFileSync(entryExportFile, `${statement}
|
|
25
|
+
`);
|
|
26
|
+
}
|
|
27
|
+
} catch {
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
const getPath = () => entryExportFile;
|
|
31
|
+
return {
|
|
32
|
+
addExport,
|
|
33
|
+
getPath
|
|
34
|
+
};
|
|
35
|
+
});
|