@modern-js/builder 3.9.1 → 3.9.3
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/dist/cjs/shared/parseCommonConfig.js +11 -14
- package/dist/cjs/shared/pluginOptions.js +121 -0
- package/dist/esm/shared/parseCommonConfig.mjs +11 -14
- package/dist/esm/shared/pluginOptions.mjs +74 -0
- package/dist/esm-node/shared/parseCommonConfig.mjs +11 -14
- package/dist/esm-node/shared/pluginOptions.mjs +75 -0
- package/dist/types/shared/pluginOptions.d.ts +32 -0
- package/dist/types/types.d.ts +25 -5
- package/package.json +13 -13
|
@@ -43,6 +43,7 @@ const globalVars_js_namespaceObject = require("../plugins/globalVars.js");
|
|
|
43
43
|
const htmlMinify_js_namespaceObject = require("../plugins/htmlMinify.js");
|
|
44
44
|
const runtimeChunk_js_namespaceObject = require("../plugins/runtimeChunk.js");
|
|
45
45
|
const external_devServer_js_namespaceObject = require("./devServer.js");
|
|
46
|
+
const external_pluginOptions_js_namespaceObject = require("./pluginOptions.js");
|
|
46
47
|
const external_utils_js_namespaceObject = require("./utils.js");
|
|
47
48
|
const CSS_MODULES_REGEX = /\.modules?\.\w+$/i;
|
|
48
49
|
const GLOBAL_CSS_REGEX = /\.global\.\w+$/;
|
|
@@ -58,7 +59,7 @@ function removeUndefinedKey(obj) {
|
|
|
58
59
|
}
|
|
59
60
|
async function parseCommonConfig(builderConfig, options) {
|
|
60
61
|
const frameworkConfigPath = options?.frameworkConfigPath;
|
|
61
|
-
const { plugins: [...plugins] = [], splitChunks, performance: { ...performanceConfig } = {}, output: { module = false, enableCssModuleTSDeclaration, disableCssModuleExtension, disableTsChecker, disableSvgr, svgDefaultExport, assetsRetry, enableAssetManifest, sourceMap, convertToRem, polyfill, dataUriLimit = 10000, distPath = {}, ...outputConfig } = {}, html: { outputStructure, appIcon, ...htmlConfig } = {}, source: { alias, globalVars, transformImport, reactCompiler, ...sourceConfig } = {}, dev = {}, server = {}, security: { checkSyntax, sri, ...securityConfig } = {}, tools: { devServer, tsChecker, minifyCss, less, sass, htmlPlugin, autoprefixer, ...toolsConfig } = {}, environments = {}, resolve = {} } = builderConfig;
|
|
62
|
+
const { plugins: [...plugins] = [], splitChunks, performance: { ...performanceConfig } = {}, output: { module = false, enableCssModuleTSDeclaration, disableCssModuleExtension, disableTsChecker, disableSvgr, svgDefaultExport, assetsRetry, enableAssetManifest, sourceMap, convertToRem, polyfill, dataUriLimit = 10000, distPath = {}, ...outputConfig } = {}, html: { outputStructure, appIcon, ...htmlConfig } = {}, source: { alias, globalVars, transformImport, reactCompiler, ...sourceConfig } = {}, dev = {}, server = {}, security: { checkSyntax, sri, ...securityConfig } = {}, tools: { devServer, tsChecker, minifyCss, less, sass, svgr, htmlPlugin, autoprefixer, ...toolsConfig } = {}, environments = {}, resolve = {} } = builderConfig;
|
|
62
63
|
let combinedAlias;
|
|
63
64
|
if (alias || resolve.alias) combinedAlias = [].concat(alias ?? []).concat(resolve.alias ?? []);
|
|
64
65
|
const rsbuildConfig = {
|
|
@@ -140,12 +141,8 @@ async function parseCommonConfig(builderConfig, options) {
|
|
|
140
141
|
sourceMap
|
|
141
142
|
}),
|
|
142
143
|
(0, emitRouteFile_js_namespaceObject.pluginEmitRouteFile)(),
|
|
143
|
-
(0, plugin_sass_namespaceObject.pluginSass)(
|
|
144
|
-
|
|
145
|
-
}),
|
|
146
|
-
(0, plugin_less_namespaceObject.pluginLess)({
|
|
147
|
-
lessLoaderOptions: less
|
|
148
|
-
}),
|
|
144
|
+
(0, plugin_sass_namespaceObject.pluginSass)((0, external_pluginOptions_js_namespaceObject.normalizeSassOptions)(sass)),
|
|
145
|
+
(0, plugin_less_namespaceObject.pluginLess)((0, external_pluginOptions_js_namespaceObject.normalizeLessOptions)(less)),
|
|
149
146
|
(0, environmentDefaults_js_namespaceObject.pluginEnvironmentDefaults)(distPath),
|
|
150
147
|
(0, htmlMinify_js_namespaceObject.pluginHtmlMinifierTerser)()
|
|
151
148
|
];
|
|
@@ -176,14 +173,14 @@ async function parseCommonConfig(builderConfig, options) {
|
|
|
176
173
|
rsbuildPlugins.push((0, plugin_react_namespaceObject.pluginReact)(void 0 !== reactCompiler ? {
|
|
177
174
|
reactCompiler
|
|
178
175
|
} : {}));
|
|
179
|
-
|
|
176
|
+
const svgrOptions = (0, external_pluginOptions_js_namespaceObject.resolveSvgrOptions)({
|
|
177
|
+
svgr,
|
|
178
|
+
disableSvgr,
|
|
179
|
+
svgDefaultExport
|
|
180
|
+
});
|
|
181
|
+
if (false !== svgrOptions) {
|
|
180
182
|
const { pluginSvgr } = await import("@rsbuild/plugin-svgr");
|
|
181
|
-
rsbuildPlugins.push(pluginSvgr(
|
|
182
|
-
mixedImport: true,
|
|
183
|
-
svgrOptions: {
|
|
184
|
-
exportType: 'component' === svgDefaultExport ? 'default' : 'named'
|
|
185
|
-
}
|
|
186
|
-
}));
|
|
183
|
+
rsbuildPlugins.push(pluginSvgr(svgrOptions));
|
|
187
184
|
}
|
|
188
185
|
if (assetsRetry) {
|
|
189
186
|
const { pluginAssetsRetry } = await import("@rsbuild/plugin-assets-retry");
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __webpack_require__ = {};
|
|
3
|
+
(()=>{
|
|
4
|
+
__webpack_require__.d = (exports1, getters, values)=>{
|
|
5
|
+
var define = (defs, kind)=>{
|
|
6
|
+
for(var key in defs)if (__webpack_require__.o(defs, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
[kind]: defs[key]
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
define(getters, "get");
|
|
12
|
+
define(values, "value");
|
|
13
|
+
};
|
|
14
|
+
})();
|
|
15
|
+
(()=>{
|
|
16
|
+
__webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
|
|
17
|
+
})();
|
|
18
|
+
(()=>{
|
|
19
|
+
__webpack_require__.r = (exports1)=>{
|
|
20
|
+
if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
|
|
21
|
+
value: 'Module'
|
|
22
|
+
});
|
|
23
|
+
Object.defineProperty(exports1, '__esModule', {
|
|
24
|
+
value: true
|
|
25
|
+
});
|
|
26
|
+
};
|
|
27
|
+
})();
|
|
28
|
+
var __webpack_exports__ = {};
|
|
29
|
+
__webpack_require__.r(__webpack_exports__);
|
|
30
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
31
|
+
normalizeLessOptions: ()=>normalizeLessOptions,
|
|
32
|
+
normalizeSassOptions: ()=>normalizeSassOptions,
|
|
33
|
+
resetPluginOptionsWarnings: ()=>resetPluginOptionsWarnings,
|
|
34
|
+
resolveSvgrOptions: ()=>resolveSvgrOptions
|
|
35
|
+
});
|
|
36
|
+
const utils_namespaceObject = require("@modern-js/utils");
|
|
37
|
+
const LESS_PLUGIN_KEYS = [
|
|
38
|
+
'lessLoaderOptions',
|
|
39
|
+
'include',
|
|
40
|
+
'exclude',
|
|
41
|
+
'parallel'
|
|
42
|
+
];
|
|
43
|
+
const SASS_PLUGIN_KEYS = [
|
|
44
|
+
'sassLoaderOptions',
|
|
45
|
+
'include',
|
|
46
|
+
'exclude',
|
|
47
|
+
'rewriteUrls'
|
|
48
|
+
];
|
|
49
|
+
const warned = new Set();
|
|
50
|
+
const resetPluginOptionsWarnings = ()=>{
|
|
51
|
+
warned.clear();
|
|
52
|
+
};
|
|
53
|
+
const warnOnceInDev = (key, message)=>{
|
|
54
|
+
if (!(0, utils_namespaceObject.isDevCommand)() || warned.has(key)) return;
|
|
55
|
+
warned.add(key);
|
|
56
|
+
utils_namespaceObject.logger.warn(message);
|
|
57
|
+
};
|
|
58
|
+
const isPlainObject = (value)=>'object' == typeof value && null !== value && !Array.isArray(value);
|
|
59
|
+
const isPluginLevelOptions = (value, pluginKeys)=>isPlainObject(value) && pluginKeys.some((key)=>key in value);
|
|
60
|
+
const isEmptyObject = (value)=>isPlainObject(value) && 0 === Object.keys(value).length;
|
|
61
|
+
const warnIgnoredKeys = (name, value, pluginKeys, loaderOptionsKey)=>{
|
|
62
|
+
const pluginLevel = Object.keys(value).filter((key)=>pluginKeys.includes(key));
|
|
63
|
+
const ignored = Object.keys(value).filter((key)=>!pluginKeys.includes(key));
|
|
64
|
+
if (0 === ignored.length) return;
|
|
65
|
+
warnOnceInDev(`${name}:mixed`, `\`${name}\` contains plugin-level options (${pluginLevel.join(', ')}) together with other keys (${ignored.join(', ')}). The whole object is passed to the plugin, so the other keys are ignored. Move loader options under \`${loaderOptionsKey}\`.`);
|
|
66
|
+
};
|
|
67
|
+
const normalizeLessOptions = (less)=>{
|
|
68
|
+
if (isPluginLevelOptions(less, LESS_PLUGIN_KEYS)) {
|
|
69
|
+
warnIgnoredKeys('tools.less', less, LESS_PLUGIN_KEYS, 'lessLoaderOptions');
|
|
70
|
+
return less;
|
|
71
|
+
}
|
|
72
|
+
if (void 0 !== less && !isEmptyObject(less)) warnOnceInDev('tools.less', "`tools.less` now accepts the full options of @rsbuild/plugin-less. Passing less-loader options directly is deprecated and will stop working in the next major version. Move them under `lessLoaderOptions`:\n before: tools: { less: { lessOptions: { javascriptEnabled: true } } }\n after: tools: { less: { lessLoaderOptions: { lessOptions: { javascriptEnabled: true } } } }");
|
|
73
|
+
return {
|
|
74
|
+
lessLoaderOptions: less
|
|
75
|
+
};
|
|
76
|
+
};
|
|
77
|
+
const normalizeSassOptions = (sass)=>{
|
|
78
|
+
if (isPluginLevelOptions(sass, SASS_PLUGIN_KEYS)) {
|
|
79
|
+
warnIgnoredKeys('tools.sass', sass, SASS_PLUGIN_KEYS, 'sassLoaderOptions');
|
|
80
|
+
return sass;
|
|
81
|
+
}
|
|
82
|
+
if (void 0 !== sass && !isEmptyObject(sass)) warnOnceInDev('tools.sass', "`tools.sass` now accepts the full options of @rsbuild/plugin-sass. Passing sass-loader options directly is deprecated and will stop working in the next major version. Move them under `sassLoaderOptions`:\n before: tools: { sass: { sassOptions: { quietDeps: true } } }\n after: tools: { sass: { sassLoaderOptions: { sassOptions: { quietDeps: true } } } }");
|
|
83
|
+
return {
|
|
84
|
+
sassLoaderOptions: sass
|
|
85
|
+
};
|
|
86
|
+
};
|
|
87
|
+
const mergeSvgrOptions = (target, source)=>{
|
|
88
|
+
const svgrOptions = source.svgrOptions ? {
|
|
89
|
+
...target.svgrOptions,
|
|
90
|
+
...source.svgrOptions
|
|
91
|
+
} : target.svgrOptions;
|
|
92
|
+
return Object.assign(target, source, {
|
|
93
|
+
svgrOptions
|
|
94
|
+
});
|
|
95
|
+
};
|
|
96
|
+
const resolveSvgrOptions = ({ svgr, disableSvgr, svgDefaultExport })=>{
|
|
97
|
+
if (void 0 !== disableSvgr) warnOnceInDev('output.disableSvgr', disableSvgr ? '`output.disableSvgr` is deprecated and will be removed in the next major version. Use `tools: { svgr: false }` instead.' : '`output.disableSvgr` is deprecated and will be removed in the next major version. SVGR is enabled by default, so `output.disableSvgr: false` can be removed (or use `tools: { svgr: {} }` to keep it explicit).');
|
|
98
|
+
if (void 0 !== svgDefaultExport) warnOnceInDev('output.svgDefaultExport', "`output.svgDefaultExport` is deprecated and will be removed in the next major version. Use `tools.svgr.svgrOptions.exportType` instead:\n before: output: { svgDefaultExport: 'component' }\n after: tools: { svgr: { svgrOptions: { exportType: 'default' } } }\n ('url' maps to exportType: 'named')");
|
|
99
|
+
if (false === svgr) return false;
|
|
100
|
+
if (void 0 === svgr && disableSvgr) return false;
|
|
101
|
+
const defaults = {
|
|
102
|
+
mixedImport: true,
|
|
103
|
+
svgrOptions: {
|
|
104
|
+
exportType: 'component' === svgDefaultExport ? 'default' : 'named'
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
return (0, utils_namespaceObject.applyOptionsChain)(defaults, svgr, void 0, mergeSvgrOptions);
|
|
108
|
+
};
|
|
109
|
+
exports.normalizeLessOptions = __webpack_exports__.normalizeLessOptions;
|
|
110
|
+
exports.normalizeSassOptions = __webpack_exports__.normalizeSassOptions;
|
|
111
|
+
exports.resetPluginOptionsWarnings = __webpack_exports__.resetPluginOptionsWarnings;
|
|
112
|
+
exports.resolveSvgrOptions = __webpack_exports__.resolveSvgrOptions;
|
|
113
|
+
for(var __rspack_i in __webpack_exports__)if (-1 === [
|
|
114
|
+
"normalizeLessOptions",
|
|
115
|
+
"normalizeSassOptions",
|
|
116
|
+
"resetPluginOptionsWarnings",
|
|
117
|
+
"resolveSvgrOptions"
|
|
118
|
+
].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
|
|
119
|
+
Object.defineProperty(exports, '__esModule', {
|
|
120
|
+
value: true
|
|
121
|
+
});
|
|
@@ -10,6 +10,7 @@ import { pluginGlobalVars } from "../plugins/globalVars.mjs";
|
|
|
10
10
|
import { pluginHtmlMinifierTerser } from "../plugins/htmlMinify.mjs";
|
|
11
11
|
import { pluginRuntimeChunk } from "../plugins/runtimeChunk.mjs";
|
|
12
12
|
import { transformToRsbuildServerOptions } from "./devServer.mjs";
|
|
13
|
+
import { normalizeLessOptions, normalizeSassOptions, resolveSvgrOptions } from "./pluginOptions.mjs";
|
|
13
14
|
import { NODE_MODULES_REGEX } from "./utils.mjs";
|
|
14
15
|
const CSS_MODULES_REGEX = /\.modules?\.\w+$/i;
|
|
15
16
|
const GLOBAL_CSS_REGEX = /\.global\.\w+$/;
|
|
@@ -25,7 +26,7 @@ function removeUndefinedKey(obj) {
|
|
|
25
26
|
}
|
|
26
27
|
async function parseCommonConfig(builderConfig, options) {
|
|
27
28
|
const frameworkConfigPath = options?.frameworkConfigPath;
|
|
28
|
-
const { plugins: [...plugins] = [], splitChunks, performance: { ...performanceConfig } = {}, output: { module = false, enableCssModuleTSDeclaration, disableCssModuleExtension, disableTsChecker, disableSvgr, svgDefaultExport, assetsRetry, enableAssetManifest, sourceMap, convertToRem, polyfill, dataUriLimit = 10000, distPath = {}, ...outputConfig } = {}, html: { outputStructure, appIcon, ...htmlConfig } = {}, source: { alias, globalVars, transformImport, reactCompiler, ...sourceConfig } = {}, dev = {}, server = {}, security: { checkSyntax, sri, ...securityConfig } = {}, tools: { devServer, tsChecker, minifyCss, less, sass, htmlPlugin, autoprefixer, ...toolsConfig } = {}, environments = {}, resolve = {} } = builderConfig;
|
|
29
|
+
const { plugins: [...plugins] = [], splitChunks, performance: { ...performanceConfig } = {}, output: { module = false, enableCssModuleTSDeclaration, disableCssModuleExtension, disableTsChecker, disableSvgr, svgDefaultExport, assetsRetry, enableAssetManifest, sourceMap, convertToRem, polyfill, dataUriLimit = 10000, distPath = {}, ...outputConfig } = {}, html: { outputStructure, appIcon, ...htmlConfig } = {}, source: { alias, globalVars, transformImport, reactCompiler, ...sourceConfig } = {}, dev = {}, server = {}, security: { checkSyntax, sri, ...securityConfig } = {}, tools: { devServer, tsChecker, minifyCss, less, sass, svgr, htmlPlugin, autoprefixer, ...toolsConfig } = {}, environments = {}, resolve = {} } = builderConfig;
|
|
29
30
|
let combinedAlias;
|
|
30
31
|
if (alias || resolve.alias) combinedAlias = [].concat(alias ?? []).concat(resolve.alias ?? []);
|
|
31
32
|
const rsbuildConfig = {
|
|
@@ -107,12 +108,8 @@ async function parseCommonConfig(builderConfig, options) {
|
|
|
107
108
|
sourceMap
|
|
108
109
|
}),
|
|
109
110
|
pluginEmitRouteFile(),
|
|
110
|
-
pluginSass(
|
|
111
|
-
|
|
112
|
-
}),
|
|
113
|
-
pluginLess({
|
|
114
|
-
lessLoaderOptions: less
|
|
115
|
-
}),
|
|
111
|
+
pluginSass(normalizeSassOptions(sass)),
|
|
112
|
+
pluginLess(normalizeLessOptions(less)),
|
|
116
113
|
pluginEnvironmentDefaults(distPath),
|
|
117
114
|
pluginHtmlMinifierTerser()
|
|
118
115
|
];
|
|
@@ -143,14 +140,14 @@ async function parseCommonConfig(builderConfig, options) {
|
|
|
143
140
|
rsbuildPlugins.push(pluginReact(void 0 !== reactCompiler ? {
|
|
144
141
|
reactCompiler
|
|
145
142
|
} : {}));
|
|
146
|
-
|
|
143
|
+
const svgrOptions = resolveSvgrOptions({
|
|
144
|
+
svgr,
|
|
145
|
+
disableSvgr,
|
|
146
|
+
svgDefaultExport
|
|
147
|
+
});
|
|
148
|
+
if (false !== svgrOptions) {
|
|
147
149
|
const { pluginSvgr } = await import("@rsbuild/plugin-svgr");
|
|
148
|
-
rsbuildPlugins.push(pluginSvgr(
|
|
149
|
-
mixedImport: true,
|
|
150
|
-
svgrOptions: {
|
|
151
|
-
exportType: 'component' === svgDefaultExport ? 'default' : 'named'
|
|
152
|
-
}
|
|
153
|
-
}));
|
|
150
|
+
rsbuildPlugins.push(pluginSvgr(svgrOptions));
|
|
154
151
|
}
|
|
155
152
|
if (assetsRetry) {
|
|
156
153
|
const { pluginAssetsRetry } = await import("@rsbuild/plugin-assets-retry");
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { applyOptionsChain, isDevCommand, logger } from "@modern-js/utils";
|
|
2
|
+
const LESS_PLUGIN_KEYS = [
|
|
3
|
+
'lessLoaderOptions',
|
|
4
|
+
'include',
|
|
5
|
+
'exclude',
|
|
6
|
+
'parallel'
|
|
7
|
+
];
|
|
8
|
+
const SASS_PLUGIN_KEYS = [
|
|
9
|
+
'sassLoaderOptions',
|
|
10
|
+
'include',
|
|
11
|
+
'exclude',
|
|
12
|
+
'rewriteUrls'
|
|
13
|
+
];
|
|
14
|
+
const warned = new Set();
|
|
15
|
+
const resetPluginOptionsWarnings = ()=>{
|
|
16
|
+
warned.clear();
|
|
17
|
+
};
|
|
18
|
+
const warnOnceInDev = (key, message)=>{
|
|
19
|
+
if (!isDevCommand() || warned.has(key)) return;
|
|
20
|
+
warned.add(key);
|
|
21
|
+
logger.warn(message);
|
|
22
|
+
};
|
|
23
|
+
const isPlainObject = (value)=>'object' == typeof value && null !== value && !Array.isArray(value);
|
|
24
|
+
const isPluginLevelOptions = (value, pluginKeys)=>isPlainObject(value) && pluginKeys.some((key)=>key in value);
|
|
25
|
+
const isEmptyObject = (value)=>isPlainObject(value) && 0 === Object.keys(value).length;
|
|
26
|
+
const warnIgnoredKeys = (name, value, pluginKeys, loaderOptionsKey)=>{
|
|
27
|
+
const pluginLevel = Object.keys(value).filter((key)=>pluginKeys.includes(key));
|
|
28
|
+
const ignored = Object.keys(value).filter((key)=>!pluginKeys.includes(key));
|
|
29
|
+
if (0 === ignored.length) return;
|
|
30
|
+
warnOnceInDev(`${name}:mixed`, `\`${name}\` contains plugin-level options (${pluginLevel.join(', ')}) together with other keys (${ignored.join(', ')}). The whole object is passed to the plugin, so the other keys are ignored. Move loader options under \`${loaderOptionsKey}\`.`);
|
|
31
|
+
};
|
|
32
|
+
const normalizeLessOptions = (less)=>{
|
|
33
|
+
if (isPluginLevelOptions(less, LESS_PLUGIN_KEYS)) {
|
|
34
|
+
warnIgnoredKeys('tools.less', less, LESS_PLUGIN_KEYS, 'lessLoaderOptions');
|
|
35
|
+
return less;
|
|
36
|
+
}
|
|
37
|
+
if (void 0 !== less && !isEmptyObject(less)) warnOnceInDev('tools.less', "`tools.less` now accepts the full options of @rsbuild/plugin-less. Passing less-loader options directly is deprecated and will stop working in the next major version. Move them under `lessLoaderOptions`:\n before: tools: { less: { lessOptions: { javascriptEnabled: true } } }\n after: tools: { less: { lessLoaderOptions: { lessOptions: { javascriptEnabled: true } } } }");
|
|
38
|
+
return {
|
|
39
|
+
lessLoaderOptions: less
|
|
40
|
+
};
|
|
41
|
+
};
|
|
42
|
+
const normalizeSassOptions = (sass)=>{
|
|
43
|
+
if (isPluginLevelOptions(sass, SASS_PLUGIN_KEYS)) {
|
|
44
|
+
warnIgnoredKeys('tools.sass', sass, SASS_PLUGIN_KEYS, 'sassLoaderOptions');
|
|
45
|
+
return sass;
|
|
46
|
+
}
|
|
47
|
+
if (void 0 !== sass && !isEmptyObject(sass)) warnOnceInDev('tools.sass', "`tools.sass` now accepts the full options of @rsbuild/plugin-sass. Passing sass-loader options directly is deprecated and will stop working in the next major version. Move them under `sassLoaderOptions`:\n before: tools: { sass: { sassOptions: { quietDeps: true } } }\n after: tools: { sass: { sassLoaderOptions: { sassOptions: { quietDeps: true } } } }");
|
|
48
|
+
return {
|
|
49
|
+
sassLoaderOptions: sass
|
|
50
|
+
};
|
|
51
|
+
};
|
|
52
|
+
const mergeSvgrOptions = (target, source)=>{
|
|
53
|
+
const svgrOptions = source.svgrOptions ? {
|
|
54
|
+
...target.svgrOptions,
|
|
55
|
+
...source.svgrOptions
|
|
56
|
+
} : target.svgrOptions;
|
|
57
|
+
return Object.assign(target, source, {
|
|
58
|
+
svgrOptions
|
|
59
|
+
});
|
|
60
|
+
};
|
|
61
|
+
const resolveSvgrOptions = ({ svgr, disableSvgr, svgDefaultExport })=>{
|
|
62
|
+
if (void 0 !== disableSvgr) warnOnceInDev('output.disableSvgr', disableSvgr ? '`output.disableSvgr` is deprecated and will be removed in the next major version. Use `tools: { svgr: false }` instead.' : '`output.disableSvgr` is deprecated and will be removed in the next major version. SVGR is enabled by default, so `output.disableSvgr: false` can be removed (or use `tools: { svgr: {} }` to keep it explicit).');
|
|
63
|
+
if (void 0 !== svgDefaultExport) warnOnceInDev('output.svgDefaultExport', "`output.svgDefaultExport` is deprecated and will be removed in the next major version. Use `tools.svgr.svgrOptions.exportType` instead:\n before: output: { svgDefaultExport: 'component' }\n after: tools: { svgr: { svgrOptions: { exportType: 'default' } } }\n ('url' maps to exportType: 'named')");
|
|
64
|
+
if (false === svgr) return false;
|
|
65
|
+
if (void 0 === svgr && disableSvgr) return false;
|
|
66
|
+
const defaults = {
|
|
67
|
+
mixedImport: true,
|
|
68
|
+
svgrOptions: {
|
|
69
|
+
exportType: 'component' === svgDefaultExport ? 'default' : 'named'
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
return applyOptionsChain(defaults, svgr, void 0, mergeSvgrOptions);
|
|
73
|
+
};
|
|
74
|
+
export { normalizeLessOptions, normalizeSassOptions, resetPluginOptionsWarnings, resolveSvgrOptions };
|
|
@@ -11,6 +11,7 @@ import { pluginGlobalVars } from "../plugins/globalVars.mjs";
|
|
|
11
11
|
import { pluginHtmlMinifierTerser } from "../plugins/htmlMinify.mjs";
|
|
12
12
|
import { pluginRuntimeChunk } from "../plugins/runtimeChunk.mjs";
|
|
13
13
|
import { transformToRsbuildServerOptions } from "./devServer.mjs";
|
|
14
|
+
import { normalizeLessOptions, normalizeSassOptions, resolveSvgrOptions } from "./pluginOptions.mjs";
|
|
14
15
|
import { NODE_MODULES_REGEX } from "./utils.mjs";
|
|
15
16
|
const CSS_MODULES_REGEX = /\.modules?\.\w+$/i;
|
|
16
17
|
const GLOBAL_CSS_REGEX = /\.global\.\w+$/;
|
|
@@ -26,7 +27,7 @@ function removeUndefinedKey(obj) {
|
|
|
26
27
|
}
|
|
27
28
|
async function parseCommonConfig(builderConfig, options) {
|
|
28
29
|
const frameworkConfigPath = options?.frameworkConfigPath;
|
|
29
|
-
const { plugins: [...plugins] = [], splitChunks, performance: { ...performanceConfig } = {}, output: { module = false, enableCssModuleTSDeclaration, disableCssModuleExtension, disableTsChecker, disableSvgr, svgDefaultExport, assetsRetry, enableAssetManifest, sourceMap, convertToRem, polyfill, dataUriLimit = 10000, distPath = {}, ...outputConfig } = {}, html: { outputStructure, appIcon, ...htmlConfig } = {}, source: { alias, globalVars, transformImport, reactCompiler, ...sourceConfig } = {}, dev = {}, server = {}, security: { checkSyntax, sri, ...securityConfig } = {}, tools: { devServer, tsChecker, minifyCss, less, sass, htmlPlugin, autoprefixer, ...toolsConfig } = {}, environments = {}, resolve = {} } = builderConfig;
|
|
30
|
+
const { plugins: [...plugins] = [], splitChunks, performance: { ...performanceConfig } = {}, output: { module = false, enableCssModuleTSDeclaration, disableCssModuleExtension, disableTsChecker, disableSvgr, svgDefaultExport, assetsRetry, enableAssetManifest, sourceMap, convertToRem, polyfill, dataUriLimit = 10000, distPath = {}, ...outputConfig } = {}, html: { outputStructure, appIcon, ...htmlConfig } = {}, source: { alias, globalVars, transformImport, reactCompiler, ...sourceConfig } = {}, dev = {}, server = {}, security: { checkSyntax, sri, ...securityConfig } = {}, tools: { devServer, tsChecker, minifyCss, less, sass, svgr, htmlPlugin, autoprefixer, ...toolsConfig } = {}, environments = {}, resolve = {} } = builderConfig;
|
|
30
31
|
let combinedAlias;
|
|
31
32
|
if (alias || resolve.alias) combinedAlias = [].concat(alias ?? []).concat(resolve.alias ?? []);
|
|
32
33
|
const rsbuildConfig = {
|
|
@@ -108,12 +109,8 @@ async function parseCommonConfig(builderConfig, options) {
|
|
|
108
109
|
sourceMap
|
|
109
110
|
}),
|
|
110
111
|
pluginEmitRouteFile(),
|
|
111
|
-
pluginSass(
|
|
112
|
-
|
|
113
|
-
}),
|
|
114
|
-
pluginLess({
|
|
115
|
-
lessLoaderOptions: less
|
|
116
|
-
}),
|
|
112
|
+
pluginSass(normalizeSassOptions(sass)),
|
|
113
|
+
pluginLess(normalizeLessOptions(less)),
|
|
117
114
|
pluginEnvironmentDefaults(distPath),
|
|
118
115
|
pluginHtmlMinifierTerser()
|
|
119
116
|
];
|
|
@@ -144,14 +141,14 @@ async function parseCommonConfig(builderConfig, options) {
|
|
|
144
141
|
rsbuildPlugins.push(pluginReact(void 0 !== reactCompiler ? {
|
|
145
142
|
reactCompiler
|
|
146
143
|
} : {}));
|
|
147
|
-
|
|
144
|
+
const svgrOptions = resolveSvgrOptions({
|
|
145
|
+
svgr,
|
|
146
|
+
disableSvgr,
|
|
147
|
+
svgDefaultExport
|
|
148
|
+
});
|
|
149
|
+
if (false !== svgrOptions) {
|
|
148
150
|
const { pluginSvgr } = await import("@rsbuild/plugin-svgr");
|
|
149
|
-
rsbuildPlugins.push(pluginSvgr(
|
|
150
|
-
mixedImport: true,
|
|
151
|
-
svgrOptions: {
|
|
152
|
-
exportType: 'component' === svgDefaultExport ? 'default' : 'named'
|
|
153
|
-
}
|
|
154
|
-
}));
|
|
151
|
+
rsbuildPlugins.push(pluginSvgr(svgrOptions));
|
|
155
152
|
}
|
|
156
153
|
if (assetsRetry) {
|
|
157
154
|
const { pluginAssetsRetry } = await import("@rsbuild/plugin-assets-retry");
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import "node:module";
|
|
2
|
+
import { applyOptionsChain, isDevCommand, logger } from "@modern-js/utils";
|
|
3
|
+
const LESS_PLUGIN_KEYS = [
|
|
4
|
+
'lessLoaderOptions',
|
|
5
|
+
'include',
|
|
6
|
+
'exclude',
|
|
7
|
+
'parallel'
|
|
8
|
+
];
|
|
9
|
+
const SASS_PLUGIN_KEYS = [
|
|
10
|
+
'sassLoaderOptions',
|
|
11
|
+
'include',
|
|
12
|
+
'exclude',
|
|
13
|
+
'rewriteUrls'
|
|
14
|
+
];
|
|
15
|
+
const warned = new Set();
|
|
16
|
+
const resetPluginOptionsWarnings = ()=>{
|
|
17
|
+
warned.clear();
|
|
18
|
+
};
|
|
19
|
+
const warnOnceInDev = (key, message)=>{
|
|
20
|
+
if (!isDevCommand() || warned.has(key)) return;
|
|
21
|
+
warned.add(key);
|
|
22
|
+
logger.warn(message);
|
|
23
|
+
};
|
|
24
|
+
const isPlainObject = (value)=>'object' == typeof value && null !== value && !Array.isArray(value);
|
|
25
|
+
const isPluginLevelOptions = (value, pluginKeys)=>isPlainObject(value) && pluginKeys.some((key)=>key in value);
|
|
26
|
+
const isEmptyObject = (value)=>isPlainObject(value) && 0 === Object.keys(value).length;
|
|
27
|
+
const warnIgnoredKeys = (name, value, pluginKeys, loaderOptionsKey)=>{
|
|
28
|
+
const pluginLevel = Object.keys(value).filter((key)=>pluginKeys.includes(key));
|
|
29
|
+
const ignored = Object.keys(value).filter((key)=>!pluginKeys.includes(key));
|
|
30
|
+
if (0 === ignored.length) return;
|
|
31
|
+
warnOnceInDev(`${name}:mixed`, `\`${name}\` contains plugin-level options (${pluginLevel.join(', ')}) together with other keys (${ignored.join(', ')}). The whole object is passed to the plugin, so the other keys are ignored. Move loader options under \`${loaderOptionsKey}\`.`);
|
|
32
|
+
};
|
|
33
|
+
const normalizeLessOptions = (less)=>{
|
|
34
|
+
if (isPluginLevelOptions(less, LESS_PLUGIN_KEYS)) {
|
|
35
|
+
warnIgnoredKeys('tools.less', less, LESS_PLUGIN_KEYS, 'lessLoaderOptions');
|
|
36
|
+
return less;
|
|
37
|
+
}
|
|
38
|
+
if (void 0 !== less && !isEmptyObject(less)) warnOnceInDev('tools.less', "`tools.less` now accepts the full options of @rsbuild/plugin-less. Passing less-loader options directly is deprecated and will stop working in the next major version. Move them under `lessLoaderOptions`:\n before: tools: { less: { lessOptions: { javascriptEnabled: true } } }\n after: tools: { less: { lessLoaderOptions: { lessOptions: { javascriptEnabled: true } } } }");
|
|
39
|
+
return {
|
|
40
|
+
lessLoaderOptions: less
|
|
41
|
+
};
|
|
42
|
+
};
|
|
43
|
+
const normalizeSassOptions = (sass)=>{
|
|
44
|
+
if (isPluginLevelOptions(sass, SASS_PLUGIN_KEYS)) {
|
|
45
|
+
warnIgnoredKeys('tools.sass', sass, SASS_PLUGIN_KEYS, 'sassLoaderOptions');
|
|
46
|
+
return sass;
|
|
47
|
+
}
|
|
48
|
+
if (void 0 !== sass && !isEmptyObject(sass)) warnOnceInDev('tools.sass', "`tools.sass` now accepts the full options of @rsbuild/plugin-sass. Passing sass-loader options directly is deprecated and will stop working in the next major version. Move them under `sassLoaderOptions`:\n before: tools: { sass: { sassOptions: { quietDeps: true } } }\n after: tools: { sass: { sassLoaderOptions: { sassOptions: { quietDeps: true } } } }");
|
|
49
|
+
return {
|
|
50
|
+
sassLoaderOptions: sass
|
|
51
|
+
};
|
|
52
|
+
};
|
|
53
|
+
const mergeSvgrOptions = (target, source)=>{
|
|
54
|
+
const svgrOptions = source.svgrOptions ? {
|
|
55
|
+
...target.svgrOptions,
|
|
56
|
+
...source.svgrOptions
|
|
57
|
+
} : target.svgrOptions;
|
|
58
|
+
return Object.assign(target, source, {
|
|
59
|
+
svgrOptions
|
|
60
|
+
});
|
|
61
|
+
};
|
|
62
|
+
const resolveSvgrOptions = ({ svgr, disableSvgr, svgDefaultExport })=>{
|
|
63
|
+
if (void 0 !== disableSvgr) warnOnceInDev('output.disableSvgr', disableSvgr ? '`output.disableSvgr` is deprecated and will be removed in the next major version. Use `tools: { svgr: false }` instead.' : '`output.disableSvgr` is deprecated and will be removed in the next major version. SVGR is enabled by default, so `output.disableSvgr: false` can be removed (or use `tools: { svgr: {} }` to keep it explicit).');
|
|
64
|
+
if (void 0 !== svgDefaultExport) warnOnceInDev('output.svgDefaultExport', "`output.svgDefaultExport` is deprecated and will be removed in the next major version. Use `tools.svgr.svgrOptions.exportType` instead:\n before: output: { svgDefaultExport: 'component' }\n after: tools: { svgr: { svgrOptions: { exportType: 'default' } } }\n ('url' maps to exportType: 'named')");
|
|
65
|
+
if (false === svgr) return false;
|
|
66
|
+
if (void 0 === svgr && disableSvgr) return false;
|
|
67
|
+
const defaults = {
|
|
68
|
+
mixedImport: true,
|
|
69
|
+
svgrOptions: {
|
|
70
|
+
exportType: 'component' === svgDefaultExport ? 'default' : 'named'
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
return applyOptionsChain(defaults, svgr, void 0, mergeSvgrOptions);
|
|
74
|
+
};
|
|
75
|
+
export { normalizeLessOptions, normalizeSassOptions, resetPluginOptionsWarnings, resolveSvgrOptions };
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { PluginLessOptions } from '@rsbuild/plugin-less';
|
|
2
|
+
import type { PluginSassOptions } from '@rsbuild/plugin-sass';
|
|
3
|
+
import type { PluginSvgrOptions, SvgDefaultExport } from '@rsbuild/plugin-svgr';
|
|
4
|
+
import type { BuilderConfig } from '../types.js';
|
|
5
|
+
type BuilderToolsConfig = NonNullable<BuilderConfig['tools']>;
|
|
6
|
+
/** Reset the warn-once state. Only meant for unit tests. */
|
|
7
|
+
export declare const resetPluginOptionsWarnings: () => void;
|
|
8
|
+
/**
|
|
9
|
+
* `tools.less` accepts either the full options of `@rsbuild/plugin-less`
|
|
10
|
+
* or, for backward compatibility, the less-loader options directly
|
|
11
|
+
* (object, function or array form). The legacy form is wrapped into
|
|
12
|
+
* `lessLoaderOptions` so the generated bundler config stays unchanged.
|
|
13
|
+
*/
|
|
14
|
+
export declare const normalizeLessOptions: (less: BuilderToolsConfig["less"]) => PluginLessOptions;
|
|
15
|
+
/**
|
|
16
|
+
* Same as {@link normalizeLessOptions} for `tools.sass`.
|
|
17
|
+
*/
|
|
18
|
+
export declare const normalizeSassOptions: (sass: BuilderToolsConfig["sass"]) => PluginSassOptions;
|
|
19
|
+
/**
|
|
20
|
+
* Resolve the options passed to `@rsbuild/plugin-svgr`, or `false` when the
|
|
21
|
+
* plugin should not be registered.
|
|
22
|
+
*
|
|
23
|
+
* `tools.svgr` takes precedence over the deprecated `output.disableSvgr` and
|
|
24
|
+
* `output.svgDefaultExport`; the two legacy options keep working when
|
|
25
|
+
* `tools.svgr` is not set.
|
|
26
|
+
*/
|
|
27
|
+
export declare const resolveSvgrOptions: ({ svgr, disableSvgr, svgDefaultExport, }: {
|
|
28
|
+
svgr: BuilderToolsConfig["svgr"];
|
|
29
|
+
disableSvgr?: boolean;
|
|
30
|
+
svgDefaultExport?: SvgDefaultExport;
|
|
31
|
+
}) => PluginSvgrOptions | false;
|
|
32
|
+
export {};
|
package/dist/types/types.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ import type { PluginReactOptions } from '@rsbuild/plugin-react';
|
|
|
8
8
|
import type { PluginRemOptions } from '@rsbuild/plugin-rem';
|
|
9
9
|
import type { PluginSassOptions } from '@rsbuild/plugin-sass';
|
|
10
10
|
import type { PluginSourceBuildOptions } from '@rsbuild/plugin-source-build';
|
|
11
|
-
import type { SvgDefaultExport } from '@rsbuild/plugin-svgr';
|
|
11
|
+
import type { PluginSvgrOptions, SvgDefaultExport } from '@rsbuild/plugin-svgr';
|
|
12
12
|
import type { PluginTypeCheckerOptions } from '@rsbuild/plugin-type-check';
|
|
13
13
|
import type { Options as AutoprefixerOptions } from 'autoprefixer';
|
|
14
14
|
export type CacheGroup = Rspack.OptimizationSplitChunksCacheGroup;
|
|
@@ -100,13 +100,29 @@ export type BuilderExtraConfig = {
|
|
|
100
100
|
*/
|
|
101
101
|
minifyCss?: PluginCssMinimizerOptions['pluginOptions'];
|
|
102
102
|
/**
|
|
103
|
-
* Modify the
|
|
103
|
+
* Modify the options of [@rsbuild/plugin-less](https://rsbuild.rs/plugins/list/plugin-less),
|
|
104
|
+
* such as `lessLoaderOptions`, `include`, `exclude` and `parallel`.
|
|
105
|
+
*
|
|
106
|
+
* Passing the [less-loader](https://github.com/webpack-contrib/less-loader)
|
|
107
|
+
* options directly is still supported for backward compatibility, but is
|
|
108
|
+
* deprecated: move them under `lessLoaderOptions`.
|
|
109
|
+
*/
|
|
110
|
+
less?: PluginLessOptions['lessLoaderOptions'] | PluginLessOptions;
|
|
111
|
+
/**
|
|
112
|
+
* Modify the options of [@rsbuild/plugin-sass](https://rsbuild.rs/plugins/list/plugin-sass),
|
|
113
|
+
* such as `sassLoaderOptions`, `include`, `exclude` and `rewriteUrls`.
|
|
114
|
+
*
|
|
115
|
+
* Passing the [sass-loader](https://github.com/webpack-contrib/sass-loader)
|
|
116
|
+
* options directly is still supported for backward compatibility, but is
|
|
117
|
+
* deprecated: move them under `sassLoaderOptions`.
|
|
104
118
|
*/
|
|
105
|
-
|
|
119
|
+
sass?: PluginSassOptions['sassLoaderOptions'] | PluginSassOptions;
|
|
106
120
|
/**
|
|
107
|
-
* Modify the
|
|
121
|
+
* Modify the options of [@rsbuild/plugin-svgr](https://rsbuild.rs/plugins/list/plugin-svgr),
|
|
122
|
+
* such as `svgrOptions`, `parallel`, `exclude` and `query`.
|
|
123
|
+
* Set to `false` to disable SVGR; all `.svg` files are then treated as static assets.
|
|
108
124
|
*/
|
|
109
|
-
|
|
125
|
+
svgr?: ConfigChain<PluginSvgrOptions> | false;
|
|
110
126
|
};
|
|
111
127
|
dev?: {
|
|
112
128
|
/** Set the page URL to open when the server starts. */
|
|
@@ -177,10 +193,14 @@ export type BuilderExtraConfig = {
|
|
|
177
193
|
disableTsChecker?: boolean;
|
|
178
194
|
/**
|
|
179
195
|
* Configure the default export type of SVG files.
|
|
196
|
+
* @deprecated Use `tools.svgr.svgrOptions.exportType` instead:
|
|
197
|
+
* `'component'` maps to `exportType: 'default'`, `'url'` maps to `exportType: 'named'`.
|
|
180
198
|
*/
|
|
181
199
|
svgDefaultExport?: SvgDefaultExport;
|
|
182
200
|
/**
|
|
183
201
|
* Whether to transform SVGs into React components. If true, will treat all .svg files as assets.
|
|
202
|
+
* @deprecated Use `tools.svgr` instead: `output.disableSvgr: true` maps to `tools.svgr: false`;
|
|
203
|
+
* `false` is the default behavior and can simply be removed.
|
|
184
204
|
*/
|
|
185
205
|
disableSvgr?: boolean;
|
|
186
206
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@modern-js/builder",
|
|
3
|
-
"version": "3.9.
|
|
3
|
+
"version": "3.9.3",
|
|
4
4
|
"description": "A builder for Modern.js",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"dist"
|
|
27
27
|
],
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@rsbuild/core": "2.2.
|
|
29
|
+
"@rsbuild/core": "2.2.9",
|
|
30
30
|
"@rsbuild/plugin-assets-retry": "2.0.2",
|
|
31
31
|
"@rsbuild/plugin-check-syntax": "2.0.1",
|
|
32
32
|
"@rsbuild/plugin-css-minimizer": "2.0.1",
|
|
@@ -34,19 +34,19 @@
|
|
|
34
34
|
"@rsbuild/plugin-react": "2.1.0",
|
|
35
35
|
"@rsbuild/plugin-rem": "1.0.6",
|
|
36
36
|
"@rsbuild/plugin-sass": "2.0.1",
|
|
37
|
-
"@rsbuild/plugin-source-build": "1.0.
|
|
37
|
+
"@rsbuild/plugin-source-build": "1.0.7",
|
|
38
38
|
"@rsbuild/plugin-svgr": "2.0.5",
|
|
39
39
|
"@rsbuild/plugin-type-check": "1.6.0",
|
|
40
40
|
"@rsbuild/plugin-typed-css-modules": "1.2.4",
|
|
41
41
|
"@swc/core": "1.15.41",
|
|
42
42
|
"@swc/helpers": "^0.5.17",
|
|
43
43
|
"autoprefixer": "10.4.27",
|
|
44
|
-
"browserslist": "4.
|
|
44
|
+
"browserslist": "4.29.0",
|
|
45
45
|
"core-js": "^3.48.0",
|
|
46
46
|
"cssnano": "6.1.2",
|
|
47
47
|
"html-minifier-terser": "^7.2.0",
|
|
48
48
|
"lodash": "^4.18.1",
|
|
49
|
-
"postcss": "^8.5.
|
|
49
|
+
"postcss": "^8.5.28",
|
|
50
50
|
"postcss-custom-properties": "13.3.12",
|
|
51
51
|
"postcss-flexbugs-fixes": "5.0.2",
|
|
52
52
|
"postcss-font-variant": "5.0.0",
|
|
@@ -56,19 +56,19 @@
|
|
|
56
56
|
"postcss-page-break": "3.0.4",
|
|
57
57
|
"rsbuild-plugin-rsc": "0.1.1",
|
|
58
58
|
"rspack-manifest-plugin": "5.2.2",
|
|
59
|
-
"ts-deepmerge": "
|
|
60
|
-
"@modern-js/utils": "3.9.
|
|
59
|
+
"ts-deepmerge": "8.0.0",
|
|
60
|
+
"@modern-js/utils": "3.9.3"
|
|
61
61
|
},
|
|
62
62
|
"devDependencies": {
|
|
63
|
-
"@rslib/core": "1.0.
|
|
63
|
+
"@rslib/core": "1.0.1",
|
|
64
64
|
"@types/html-minifier-terser": "^7.0.2",
|
|
65
|
-
"@types/lodash": "^4.17.
|
|
65
|
+
"@types/lodash": "^4.17.25",
|
|
66
66
|
"react": "^19.2.8",
|
|
67
|
-
"terser": "^5.
|
|
67
|
+
"terser": "^5.51.2",
|
|
68
68
|
"typescript": "^5.3.0",
|
|
69
|
-
"@modern-js/
|
|
70
|
-
"@
|
|
71
|
-
"@
|
|
69
|
+
"@modern-js/rslib": "2.68.10",
|
|
70
|
+
"@modern-js/types": "3.9.3",
|
|
71
|
+
"@scripts/rstest-config": "2.66.0"
|
|
72
72
|
},
|
|
73
73
|
"publishConfig": {
|
|
74
74
|
"access": "public",
|