@lark-apaas/fullstack-rspack-preset 1.0.42 → 1.0.44
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/module-alias/echarts-for-react.d.ts +1 -0
- package/lib/module-alias/echarts-for-react.js +42 -9
- package/lib/module-alias/registry_echarts_theme.d.ts +2 -6
- package/lib/module-alias/registry_echarts_theme.js +1 -1
- package/lib/preset.js +11 -0
- package/lib/rspack-plugins/static-assets-plugin.js +49 -2
- package/package.json +1 -1
- package/lib/rspack-plugins/environment-injection-plugin.d.ts +0 -9
- package/lib/rspack-plugins/environment-injection-plugin.js +0 -112
|
@@ -45,6 +45,15 @@ function convertColorToHex(color) {
|
|
|
45
45
|
return color;
|
|
46
46
|
}
|
|
47
47
|
}
|
|
48
|
+
function convertColorValue(propValue, visited) {
|
|
49
|
+
if (typeof propValue === 'string') {
|
|
50
|
+
return convertColorToHex(propValue);
|
|
51
|
+
}
|
|
52
|
+
if (Array.isArray(propValue)) {
|
|
53
|
+
return propValue.map((item) => typeof item === 'string' ? convertColorToHex(item) : transformColors(item, visited));
|
|
54
|
+
}
|
|
55
|
+
return transformColors(propValue, visited);
|
|
56
|
+
}
|
|
48
57
|
/**
|
|
49
58
|
* Deep traverse object to transform all HSL colors in 'color' property
|
|
50
59
|
*/
|
|
@@ -57,8 +66,6 @@ function transformColors(value, visited = new WeakSet()) {
|
|
|
57
66
|
return value;
|
|
58
67
|
if (value instanceof Date || value instanceof RegExp)
|
|
59
68
|
return value;
|
|
60
|
-
if (typeof value === 'function')
|
|
61
|
-
return value;
|
|
62
69
|
visited.add(value);
|
|
63
70
|
if (Array.isArray(value)) {
|
|
64
71
|
return value.map((item) => transformColors(item, visited));
|
|
@@ -69,14 +76,11 @@ function transformColors(value, visited = new WeakSet()) {
|
|
|
69
76
|
continue;
|
|
70
77
|
const propValue = value[key];
|
|
71
78
|
if (key === 'color') {
|
|
72
|
-
if (typeof propValue === '
|
|
73
|
-
result[key] =
|
|
74
|
-
}
|
|
75
|
-
else if (Array.isArray(propValue)) {
|
|
76
|
-
result[key] = propValue.map((item) => typeof item === 'string' ? convertColorToHex(item) : transformColors(item, visited));
|
|
79
|
+
if (typeof propValue === 'function') {
|
|
80
|
+
result[key] = (...args) => convertColorValue(propValue(...args), visited);
|
|
77
81
|
}
|
|
78
82
|
else {
|
|
79
|
-
result[key] =
|
|
83
|
+
result[key] = convertColorValue(propValue, visited);
|
|
80
84
|
}
|
|
81
85
|
}
|
|
82
86
|
else {
|
|
@@ -85,14 +89,43 @@ function transformColors(value, visited = new WeakSet()) {
|
|
|
85
89
|
}
|
|
86
90
|
return result;
|
|
87
91
|
}
|
|
92
|
+
/**
|
|
93
|
+
* Remove label.color and emphasis.label.color from funnel series
|
|
94
|
+
* to let ECharts use default contrast colors
|
|
95
|
+
*/
|
|
96
|
+
function removeFunnelLabelColor(option) {
|
|
97
|
+
if (!Array.isArray(option.series))
|
|
98
|
+
return option;
|
|
99
|
+
const series = option.series.map((item) => {
|
|
100
|
+
if (item?.type !== 'funnel')
|
|
101
|
+
return item;
|
|
102
|
+
let result = { ...item };
|
|
103
|
+
// remove label.color
|
|
104
|
+
if (result.label && typeof result.label === 'object') {
|
|
105
|
+
const { color: _, ...labelRest } = result.label;
|
|
106
|
+
result = { ...result, label: labelRest };
|
|
107
|
+
}
|
|
108
|
+
// remove emphasis.label.color
|
|
109
|
+
const emphasis = result.emphasis;
|
|
110
|
+
if (emphasis?.label && typeof emphasis.label === 'object') {
|
|
111
|
+
const { color: _, ...emphasisLabelRest } = emphasis.label;
|
|
112
|
+
result = { ...result, emphasis: { ...emphasis, label: emphasisLabelRest } };
|
|
113
|
+
}
|
|
114
|
+
return result;
|
|
115
|
+
});
|
|
116
|
+
return { ...option, series };
|
|
117
|
+
}
|
|
88
118
|
/**
|
|
89
119
|
* EChartsReact wrapper component
|
|
90
120
|
* - Automatically converts HSL colors to hex in option
|
|
121
|
+
* - Removes label.color from funnel series
|
|
91
122
|
*/
|
|
92
123
|
class EChartsReact extends react_1.default.Component {
|
|
93
124
|
render() {
|
|
94
125
|
const { option, ...rest } = this.props;
|
|
95
|
-
const transformedOption = option
|
|
126
|
+
const transformedOption = option
|
|
127
|
+
? removeFunnelLabelColor(transformColors(option))
|
|
128
|
+
: option;
|
|
96
129
|
return react_1.default.createElement(echarts_for_react_1.default, {
|
|
97
130
|
option: transformedOption,
|
|
98
131
|
...rest,
|
|
@@ -8,9 +8,7 @@ export declare function getCssVariable(varName: string, element?: HTMLElement):
|
|
|
8
8
|
export declare function generateEChartsTheme(element?: HTMLElement): {
|
|
9
9
|
color: string[];
|
|
10
10
|
backgroundColor: string;
|
|
11
|
-
textStyle: {
|
|
12
|
-
color: string;
|
|
13
|
-
};
|
|
11
|
+
textStyle: {};
|
|
14
12
|
title: {
|
|
15
13
|
textStyle: {
|
|
16
14
|
color: string;
|
|
@@ -352,9 +350,7 @@ export declare function generateEChartsTheme(element?: HTMLElement): {
|
|
|
352
350
|
export declare function getShadcnEChartsTheme(): {
|
|
353
351
|
color: string[];
|
|
354
352
|
backgroundColor: string;
|
|
355
|
-
textStyle: {
|
|
356
|
-
color: string;
|
|
357
|
-
};
|
|
353
|
+
textStyle: {};
|
|
358
354
|
title: {
|
|
359
355
|
textStyle: {
|
|
360
356
|
color: string;
|
package/lib/preset.js
CHANGED
|
@@ -46,9 +46,20 @@ function createRecommendRspackConfig(options) {
|
|
|
46
46
|
resolve: {
|
|
47
47
|
mainFields: ['module', 'browser', 'main'],
|
|
48
48
|
extensions: ['.js', '.jsx', '.ts', '.tsx', '.json'],
|
|
49
|
+
alias: {
|
|
50
|
+
// 确保所有 echarts 子路径导入(如 echarts/core, echarts/lib/...)
|
|
51
|
+
// 都解析到 preset 自带的 echarts,避免第三方扩展(如 echarts-wordcloud)
|
|
52
|
+
// 安装了独立的 echarts 副本导致注册不到同一个实例上
|
|
53
|
+
echarts: path_1.default.dirname(require.resolve('echarts/package.json')),
|
|
54
|
+
},
|
|
49
55
|
},
|
|
50
56
|
module: {
|
|
51
57
|
rules: [
|
|
58
|
+
// Support ?raw query to import file content as string (like Vite's ?raw)
|
|
59
|
+
{
|
|
60
|
+
resourceQuery: /\?raw$/,
|
|
61
|
+
type: 'asset/source',
|
|
62
|
+
},
|
|
52
63
|
{
|
|
53
64
|
test: /\.svg$/,
|
|
54
65
|
type: 'asset',
|
|
@@ -75,6 +75,40 @@ const MIME_TYPES = {
|
|
|
75
75
|
};
|
|
76
76
|
const SHARED_STATIC_PREFIX = '@shared/static/';
|
|
77
77
|
const PLUGIN_NAME = 'StaticAssetsPlugin';
|
|
78
|
+
/** File extensions that should be resolved as normal modules instead of static asset URLs */
|
|
79
|
+
const SCRIPT_EXTENSIONS = ['.ts', '.tsx', '.js', '.jsx', '.mts', '.cts', '.mjs', '.cjs'];
|
|
80
|
+
/**
|
|
81
|
+
* Split a relative path into the clean path and optional query string.
|
|
82
|
+
* e.g. "file.md?raw" → ["file.md", "?raw"]
|
|
83
|
+
*/
|
|
84
|
+
function splitQuery(relativePath) {
|
|
85
|
+
const qIndex = relativePath.indexOf('?');
|
|
86
|
+
if (qIndex === -1)
|
|
87
|
+
return [relativePath, ''];
|
|
88
|
+
return [relativePath.slice(0, qIndex), relativePath.slice(qIndex)];
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Try to resolve a relative path to a real script file on disk.
|
|
92
|
+
* Handles both explicit extensions (utils.ts) and extensionless imports (utils).
|
|
93
|
+
* Returns the absolute path if found, null otherwise.
|
|
94
|
+
*/
|
|
95
|
+
function resolveScriptFile(staticDir, cleanPath) {
|
|
96
|
+
const ext = path.extname(cleanPath).toLowerCase();
|
|
97
|
+
// Has explicit script extension → resolve directly
|
|
98
|
+
if (ext && SCRIPT_EXTENSIONS.includes(ext)) {
|
|
99
|
+
return path.join(staticDir, cleanPath);
|
|
100
|
+
}
|
|
101
|
+
// No extension → probe for matching script file on disk
|
|
102
|
+
if (!ext) {
|
|
103
|
+
for (const scriptExt of SCRIPT_EXTENSIONS) {
|
|
104
|
+
const fullPath = path.join(staticDir, cleanPath + scriptExt);
|
|
105
|
+
if (fs.existsSync(fullPath)) {
|
|
106
|
+
return fullPath;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return null;
|
|
111
|
+
}
|
|
78
112
|
class StaticAssetsPlugin {
|
|
79
113
|
constructor(options = {}) {
|
|
80
114
|
this.jsonDataCache = null;
|
|
@@ -218,10 +252,23 @@ class StaticAssetsPlugin {
|
|
|
218
252
|
return;
|
|
219
253
|
}
|
|
220
254
|
const relativePath = request.slice(SHARED_STATIC_PREFIX.length);
|
|
255
|
+
const [cleanPath, query] = splitQuery(relativePath);
|
|
256
|
+
// Imports with query params (e.g. ?raw) should resolve to real
|
|
257
|
+
// paths and let Rspack's native handling process them
|
|
258
|
+
if (query) {
|
|
259
|
+
resolveData.request = path.join(this.staticDir, cleanPath) + query;
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
262
|
+
// JS/TS files should be resolved to their real paths and bundled normally
|
|
263
|
+
const scriptPath = resolveScriptFile(this.staticDir, cleanPath);
|
|
264
|
+
if (scriptPath) {
|
|
265
|
+
resolveData.request = scriptPath;
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
221
268
|
// Generate virtual module content
|
|
222
|
-
const content = this.generateVirtualModuleContent(
|
|
269
|
+
const content = this.generateVirtualModuleContent(cleanPath);
|
|
223
270
|
// Create a virtual module file
|
|
224
|
-
const virtualModulePath = path.join(virtualModulesDir,
|
|
271
|
+
const virtualModulePath = path.join(virtualModulesDir, cleanPath.replace(/[/\\]/g, '_') + '.js');
|
|
225
272
|
// Only write to disk if content has changed
|
|
226
273
|
const existingContent = writtenModules.get(virtualModulePath);
|
|
227
274
|
if (existingContent !== content) {
|
package/package.json
CHANGED
|
@@ -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
|
-
}
|