ptech-preset 0.1.0 → 0.1.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/README.md +6 -6
- package/dist/index.js +31 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#
|
|
1
|
+
# ptech-preset
|
|
2
2
|
|
|
3
3
|
A comprehensive Rsbuild preset with Module Federation, auto-expose, and auto-remotes functionality.
|
|
4
4
|
|
|
@@ -23,7 +23,7 @@ npm i -S fast-glob
|
|
|
23
23
|
|
|
24
24
|
```bash
|
|
25
25
|
npm i -D @rsbuild/core @rsbuild/plugin-react @module-federation/rsbuild-plugin
|
|
26
|
-
npm i -D
|
|
26
|
+
npm i -D ptech-preset
|
|
27
27
|
```
|
|
28
28
|
|
|
29
29
|
## Quick Start
|
|
@@ -33,7 +33,7 @@ npm i -D @precio/rsbuild-preset
|
|
|
33
33
|
```typescript
|
|
34
34
|
// rsbuild.config.ts
|
|
35
35
|
import { defineConfig } from '@rsbuild/core';
|
|
36
|
-
import { pluginPrecioPreset } from '
|
|
36
|
+
import { pluginPrecioPreset } from 'ptech-preset';
|
|
37
37
|
|
|
38
38
|
export default defineConfig({
|
|
39
39
|
plugins: [
|
|
@@ -51,7 +51,7 @@ export default defineConfig({
|
|
|
51
51
|
```typescript
|
|
52
52
|
// rsbuild.config.ts
|
|
53
53
|
import { defineConfig } from '@rsbuild/core';
|
|
54
|
-
import { pluginPrecioPreset } from '
|
|
54
|
+
import { pluginPrecioPreset } from 'ptech-preset';
|
|
55
55
|
|
|
56
56
|
export default defineConfig({
|
|
57
57
|
plugins: [
|
|
@@ -230,7 +230,7 @@ type SharedEntry =
|
|
|
230
230
|
```typescript
|
|
231
231
|
// rsbuild.config.ts
|
|
232
232
|
import { defineConfig } from '@rsbuild/core';
|
|
233
|
-
import { pluginPrecioPreset } from '
|
|
233
|
+
import { pluginPrecioPreset } from 'ptech-preset';
|
|
234
234
|
|
|
235
235
|
export default defineConfig({
|
|
236
236
|
plugins: [
|
|
@@ -252,7 +252,7 @@ export default defineConfig({
|
|
|
252
252
|
```typescript
|
|
253
253
|
// rsbuild.config.ts
|
|
254
254
|
import { defineConfig } from '@rsbuild/core';
|
|
255
|
-
import { pluginPrecioPreset } from '
|
|
255
|
+
import { pluginPrecioPreset } from 'ptech-preset';
|
|
256
256
|
|
|
257
257
|
export default defineConfig({
|
|
258
258
|
plugins: [
|
package/dist/index.js
CHANGED
|
@@ -79,6 +79,22 @@ async function collectAutoRemotes(opts = {}) {
|
|
|
79
79
|
}
|
|
80
80
|
return remotes;
|
|
81
81
|
}
|
|
82
|
+
function makeExposeCacheGroups(exposes) {
|
|
83
|
+
const groups = {};
|
|
84
|
+
for (const [key, rel] of Object.entries(exposes)) {
|
|
85
|
+
const safeName = key.replace(/[^a-z0-9]/gi, "-").replace(/^-+/, "");
|
|
86
|
+
const abs = path.resolve(process.cwd(), rel.replace(/^\.\//, ""));
|
|
87
|
+
const escaped = abs.replace(/\\/g, "\\\\");
|
|
88
|
+
groups[`expose-${safeName}`] = {
|
|
89
|
+
test: new RegExp(escaped),
|
|
90
|
+
name: `expose-${safeName}`,
|
|
91
|
+
// chunk name: expose-AnimatedButton
|
|
92
|
+
chunks: "all",
|
|
93
|
+
enforce: true
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
return groups;
|
|
97
|
+
}
|
|
82
98
|
|
|
83
99
|
// src/index.ts
|
|
84
100
|
function pluginPrecioPreset(opts) {
|
|
@@ -140,14 +156,27 @@ function pluginPrecioPreset(opts) {
|
|
|
140
156
|
manifest: opts.mf.manifest ?? false,
|
|
141
157
|
exposes,
|
|
142
158
|
remotes,
|
|
143
|
-
shared
|
|
159
|
+
shared,
|
|
160
|
+
dts: {
|
|
161
|
+
generateTypes: {
|
|
162
|
+
typesFolder: "@mf-types",
|
|
163
|
+
deleteTypesFolder: false,
|
|
164
|
+
compileInChildProcess: true,
|
|
165
|
+
abortOnError: false
|
|
166
|
+
},
|
|
167
|
+
consumeTypes: true
|
|
168
|
+
}
|
|
144
169
|
})
|
|
145
170
|
];
|
|
146
171
|
config.performance = {
|
|
147
172
|
...config.performance ?? {},
|
|
148
173
|
chunkSplit: {
|
|
149
174
|
strategy: "split-by-module",
|
|
150
|
-
|
|
175
|
+
override: {
|
|
176
|
+
cacheGroups: {
|
|
177
|
+
...makeExposeCacheGroups(exposes)
|
|
178
|
+
}
|
|
179
|
+
},
|
|
151
180
|
...config.performance?.chunkSplit ?? {}
|
|
152
181
|
}
|
|
153
182
|
};
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/autoExpose.ts","../src/autoRemotes.ts","../src/index.ts"],"names":["fs","path"],"mappings":"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","file":"index.js","sourcesContent":["import path from 'node:path';\r\nimport fs from 'node:fs';\r\nimport fg from 'fast-glob';\r\nimport type { AutoExposeOptions } from './types';\r\n\r\nexport async function collectAutoExposes(opts: AutoExposeOptions = {}) {\r\n if (opts.enabled === false) return {};\r\n \r\n const globs = opts.globs ?? ['src/components/**/*.{ts,tsx}'];\r\n const baseDir = path.resolve(process.cwd(), opts.baseDir ?? 'src');\r\n const tag = opts.tag ?? 'expose';\r\n\r\n const files = await fg(globs, { \r\n cwd: process.cwd(), \r\n absolute: true, \r\n ignore: ['**/*.d.ts'] \r\n });\r\n \r\n const exposes: Record<string, string> = {};\r\n\r\n for (const abs of files) {\r\n const text = fs.readFileSync(abs, 'utf8');\r\n \r\n // Tìm /** @expose Name */\r\n const m = text.match(new RegExp(`/\\\\*\\\\*[^*]*\\\\*+[^/]*@${tag}\\\\s*([^*\\\\n\\\\r]*)`, 'm'));\r\n if (!m) continue;\r\n\r\n // lấy tên sau @expose, nếu trống => dùng baseName file\r\n const raw = (m[1] || '').trim();\r\n const key = raw || path.basename(abs).replace(/\\.(tsx?|jsx?)$/, '');\r\n const rel = path.relative(baseDir, abs).replace(/\\\\/g, '/');\r\n exposes[`./${key}`] = `./${rel}`;\r\n }\r\n \r\n return exposes;\r\n}\r\n\r\n// Extended version that also supports exposeComponent wrapper\r\nexport async function collectAutoExposesWithWrapper(opts: AutoExposeOptions = {}) {\r\n if (opts.enabled === false) return {};\r\n \r\n const globs = opts.globs ?? ['src/components/**/*.{ts,tsx}'];\r\n const baseDir = path.resolve(process.cwd(), opts.baseDir ?? 'src');\r\n const tag = opts.tag ?? 'expose';\r\n\r\n const files = await fg(globs, { \r\n cwd: process.cwd(), \r\n absolute: true, \r\n ignore: ['**/*.d.ts'] \r\n });\r\n \r\n const exposes: Record<string, string> = {};\r\n\r\n for (const abs of files) {\r\n const text = fs.readFileSync(abs, 'utf8');\r\n \r\n // 1. Tìm /** @expose Name */\r\n const jsdocMatch = text.match(new RegExp(`/\\\\*\\\\*[^*]*\\\\*+[^/]*@${tag}\\\\s*([^*\\\\n\\\\r]*)`, 'm'));\r\n if (jsdocMatch) {\r\n const raw = (jsdocMatch[1] || '').trim();\r\n const key = raw || path.basename(abs).replace(/\\.(tsx?|jsx?)$/, '');\r\n const rel = path.relative(baseDir, abs).replace(/\\\\/g, '/');\r\n exposes[`./${key}`] = `./${rel}`;\r\n continue;\r\n }\r\n\r\n // 2. Tìm exposeComponent(comp, 'Key')\r\n const wrapperMatch = text.match(/exposeComponent\\s*\\(\\s*[^,]+,\\s*['\"`]([^'\"`]+)['\"`]\\s*\\)/);\r\n if (wrapperMatch) {\r\n const key = wrapperMatch[1];\r\n const rel = path.relative(baseDir, abs).replace(/\\\\/g, '/');\r\n exposes[`./${key}`] = `./${rel}`;\r\n }\r\n }\r\n \r\n return exposes;\r\n}\r\n","import fs from 'node:fs';\r\nimport path from 'node:path';\r\nimport type { AutoRemotesOptions } from './types';\r\n\r\nexport async function collectAutoRemotes(opts: AutoRemotesOptions = {}) {\r\n const remotes: Record<string, string> = {};\r\n const prefix = opts.envPrefix ?? 'REMOTE_';\r\n\r\n // 1) ENV variables\r\n for (const [k, v] of Object.entries(process.env)) {\r\n if (!v) continue;\r\n if (k.startsWith(prefix)) {\r\n const scope = k.slice(prefix.length).toLowerCase();\r\n remotes[scope] = `${scope}@${v}`;\r\n }\r\n }\r\n\r\n // 2) Manifest JSON (local hoặc http)\r\n const manifestPathOrUrl = opts.manifestPathOrUrl;\r\n if (manifestPathOrUrl) {\r\n let obj: Record<string, string> = {};\r\n \r\n if (/^https?:\\/\\//i.test(manifestPathOrUrl)) {\r\n // HTTP/HTTPS URL\r\n try {\r\n const res = await fetch(manifestPathOrUrl);\r\n if (!res.ok) {\r\n console.warn(`Failed to fetch manifest from ${manifestPathOrUrl}: ${res.status} ${res.statusText}`);\r\n } else {\r\n obj = await res.json();\r\n }\r\n } catch (error) {\r\n console.warn(`Error fetching manifest from ${manifestPathOrUrl}:`, error);\r\n }\r\n } else {\r\n // Local file path\r\n try {\r\n const manifestPath = path.resolve(manifestPathOrUrl);\r\n if (fs.existsSync(manifestPath)) {\r\n obj = JSON.parse(fs.readFileSync(manifestPath, 'utf8'));\r\n } else {\r\n console.warn(`Manifest file not found: ${manifestPath}`);\r\n }\r\n } catch (error) {\r\n console.warn(`Error reading manifest file ${manifestPathOrUrl}:`, error);\r\n }\r\n }\r\n \r\n // Process manifest entries\r\n for (const [scope, url] of Object.entries(obj)) {\r\n if (typeof url === 'string' && url.trim()) {\r\n remotes[scope] = `${scope}@${url}`;\r\n }\r\n }\r\n }\r\n \r\n return remotes;\r\n}\r\n","import type { RsbuildConfig, RsbuildPlugin } from \"@rsbuild/core\";\r\nimport { pluginReact } from \"@rsbuild/plugin-react\";\r\nimport { pluginModuleFederation } from \"@module-federation/rsbuild-plugin\";\r\nimport type { PrecioPresetOptions, SharedEntry } from \"./types\";\r\nimport { collectAutoExposesWithWrapper } from \"./autoExpose\";\r\nimport { collectAutoRemotes } from \"./autoRemotes\";\r\n\r\nexport function pluginPrecioPreset(opts: PrecioPresetOptions): RsbuildPlugin {\r\n return {\r\n name: \"precio-rsbuild-preset\",\r\n async setup(api) {\r\n const isProd = process.env.NODE_ENV === \"production\";\r\n const CDN = opts.cdn ?? process.env.CDN_URL;\r\n\r\n // Chuẩn bị dữ liệu \"thông minh\"\r\n const autoExposes = await collectAutoExposesWithWrapper(opts.autoExpose);\r\n const autoRemotes = await collectAutoRemotes(opts.autoRemotes);\r\n\r\n api.modifyRsbuildConfig((config: RsbuildConfig) => {\r\n // HTML\r\n config.html = {\r\n ...(config.html ?? {}),\r\n title: opts.html?.title ?? config.html?.title ?? \"Precio App\",\r\n meta: {\r\n viewport: \"width=device-width, initial-scale=1\",\r\n description: opts.html?.description ?? \"Precio App\",\r\n ...(config.html?.meta ?? {}),\r\n },\r\n };\r\n\r\n // OUTPUT\r\n const out = opts.output ?? {};\r\n config.output = {\r\n ...(config.output ?? {}),\r\n assetPrefix: isProd ? CDN ?? \"/\" : out.assetPrefixInDev ?? \"/\",\r\n sourceMap: isProd ? out.sourceMapProd ?? false : true,\r\n filenameHash: out.hashFilenames ?? true,\r\n filename: {\r\n js: out.filename?.js ?? \"static/js/[name].[contenthash:8].js\",\r\n css: out.filename?.css ?? \"static/css/[name].[contenthash:8].css\",\r\n ...(config.output?.filename ?? {}),\r\n },\r\n distPath: {\r\n js: out.distPath?.js ?? \"static/js\",\r\n css: out.distPath?.css ?? \"static/css\",\r\n ...(config.output?.distPath ?? {}),\r\n },\r\n };\r\n\r\n // SHARED (giữ literal type cho false)\r\n const shared = {\r\n react: {\r\n singleton: true,\r\n eager: true,\r\n requiredVersion: false as const,\r\n },\r\n \"react-dom\": {\r\n singleton: true,\r\n eager: true,\r\n requiredVersion: false as const,\r\n },\r\n ...(opts.mf?.shared ?? {}),\r\n } satisfies Record<string, SharedEntry>;\r\n\r\n // Exposes/Remotes: auto + cho phép override thủ công\r\n const exposes = { ...autoExposes, ...(opts.mf.exposes ?? {}) };\r\n const remotes = { ...autoRemotes, ...(opts.mf.remotes ?? {}) };\r\n\r\n config.plugins = [\r\n ...(config.plugins ?? []),\r\n pluginReact(),\r\n pluginModuleFederation({\r\n name: opts.mf.name,\r\n filename: opts.mf.filename ?? \"static/js/remoteEntry.js\",\r\n manifest: opts.mf.manifest ?? false,\r\n exposes,\r\n remotes,\r\n shared,\r\n } as any),\r\n ];\r\n\r\n config.performance = {\r\n ...(config.performance ?? {}),\r\n chunkSplit: {\r\n strategy: \"split-by-module\",\r\n forceSplitting: [/node_modules\\/react/, /node_modules\\/react-dom/],\r\n ...(config.performance?.chunkSplit ?? {}),\r\n },\r\n };\r\n\r\n return config;\r\n });\r\n },\r\n };\r\n}\r\n\r\n// Export types for consumers\r\nexport type {\r\n PrecioPresetOptions,\r\n AutoExposeOptions,\r\n AutoRemotesOptions,\r\n SharedEntry,\r\n} from \"./types\";\r\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/autoExpose.ts","../src/autoRemotes.ts","../src/chunkUtils.ts","../src/index.ts"],"names":["fs","path"],"mappings":"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","file":"index.js","sourcesContent":["import path from 'node:path';\r\nimport fs from 'node:fs';\r\nimport fg from 'fast-glob';\r\nimport type { AutoExposeOptions } from './types';\r\n\r\nexport async function collectAutoExposes(opts: AutoExposeOptions = {}) {\r\n if (opts.enabled === false) return {};\r\n \r\n const globs = opts.globs ?? ['src/components/**/*.{ts,tsx}'];\r\n const baseDir = path.resolve(process.cwd(), opts.baseDir ?? 'src');\r\n const tag = opts.tag ?? 'expose';\r\n\r\n const files = await fg(globs, { \r\n cwd: process.cwd(), \r\n absolute: true, \r\n ignore: ['**/*.d.ts'] \r\n });\r\n \r\n const exposes: Record<string, string> = {};\r\n\r\n for (const abs of files) {\r\n const text = fs.readFileSync(abs, 'utf8');\r\n \r\n // Tìm /** @expose Name */\r\n const m = text.match(new RegExp(`/\\\\*\\\\*[^*]*\\\\*+[^/]*@${tag}\\\\s*([^*\\\\n\\\\r]*)`, 'm'));\r\n if (!m) continue;\r\n\r\n // lấy tên sau @expose, nếu trống => dùng baseName file\r\n const raw = (m[1] || '').trim();\r\n const key = raw || path.basename(abs).replace(/\\.(tsx?|jsx?)$/, '');\r\n const rel = path.relative(baseDir, abs).replace(/\\\\/g, '/');\r\n exposes[`./${key}`] = `./${rel}`;\r\n }\r\n \r\n return exposes;\r\n}\r\n\r\n// Extended version that also supports exposeComponent wrapper\r\nexport async function collectAutoExposesWithWrapper(opts: AutoExposeOptions = {}) {\r\n if (opts.enabled === false) return {};\r\n \r\n const globs = opts.globs ?? ['src/components/**/*.{ts,tsx}'];\r\n const baseDir = path.resolve(process.cwd(), opts.baseDir ?? 'src');\r\n const tag = opts.tag ?? 'expose';\r\n\r\n const files = await fg(globs, { \r\n cwd: process.cwd(), \r\n absolute: true, \r\n ignore: ['**/*.d.ts'] \r\n });\r\n \r\n const exposes: Record<string, string> = {};\r\n\r\n for (const abs of files) {\r\n const text = fs.readFileSync(abs, 'utf8');\r\n \r\n // 1. Tìm /** @expose Name */\r\n const jsdocMatch = text.match(new RegExp(`/\\\\*\\\\*[^*]*\\\\*+[^/]*@${tag}\\\\s*([^*\\\\n\\\\r]*)`, 'm'));\r\n if (jsdocMatch) {\r\n const raw = (jsdocMatch[1] || '').trim();\r\n const key = raw || path.basename(abs).replace(/\\.(tsx?|jsx?)$/, '');\r\n const rel = path.relative(baseDir, abs).replace(/\\\\/g, '/');\r\n exposes[`./${key}`] = `./${rel}`;\r\n continue;\r\n }\r\n\r\n // 2. Tìm exposeComponent(comp, 'Key')\r\n const wrapperMatch = text.match(/exposeComponent\\s*\\(\\s*[^,]+,\\s*['\"`]([^'\"`]+)['\"`]\\s*\\)/);\r\n if (wrapperMatch) {\r\n const key = wrapperMatch[1];\r\n const rel = path.relative(baseDir, abs).replace(/\\\\/g, '/');\r\n exposes[`./${key}`] = `./${rel}`;\r\n }\r\n }\r\n \r\n return exposes;\r\n}\r\n","import fs from 'node:fs';\r\nimport path from 'node:path';\r\nimport type { AutoRemotesOptions } from './types';\r\n\r\nexport async function collectAutoRemotes(opts: AutoRemotesOptions = {}) {\r\n const remotes: Record<string, string> = {};\r\n const prefix = opts.envPrefix ?? 'REMOTE_';\r\n\r\n // 1) ENV variables\r\n for (const [k, v] of Object.entries(process.env)) {\r\n if (!v) continue;\r\n if (k.startsWith(prefix)) {\r\n const scope = k.slice(prefix.length).toLowerCase();\r\n remotes[scope] = `${scope}@${v}`;\r\n }\r\n }\r\n\r\n // 2) Manifest JSON (local hoặc http)\r\n const manifestPathOrUrl = opts.manifestPathOrUrl;\r\n if (manifestPathOrUrl) {\r\n let obj: Record<string, string> = {};\r\n \r\n if (/^https?:\\/\\//i.test(manifestPathOrUrl)) {\r\n // HTTP/HTTPS URL\r\n try {\r\n const res = await fetch(manifestPathOrUrl);\r\n if (!res.ok) {\r\n console.warn(`Failed to fetch manifest from ${manifestPathOrUrl}: ${res.status} ${res.statusText}`);\r\n } else {\r\n obj = await res.json();\r\n }\r\n } catch (error) {\r\n console.warn(`Error fetching manifest from ${manifestPathOrUrl}:`, error);\r\n }\r\n } else {\r\n // Local file path\r\n try {\r\n const manifestPath = path.resolve(manifestPathOrUrl);\r\n if (fs.existsSync(manifestPath)) {\r\n obj = JSON.parse(fs.readFileSync(manifestPath, 'utf8'));\r\n } else {\r\n console.warn(`Manifest file not found: ${manifestPath}`);\r\n }\r\n } catch (error) {\r\n console.warn(`Error reading manifest file ${manifestPathOrUrl}:`, error);\r\n }\r\n }\r\n \r\n // Process manifest entries\r\n for (const [scope, url] of Object.entries(obj)) {\r\n if (typeof url === 'string' && url.trim()) {\r\n remotes[scope] = `${scope}@${url}`;\r\n }\r\n }\r\n }\r\n \r\n return remotes;\r\n}\r\n","import path from 'node:path';\r\n\r\n/**\r\n * Generate cache groups to force each expose into its own chunk\r\n * This ensures each exposed component gets its own separate JavaScript chunk\r\n */\r\nexport function makeExposeCacheGroups(exposes: Record<string, string>) {\r\n const groups: Record<string, any> = {};\r\n \r\n for (const [key, rel] of Object.entries(exposes)) {\r\n // Create a safe name for the chunk (replace special characters with dashes)\r\n const safeName = key.replace(/[^a-z0-9]/gi, '-').replace(/^-+/, '');\r\n \r\n // Convert relative path to absolute path\r\n const abs = path.resolve(process.cwd(), rel.replace(/^\\.\\//, ''));\r\n \r\n // Escape backslashes for RegExp (Windows compatibility)\r\n const escaped = abs.replace(/\\\\/g, '\\\\\\\\');\r\n \r\n groups[`expose-${safeName}`] = {\r\n test: new RegExp(escaped),\r\n name: `expose-${safeName}`, // chunk name: expose-AnimatedButton\r\n chunks: 'all',\r\n enforce: true,\r\n };\r\n }\r\n \r\n return groups;\r\n}\r\n","import type { RsbuildConfig, RsbuildPlugin } from \"@rsbuild/core\";\r\nimport { pluginReact } from \"@rsbuild/plugin-react\";\r\nimport { pluginModuleFederation } from \"@module-federation/rsbuild-plugin\";\r\nimport type { PrecioPresetOptions, SharedEntry } from \"./types\";\r\nimport { collectAutoExposesWithWrapper } from \"./autoExpose\";\r\nimport { collectAutoRemotes } from \"./autoRemotes\";\r\nimport { makeExposeCacheGroups } from \"./chunkUtils\";\r\n\r\nexport function pluginPrecioPreset(opts: PrecioPresetOptions): RsbuildPlugin {\r\n return {\r\n name: \"precio-rsbuild-preset\",\r\n async setup(api) {\r\n const isProd = process.env.NODE_ENV === \"production\";\r\n const CDN = opts.cdn ?? process.env.CDN_URL;\r\n\r\n const autoExposes = await collectAutoExposesWithWrapper(opts.autoExpose);\r\n const autoRemotes = await collectAutoRemotes(opts.autoRemotes);\r\n\r\n api.modifyRsbuildConfig((config: RsbuildConfig) => {\r\n \r\n config.html = {\r\n ...(config.html ?? {}),\r\n title: opts.html?.title ?? config.html?.title ?? \"Precio App\",\r\n meta: {\r\n viewport: \"width=device-width, initial-scale=1\",\r\n description: opts.html?.description ?? \"Precio App\",\r\n ...(config.html?.meta ?? {}),\r\n },\r\n };\r\n\r\n const out = opts.output ?? {};\r\n config.output = {\r\n ...(config.output ?? {}),\r\n assetPrefix: isProd ? CDN ?? \"/\" : out.assetPrefixInDev ?? \"/\",\r\n sourceMap: isProd ? out.sourceMapProd ?? false : true,\r\n filenameHash: out.hashFilenames ?? true,\r\n filename: {\r\n js: out.filename?.js ?? \"static/js/[name].[contenthash:8].js\",\r\n css: out.filename?.css ?? \"static/css/[name].[contenthash:8].css\",\r\n ...(config.output?.filename ?? {}),\r\n },\r\n distPath: {\r\n js: out.distPath?.js ?? \"static/js\",\r\n css: out.distPath?.css ?? \"static/css\",\r\n ...(config.output?.distPath ?? {}),\r\n },\r\n };\r\n const shared = {\r\n react: {\r\n singleton: true,\r\n eager: true,\r\n requiredVersion: false as const,\r\n },\r\n \"react-dom\": {\r\n singleton: true,\r\n eager: true,\r\n requiredVersion: false as const,\r\n },\r\n ...(opts.mf?.shared ?? {}),\r\n } satisfies Record<string, SharedEntry>;\r\n\r\n const exposes = { ...autoExposes, ...(opts.mf.exposes ?? {}) };\r\n const remotes = { ...autoRemotes, ...(opts.mf.remotes ?? {}) };\r\n\r\n config.plugins = [\r\n ...(config.plugins ?? []),\r\n pluginReact(),\r\n pluginModuleFederation({\r\n name: opts.mf.name,\r\n filename: opts.mf.filename ?? \"static/js/remoteEntry.js\",\r\n manifest: opts.mf.manifest ?? false,\r\n exposes,\r\n remotes,\r\n shared,\r\n dts: {\r\n generateTypes: {\r\n typesFolder: '@mf-types',\r\n deleteTypesFolder: false,\r\n compileInChildProcess: true,\r\n abortOnError: false,\r\n },\r\n consumeTypes: true,\r\n },\r\n } as any),\r\n ];\r\n\r\n config.performance = {\r\n ...(config.performance ?? {}),\r\n chunkSplit: {\r\n strategy: \"split-by-module\",\r\n override: {\r\n cacheGroups: {\r\n ...makeExposeCacheGroups(exposes),\r\n },\r\n },\r\n ...(config.performance?.chunkSplit ?? {}),\r\n },\r\n };\r\n\r\n return config;\r\n });\r\n },\r\n };\r\n}\r\n\r\nexport type {\r\n PrecioPresetOptions,\r\n AutoExposeOptions,\r\n AutoRemotesOptions,\r\n SharedEntry,\r\n} from \"./types\";\r\n"]}
|