@lark-apaas/fullstack-rspack-preset 1.0.34 → 1.0.35-alpha.1

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/lib/index.js CHANGED
@@ -6,6 +6,7 @@ const webpack_merge_1 = require("webpack-merge");
6
6
  const devtool_kits_1 = require("@lark-apaas/devtool-kits");
7
7
  const preset_1 = require("./preset");
8
8
  const normalize_base_path_1 = require("./utils/normalize-base-path");
9
+ const inject_runtime_entry_1 = require("./utils/inject-runtime-entry");
9
10
  /**
10
11
  * 定义 Fullstack Rspack 配置
11
12
  *
@@ -69,6 +70,14 @@ function createFullstackRspackConfig(overrides = {}) {
69
70
  clientBasePath,
70
71
  publicPath,
71
72
  });
72
- // 5. 深度合并用户配置
73
- return (0, webpack_merge_1.merge)(baseConfig, overrides);
73
+ // 5. 注入 runtime 模块到用户入口
74
+ // 确保全局初始化逻辑(样式、dayjs、axios、observable、server-log)在用户代码之前执行
75
+ const processedOverrides = {
76
+ ...overrides,
77
+ };
78
+ if (overrides.entry) {
79
+ processedOverrides.entry = (0, inject_runtime_entry_1.injectRuntimeEntry)(overrides.entry);
80
+ }
81
+ // 6. 深度合并用户配置
82
+ return (0, webpack_merge_1.merge)(baseConfig, processedOverrides);
74
83
  }
@@ -0,0 +1,148 @@
1
+ {
2
+ "version": 1,
3
+ "themeName": "UD Theme Style",
4
+ "theme": {
5
+ "seriesCnt": "6",
6
+ "backgroundColor": "rgba(0,0,0,0)",
7
+ "titleColor": "#1f2329",
8
+ "subtitleColor": "#8f959e",
9
+ "textColorShow": false,
10
+ "textColor": "#333",
11
+ "markTextColor": "#ffffff",
12
+ "color": [
13
+ "#3370eb",
14
+ "#1bcebf",
15
+ "#ffc60a",
16
+ "#ed6d0c",
17
+ "#dca1e4",
18
+ "#25b2e5",
19
+ "#6dcdeb",
20
+ "#288fcb",
21
+ "#94b5f5",
22
+ "#8f61d1",
23
+ "#8f61d1",
24
+ "#bf78e9",
25
+ "#008280",
26
+ "#27ad8e",
27
+ "#7bc335"
28
+ ],
29
+ "borderColor": "#dee0e3",
30
+ "borderWidth": 0,
31
+ "visualMapColor": ["#25b2e5", "#6dcdeb", "#288fcb"],
32
+ "legendTextColor": "#8f959e",
33
+ "kColor": "#fdc6c4",
34
+ "kColor0": "transparent",
35
+ "kBorderColor": "#f54a45",
36
+ "kBorderColor0": "#32a645",
37
+ "kBorderWidth": "2",
38
+ "lineWidth": "1",
39
+ "symbolSize": "6",
40
+ "symbol": "emptyCircle",
41
+ "symbolBorderWidth": "1",
42
+ "lineSmooth": true,
43
+ "graphLineWidth": 1,
44
+ "graphLineColor": "#dee0e3",
45
+ "mapLabelColor": "#000",
46
+ "mapLabelColorE": "#516b91",
47
+ "mapBorderColor": "#516b91",
48
+ "mapBorderColorE": "#516b91",
49
+ "mapBorderWidth": 0.5,
50
+ "mapBorderWidthE": 1,
51
+ "mapAreaColor": "#f3f3f3",
52
+ "mapAreaColorE": "#a5e7f0",
53
+ "axes": [
54
+ {
55
+ "type": "all",
56
+ "name": "通用坐标轴",
57
+ "axisLineShow": true,
58
+ "axisLineColor": "#dee0e3",
59
+ "axisTickShow": false,
60
+ "axisTickColor": "#333",
61
+ "axisLabelShow": true,
62
+ "axisLabelColor": "#8f959e",
63
+ "splitLineShow": true,
64
+ "splitLineColor": ["#dee0e3"],
65
+ "splitAreaShow": false,
66
+ "splitAreaColor": ["rgba(250,250,250,0.05)", "rgba(200,200,200,0.02)"]
67
+ },
68
+ {
69
+ "type": "category",
70
+ "name": "类目坐标轴",
71
+ "axisLineShow": true,
72
+ "axisLineColor": "#333",
73
+ "axisTickShow": true,
74
+ "axisTickColor": "#333",
75
+ "axisLabelShow": true,
76
+ "axisLabelColor": "#333",
77
+ "splitLineShow": false,
78
+ "splitLineColor": ["#ccc"],
79
+ "splitAreaShow": false,
80
+ "splitAreaColor": ["rgba(250,250,250,0.3)", "rgba(200,200,200,0.3)"]
81
+ },
82
+ {
83
+ "type": "value",
84
+ "name": "数值坐标轴",
85
+ "axisLineShow": true,
86
+ "axisLineColor": "#333",
87
+ "axisTickShow": true,
88
+ "axisTickColor": "#333",
89
+ "axisLabelShow": true,
90
+ "axisLabelColor": "#333",
91
+ "splitLineShow": true,
92
+ "splitLineColor": ["#ccc"],
93
+ "splitAreaShow": false,
94
+ "splitAreaColor": ["rgba(250,250,250,0.3)", "rgba(200,200,200,0.3)"]
95
+ },
96
+ {
97
+ "type": "log",
98
+ "name": "对数坐标轴",
99
+ "axisLineShow": true,
100
+ "axisLineColor": "#333",
101
+ "axisTickShow": true,
102
+ "axisTickColor": "#333",
103
+ "axisLabelShow": true,
104
+ "axisLabelColor": "#333",
105
+ "splitLineShow": true,
106
+ "splitLineColor": ["#ccc"],
107
+ "splitAreaShow": false,
108
+ "splitAreaColor": ["rgba(250,250,250,0.3)", "rgba(200,200,200,0.3)"]
109
+ },
110
+ {
111
+ "type": "time",
112
+ "name": "时间坐标轴",
113
+ "axisLineShow": true,
114
+ "axisLineColor": "#333",
115
+ "axisTickShow": true,
116
+ "axisTickColor": "#333",
117
+ "axisLabelShow": true,
118
+ "axisLabelColor": "#333",
119
+ "splitLineShow": true,
120
+ "splitLineColor": ["#ccc"],
121
+ "splitAreaShow": false,
122
+ "splitAreaColor": ["rgba(250,250,250,0.3)", "rgba(200,200,200,0.3)"]
123
+ }
124
+ ],
125
+ "axisSeperateSetting": false,
126
+ "toolboxColor": "#8f959e",
127
+ "toolboxEmphasisColor": "#1f2329",
128
+ "tooltipAxisColor": "#dee0e3",
129
+ "tooltipAxisWidth": 1,
130
+ "timelineLineColor": "#336df4",
131
+ "timelineLineWidth": "-1",
132
+ "timelineItemColor": "#336df4",
133
+ "timelineItemColorE": "#1456f0",
134
+ "timelineCheckColor": "#1456f0",
135
+ "timelineCheckBorderColor": "#94b4ff",
136
+ "timelineItemBorderWidth": "0.5",
137
+ "timelineControlColor": "#336df4",
138
+ "timelineControlBorderColor": "#336df4",
139
+ "timelineControlBorderWidth": 0.5,
140
+ "timelineLabelColor": "#8f959e",
141
+ "datazoomBackgroundColor": "rgba(0,0,0,0)",
142
+ "datazoomDataColor": "rgba(255,255,255,0.3)",
143
+ "datazoomFillColor": "rgba(167,183,204,0.4)",
144
+ "datazoomHandleColor": "#a7b7cc",
145
+ "datazoomHandleWidth": "100",
146
+ "datazoomLabelColor": "#333"
147
+ }
148
+ }
package/lib/preset.js CHANGED
@@ -13,6 +13,7 @@ const route_parser_plugin_1 = __importDefault(require("./rspack-plugins/route-pa
13
13
  const slardar_performance_monitor_plugin_1 = __importDefault(require("./rspack-plugins/slardar-performance-monitor-plugin"));
14
14
  const view_context_injection_plugin_1 = __importDefault(require("./rspack-plugins/view-context-injection-plugin"));
15
15
  const og_meta_injection_plugin_1 = __importDefault(require("./rspack-plugins/og-meta-injection-plugin"));
16
+ const runtime_injection_plugin_1 = __importDefault(require("./rspack-plugins/runtime-injection-plugin"));
16
17
  const dev_server_snapdom_proxy_1 = require("./utils/dev-server-snapdom-proxy");
17
18
  function sendBackendUnavailable502(_err, _req, res) {
18
19
  if (res.headersSent)
@@ -143,6 +144,8 @@ function createRecommendRspackConfig(options) {
143
144
  ],
144
145
  },
145
146
  plugins: [
147
+ // 运行时注入插件 - 自动将 @lark-apaas/client-toolkit/runtime 注入到所有入口之前
148
+ new runtime_injection_plugin_1.default(),
146
149
  // 针对 clsx/echarts 等包,让其默认好用
147
150
  new core_1.default.NormalModuleReplacementPlugin(/^(clsx|echarts)$/, function (resource) {
148
151
  if (!resource.context.endsWith('module-alias')) {
@@ -160,6 +163,8 @@ function createRecommendRspackConfig(options) {
160
163
  'process.env.CLIENT_BASE_PATH': JSON.stringify(clientBasePath),
161
164
  'process.env.FORCE_FRAMEWORK_DOMAIN_MAIN': JSON.stringify(process.env.FORCE_FRAMEWORK_DOMAIN_MAIN ?? ''),
162
165
  'process.env.CWD': JSON.stringify(''),
166
+ // runtime 注入标志位,用于 client-toolkit 兼容性判断
167
+ 'process.env.__RUNTIME_INJECTED__': JSON.stringify('true'),
163
168
  // 解决 window 未定义问题
164
169
  'typeof window': JSON.stringify('object'),
165
170
  window: 'globalThis',
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Runtime Injection Plugin
3
+ *
4
+ * 在编译时自动将 @lark-apaas/client-toolkit/runtime 注入到所有入口之前
5
+ * 支持 extends 配置方式
6
+ */
7
+ import type { Compiler } from '@rspack/core';
8
+ export declare class RuntimeInjectionPlugin {
9
+ apply(compiler: Compiler): void;
10
+ private injectRuntime;
11
+ }
12
+ export default RuntimeInjectionPlugin;
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ /**
3
+ * Runtime Injection Plugin
4
+ *
5
+ * 在编译时自动将 @lark-apaas/client-toolkit/runtime 注入到所有入口之前
6
+ * 支持 extends 配置方式
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.RuntimeInjectionPlugin = void 0;
10
+ const RUNTIME_MODULE = '@lark-apaas/client-toolkit/runtime';
11
+ const PLUGIN_NAME = 'RuntimeInjectionPlugin';
12
+ class RuntimeInjectionPlugin {
13
+ apply(compiler) {
14
+ compiler.hooks.entryOption.tap(PLUGIN_NAME, (_context, entry) => {
15
+ // entry 在 entryOption 钩子中已经被标准化为对象格式
16
+ if (typeof entry === 'function') {
17
+ // 动态 entry,需要包装函数
18
+ const originalEntry = entry;
19
+ compiler.options.entry = async () => {
20
+ const resolved = await originalEntry();
21
+ return this.injectRuntime(resolved);
22
+ };
23
+ }
24
+ else {
25
+ // 静态 entry 对象
26
+ compiler.options.entry = this.injectRuntime(entry);
27
+ }
28
+ // 返回 true 表示已处理 entry
29
+ return true;
30
+ });
31
+ }
32
+ injectRuntime(entry) {
33
+ const result = {};
34
+ for (const [name, descriptor] of Object.entries(entry)) {
35
+ const entryDesc = descriptor;
36
+ const imports = entryDesc.import || [];
37
+ // 检查是否已经包含 runtime
38
+ if (imports.includes(RUNTIME_MODULE)) {
39
+ result[name] = entryDesc;
40
+ continue;
41
+ }
42
+ // 注入 runtime 到最前面
43
+ result[name] = {
44
+ ...entryDesc,
45
+ import: [RUNTIME_MODULE, ...imports],
46
+ };
47
+ }
48
+ return result;
49
+ }
50
+ }
51
+ exports.RuntimeInjectionPlugin = RuntimeInjectionPlugin;
52
+ exports.default = RuntimeInjectionPlugin;
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Runtime Entry 注入工具
3
+ *
4
+ * 将 @lark-apaas/client-toolkit/runtime 自动注入到用户入口之前
5
+ * 确保全局初始化逻辑(样式、dayjs、axios、observable、server-log)在用户代码之前执行
6
+ */
7
+ import type { Entry } from '@rspack/core';
8
+ /**
9
+ * 将 runtime 模块注入到 entry 配置中
10
+ *
11
+ * @param entry - 用户的 entry 配置
12
+ * @returns 注入 runtime 后的 entry 配置
13
+ *
14
+ * @example
15
+ * ```typescript
16
+ * // 字符串入口
17
+ * injectRuntimeEntry('./src/index.tsx')
18
+ * // => ['@lark-apaas/client-toolkit/runtime', './src/index.tsx']
19
+ *
20
+ * // 数组入口
21
+ * injectRuntimeEntry(['./src/polyfill.ts', './src/index.tsx'])
22
+ * // => ['@lark-apaas/client-toolkit/runtime', './src/polyfill.ts', './src/index.tsx']
23
+ *
24
+ * // 对象入口
25
+ * injectRuntimeEntry({ main: './src/index.tsx' })
26
+ * // => { main: ['@lark-apaas/client-toolkit/runtime', './src/index.tsx'] }
27
+ * ```
28
+ */
29
+ export declare function injectRuntimeEntry(entry: Entry | undefined): Entry | undefined;
@@ -0,0 +1,111 @@
1
+ "use strict";
2
+ /**
3
+ * Runtime Entry 注入工具
4
+ *
5
+ * 将 @lark-apaas/client-toolkit/runtime 自动注入到用户入口之前
6
+ * 确保全局初始化逻辑(样式、dayjs、axios、observable、server-log)在用户代码之前执行
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.injectRuntimeEntry = injectRuntimeEntry;
10
+ const RUNTIME_MODULE = '@lark-apaas/client-toolkit/runtime';
11
+ /**
12
+ * 将 runtime 模块注入到 entry 配置中
13
+ *
14
+ * @param entry - 用户的 entry 配置
15
+ * @returns 注入 runtime 后的 entry 配置
16
+ *
17
+ * @example
18
+ * ```typescript
19
+ * // 字符串入口
20
+ * injectRuntimeEntry('./src/index.tsx')
21
+ * // => ['@lark-apaas/client-toolkit/runtime', './src/index.tsx']
22
+ *
23
+ * // 数组入口
24
+ * injectRuntimeEntry(['./src/polyfill.ts', './src/index.tsx'])
25
+ * // => ['@lark-apaas/client-toolkit/runtime', './src/polyfill.ts', './src/index.tsx']
26
+ *
27
+ * // 对象入口
28
+ * injectRuntimeEntry({ main: './src/index.tsx' })
29
+ * // => { main: ['@lark-apaas/client-toolkit/runtime', './src/index.tsx'] }
30
+ * ```
31
+ */
32
+ function injectRuntimeEntry(entry) {
33
+ if (!entry) {
34
+ return entry;
35
+ }
36
+ // 字符串入口:'./src/index.tsx'
37
+ if (typeof entry === 'string') {
38
+ return [RUNTIME_MODULE, entry];
39
+ }
40
+ // 数组入口:['./src/polyfill.ts', './src/index.tsx']
41
+ if (Array.isArray(entry)) {
42
+ // 避免重复注入
43
+ if (entry.includes(RUNTIME_MODULE)) {
44
+ return entry;
45
+ }
46
+ return [RUNTIME_MODULE, ...entry];
47
+ }
48
+ // 函数入口:() => './src/index.tsx' 或 () => Promise<...>
49
+ if (typeof entry === 'function') {
50
+ return async () => {
51
+ const resolvedEntry = await entry();
52
+ return injectRuntimeEntry(resolvedEntry);
53
+ };
54
+ }
55
+ // 对象入口:{ main: './src/index.tsx' } 或 { main: { import: './src/index.tsx' } }
56
+ if (typeof entry === 'object') {
57
+ const result = {};
58
+ for (const [key, value] of Object.entries(entry)) {
59
+ if (typeof value === 'string') {
60
+ // { main: './src/index.tsx' }
61
+ result[key] = [RUNTIME_MODULE, value];
62
+ }
63
+ else if (Array.isArray(value)) {
64
+ // { main: ['./src/polyfill.ts', './src/index.tsx'] }
65
+ if (value.includes(RUNTIME_MODULE)) {
66
+ result[key] = value;
67
+ }
68
+ else {
69
+ result[key] = [RUNTIME_MODULE, ...value];
70
+ }
71
+ }
72
+ else if (typeof value === 'object' && value !== null) {
73
+ // { main: { import: './src/index.tsx', ... } }
74
+ const entryDescription = value;
75
+ if (entryDescription.import) {
76
+ const importValue = entryDescription.import;
77
+ let newImport;
78
+ if (typeof importValue === 'string') {
79
+ newImport = [RUNTIME_MODULE, importValue];
80
+ }
81
+ else if (Array.isArray(importValue)) {
82
+ if (importValue.includes(RUNTIME_MODULE)) {
83
+ newImport = importValue;
84
+ }
85
+ else {
86
+ newImport = [RUNTIME_MODULE, ...importValue];
87
+ }
88
+ }
89
+ else {
90
+ newImport = [RUNTIME_MODULE];
91
+ }
92
+ result[key] = {
93
+ ...entryDescription,
94
+ import: newImport,
95
+ };
96
+ }
97
+ else {
98
+ // 没有 import 字段的情况,保持原样
99
+ result[key] = value;
100
+ }
101
+ }
102
+ else {
103
+ // 其他情况保持原样
104
+ result[key] = value;
105
+ }
106
+ }
107
+ return result;
108
+ }
109
+ // 未知类型,保持原样
110
+ return entry;
111
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lark-apaas/fullstack-rspack-preset",
3
- "version": "1.0.34",
3
+ "version": "1.0.35-alpha.1",
4
4
  "files": [
5
5
  "lib",
6
6
  "patches",
@@ -55,6 +55,7 @@
55
55
  "vitest": "^2.1.8"
56
56
  },
57
57
  "peerDependencies": {
58
+ "@lark-apaas/client-toolkit": "^1.2.8-alpha.2",
58
59
  "@rspack/core": "^1.5.5",
59
60
  "react": ">=16.14.0",
60
61
  "react-dom": ">=16.14.0"
@@ -1,9 +0,0 @@
1
- interface EnvironmentInjectionPluginOptions {
2
- environment?: string;
3
- }
4
- declare class EnvironmentInjectionPlugin {
5
- private options;
6
- constructor(options?: EnvironmentInjectionPluginOptions);
7
- apply(compiler: unknown): void;
8
- }
9
- export default EnvironmentInjectionPlugin;
@@ -1,112 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- class EnvironmentInjectionPlugin {
4
- constructor(options) {
5
- this.options = options || {};
6
- }
7
- apply(compiler) {
8
- const compilerLike = getCompilerLike(compiler);
9
- if (!compilerLike)
10
- return;
11
- compilerLike.hooks.compilation.tap('EnvironmentInjectionPlugin', (compilation) => {
12
- try {
13
- const HtmlPlugin = resolveHtmlPlugin(compilerLike);
14
- if (!HtmlPlugin) {
15
- console.warn('EnvironmentInjectionPlugin: HtmlRspackPlugin not found');
16
- return;
17
- }
18
- const hooks = HtmlPlugin.getHooks(compilation);
19
- hooks.alterAssetTagGroups.tap('EnvironmentInjectionPlugin', (data) => {
20
- const mapped = mapToWindowEnvironment(this.options.environment ??
21
- process.env.FORCE_FRAMEWORK_ENVIRONMENT);
22
- const envTag = {
23
- tagName: 'script',
24
- voidTag: false,
25
- innerHTML: `(() => {
26
- const templateValue = '{{environment}}';
27
- const resolved =
28
- templateValue && templateValue !== '{{environment}}'
29
- ? templateValue
30
- : ${JSON.stringify(mapped)};
31
- window.ENVIRONMENT = resolved;
32
- })();`,
33
- attributes: {},
34
- };
35
- const headIndex = findMainJsIndex(data.headTags);
36
- if (headIndex !== -1) {
37
- data.headTags.splice(headIndex, 0, envTag);
38
- return data;
39
- }
40
- const bodyIndex = findMainJsIndex(data.bodyTags);
41
- if (bodyIndex !== -1) {
42
- data.bodyTags.splice(bodyIndex, 0, envTag);
43
- return data;
44
- }
45
- data.headTags.unshift(envTag);
46
- return data;
47
- });
48
- }
49
- catch (error) {
50
- console.error('Error in EnvironmentInjectionPlugin:', error);
51
- }
52
- });
53
- }
54
- }
55
- exports.default = EnvironmentInjectionPlugin;
56
- function mapToWindowEnvironment(input) {
57
- const value = (input || '').trim().toLowerCase();
58
- if (value === 'boe')
59
- return 'staging';
60
- if (value === 'pre')
61
- return 'gray';
62
- if (value === 'online')
63
- return 'online';
64
- return '';
65
- }
66
- function findMainJsIndex(tags) {
67
- if (!Array.isArray(tags))
68
- return -1;
69
- return tags.findIndex((tag) => {
70
- if (!tag || tag.tagName !== 'script')
71
- return false;
72
- const src = tag.attributes?.src;
73
- return typeof src === 'string' && src.includes('main.js');
74
- });
75
- }
76
- function getCompilerLike(input) {
77
- if (!input || typeof input !== 'object')
78
- return;
79
- const hooks = input.hooks;
80
- if (!hooks || typeof hooks !== 'object')
81
- return;
82
- const compilation = hooks.compilation;
83
- if (!compilation || typeof compilation !== 'object')
84
- return;
85
- const tap = compilation.tap;
86
- if (typeof tap !== 'function')
87
- return;
88
- return input;
89
- }
90
- function resolveHtmlPlugin(compiler) {
91
- const fromWebpack = getHtmlPluginLike(compiler.webpack?.HtmlRspackPlugin);
92
- if (fromWebpack)
93
- return fromWebpack;
94
- const fromRspack = getHtmlPluginLike(compiler.rspack?.HtmlRspackPlugin);
95
- if (fromRspack)
96
- return fromRspack;
97
- const fromCtor = getHtmlPluginLike(compiler.constructor?.webpack?.HtmlRspackPlugin);
98
- if (fromCtor)
99
- return fromCtor;
100
- return;
101
- }
102
- function getHtmlPluginLike(value) {
103
- if (!value)
104
- return;
105
- const type = typeof value;
106
- if (type !== 'function' && type !== 'object')
107
- return;
108
- const getHooks = value.getHooks;
109
- if (typeof getHooks !== 'function')
110
- return;
111
- return value;
112
- }