ptech-preset 1.2.5 → 1.2.7

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/index.d.ts CHANGED
@@ -13,6 +13,10 @@ type MfAutoOptions = {
13
13
  stylesExposeKey?: string;
14
14
  separateExposes?: boolean;
15
15
  separateExposeChunkPrefix?: string;
16
+ /** thư mục chứa types đã consume; mặc định "@mf-types" */
17
+ typesFolder?: string;
18
+ /** env để ép refresh types ở dev (khởi động lại dev) */
19
+ devTypesRefreshEnvVar?: string;
16
20
  mf: Record<string, any>;
17
21
  };
18
22
  declare function pluginCore(opts: MfAutoOptions): RsbuildPlugin;
package/dist/index.js CHANGED
@@ -17,10 +17,7 @@ async function collectAutoExposes(opts = {}) {
17
17
  absolute: true,
18
18
  ignore: ["**/*.d.ts"]
19
19
  });
20
- const jsdocRe = new RegExp(
21
- String.raw`/\*\*[\s\S]*?@${tag}(?:\s+([^\s*]+))?[\s\S]*?\*/`,
22
- "m"
23
- );
20
+ const jsdocRe = new RegExp(String.raw`/\*\*[\s\S]*?@${tag}(?:\s+([^\s*]+))?[\s\S]*?\*/`, "m");
24
21
  const exposes = {};
25
22
  const root = process.cwd();
26
23
  for (const abs of files) {
@@ -50,10 +47,7 @@ async function collectAutoExposesWithWrapper(opts = {}) {
50
47
  ignore: ["**/*.d.ts"]
51
48
  });
52
49
  const root = process.cwd();
