@next-core/build-next-bricks 1.3.1 → 1.4.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/index.d.ts +3 -1
- package/package.json +2 -2
- package/src/EmitBricksJsonPlugin.js +3 -0
- package/src/build.js +22 -29
- package/src/scanBricks.js +66 -29
package/index.d.ts
CHANGED
|
@@ -81,7 +81,9 @@ export interface BuildNextBricksConfig {
|
|
|
81
81
|
imageAssetFilename?: string | ((pathData: any, assetInfo: any) => string);
|
|
82
82
|
plugins?: Configuration["plugins"];
|
|
83
83
|
moduleRules?: RuleSetRule[];
|
|
84
|
-
exposes?: ConstructorParameters<
|
|
84
|
+
exposes?: ConstructorParameters<
|
|
85
|
+
typeof container.ModuleFederationPlugin
|
|
86
|
+
>[0]["exposes"];
|
|
85
87
|
dependencies?: Record<string, string[]>;
|
|
86
88
|
optimization?: Configuration["optimization"];
|
|
87
89
|
moduleFederationShared?: SharedObject | false;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@next-core/build-next-bricks",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.1",
|
|
4
4
|
"description": "Build next bricks",
|
|
5
5
|
"homepage": "https://github.com/easyops-cn/next-core/tree/master/packages/build-next-bricks",
|
|
6
6
|
"license": "GPL-3.0",
|
|
@@ -46,5 +46,5 @@
|
|
|
46
46
|
"typescript": "^5.0.3",
|
|
47
47
|
"webpack": "^5.78.0"
|
|
48
48
|
},
|
|
49
|
-
"gitHead": "
|
|
49
|
+
"gitHead": "4b4ee2a1f0853f0538ba78973cd10d76c5312027"
|
|
50
50
|
}
|
|
@@ -9,6 +9,7 @@ export default class EmitBricksJsonPlugin {
|
|
|
9
9
|
constructor(options) {
|
|
10
10
|
this.packageName = options.packageName;
|
|
11
11
|
this.bricks = options.bricks;
|
|
12
|
+
this.elements = options.elements;
|
|
12
13
|
this.processors = options.processors;
|
|
13
14
|
this.dependencies = options.dependencies;
|
|
14
15
|
}
|
|
@@ -45,6 +46,7 @@ export default class EmitBricksJsonPlugin {
|
|
|
45
46
|
{
|
|
46
47
|
id: `bricks/${this.packageName}`,
|
|
47
48
|
bricks: this.bricks,
|
|
49
|
+
elements: this.elements,
|
|
48
50
|
processors: this.processors,
|
|
49
51
|
dependencies: this.dependencies,
|
|
50
52
|
filePath: jsFilePath,
|
|
@@ -59,6 +61,7 @@ export default class EmitBricksJsonPlugin {
|
|
|
59
61
|
);
|
|
60
62
|
|
|
61
63
|
console.log("Defined bricks:", this.bricks);
|
|
64
|
+
console.log("Defined elements:", this.elements);
|
|
62
65
|
console.log("Defined processors:", this.processors);
|
|
63
66
|
console.log("Found dependencies:", this.dependencies);
|
|
64
67
|
callback();
|
package/src/build.js
CHANGED
|
@@ -60,7 +60,6 @@ const getCssLoaders = (cssOptions) => [
|
|
|
60
60
|
*/
|
|
61
61
|
async function getWebpackConfig(config) {
|
|
62
62
|
const packageDir = process.cwd();
|
|
63
|
-
// const isContainer = config.type === "container";
|
|
64
63
|
const isBricks = !config.type || config.type === "bricks";
|
|
65
64
|
const mode = config.mode || process.env.NODE_ENV;
|
|
66
65
|
|
|
@@ -126,7 +125,7 @@ async function getWebpackConfig(config) {
|
|
|
126
125
|
}
|
|
127
126
|
);
|
|
128
127
|
} catch (e) {
|
|
129
|
-
console.
|
|
128
|
+
console.warn(`Shared package not found: "${dep}"`);
|
|
130
129
|
return;
|
|
131
130
|
}
|
|
132
131
|
const depPackageJsonFile = await readFile(depPackageJsonPath, {
|
|
@@ -159,29 +158,28 @@ async function getWebpackConfig(config) {
|
|
|
159
158
|
/** @type {string[]} */
|
|
160
159
|
const bricks = [];
|
|
161
160
|
/** @type {string[]} */
|
|
161
|
+
const elements = [];
|
|
162
|
+
/** @type {string[]} */
|
|
162
163
|
const processors = [];
|
|
163
164
|
if (isBricks) {
|
|
164
|
-
for (const key of Object.
|
|
165
|
+
for (const [key, val] of Object.entries(config.exposes)) {
|
|
165
166
|
const segments = key.split("/");
|
|
166
167
|
const name = segments.pop();
|
|
167
168
|
const namespace = segments.pop();
|
|
168
169
|
if (namespace === "processors") {
|
|
169
170
|
processors.push(`${camelPackageName}.${name}`);
|
|
170
171
|
} else {
|
|
171
|
-
|
|
172
|
+
if (val[Symbol.for("noNamespace")]) {
|
|
173
|
+
elements.push(name);
|
|
174
|
+
} else {
|
|
175
|
+
bricks.push(`${packageName}.${name}`);
|
|
176
|
+
}
|
|
172
177
|
}
|
|
173
178
|
}
|
|
174
179
|
}
|
|
175
180
|
|
|
176
181
|
/** @type {Record<string, { import: string; name: string; }>} */
|
|
177
182
|
const extraExposes = {};
|
|
178
|
-
// const initializeTsPath = path.join(packageDir, "src/initialize.ts");
|
|
179
|
-
// if (fs.existsSync(initializeTsPath)) {
|
|
180
|
-
// extraExposes.initialize = {
|
|
181
|
-
// import: `./${path.relative(packageDir, initializeTsPath)}`,
|
|
182
|
-
// name: "initialize",
|
|
183
|
-
// };
|
|
184
|
-
// }
|
|
185
183
|
|
|
186
184
|
const outputPath = path.join(packageDir, config.outputPath ?? "dist");
|
|
187
185
|
const chunksDir = isBricks ? "chunks/" : "";
|
|
@@ -218,9 +216,6 @@ async function getWebpackConfig(config) {
|
|
|
218
216
|
{
|
|
219
217
|
test: /\.css$/,
|
|
220
218
|
exclude: /\.(module|shadow|lazy)\.css$/,
|
|
221
|
-
// resourceQuery: {
|
|
222
|
-
// not: /shadow/
|
|
223
|
-
// },
|
|
224
219
|
sideEffects: true,
|
|
225
220
|
use: [
|
|
226
221
|
config.extractCss ? MiniCssExtractPlugin.loader : "style-loader",
|
|
@@ -235,15 +230,18 @@ async function getWebpackConfig(config) {
|
|
|
235
230
|
}),
|
|
236
231
|
],
|
|
237
232
|
},
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
233
|
+
{
|
|
234
|
+
test: /\.module\.css$/,
|
|
235
|
+
sideEffects: true,
|
|
236
|
+
use: [
|
|
237
|
+
config.extractCss ? MiniCssExtractPlugin.loader : "style-loader",
|
|
238
|
+
...getCssLoaders({
|
|
239
|
+
modules: {
|
|
240
|
+
localIdentName: "[local]--[hash:base64:8]",
|
|
241
|
+
},
|
|
242
|
+
}),
|
|
243
|
+
],
|
|
244
|
+
},
|
|
247
245
|
{
|
|
248
246
|
test: /\.[tj]sx?$/,
|
|
249
247
|
loader: "babel-loader",
|
|
@@ -296,12 +294,6 @@ async function getWebpackConfig(config) {
|
|
|
296
294
|
? {
|
|
297
295
|
splitChunks: {
|
|
298
296
|
cacheGroups: {
|
|
299
|
-
react: {
|
|
300
|
-
test: /[\\/]node_modules[\\/](?:react(?:-dom)?|scheduler)[\\/]/,
|
|
301
|
-
priority: -10,
|
|
302
|
-
reuseExistingChunk: true,
|
|
303
|
-
name: "react",
|
|
304
|
-
},
|
|
305
297
|
default: {
|
|
306
298
|
minChunks: 2,
|
|
307
299
|
priority: -20,
|
|
@@ -369,6 +361,7 @@ async function getWebpackConfig(config) {
|
|
|
369
361
|
new EmitBricksJsonPlugin({
|
|
370
362
|
packageName,
|
|
371
363
|
bricks,
|
|
364
|
+
elements,
|
|
372
365
|
processors,
|
|
373
366
|
dependencies: config.dependencies,
|
|
374
367
|
}),
|
package/src/scanBricks.js
CHANGED
|
@@ -11,6 +11,7 @@ const { escapeRegExp } = _;
|
|
|
11
11
|
|
|
12
12
|
const validBrickName =
|
|
13
13
|
/^[a-z][a-z0-9]*(-[a-z0-9]+)*\.[a-z][a-z0-9]*(-[a-z0-9]+)+$/;
|
|
14
|
+
const validCustomElementName = /^[a-z][a-z0-9]*(-[a-z0-9]+)+$/;
|
|
14
15
|
const validProcessorName = /^[a-z][a-zA-Z0-9]*\.[a-z][a-zA-Z0-9]*$/;
|
|
15
16
|
const validExposeName = /^[-\w]+$/;
|
|
16
17
|
|
|
@@ -18,7 +19,7 @@ const validExposeName = /^[-\w]+$/;
|
|
|
18
19
|
* Scan defined bricks by AST.
|
|
19
20
|
*
|
|
20
21
|
* @param {string} packageDir
|
|
21
|
-
* @returns {Promise<{exposes: Record<string, { import: string; name: string; }; dependencies: Record<string, string[]>}>>}
|
|
22
|
+
* @returns {Promise<{exposes: Record<string, { import: string; name: string; noNamespace?: boolean; }; dependencies: Record<string, string[]>}>>}
|
|
22
23
|
*/
|
|
23
24
|
export default async function scanBricks(packageDir) {
|
|
24
25
|
/** @type {Map<string, { import: string; name: string; }>} */
|
|
@@ -85,6 +86,18 @@ export default async function scanBricks(packageDir) {
|
|
|
85
86
|
let nextOverrideImport = overrideImport;
|
|
86
87
|
if (content.startsWith("// Merge bricks")) {
|
|
87
88
|
nextOverrideImport = filePath;
|
|
89
|
+
} else if (content.startsWith("// Define brick")) {
|
|
90
|
+
// Match any source files starting with specific comments:
|
|
91
|
+
// `// Define brick: sl-alert` or
|
|
92
|
+
// `// Define bricks: sl-alert, sl-icon`
|
|
93
|
+
const firstLine = content.split("\n", 1)[0];
|
|
94
|
+
const match = firstLine.match(/^\/\/ Define bricks?: (.+)$/);
|
|
95
|
+
if (match) {
|
|
96
|
+
const bricks = match[1].split(/,\s*/g);
|
|
97
|
+
for (const brick of bricks) {
|
|
98
|
+
collectBrick(brick);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
88
101
|
}
|
|
89
102
|
|
|
90
103
|
/**
|
|
@@ -123,6 +136,57 @@ export default async function scanBricks(packageDir) {
|
|
|
123
136
|
}
|
|
124
137
|
}
|
|
125
138
|
|
|
139
|
+
/**
|
|
140
|
+
* @param {string} fullName
|
|
141
|
+
*/
|
|
142
|
+
function collectBrick(fullName) {
|
|
143
|
+
/** @type string */
|
|
144
|
+
let brickNamespace;
|
|
145
|
+
/** @type string */
|
|
146
|
+
let brickName;
|
|
147
|
+
let noNamespace = false;
|
|
148
|
+
if (fullName.includes(".")) {
|
|
149
|
+
[brickNamespace, brickName] = fullName.split(".");
|
|
150
|
+
if (brickNamespace !== packageName) {
|
|
151
|
+
throw new Error(
|
|
152
|
+
`Invalid brick: "${fullName}", expecting prefixed with the package name: "${packageName}"`
|
|
153
|
+
);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
if (!validBrickName.test(fullName)) {
|
|
157
|
+
throw new Error(
|
|
158
|
+
`Invalid brick: "${fullName}", expecting: "PACKAGE-NAME.BRICK-NAME", where PACKAGE-NAME and BRICK-NAME must be lower-kebab-case, and BRICK-NAME must include a \`-\``
|
|
159
|
+
);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
if (brickName.startsWith("tpl-")) {
|
|
163
|
+
throw new Error(
|
|
164
|
+
`Invalid brick: "${fullName}", the brick name cannot be started with "tpl-"`
|
|
165
|
+
);
|
|
166
|
+
}
|
|
167
|
+
} else {
|
|
168
|
+
// For third-party custom elements, there maybe no namespace.
|
|
169
|
+
brickName = fullName;
|
|
170
|
+
noNamespace = true;
|
|
171
|
+
if (!validCustomElementName.test(brickName)) {
|
|
172
|
+
throw new Error(
|
|
173
|
+
`Invalid brick: "${fullName}", the brick name must include a \`-\``
|
|
174
|
+
);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
brickSourceFiles.set(fullName, filePath);
|
|
179
|
+
|
|
180
|
+
exposes.set(`./${brickName}`, {
|
|
181
|
+
import: `./${path
|
|
182
|
+
.relative(packageDir, overrideImport || filePath)
|
|
183
|
+
.replace(/\.[^.]+$/, "")
|
|
184
|
+
.replace(/\/index$/, "")}`,
|
|
185
|
+
name: getExposeName(brickName),
|
|
186
|
+
[Symbol.for("noNamespace")]: noNamespace,
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
|
|
126
190
|
traverse(ast, {
|
|
127
191
|
CallExpression({ node: { callee, arguments: args } }) {
|
|
128
192
|
// Match `customProcessors.define(...)`
|
|
@@ -172,34 +236,7 @@ export default async function scanBricks(packageDir) {
|
|
|
172
236
|
) {
|
|
173
237
|
const { type, value: fullName } = args[0];
|
|
174
238
|
if (type === "StringLiteral") {
|
|
175
|
-
|
|
176
|
-
if (brickNamespace !== packageName) {
|
|
177
|
-
throw new Error(
|
|
178
|
-
`Invalid brick: "${fullName}", expecting prefixed with the package name: "${packageName}"`
|
|
179
|
-
);
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
if (!validBrickName.test(fullName)) {
|
|
183
|
-
throw new Error(
|
|
184
|
-
`Invalid brick: "${fullName}", expecting: "PACKAGE-NAME.BRICK-NAME", where PACKAGE-NAME and BRICK-NAME must be lower-kebab-case, and BRICK-NAME must include a \`-\``
|
|
185
|
-
);
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
if (brickName.startsWith("tpl-")) {
|
|
189
|
-
throw new Error(
|
|
190
|
-
`Invalid brick: "${fullName}", the brick name cannot be started with "tpl-"`
|
|
191
|
-
);
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
brickSourceFiles.set(fullName, filePath);
|
|
195
|
-
|
|
196
|
-
exposes.set(`./${brickName}`, {
|
|
197
|
-
import: `./${path
|
|
198
|
-
.relative(packageDir, overrideImport || filePath)
|
|
199
|
-
.replace(/\.[^.]+$/, "")
|
|
200
|
-
.replace(/\/index$/, "")}`,
|
|
201
|
-
name: getExposeName(brickName),
|
|
202
|
-
});
|
|
239
|
+
collectBrick(fullName);
|
|
203
240
|
} else {
|
|
204
241
|
throw new Error(
|
|
205
242
|
"Please call `customElements.define()` only with literal string"
|