@omnific/react-scripts 0.1.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/README.md +22 -0
- package/dist/env-DxzdvROc.js +22 -0
- package/dist/index.js +29 -0
- package/dist/main.cjs +73 -0
- package/dist/main.d.cts +30 -0
- package/dist/main.d.ts +30 -0
- package/dist/main.js +43 -0
- package/dist/rspack.config-8gFQGJU3.js +285 -0
- package/dist/scripts/build.js +195 -0
- package/dist/scripts/dev.js +299 -0
- package/package.json +68 -0
package/README.md
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# @omnific/react-scripts
|
|
2
|
+
|
|
3
|
+
Usage:
|
|
4
|
+
|
|
5
|
+
```sh
|
|
6
|
+
npm i -D @omnific/react-scripts @swc/helpers tailwindcss
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
In `package.json`:
|
|
10
|
+
|
|
11
|
+
```json
|
|
12
|
+
{
|
|
13
|
+
"scripts": {
|
|
14
|
+
"dev": "react-scripts dev",
|
|
15
|
+
"build": "react-scripts build"
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Create `react-scripts.config.ts`, `react-scripts.config.mts`, `react-scripts.config.mjs`, or `react-scripts.config.cjs` if you need to customize Rspack.
|
|
21
|
+
|
|
22
|
+
Use `.mjs` or `.cjs` if your runtime Node.js version does not support native TypeScript imports.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
//#region utils/env.ts
|
|
2
|
+
const DEVELOPMENT = "development";
|
|
3
|
+
const PRODUCTION = "production";
|
|
4
|
+
const envKeys = ["NODE_ENV", "SCRIPT"];
|
|
5
|
+
/**
|
|
6
|
+
* 设置环境变量
|
|
7
|
+
* @param env
|
|
8
|
+
*/
|
|
9
|
+
function setEnv(data) {
|
|
10
|
+
for (const key of envKeys) if (data[key]) process.env[key] = data[key];
|
|
11
|
+
}
|
|
12
|
+
function getEnv() {
|
|
13
|
+
return process.env.NODE_ENV || "development";
|
|
14
|
+
}
|
|
15
|
+
function isDevelopment() {
|
|
16
|
+
return getEnv() === DEVELOPMENT;
|
|
17
|
+
}
|
|
18
|
+
function isProduction() {
|
|
19
|
+
return getEnv() === PRODUCTION;
|
|
20
|
+
}
|
|
21
|
+
//#endregion
|
|
22
|
+
export { isProduction as a, isDevelopment as i, PRODUCTION as n, setEnv as o, getEnv as r, DEVELOPMENT as t };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { n as PRODUCTION, o as setEnv, t as DEVELOPMENT } from "./env-DxzdvROc.js";
|
|
3
|
+
import { styleText } from "node:util";
|
|
4
|
+
//#region index.ts
|
|
5
|
+
process.on("unhandledRejection", (error) => {
|
|
6
|
+
if (error instanceof Error) {
|
|
7
|
+
console.log(styleText("red", error.message));
|
|
8
|
+
process.exit(1);
|
|
9
|
+
} else throw error;
|
|
10
|
+
});
|
|
11
|
+
const args = process.argv.slice(2);
|
|
12
|
+
const scriptLoaders = {
|
|
13
|
+
build: () => import("./scripts/build.js"),
|
|
14
|
+
dev: () => import("./scripts/dev.js")
|
|
15
|
+
};
|
|
16
|
+
const scriptIndex = args.findIndex((script) => script === "build" || script === "dev");
|
|
17
|
+
if (scriptIndex === -1) {
|
|
18
|
+
console.log("Unknown script \"" + args[0] + "\".");
|
|
19
|
+
process.exit(1);
|
|
20
|
+
} else {
|
|
21
|
+
const script = args[scriptIndex];
|
|
22
|
+
setEnv({
|
|
23
|
+
NODE_ENV: script === "dev" ? DEVELOPMENT : PRODUCTION,
|
|
24
|
+
SCRIPT: script
|
|
25
|
+
});
|
|
26
|
+
await scriptLoaders[script]();
|
|
27
|
+
}
|
|
28
|
+
//#endregion
|
|
29
|
+
export {};
|
package/dist/main.cjs
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
//#region \0rolldown/runtime.js
|
|
3
|
+
var __create = Object.create;
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
8
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
11
|
+
key = keys[i];
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
13
|
+
get: ((k) => from[k]).bind(null, key),
|
|
14
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
20
|
+
value: mod,
|
|
21
|
+
enumerable: true
|
|
22
|
+
}) : target, mod));
|
|
23
|
+
//#endregion
|
|
24
|
+
let node_fs = require("node:fs");
|
|
25
|
+
node_fs = __toESM(node_fs, 1);
|
|
26
|
+
let node_path = require("node:path");
|
|
27
|
+
node_path = __toESM(node_path, 1);
|
|
28
|
+
//#region utils/env.ts
|
|
29
|
+
const DEVELOPMENT = "development";
|
|
30
|
+
const PRODUCTION = "production";
|
|
31
|
+
function getEnv() {
|
|
32
|
+
return process.env.NODE_ENV || "development";
|
|
33
|
+
}
|
|
34
|
+
function isDevelopment() {
|
|
35
|
+
return getEnv() === DEVELOPMENT;
|
|
36
|
+
}
|
|
37
|
+
function isProduction() {
|
|
38
|
+
return getEnv() === PRODUCTION;
|
|
39
|
+
}
|
|
40
|
+
function isBuild() {
|
|
41
|
+
return process.env.SCRIPT === "build";
|
|
42
|
+
}
|
|
43
|
+
//#endregion
|
|
44
|
+
//#region paths.ts
|
|
45
|
+
const appDirectory = node_fs.default.realpathSync(process.cwd());
|
|
46
|
+
function resolveApp(relativePath) {
|
|
47
|
+
return node_path.default.resolve(appDirectory, relativePath);
|
|
48
|
+
}
|
|
49
|
+
var paths_default = {
|
|
50
|
+
appSrc: resolveApp("src"),
|
|
51
|
+
appPath: resolveApp("."),
|
|
52
|
+
appBuild: resolveApp("build"),
|
|
53
|
+
appIndexJs: resolveApp("src/index.tsx"),
|
|
54
|
+
publicUrlOrPath: isDevelopment() ? "/" : "./",
|
|
55
|
+
appHtml: resolveApp("public/index.html"),
|
|
56
|
+
appTsConfig: resolveApp("./tsconfig.json"),
|
|
57
|
+
appNodeModules: resolveApp("node_modules"),
|
|
58
|
+
appPackageJson: resolveApp("package.json"),
|
|
59
|
+
appPublic: resolveApp("public"),
|
|
60
|
+
config: resolveApp("react-scripts.config")
|
|
61
|
+
};
|
|
62
|
+
//#endregion
|
|
63
|
+
//#region main.ts
|
|
64
|
+
function defineConfig(config) {
|
|
65
|
+
return config;
|
|
66
|
+
}
|
|
67
|
+
//#endregion
|
|
68
|
+
exports.defineConfig = defineConfig;
|
|
69
|
+
exports.getEnv = getEnv;
|
|
70
|
+
exports.isBuild = isBuild;
|
|
71
|
+
exports.isDevelopment = isDevelopment;
|
|
72
|
+
exports.isProduction = isProduction;
|
|
73
|
+
exports.paths = paths_default;
|
package/dist/main.d.cts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { Configuration } from "@rspack/core";
|
|
2
|
+
|
|
3
|
+
//#region paths.d.ts
|
|
4
|
+
declare const _default: {
|
|
5
|
+
appSrc: string;
|
|
6
|
+
appPath: string;
|
|
7
|
+
appBuild: string;
|
|
8
|
+
appIndexJs: string;
|
|
9
|
+
publicUrlOrPath: string;
|
|
10
|
+
appHtml: string;
|
|
11
|
+
appTsConfig: string;
|
|
12
|
+
appNodeModules: string;
|
|
13
|
+
appPackageJson: string;
|
|
14
|
+
appPublic: string;
|
|
15
|
+
config: string;
|
|
16
|
+
};
|
|
17
|
+
//#endregion
|
|
18
|
+
//#region utils/env.d.ts
|
|
19
|
+
declare function getEnv(): string;
|
|
20
|
+
declare function isDevelopment(): boolean;
|
|
21
|
+
declare function isProduction(): boolean;
|
|
22
|
+
declare function isBuild(): boolean;
|
|
23
|
+
//#endregion
|
|
24
|
+
//#region main.d.ts
|
|
25
|
+
type ReactScriptsConfig = {
|
|
26
|
+
configureRspack?: (config: Configuration) => Configuration;
|
|
27
|
+
};
|
|
28
|
+
declare function defineConfig(config: ReactScriptsConfig): ReactScriptsConfig;
|
|
29
|
+
//#endregion
|
|
30
|
+
export { ReactScriptsConfig, defineConfig, getEnv, isBuild, isDevelopment, isProduction, _default as paths };
|
package/dist/main.d.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { Configuration } from "@rspack/core";
|
|
2
|
+
|
|
3
|
+
//#region paths.d.ts
|
|
4
|
+
declare const _default: {
|
|
5
|
+
appSrc: string;
|
|
6
|
+
appPath: string;
|
|
7
|
+
appBuild: string;
|
|
8
|
+
appIndexJs: string;
|
|
9
|
+
publicUrlOrPath: string;
|
|
10
|
+
appHtml: string;
|
|
11
|
+
appTsConfig: string;
|
|
12
|
+
appNodeModules: string;
|
|
13
|
+
appPackageJson: string;
|
|
14
|
+
appPublic: string;
|
|
15
|
+
config: string;
|
|
16
|
+
};
|
|
17
|
+
//#endregion
|
|
18
|
+
//#region utils/env.d.ts
|
|
19
|
+
declare function getEnv(): string;
|
|
20
|
+
declare function isDevelopment(): boolean;
|
|
21
|
+
declare function isProduction(): boolean;
|
|
22
|
+
declare function isBuild(): boolean;
|
|
23
|
+
//#endregion
|
|
24
|
+
//#region main.d.ts
|
|
25
|
+
type ReactScriptsConfig = {
|
|
26
|
+
configureRspack?: (config: Configuration) => Configuration;
|
|
27
|
+
};
|
|
28
|
+
declare function defineConfig(config: ReactScriptsConfig): ReactScriptsConfig;
|
|
29
|
+
//#endregion
|
|
30
|
+
export { ReactScriptsConfig, defineConfig, getEnv, isBuild, isDevelopment, isProduction, _default as paths };
|
package/dist/main.js
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
//#region utils/env.ts
|
|
4
|
+
const DEVELOPMENT = "development";
|
|
5
|
+
const PRODUCTION = "production";
|
|
6
|
+
function getEnv() {
|
|
7
|
+
return process.env.NODE_ENV || "development";
|
|
8
|
+
}
|
|
9
|
+
function isDevelopment() {
|
|
10
|
+
return getEnv() === DEVELOPMENT;
|
|
11
|
+
}
|
|
12
|
+
function isProduction() {
|
|
13
|
+
return getEnv() === PRODUCTION;
|
|
14
|
+
}
|
|
15
|
+
function isBuild() {
|
|
16
|
+
return process.env.SCRIPT === "build";
|
|
17
|
+
}
|
|
18
|
+
//#endregion
|
|
19
|
+
//#region paths.ts
|
|
20
|
+
const appDirectory = fs.realpathSync(process.cwd());
|
|
21
|
+
function resolveApp(relativePath) {
|
|
22
|
+
return path.resolve(appDirectory, relativePath);
|
|
23
|
+
}
|
|
24
|
+
var paths_default = {
|
|
25
|
+
appSrc: resolveApp("src"),
|
|
26
|
+
appPath: resolveApp("."),
|
|
27
|
+
appBuild: resolveApp("build"),
|
|
28
|
+
appIndexJs: resolveApp("src/index.tsx"),
|
|
29
|
+
publicUrlOrPath: isDevelopment() ? "/" : "./",
|
|
30
|
+
appHtml: resolveApp("public/index.html"),
|
|
31
|
+
appTsConfig: resolveApp("./tsconfig.json"),
|
|
32
|
+
appNodeModules: resolveApp("node_modules"),
|
|
33
|
+
appPackageJson: resolveApp("package.json"),
|
|
34
|
+
appPublic: resolveApp("public"),
|
|
35
|
+
config: resolveApp("react-scripts.config")
|
|
36
|
+
};
|
|
37
|
+
//#endregion
|
|
38
|
+
//#region main.ts
|
|
39
|
+
function defineConfig(config) {
|
|
40
|
+
return config;
|
|
41
|
+
}
|
|
42
|
+
//#endregion
|
|
43
|
+
export { defineConfig, getEnv, isBuild, isDevelopment, isProduction, paths_default as paths };
|
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
import { a as isProduction, i as isDevelopment, r as getEnv } from "./env-DxzdvROc.js";
|
|
2
|
+
import { createRequire } from "node:module";
|
|
3
|
+
import { rspack } from "@rspack/core";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import fs, { existsSync } from "node:fs";
|
|
6
|
+
import { ReactRefreshRspackPlugin } from "@rspack/plugin-react-refresh";
|
|
7
|
+
//#region paths.ts
|
|
8
|
+
const appDirectory = fs.realpathSync(process.cwd());
|
|
9
|
+
function resolveApp(relativePath) {
|
|
10
|
+
return path.resolve(appDirectory, relativePath);
|
|
11
|
+
}
|
|
12
|
+
var paths_default = {
|
|
13
|
+
appSrc: resolveApp("src"),
|
|
14
|
+
appPath: resolveApp("."),
|
|
15
|
+
appBuild: resolveApp("build"),
|
|
16
|
+
appIndexJs: resolveApp("src/index.tsx"),
|
|
17
|
+
publicUrlOrPath: isDevelopment() ? "/" : "./",
|
|
18
|
+
appHtml: resolveApp("public/index.html"),
|
|
19
|
+
appTsConfig: resolveApp("./tsconfig.json"),
|
|
20
|
+
appNodeModules: resolveApp("node_modules"),
|
|
21
|
+
appPackageJson: resolveApp("package.json"),
|
|
22
|
+
appPublic: resolveApp("public"),
|
|
23
|
+
config: resolveApp("react-scripts.config")
|
|
24
|
+
};
|
|
25
|
+
//#endregion
|
|
26
|
+
//#region utils/find-entry-file.ts
|
|
27
|
+
const fileExtensions = [
|
|
28
|
+
"ts",
|
|
29
|
+
"mts",
|
|
30
|
+
"mjs",
|
|
31
|
+
"cjs",
|
|
32
|
+
"js"
|
|
33
|
+
];
|
|
34
|
+
/**
|
|
35
|
+
* Find a file with any of the supported JavaScript extensions
|
|
36
|
+
* @param basePath - The base path without extension
|
|
37
|
+
* @returns The file path with extension if found, or a default path
|
|
38
|
+
*/
|
|
39
|
+
function findEntryFile(basePath) {
|
|
40
|
+
for (const ext of fileExtensions) {
|
|
41
|
+
const filePath = `${basePath}.${ext}`;
|
|
42
|
+
if (existsSync(filePath)) return filePath;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
//#endregion
|
|
46
|
+
//#region config.ts
|
|
47
|
+
function isPlainObject(value) {
|
|
48
|
+
return typeof value === "object" && value !== null;
|
|
49
|
+
}
|
|
50
|
+
function createConfigImportError(configPath, error) {
|
|
51
|
+
const isTypeScriptConfig = /\.(cts|mts|ts)$/.test(configPath);
|
|
52
|
+
const fileName = path.basename(configPath);
|
|
53
|
+
return new Error(`Failed to load ${fileName} with native import().${isTypeScriptConfig ? ` Native TypeScript import requires Node.js >= 22.18.0. On older Node.js versions, rename the config file to .mjs or .cjs.` : ""}`, { cause: error });
|
|
54
|
+
}
|
|
55
|
+
async function loadReactScriptsConfig() {
|
|
56
|
+
const configPath = findEntryFile(paths_default.config);
|
|
57
|
+
if (!configPath) return {};
|
|
58
|
+
let moduleNamespace;
|
|
59
|
+
try {
|
|
60
|
+
moduleNamespace = await import(configPath);
|
|
61
|
+
} catch (error) {
|
|
62
|
+
throw createConfigImportError(configPath, error);
|
|
63
|
+
}
|
|
64
|
+
const config = moduleNamespace.default ?? moduleNamespace;
|
|
65
|
+
if (!isPlainObject(config)) throw new TypeError(`${path.basename(configPath)} must export a configuration object.`);
|
|
66
|
+
return config;
|
|
67
|
+
}
|
|
68
|
+
//#endregion
|
|
69
|
+
//#region utils/detect-package.ts
|
|
70
|
+
const require$1 = createRequire(import.meta.url);
|
|
71
|
+
function detectPackage(packageName) {
|
|
72
|
+
try {
|
|
73
|
+
require$1.resolve(packageName);
|
|
74
|
+
return true;
|
|
75
|
+
} catch {
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
//#endregion
|
|
80
|
+
//#region alias.ts
|
|
81
|
+
const moduleFileExtensions = [
|
|
82
|
+
"ts",
|
|
83
|
+
"tsx",
|
|
84
|
+
"js",
|
|
85
|
+
"json",
|
|
86
|
+
"mjs",
|
|
87
|
+
"jsx"
|
|
88
|
+
].map((ext) => `.${ext}`);
|
|
89
|
+
const aliasSymbol = {
|
|
90
|
+
src: "@",
|
|
91
|
+
root: "@app"
|
|
92
|
+
};
|
|
93
|
+
const alias = {
|
|
94
|
+
[aliasSymbol.src]: paths_default.appSrc,
|
|
95
|
+
[aliasSymbol.root]: paths_default.appPath
|
|
96
|
+
};
|
|
97
|
+
//#endregion
|
|
98
|
+
//#region rspack.config.ts
|
|
99
|
+
const hasJsxRuntime = detectPackage("react/jsx-runtime");
|
|
100
|
+
const hasTailwind = detectPackage("tailwindcss");
|
|
101
|
+
const hasSwcHelper = detectPackage("@swc/helpers");
|
|
102
|
+
const lessRegex = /\.less$/;
|
|
103
|
+
const sassRegex = /\.(scss|sass)$/;
|
|
104
|
+
const cssRegex = /\.css$/;
|
|
105
|
+
const imageInlineSizeLimit = 1e4;
|
|
106
|
+
const require = createRequire(import.meta.url);
|
|
107
|
+
function resolvePackage(packageName) {
|
|
108
|
+
return require.resolve(packageName);
|
|
109
|
+
}
|
|
110
|
+
async function createRspackConfig() {
|
|
111
|
+
const isEnvironmentDevelopment = isDevelopment();
|
|
112
|
+
const isEnvironmentProduction = isProduction();
|
|
113
|
+
function getStyleLoaders(preProcessor) {
|
|
114
|
+
const loaders = [
|
|
115
|
+
isEnvironmentProduction && {
|
|
116
|
+
loader: rspack.CssExtractRspackPlugin.loader,
|
|
117
|
+
options: paths_default.publicUrlOrPath.startsWith(".") ? { publicPath: "../../" } : {}
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
loader: "builtin:lightningcss-loader",
|
|
121
|
+
/** @type {import('@rspack/core').LightningcssLoaderOptions} */
|
|
122
|
+
options: { minify: isEnvironmentProduction }
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
loader: resolvePackage("postcss-loader"),
|
|
126
|
+
options: hasTailwind ? { postcssOptions: {
|
|
127
|
+
ident: "postcss",
|
|
128
|
+
config: false,
|
|
129
|
+
plugins: [require("@tailwindcss/postcss")]
|
|
130
|
+
} } : void 0
|
|
131
|
+
}
|
|
132
|
+
].filter(Boolean);
|
|
133
|
+
if (preProcessor) loaders.push(preProcessor);
|
|
134
|
+
return loaders;
|
|
135
|
+
}
|
|
136
|
+
const config = {
|
|
137
|
+
target: ["browserslist"],
|
|
138
|
+
stats: "errors-warnings",
|
|
139
|
+
mode: getEnv(),
|
|
140
|
+
bail: isEnvironmentProduction,
|
|
141
|
+
devtool: isEnvironmentDevelopment && "cheap-module-source-map",
|
|
142
|
+
entry: paths_default.appIndexJs,
|
|
143
|
+
output: {
|
|
144
|
+
path: paths_default.appBuild,
|
|
145
|
+
pathinfo: isEnvironmentDevelopment,
|
|
146
|
+
filename: isEnvironmentProduction ? "static/js/[name].[contenthash:8].js" : "static/js/[name].js",
|
|
147
|
+
chunkFilename: isEnvironmentProduction ? "static/js/[name].[contenthash:8].chunk.js" : "static/js/[name].chunk.js",
|
|
148
|
+
assetModuleFilename: "static/media/[name].[hash][ext]",
|
|
149
|
+
publicPath: paths_default.publicUrlOrPath,
|
|
150
|
+
devtoolModuleFilenameTemplate: isEnvironmentProduction ? (info) => path.relative(paths_default.appSrc, info.absoluteResourcePath).replaceAll("\\", "/") : (info) => path.resolve(info.absoluteResourcePath).replaceAll("\\", "/")
|
|
151
|
+
},
|
|
152
|
+
infrastructureLogging: { level: "none" },
|
|
153
|
+
optimization: {
|
|
154
|
+
runtimeChunk: "single",
|
|
155
|
+
splitChunks: {
|
|
156
|
+
chunks: "async",
|
|
157
|
+
minChunks: 1,
|
|
158
|
+
minSize: 2e4,
|
|
159
|
+
maxAsyncRequests: 30,
|
|
160
|
+
maxInitialRequests: 30,
|
|
161
|
+
cacheGroups: {
|
|
162
|
+
vendors: {
|
|
163
|
+
test: /[/\\]node_modules[/\\]/,
|
|
164
|
+
name: "chunk-vendors",
|
|
165
|
+
priority: -10,
|
|
166
|
+
reuseExistingChunk: true
|
|
167
|
+
},
|
|
168
|
+
default: {
|
|
169
|
+
minChunks: 2,
|
|
170
|
+
priority: -20,
|
|
171
|
+
reuseExistingChunk: true
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
},
|
|
175
|
+
minimizer: [new rspack.LightningCssMinimizerRspackPlugin(), new rspack.SwcJsMinimizerRspackPlugin({
|
|
176
|
+
extractComments: false,
|
|
177
|
+
minimizerOptions: {
|
|
178
|
+
minify: true,
|
|
179
|
+
mangle: true,
|
|
180
|
+
ecma: 5,
|
|
181
|
+
compress: { passes: 2 },
|
|
182
|
+
format: { comments: false }
|
|
183
|
+
}
|
|
184
|
+
})]
|
|
185
|
+
},
|
|
186
|
+
resolve: {
|
|
187
|
+
extensions: moduleFileExtensions,
|
|
188
|
+
alias
|
|
189
|
+
},
|
|
190
|
+
module: {
|
|
191
|
+
rules: [{ oneOf: [
|
|
192
|
+
{
|
|
193
|
+
test: [/\.avif$/],
|
|
194
|
+
type: "asset",
|
|
195
|
+
mimetype: "image/avif",
|
|
196
|
+
parser: { dataUrlCondition: { maxSize: imageInlineSizeLimit } }
|
|
197
|
+
},
|
|
198
|
+
{
|
|
199
|
+
test: [
|
|
200
|
+
/\.bmp$/,
|
|
201
|
+
/\.gif$/,
|
|
202
|
+
/\.jpe?g$/,
|
|
203
|
+
/\.png$/
|
|
204
|
+
],
|
|
205
|
+
type: "asset",
|
|
206
|
+
parser: { dataUrlCondition: { maxSize: imageInlineSizeLimit } }
|
|
207
|
+
},
|
|
208
|
+
{
|
|
209
|
+
test: /\.[jt]sx?$/,
|
|
210
|
+
exclude: [/node_modules/],
|
|
211
|
+
use: {
|
|
212
|
+
loader: "builtin:swc-loader",
|
|
213
|
+
options: {
|
|
214
|
+
jsc: {
|
|
215
|
+
externalHelpers: hasSwcHelper,
|
|
216
|
+
loose: true,
|
|
217
|
+
parser: {
|
|
218
|
+
syntax: "typescript",
|
|
219
|
+
tsx: true
|
|
220
|
+
},
|
|
221
|
+
transform: { react: {
|
|
222
|
+
throwIfNamespace: true,
|
|
223
|
+
development: isEnvironmentDevelopment,
|
|
224
|
+
useBuiltins: true,
|
|
225
|
+
runtime: hasJsxRuntime ? "automatic" : "classic",
|
|
226
|
+
refresh: isEnvironmentDevelopment
|
|
227
|
+
} }
|
|
228
|
+
},
|
|
229
|
+
module: { type: "es6" }
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
},
|
|
233
|
+
{
|
|
234
|
+
test: lessRegex,
|
|
235
|
+
use: getStyleLoaders({ loader: resolvePackage("less-loader") }),
|
|
236
|
+
sideEffects: true,
|
|
237
|
+
type: "css/auto"
|
|
238
|
+
},
|
|
239
|
+
{
|
|
240
|
+
test: sassRegex,
|
|
241
|
+
use: getStyleLoaders({
|
|
242
|
+
loader: resolvePackage("sass-loader"),
|
|
243
|
+
options: {
|
|
244
|
+
api: "modern-compiler",
|
|
245
|
+
implementation: resolvePackage("sass-embedded")
|
|
246
|
+
}
|
|
247
|
+
}),
|
|
248
|
+
sideEffects: true,
|
|
249
|
+
type: "css/auto"
|
|
250
|
+
},
|
|
251
|
+
{
|
|
252
|
+
test: cssRegex,
|
|
253
|
+
use: getStyleLoaders(),
|
|
254
|
+
sideEffects: true,
|
|
255
|
+
type: "css/auto"
|
|
256
|
+
},
|
|
257
|
+
{
|
|
258
|
+
exclude: [
|
|
259
|
+
/^$/,
|
|
260
|
+
/\.(js|mjs|jsx|ts|tsx)$/,
|
|
261
|
+
/\.html$/,
|
|
262
|
+
/\.json$/
|
|
263
|
+
],
|
|
264
|
+
type: "asset/resource"
|
|
265
|
+
}
|
|
266
|
+
] }],
|
|
267
|
+
parser: { "css/auto": { namedExports: false } }
|
|
268
|
+
},
|
|
269
|
+
plugins: [
|
|
270
|
+
new rspack.HtmlRspackPlugin({
|
|
271
|
+
inject: true,
|
|
272
|
+
template: paths_default.appHtml,
|
|
273
|
+
minify: isEnvironmentProduction
|
|
274
|
+
}),
|
|
275
|
+
isEnvironmentDevelopment && new rspack.CaseSensitivePlugin(),
|
|
276
|
+
isEnvironmentDevelopment && new ReactRefreshRspackPlugin()
|
|
277
|
+
],
|
|
278
|
+
performance: false
|
|
279
|
+
};
|
|
280
|
+
const reactScriptsConfig = await loadReactScriptsConfig();
|
|
281
|
+
if (reactScriptsConfig.configureRspack) reactScriptsConfig.configureRspack(config);
|
|
282
|
+
return config;
|
|
283
|
+
}
|
|
284
|
+
//#endregion
|
|
285
|
+
export { paths_default as n, createRspackConfig as t };
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
import { n as paths_default, t as createRspackConfig } from "../rspack.config-8gFQGJU3.js";
|
|
2
|
+
import { styleText } from "node:util";
|
|
3
|
+
import fs from "node:fs/promises";
|
|
4
|
+
import { exit } from "node:process";
|
|
5
|
+
import { rspack } from "@rspack/core";
|
|
6
|
+
import path from "node:path";
|
|
7
|
+
import fs$1 from "node:fs";
|
|
8
|
+
import prettyBytes from "pretty-bytes";
|
|
9
|
+
import zlib from "node:zlib";
|
|
10
|
+
//#region utils/fs-extra.ts
|
|
11
|
+
async function emptyDirectory(directory) {
|
|
12
|
+
await fs.rm(directory, {
|
|
13
|
+
recursive: true,
|
|
14
|
+
force: true
|
|
15
|
+
});
|
|
16
|
+
await fs.mkdir(directory, { recursive: true });
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* 读取文件夹下的所有文件
|
|
20
|
+
* @param path
|
|
21
|
+
* @returns
|
|
22
|
+
*/
|
|
23
|
+
async function readdir(path$1) {
|
|
24
|
+
let fileList = [];
|
|
25
|
+
const files = await fs.readdir(path$1);
|
|
26
|
+
if (files.length === 0) return [];
|
|
27
|
+
for (const file of files) {
|
|
28
|
+
const filePath = path.join(path$1, file);
|
|
29
|
+
if ((await fs.stat(filePath)).isDirectory()) fileList = [...fileList, ...await readdir(filePath)];
|
|
30
|
+
else fileList.push(filePath);
|
|
31
|
+
}
|
|
32
|
+
return fileList;
|
|
33
|
+
}
|
|
34
|
+
//#endregion
|
|
35
|
+
//#region utils/gzip-size.ts
|
|
36
|
+
function getOptions(options) {
|
|
37
|
+
return {
|
|
38
|
+
level: 9,
|
|
39
|
+
...options
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
function gzipSync(input, options) {
|
|
43
|
+
return zlib.gzipSync(input, getOptions(options)).length;
|
|
44
|
+
}
|
|
45
|
+
//#endregion
|
|
46
|
+
//#region utils/strip-ansi.ts
|
|
47
|
+
function ansiRegex(options = {}) {
|
|
48
|
+
const { onlyFirst } = options;
|
|
49
|
+
const pattern = [String.raw`[\u001B\u009B][[\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\d\/#&.:=?%@~_]+)*|[a-zA-Z\d]+(?:;[-a-zA-Z\d\/#&.:=?%@~_]*)*)?\u0007)`, String.raw`(?:(?:\d{1,4}(?:;\d{0,4})*)?[\dA-PR-TZcf-nq-uy=><~]))`].join("|");
|
|
50
|
+
return new RegExp(pattern, onlyFirst ? void 0 : "g");
|
|
51
|
+
}
|
|
52
|
+
function stripAnsi(string) {
|
|
53
|
+
const regex = ansiRegex();
|
|
54
|
+
return string.replace(regex, "");
|
|
55
|
+
}
|
|
56
|
+
//#endregion
|
|
57
|
+
//#region utils/file-size-reporter.ts
|
|
58
|
+
const WARN_AFTER_BUNDLE_GZIP_SIZE = 512 * 1024;
|
|
59
|
+
const WARN_AFTER_CHUNK_GZIP_SIZE = 1024 * 1024;
|
|
60
|
+
/**
|
|
61
|
+
* 是不是可以读取的资源
|
|
62
|
+
* @param asset
|
|
63
|
+
* @returns
|
|
64
|
+
*/
|
|
65
|
+
function canReadAsset(asset) {
|
|
66
|
+
return /\.(js|css)$/.test(asset) && !/service-worker\.js/.test(asset) && !/precache-manifest\.[\da-f]+\.js/.test(asset);
|
|
67
|
+
}
|
|
68
|
+
function removeFileNameHash(buildFolder, fileName) {
|
|
69
|
+
return fileName.replace(buildFolder, "").replaceAll("\\", "/").replace(/\/?(.*)(\.[\da-f]+)(\.chunk)?(\.js|\.css)/, (match, p1, p2, p3, p4) => p1 + p4);
|
|
70
|
+
}
|
|
71
|
+
async function measureFileSizesBeforeBuild(buildFolder) {
|
|
72
|
+
const result = {
|
|
73
|
+
root: buildFolder,
|
|
74
|
+
sizes: {}
|
|
75
|
+
};
|
|
76
|
+
try {
|
|
77
|
+
const files = await readdir(buildFolder);
|
|
78
|
+
if (Array.isArray(files) && files.length > 0) {
|
|
79
|
+
const canReadAssetFiles = files.filter((item) => canReadAsset(item));
|
|
80
|
+
for (const fileName of canReadAssetFiles) {
|
|
81
|
+
const stats = fs$1.statSync(fileName);
|
|
82
|
+
const fileKey = removeFileNameHash(buildFolder, fileName);
|
|
83
|
+
result.sizes[fileKey] = stats.size;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
} catch {
|
|
87
|
+
return result;
|
|
88
|
+
}
|
|
89
|
+
return result;
|
|
90
|
+
}
|
|
91
|
+
function getDifferenceLabel(currentSize, previousSize) {
|
|
92
|
+
const FIFTY_KILOBYTES = 1024 * 50;
|
|
93
|
+
const difference = currentSize - previousSize;
|
|
94
|
+
const fileSize = Number.isNaN(difference) ? "0" : prettyBytes(difference);
|
|
95
|
+
if (difference >= FIFTY_KILOBYTES) return styleText("red", "+" + fileSize);
|
|
96
|
+
else if (difference < FIFTY_KILOBYTES && difference > 0) return styleText("yellow", "+" + fileSize);
|
|
97
|
+
else if (difference < 0) return styleText("green", fileSize);
|
|
98
|
+
else return "";
|
|
99
|
+
}
|
|
100
|
+
function printFileSizesAfterBuild(stats, previousSizeMap) {
|
|
101
|
+
let suggestBundleSplitting = false;
|
|
102
|
+
const root = previousSizeMap.root;
|
|
103
|
+
const sizes = previousSizeMap.sizes;
|
|
104
|
+
const statCompilation = stats.toJson({
|
|
105
|
+
all: false,
|
|
106
|
+
assets: true
|
|
107
|
+
});
|
|
108
|
+
if (statCompilation.assets) {
|
|
109
|
+
const assets = [];
|
|
110
|
+
const gzipLabelLengthList = [];
|
|
111
|
+
const sizeLabelLengthList = [];
|
|
112
|
+
for (const asset of statCompilation.assets) {
|
|
113
|
+
if (!canReadAsset(asset.name)) continue;
|
|
114
|
+
const fileContents = fs$1.readFileSync(path.join(root, asset.name));
|
|
115
|
+
const previousSize = sizes[removeFileNameHash(root, asset.name)];
|
|
116
|
+
const difference = getDifferenceLabel(asset.size, previousSize);
|
|
117
|
+
const sizeLabel = prettyBytes(asset.size) + (difference ? " (" + difference + ")" : "");
|
|
118
|
+
const gzipLabel = "gzip : " + prettyBytes(gzipSync(fileContents));
|
|
119
|
+
const sizeLabelLength = stripAnsi(sizeLabel).length;
|
|
120
|
+
const gzipLabelLength = stripAnsi(gzipLabel).length;
|
|
121
|
+
assets.push({
|
|
122
|
+
folder: path.join(path.basename(paths_default.appBuild), path.dirname(asset.name)),
|
|
123
|
+
name: path.basename(asset.name),
|
|
124
|
+
size: asset.size,
|
|
125
|
+
sizeLabel,
|
|
126
|
+
gzipLabel,
|
|
127
|
+
sizeLabelLength,
|
|
128
|
+
gzipLabelLength
|
|
129
|
+
});
|
|
130
|
+
gzipLabelLengthList.push(gzipLabelLength);
|
|
131
|
+
sizeLabelLengthList.push(sizeLabelLength);
|
|
132
|
+
}
|
|
133
|
+
assets.sort((a, b) => b.size - a.size);
|
|
134
|
+
const longestSizeLabelLength = Math.max.apply(void 0, sizeLabelLengthList);
|
|
135
|
+
const longestGzipSizeLabelLength = Math.max.apply(void 0, gzipLabelLengthList);
|
|
136
|
+
for (const asset of assets) {
|
|
137
|
+
let sizeLabel = asset.sizeLabel;
|
|
138
|
+
let gzipLabel = asset.gzipLabel;
|
|
139
|
+
const sizeLabelLength = asset.sizeLabelLength;
|
|
140
|
+
const gzipLabelLength = asset.gzipLabelLength;
|
|
141
|
+
if (sizeLabelLength < longestSizeLabelLength) sizeLabel += " ".repeat(longestSizeLabelLength - sizeLabelLength);
|
|
142
|
+
if (gzipLabelLength < longestGzipSizeLabelLength) gzipLabel += " ".repeat(longestGzipSizeLabelLength - gzipLabelLength);
|
|
143
|
+
const maxRecommendedSize = asset.name.indexOf("main.") === 0 ? WARN_AFTER_BUNDLE_GZIP_SIZE : WARN_AFTER_CHUNK_GZIP_SIZE;
|
|
144
|
+
const isLarge = maxRecommendedSize && asset.size > maxRecommendedSize;
|
|
145
|
+
if (isLarge && path.extname(asset.name) === ".js") suggestBundleSplitting = true;
|
|
146
|
+
console.log(" " + (isLarge ? styleText("yellow", sizeLabel) : sizeLabel) + " " + gzipLabel, " " + styleText("dim", asset.folder + path.sep) + styleText("cyan", asset.name));
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
if (suggestBundleSplitting) {
|
|
150
|
+
console.log();
|
|
151
|
+
console.log(styleText("yellow", "The bundle size is significantly larger than recommended."));
|
|
152
|
+
console.log(styleText("yellow", "You can also analyze the project dependencies: https://goo.gl/LeUzfb"));
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
//#endregion
|
|
156
|
+
//#region scripts/build.ts
|
|
157
|
+
async function startBuild() {
|
|
158
|
+
try {
|
|
159
|
+
const previousFileSizes = await measureFileSizesBeforeBuild(paths_default.appBuild);
|
|
160
|
+
await emptyDirectory(paths_default.appBuild);
|
|
161
|
+
await copyPublicFolder();
|
|
162
|
+
const stats = await build();
|
|
163
|
+
console.log(styleText("green", "Compiled successfully.\n"));
|
|
164
|
+
console.log("File sizes after gzip:\n");
|
|
165
|
+
if (stats) printFileSizesAfterBuild(stats, previousFileSizes);
|
|
166
|
+
console.log();
|
|
167
|
+
} catch (error) {
|
|
168
|
+
console.log(styleText("red", "Failed to compile.\n"));
|
|
169
|
+
if (error && error.message) console.log(error.message);
|
|
170
|
+
exit(1);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
function copyPublicFolder() {
|
|
174
|
+
return fs.cp(paths_default.appPublic, paths_default.appBuild, {
|
|
175
|
+
recursive: true,
|
|
176
|
+
filter: (source) => source !== paths_default.appHtml
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Create the production build and print the deployment instructions.
|
|
181
|
+
* @returns
|
|
182
|
+
*/
|
|
183
|
+
async function build() {
|
|
184
|
+
console.log("Creating an optimized production build...");
|
|
185
|
+
const compiler = rspack(await createRspackConfig());
|
|
186
|
+
return new Promise((resolve, reject) => {
|
|
187
|
+
compiler.run((error, stats) => {
|
|
188
|
+
if (error) return reject(error);
|
|
189
|
+
return resolve(stats);
|
|
190
|
+
});
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
await startBuild();
|
|
194
|
+
//#endregion
|
|
195
|
+
export {};
|
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
import { n as paths_default, t as createRspackConfig } from "../rspack.config-8gFQGJU3.js";
|
|
2
|
+
import { createRequire } from "node:module";
|
|
3
|
+
import { styleText } from "node:util";
|
|
4
|
+
import { exit } from "node:process";
|
|
5
|
+
import { rspack } from "@rspack/core";
|
|
6
|
+
import path from "node:path";
|
|
7
|
+
import { RspackDevServer } from "@rspack/dev-server";
|
|
8
|
+
import url from "node:url";
|
|
9
|
+
import prompts from "prompts";
|
|
10
|
+
import getPort from "get-port";
|
|
11
|
+
import os from "node:os";
|
|
12
|
+
//#region utils/address.ts
|
|
13
|
+
function getDefaultInterfaceName() {
|
|
14
|
+
let value = "eth";
|
|
15
|
+
const platform = os.platform();
|
|
16
|
+
if (platform === "darwin") value = "en";
|
|
17
|
+
else if (platform === "win32") value = void 0;
|
|
18
|
+
return value;
|
|
19
|
+
}
|
|
20
|
+
function matchName(actualFamily, expectedFamily) {
|
|
21
|
+
if (expectedFamily === "IPv4") return actualFamily === "IPv4" || actualFamily === 4;
|
|
22
|
+
if (expectedFamily === "IPv6") return actualFamily === "IPv6" || actualFamily === 6;
|
|
23
|
+
return actualFamily === expectedFamily;
|
|
24
|
+
}
|
|
25
|
+
function findAddressFromInterface(items, expectedFamily, ignoreLoAddress = false) {
|
|
26
|
+
let firstMatchItem;
|
|
27
|
+
for (const item of items) if (matchName(item.family, expectedFamily)) {
|
|
28
|
+
if (ignoreLoAddress && item.address.startsWith("127.")) continue;
|
|
29
|
+
if (expectedFamily === "IPv6") {
|
|
30
|
+
if (item.scopeid === 0) return item;
|
|
31
|
+
if (!firstMatchItem) firstMatchItem = item;
|
|
32
|
+
} else return item;
|
|
33
|
+
}
|
|
34
|
+
return firstMatchItem;
|
|
35
|
+
}
|
|
36
|
+
function getInterfaceAddress(family, name) {
|
|
37
|
+
const interfaces = os.networkInterfaces();
|
|
38
|
+
const noName = !name;
|
|
39
|
+
name = name || getDefaultInterfaceName();
|
|
40
|
+
family = family || "IPv4";
|
|
41
|
+
if (name) for (let index = -1; index < 8; index++) {
|
|
42
|
+
const items = interfaces[name + (index >= 0 ? index : "")];
|
|
43
|
+
if (items) {
|
|
44
|
+
const item = findAddressFromInterface(items, family);
|
|
45
|
+
if (item) return item;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
if (noName) for (const k in interfaces) {
|
|
49
|
+
const items = interfaces[k];
|
|
50
|
+
if (items) {
|
|
51
|
+
const item = findAddressFromInterface(items, family, true);
|
|
52
|
+
if (item) return item;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Get current machine IPv4
|
|
58
|
+
*
|
|
59
|
+
* interfaceName: interface name, default is 'eth' on linux, 'en' on mac os.
|
|
60
|
+
*/
|
|
61
|
+
function ip(interfaceName) {
|
|
62
|
+
return getInterfaceAddress("IPv4", interfaceName)?.address;
|
|
63
|
+
}
|
|
64
|
+
//#endregion
|
|
65
|
+
//#region utils/is-root.ts
|
|
66
|
+
/**
|
|
67
|
+
* 检查进程是否以 root 用户身份运行
|
|
68
|
+
*/
|
|
69
|
+
function isRoot() {
|
|
70
|
+
return process.getuid && process.getuid() === 0;
|
|
71
|
+
}
|
|
72
|
+
//#endregion
|
|
73
|
+
//#region utils/clear-console.ts
|
|
74
|
+
/**
|
|
75
|
+
* 清除控制台的信息
|
|
76
|
+
*/
|
|
77
|
+
function clearConsole() {
|
|
78
|
+
process.stdout.write(process.platform === "win32" ? "\x1B[2J\x1B[0f" : "\x1B[2J\x1B[3J\x1B[H");
|
|
79
|
+
}
|
|
80
|
+
//#endregion
|
|
81
|
+
//#region utils/dev-server-utils.ts
|
|
82
|
+
const isInteractive$1 = process.stdout.isTTY;
|
|
83
|
+
function printInstructions(appName, urls) {
|
|
84
|
+
console.log();
|
|
85
|
+
console.log(`You can now view ${styleText("bold", appName)} in the browser.`);
|
|
86
|
+
console.log();
|
|
87
|
+
if (urls.lanUrlForTerminal) {
|
|
88
|
+
console.log(` ${styleText("bold", "Local:")} ${urls.localUrlForTerminal}`);
|
|
89
|
+
console.log(` ${styleText("bold", "On Your Network:")} ${urls.lanUrlForTerminal}`);
|
|
90
|
+
} else console.log(` ${urls.localUrlForTerminal}`);
|
|
91
|
+
console.log();
|
|
92
|
+
console.log("Note that the development build is not optimized.");
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* 准备Url 数据
|
|
96
|
+
*/
|
|
97
|
+
function prepareUrls(options) {
|
|
98
|
+
const { protocol, host, port, pathname = "/" } = options;
|
|
99
|
+
function formatUrl(hostname) {
|
|
100
|
+
return url.format({
|
|
101
|
+
protocol,
|
|
102
|
+
hostname,
|
|
103
|
+
port,
|
|
104
|
+
pathname
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
function prettyPrintUrl(hostname) {
|
|
108
|
+
return url.format({
|
|
109
|
+
protocol,
|
|
110
|
+
hostname,
|
|
111
|
+
port: styleText("bold", String(port)),
|
|
112
|
+
pathname
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
const isUnspecifiedHost = host === "0.0.0.0" || host === "::";
|
|
116
|
+
let prettyHost;
|
|
117
|
+
let lanUrlForConfig;
|
|
118
|
+
let lanUrlForTerminal;
|
|
119
|
+
if (isUnspecifiedHost) {
|
|
120
|
+
prettyHost = "localhost";
|
|
121
|
+
try {
|
|
122
|
+
lanUrlForConfig = ip();
|
|
123
|
+
if (lanUrlForConfig) if (/^10\.|^172\.(1[6-9]|2\d|3[01])\.|^192\.168\./.test(lanUrlForConfig)) lanUrlForTerminal = prettyPrintUrl(lanUrlForConfig);
|
|
124
|
+
else lanUrlForConfig = void 0;
|
|
125
|
+
} catch {}
|
|
126
|
+
} else prettyHost = host;
|
|
127
|
+
const localUrlForTerminal = prettyPrintUrl(prettyHost);
|
|
128
|
+
const localUrlForBrowser = formatUrl(prettyHost);
|
|
129
|
+
return {
|
|
130
|
+
lanUrlForConfig,
|
|
131
|
+
lanUrlForTerminal,
|
|
132
|
+
localUrlForTerminal,
|
|
133
|
+
localUrlForBrowser
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* 选择端口
|
|
138
|
+
* @param defaultPort 默认端口
|
|
139
|
+
* @param host 域名
|
|
140
|
+
*/
|
|
141
|
+
async function choosePort(options) {
|
|
142
|
+
try {
|
|
143
|
+
const port = await getPort(options);
|
|
144
|
+
if (port === options.port) return port;
|
|
145
|
+
const message = process.platform !== "win32" && port < 1024 && !isRoot() ? `Admin permissions are required to run a server on a port below 1024.` : `Something is already running on port ${port}.`;
|
|
146
|
+
if (isInteractive$1) {
|
|
147
|
+
clearConsole();
|
|
148
|
+
return (await prompts({
|
|
149
|
+
type: "confirm",
|
|
150
|
+
name: "shouldChangePort",
|
|
151
|
+
message: styleText("yellow", message) + "\n\nWould you like to run the app on another port instead",
|
|
152
|
+
initial: true
|
|
153
|
+
})).shouldChangePort ? port : void 0;
|
|
154
|
+
} else {
|
|
155
|
+
console.log(styleText("red", message));
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
} catch (error) {
|
|
159
|
+
throw new Error(styleText("red", `Could not find an open port at ${styleText("bold", options.host)}.`) + "\n" + ("Network error message: " + error.message || error) + "\n");
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* 编辑webpack配置
|
|
164
|
+
*/
|
|
165
|
+
function createCompiler(options) {
|
|
166
|
+
const { appName, config, urls } = options;
|
|
167
|
+
let compiler;
|
|
168
|
+
try {
|
|
169
|
+
compiler = rspack(config);
|
|
170
|
+
} catch (error) {
|
|
171
|
+
console.log(styleText("red", "Failed to compile."));
|
|
172
|
+
console.log();
|
|
173
|
+
console.log(error.message || error);
|
|
174
|
+
console.log();
|
|
175
|
+
exit(1);
|
|
176
|
+
}
|
|
177
|
+
compiler.hooks.invalid.tap("invalid", () => {
|
|
178
|
+
if (isInteractive$1) clearConsole();
|
|
179
|
+
console.log("Compiling...");
|
|
180
|
+
});
|
|
181
|
+
let isFirstCompile = true;
|
|
182
|
+
compiler.hooks.done.tap("done", async (stats) => {
|
|
183
|
+
if (isInteractive$1) clearConsole();
|
|
184
|
+
const statsData = stats.toJson({
|
|
185
|
+
all: false,
|
|
186
|
+
warnings: true,
|
|
187
|
+
errors: true
|
|
188
|
+
});
|
|
189
|
+
const errors = statsData.errors ?? [];
|
|
190
|
+
const warnings = statsData.warnings ?? [];
|
|
191
|
+
const isSuccessful = errors.length === 0 && warnings.length === 0;
|
|
192
|
+
if (isSuccessful) console.log(styleText("green", "Compiled successfully!"));
|
|
193
|
+
if (isSuccessful && (isInteractive$1 || isFirstCompile)) printInstructions(appName, urls);
|
|
194
|
+
isFirstCompile = false;
|
|
195
|
+
if (errors.length > 0) {
|
|
196
|
+
if (errors.length > 1) errors.length = 1;
|
|
197
|
+
console.log(styleText("red", "Failed to compile.\n"));
|
|
198
|
+
console.log(errors.join("\n\n"));
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
if (warnings.length > 0) {
|
|
202
|
+
console.log(styleText("yellow", "Compiled with warnings.\n"));
|
|
203
|
+
console.log(warnings.join("\n\n"));
|
|
204
|
+
console.log("\nSearch for the " + styleText("underline", styleText("yellow", "keywords")) + " to learn more about each warning.");
|
|
205
|
+
console.log("To ignore, add " + styleText("cyan", "// eslint-disable-next-line") + " to the line before.\n");
|
|
206
|
+
}
|
|
207
|
+
});
|
|
208
|
+
return compiler;
|
|
209
|
+
}
|
|
210
|
+
//#endregion
|
|
211
|
+
//#region utils/escape-string-regexp.ts
|
|
212
|
+
function escapeStringRegexp(string) {
|
|
213
|
+
return string.replaceAll(/[$()*+.?[\\\]^{|}]/g, String.raw`\$&`).replaceAll("-", String.raw`\x2d`);
|
|
214
|
+
}
|
|
215
|
+
//#endregion
|
|
216
|
+
//#region utils/ignored-files.ts
|
|
217
|
+
function ignoredFiles(appSource) {
|
|
218
|
+
return new RegExp(`^(?!${escapeStringRegexp(path.normalize(appSource + "/").replaceAll(/\\+/g, "/"))}).+/node_modules/`, "g");
|
|
219
|
+
}
|
|
220
|
+
//#endregion
|
|
221
|
+
//#region rspack-dev-server.ts
|
|
222
|
+
function createDevelopmentServerConfig() {
|
|
223
|
+
return {
|
|
224
|
+
allowedHosts: "all",
|
|
225
|
+
client: { overlay: true },
|
|
226
|
+
headers: {
|
|
227
|
+
"Access-Control-Allow-Origin": "*",
|
|
228
|
+
"Access-Control-Allow-Methods": "*",
|
|
229
|
+
"Access-Control-Allow-Headers": "*"
|
|
230
|
+
},
|
|
231
|
+
compress: true,
|
|
232
|
+
static: {
|
|
233
|
+
directory: paths_default.appPublic,
|
|
234
|
+
publicPath: [paths_default.publicUrlOrPath],
|
|
235
|
+
watch: { ignored: ignoredFiles(paths_default.appSrc) }
|
|
236
|
+
},
|
|
237
|
+
devMiddleware: { publicPath: paths_default.publicUrlOrPath.slice(0, -1) },
|
|
238
|
+
historyApiFallback: {
|
|
239
|
+
disableDotRule: true,
|
|
240
|
+
index: paths_default.publicUrlOrPath
|
|
241
|
+
}
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
//#endregion
|
|
245
|
+
//#region scripts/dev.ts
|
|
246
|
+
const require = createRequire(import.meta.url);
|
|
247
|
+
const isInteractive = process.stdout.isTTY;
|
|
248
|
+
const developmentServerConfig = {
|
|
249
|
+
PORT: 3e3,
|
|
250
|
+
HOST: "0.0.0.0",
|
|
251
|
+
PROTOCOL: "http"
|
|
252
|
+
};
|
|
253
|
+
async function startDevelopment() {
|
|
254
|
+
try {
|
|
255
|
+
const port = await choosePort({ port: developmentServerConfig.PORT });
|
|
256
|
+
if (port === void 0) return;
|
|
257
|
+
const config = await createRspackConfig();
|
|
258
|
+
const appName = require(paths_default.appPackageJson).name;
|
|
259
|
+
const urls = prepareUrls({
|
|
260
|
+
protocol: developmentServerConfig.PROTOCOL,
|
|
261
|
+
host: developmentServerConfig.HOST,
|
|
262
|
+
port,
|
|
263
|
+
pathname: paths_default.publicUrlOrPath.slice(0, -1)
|
|
264
|
+
});
|
|
265
|
+
const localUrlForBrowser = new URL(urls.localUrlForBrowser);
|
|
266
|
+
const compiler = createCompiler({
|
|
267
|
+
appName,
|
|
268
|
+
config,
|
|
269
|
+
urls
|
|
270
|
+
});
|
|
271
|
+
const developmentServer = new RspackDevServer({
|
|
272
|
+
...createDevelopmentServerConfig(),
|
|
273
|
+
host: localUrlForBrowser.hostname,
|
|
274
|
+
port: localUrlForBrowser.port,
|
|
275
|
+
open: true
|
|
276
|
+
}, compiler);
|
|
277
|
+
developmentServer.startCallback((error) => {
|
|
278
|
+
if (isInteractive) clearConsole();
|
|
279
|
+
console.log(styleText("cyan", "Starting the development server...\n"));
|
|
280
|
+
});
|
|
281
|
+
developmentServer.stopCallback((error) => {
|
|
282
|
+
if (error) console.log("Server stopped.", error);
|
|
283
|
+
});
|
|
284
|
+
for (const signal of ["SIGINT", "SIGTERM"]) process.on(signal, () => {
|
|
285
|
+
developmentServer.stop();
|
|
286
|
+
process.exit();
|
|
287
|
+
});
|
|
288
|
+
if (process.env.CI !== "true") process.stdin.on("end", function() {
|
|
289
|
+
developmentServer.stop();
|
|
290
|
+
exit();
|
|
291
|
+
});
|
|
292
|
+
} catch (error) {
|
|
293
|
+
if (error?.message) console.log(error.message);
|
|
294
|
+
exit(1);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
await startDevelopment();
|
|
298
|
+
//#endregion
|
|
299
|
+
export {};
|
package/package.json
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@omnific/react-scripts",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "React app scripts based on Rspack",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"keywords": [
|
|
8
|
+
"react",
|
|
9
|
+
"rspack",
|
|
10
|
+
"scripts"
|
|
11
|
+
],
|
|
12
|
+
"author": "monhan-97",
|
|
13
|
+
"repository": {
|
|
14
|
+
"type": "git",
|
|
15
|
+
"url": "git+https://github.com/monhan-97/omnific.git",
|
|
16
|
+
"directory": "packages/react-scripts"
|
|
17
|
+
},
|
|
18
|
+
"bugs": {
|
|
19
|
+
"url": "https://github.com/monhan-97/omnific.git/issues"
|
|
20
|
+
},
|
|
21
|
+
"bin": {
|
|
22
|
+
"react-scripts": "./dist/index.js"
|
|
23
|
+
},
|
|
24
|
+
"main": "./dist/main.cjs",
|
|
25
|
+
"module": "./dist/main.js",
|
|
26
|
+
"types": "./dist/main.d.ts",
|
|
27
|
+
"exports": {
|
|
28
|
+
".": {
|
|
29
|
+
"types": "./dist/main.d.ts",
|
|
30
|
+
"import": "./dist/main.js",
|
|
31
|
+
"require": "./dist/main.cjs"
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
"files": [
|
|
35
|
+
"dist",
|
|
36
|
+
"README.md"
|
|
37
|
+
],
|
|
38
|
+
"engines": {
|
|
39
|
+
"node": ">=22.12.0"
|
|
40
|
+
},
|
|
41
|
+
"dependencies": {
|
|
42
|
+
"@rspack/cli": "^2.0.1",
|
|
43
|
+
"@rspack/core": "^2.0.1",
|
|
44
|
+
"@rspack/dev-server": "^2.0.1",
|
|
45
|
+
"@rspack/plugin-react-refresh": "^2.0.0",
|
|
46
|
+
"@tailwindcss/postcss": "^4.2.4",
|
|
47
|
+
"get-port": "^7.2.0",
|
|
48
|
+
"less": "^4.6.4",
|
|
49
|
+
"less-loader": "^12.3.2",
|
|
50
|
+
"postcss": "^8.5.13",
|
|
51
|
+
"postcss-loader": "^8.2.0",
|
|
52
|
+
"pretty-bytes": "^7.1.0",
|
|
53
|
+
"prompts": "^2.4.2",
|
|
54
|
+
"react-refresh": "^0.18.0",
|
|
55
|
+
"sass-embedded": "^1.93.2",
|
|
56
|
+
"sass-loader": "^16.0.6",
|
|
57
|
+
"@omnific/types": "0.0.5"
|
|
58
|
+
},
|
|
59
|
+
"devDependencies": {
|
|
60
|
+
"@types/prompts": "^2.4.9",
|
|
61
|
+
"tsdown": "^0.21.10"
|
|
62
|
+
},
|
|
63
|
+
"scripts": {
|
|
64
|
+
"build": "tsdown -c tsdown.config.mjs",
|
|
65
|
+
"release": "pnpm pack && pnpm publish --access public",
|
|
66
|
+
"typecheck": "tsc -p tsconfig.json --noEmit"
|
|
67
|
+
}
|
|
68
|
+
}
|