53
- const jsdocRe = new RegExp(
54
- String.raw`/\*\*[\s\S]*?@expose(?:\s+([^\s*]+))?[\s\S]*?\*/`,
55
- "m"
56
- );
50
+ const jsdocRe = new RegExp(String.raw`/\*\*[\s\S]*?@expose(?:\s+([^\s*]+))?[\s\S]*?\*/`, "m");
57
51
  const wrapperRe = /exposeComponent\s*\(\s*[^,]+,\s*['"`]([^'"`]+)['"`]\s*\)/;
58
52
  const exposes = {};
59
53
  for (const abs of files) {
@@ -74,7 +68,9 @@ async function collectAutoExposesWithWrapper(opts = {}) {
74
68
  }
75
69
  }
76
70
  if (debug) {
77
- console.log(`[mf-auto] collectAutoExposesWithWrapper: ${Object.keys(exposes).length} expose(s) found`);
71
+ console.log(
72
+ `[mf-auto] collectAutoExposesWithWrapper: ${Object.keys(exposes).length} expose(s) found`
73
+ );
78
74
  }
79
75
  return exposes;
80
76
  }
@@ -169,20 +165,11 @@ function parseRemoteSpec(key, val) {
169
165
  function inferTypeUrls(remoteUrl) {
170
166
  if (typeof remoteUrl !== "string") return null;
171
167
  const base = remoteUrl.replace(/\/remoteEntry(\.[cm]?js)?(\?.*)?$/i, "");
172
- if (!base || base === remoteUrl) {
173
- const idx = remoteUrl.lastIndexOf("/");
174
- const fallbackBase = idx > 7 ? remoteUrl.slice(0, idx) : remoteUrl;
175
- return {
176
- base: fallbackBase,
177
- zip: `${fallbackBase}/@mf-types.zip`,
178
- api: `${fallbackBase}/@mf-types.d.ts`
179
- };
180
- }
181
- return {
182
- base,
183
- zip: `${base}/@mf-types.zip`,
184
- api: `${base}/@mf-types.d.ts`
185
- };
168
+ const b = base && base !== remoteUrl ? base : (() => {
169
+ const i = remoteUrl.lastIndexOf("/");
170
+ return i > 7 ? remoteUrl.slice(0, i) : remoteUrl;
171
+ })();
172
+ return { base: b, zip: `${b}/@mf-types.zip`, api: `${b}/@mf-types.d.ts` };
186
173
  }
187
174
  function buildRemoteTypeUrls(remotes) {
188
175
  const out = {};
@@ -194,11 +181,7 @@ function buildRemoteTypeUrls(remotes) {
194
181
  const t = inferTypeUrls(parsed.url);
195
182
  if (!t) continue;
196
183
  const scope = (parsed.scope || key).toString();
197
- out[scope] = {
198
- alias: scope,
199
- zip: t.zip,
200
- api: t.api
201
- };
184
+ out[scope] = { alias: scope, zip: t.zip, api: t.api };
202
185
  }
203
186
  return out;
204
187
  }
@@ -208,6 +191,40 @@ function ensureDtsObject(dts) {
208
191
  if (typeof dts === "object") return { ...dts };
209
192
  return {};
210
193
  }
194
+ async function devFetchRemoteTypesOnce(params) {
195
+ const { root, baseDir, typesFolderRel, urls } = params;
196
+ if (!urls || Object.keys(urls).length === 0) return;
197
+ const typesRootAbs = path3.resolve(root, typesFolderRel);
198
+ const remDir = path3.join(typesRootAbs, "__remotes");
199
+ fs3.mkdirSync(remDir, { recursive: true });
200
+ for (const [scope, spec] of Object.entries(urls)) {
201
+ try {
202
+ const res = await fetch(spec.api);
203
+ if (!res.ok) {
204
+ console.warn(`[mf-auto] fetch types failed for ${scope}: ${res.status} ${res.statusText}`);
205
+ continue;
206
+ }
207
+ const txt = await res.text();
208
+ fs3.writeFileSync(path3.join(remDir, `${scope}.d.ts`), txt, "utf8");
209
+ } catch (e) {
210
+ console.warn(`[mf-auto] fetch types error for ${scope}:`, e);
211
+ }
212
+ }
213
+ const refs = Object.keys(urls).map((s) => `/// <reference path="./__remotes/${s}.d.ts" />`).join(os.EOL);
214
+ const banner = `// generated by plugin-mf-auto (dev once)
215
+ `;
216
+ fs3.writeFileSync(path3.join(typesRootAbs, "index.d.ts"), banner + refs + os.EOL, "utf8");
217
+ const shimDir = path3.join(root, baseDir, ".mf-auto");
218
+ fs3.mkdirSync(shimDir, { recursive: true });
219
+ const relToIndex = path3.relative(shimDir, path3.join(typesRootAbs, "index.d.ts")).replace(/\\/g, "/");
220
+ fs3.writeFileSync(
221
+ path3.join(shimDir, "mf-types.d.ts"),
222
+ `/// <reference path="${relToIndex}" />
223
+ // generated by plugin-mf-auto
224
+ `,
225
+ "utf8"
226
+ );
227
+ }
211
228
  function pluginCore(opts) {
212
229
  const {
213
230
  baseDir = "src",
@@ -221,6 +238,8 @@ function pluginCore(opts) {
221
238
  stylesExposeKey = "./styles",
222
239
  separateExposes = true,
223
240
  separateExposeChunkPrefix = "mf-expose-",
241
+ typesFolder = "@mf-types",
242
+ devTypesRefreshEnvVar = "MF_DTS_REFRESH",
224
243
  mf
225
244
  } = opts;
226
245
  if (!mf || typeof mf !== "object") {
@@ -303,32 +322,47 @@ function pluginCore(opts) {
303
322
  mfMerged.exposes = { ...mfMerged.exposes ?? {}, [stylesExposeKey]: `./${relFromRoot}` };
304
323
  }
305
324
  }
306
- if (mfMerged.remotes && Object.keys(mfMerged.remotes).length > 0) {
325
+ const command = api?.context?.command;
326
+ const isProdLike = command === "build" || process.env.NODE_ENV === "production";
327
+ const isDev = !isProdLike;
328
+ const autoTypeUrls = buildRemoteTypeUrls(mfMerged.remotes || {});
329
+ if (isDev) {
330
+ const refresh = process.env[devTypesRefreshEnvVar] === "1";
331
+ const typesRootAbs = path3.resolve(root, typesFolder);
332
+ const indexFile = path3.join(typesRootAbs, "index.d.ts");
333
+ const needFetch = refresh || !fs3.existsSync(indexFile) || Object.keys(autoTypeUrls).some(
334
+ (s) => !fs3.existsSync(path3.join(typesRootAbs, "__remotes", `${s}.d.ts`))
335
+ );
336
+ if (Object.keys(autoTypeUrls).length > 0) {
337
+ if (needFetch) {
338
+ await devFetchRemoteTypesOnce({
339
+ root,
340
+ baseDir,
341
+ typesFolderRel: typesFolder,
342
+ urls: autoTypeUrls
343
+ });
344
+ }
345
+ const dtsObj = ensureDtsObject(mfMerged.dts);
346
+ dtsObj.generateTypes = dtsObj.generateTypes ?? { tsConfigPath: "./tsconfig.json" };
347
+ mfMerged.dts = dtsObj;
348
+ } else {
349
+ const dtsObj = ensureDtsObject(mfMerged.dts);
350
+ dtsObj.generateTypes = dtsObj.generateTypes ?? { tsConfigPath: "./tsconfig.json" };
351
+ mfMerged.dts = dtsObj;
352
+ }
353
+ } else {
307
354
  if (mfMerged.dts !== false) {
308
355
  const dtsObj = ensureDtsObject(mfMerged.dts);
309
- const autoTypeUrls = buildRemoteTypeUrls(mfMerged.remotes);
310
356
  if (Object.keys(autoTypeUrls).length > 0) {
311
357
  const existingConsume = dtsObj.consumeTypes ?? {};
312
358
  const existingRt = existingConsume.remoteTypeUrls ?? {};
313
359
  dtsObj.consumeTypes = {
314
- typesFolder: existingConsume.typesFolder ?? "@mf-types",
360
+ typesFolder: existingConsume.typesFolder ?? typesFolder,
315
361
  maxRetries: existingConsume.maxRetries ?? 3,
362
+ // ưu tiên config hiện hữu nếu trùng key
316
363
  remoteTypeUrls: { ...autoTypeUrls, ...existingRt }
317
- // existing wins? or auto wins?
318
- // Nếu muốn "khóa" theo existing ưu tiên, đảo thứ tự:
319
- // remoteTypeUrls: { ...autoTypeUrls, ...existingRt },
320
364
  };
321
- dtsObj.generateTypes = dtsObj.generateTypes ?? { tsConfigPath: "./tsconfig.json" };
322
365
  }
323
- mfMerged.dts = dtsObj;
324
- }
325
- } else {
326
- const isBuild = api?.context?.command === "build" || process.env.NODE_ENV === "production";
327
- if (typeof mfMerged.dts === "undefined") {
328
- mfMerged.dts = isBuild ? {} : {};
329
- }
330
- if (mfMerged.dts !== false) {
331
- const dtsObj = ensureDtsObject(mfMerged.dts);
332
366
  dtsObj.generateTypes = dtsObj.generateTypes ?? { tsConfigPath: "./tsconfig.json" };
333
367
  mfMerged.dts = dtsObj;
334
368
  }
@@ -336,11 +370,15 @@ function pluginCore(opts) {
336
370
  const mfPlugin = pluginModuleFederation(mfMerged);
337
371
  await mfPlugin.setup?.(api);
338
372
  const pkgSafe = getPackageName(root) || mfMerged.name || path3.basename(root).replace(/\W+/g, "");
339
- const cdnUrl = `${CDN_BASE}${pkgSafe}/`;
340
- const isProd = process.env.NODE_ENV === "production";
341
373
  api.modifyRsbuildConfig((config) => {
342
374
  config.output ??= {};
343
- if (isProd && !config.output.assetPrefix) config.output.assetPrefix = cdnUrl;
375
+ const current = config.output.assetPrefix;
376
+ const fromEnv = process.env.CDN_URL || process.env.ASSET_PREFIX;
377
+ const fallbackCdn = `${CDN_BASE}${pkgSafe}/`;
378
+ const target = fromEnv ?? fallbackCdn;
379
+ if (isProdLike && (!current || current === "/" || current === "./")) {
380
+ config.output.assetPrefix = target;
381
+ }
344
382
  return config;
345
383
  });
346
384
  if (separateExposes && mfMerged.exposes) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ptech-preset",
3
- "version": "1.2.5",
3
+ "version": "1.2.7",
4
4
  "description": "Auto Module.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",