ptech-preset
v2.9.0
Published
Auto Module.
Maintainers
Readme
ptech-preset
Rsbuild Module Federation preset for PTECH remotes and hosts.
The preset wraps @module-federation/rsbuild-plugin and centralizes:
- auto exposes from
/** @expose Name */comments orexposeComponent(component, 'Name'), - auto remotes from
REMOTE_*environment variables and optional manifest files/URLs, - default shared dependencies for React and common shell packages,
- React 19 compilation with
@rsbuild/plugin-reactandreactCompiler: true, - Tailwind CSS v4 integration with
@rsbuild/plugin-tailwindcss, - remote type hint fetching into
@mf-types, - DTS tsconfig patching,
- optional CSS exposure/injection strategies,
- fail-closed CI/production remote host allowlist validation,
- bounded, transactional remote type ZIP extraction,
- consumer-preserving and configurable production asset prefixes.
Install
npm i -D ptech-preset @module-federation/rsbuild-plugin @rsbuild/core@^2.1.0Usage
import { defineConfig } from '@rsbuild/core';
import pluginCore from 'ptech-preset';
export default defineConfig({
plugins: [
pluginCore({
baseDir: 'src',
globs: ['src/components/**/*.{ts,tsx}'],
exposesMode: 'both',
envPrefix: 'REMOTE_',
manifestPathOrUrl: process.env.MF_MANIFEST,
remoteHostAllowlist: ['cdn.example.com'],
cdnBase: 'https://cdn.example.com/remotes',
mf: {
name: 'ptechlibrary',
filename: 'static/js/remoteEntry.js',
},
}),
],
});mf is required and is passed through to @module-federation/rsbuild-plugin after the preset merges auto-generated values and defaults. The preset registers React with reactCompiler: true and Tailwind CSS v4 internally; do not register @rsbuild/plugin-react or @rsbuild/plugin-tailwindcss again in the consumer app.
Auto Exposes
By default, the preset scans src/components/**/*.{ts,tsx}.
JSDoc marker:
/** @expose AnimatedButton */
export default function AnimatedButton() {
return null;
}Wrapper marker:
exposeComponent(AnimatedButton, 'AnimatedButton');Expose priority:
manualExposesmf.exposes- auto-scan when
autoWhenEmptyandautoExposeEnabledare enabled
Generated expose keys use the Module Federation format, for example ./AnimatedButton.
Auto Remotes
Environment variables use REMOTE_ by default:
REMOTE_admin=https://cdn.example.com/admin/remoteEntry.js
REMOTE_ui=https://cdn.example.com/ui/remoteEntry.jsThe output remotes map uses <scope>@<url> values. Scope keys are normalized to lowercase.
Scopes used for fetched type output must be 1-128 letters, digits, dots,
underscores, or hyphens. Path-like values, Windows device names, and npm-style
@scope/name values are rejected; use a filesystem-safe Module Federation alias.
An optional manifest can be local or HTTP(S):
{
"admin": "https://cdn.example.com/admin/remoteEntry.js",
"ui": "https://cdn.example.com/ui/remoteEntry.js"
}Environment remotes win over manifest remotes for the same scope.
Remote Type Hints
When remotes are configured, the preset infers:
<remote-base>/@mf-types.d.ts<remote-base>/@mf-types.zip
It writes fetched types into the configured typesFolder (@mf-types by default) and writes generated helper files under .mf-auto.
Useful environment variables:
MF_DTS_REFRESH=1: force refresh of remote type zips in dev.MF_DTS_TSCONFIG=<path>: override the generated DTS tsconfig path.MF_REMOTE_ALLOWLIST=host1.example.com,*.example.net: add remote host allowlist entries.MF_ASSET_PREFIX=<prefix>: set the asset prefix when consumer Rsbuild config and the preset option omit it.MF_CDN_BASE=https://cdn.example.com/remotes: override the fallback CDN root.
Do not hand-edit generated files under .mf-auto or fetched type files under @mf-types.
Options
| Option | Type | Default | Description |
| --- | --- | --- | --- |
| baseDir | string | 'src' | Base directory used for relative source paths and DTS include defaults. |
| globs | string[] | ['src/components/**/*.{ts,tsx}'] | Files scanned for expose markers. |
| exposesMode | 'jsdoc' \| 'wrapper' \| 'both' | 'both' | Marker detection mode. |
| envPrefix | string | 'REMOTE_' | Environment prefix for auto remotes. |
| manifestPathOrUrl | string | - | Local manifest path or HTTP(S) manifest URL. |
| autoWhenEmpty | boolean | true | Auto-generate exposes/remotes only when user config is empty. |
| manualExposes | Record<string, string> | - | Explicit expose map that skips auto-scan and takes priority over mf.exposes. |
| autoExposeEnabled | boolean | true | Enables auto-scan when no explicit exposes are configured. |
| sharedEager | boolean | dev: true, build: false | Applies eager: true to default React shared entries. |
| cssInjection | 'none' \| 'wrapper' \| 'styles-expose' | 'none' | CSS handling strategy for generated exposes. |
| cssEntry | string | 'src/index.css' | CSS file used by wrapper or styles-expose modes. |
| stylesExposeKey | string | './styles' | Expose key used by styles-expose. |
| separateExposes | boolean | true | Creates separate chunks for each expose in build mode using Rsbuild 2 splitChunks. |
| separateExposeChunkPrefix | string | 'mf-expose-' | Prefix for generated expose chunk names. |
| separateExposesInDev | boolean | false | Enables separate expose chunking in dev mode. |
| typesFolder | string | '@mf-types' | Folder for remote type hints. |
| devTypesRefreshEnvVar | string | 'MF_DTS_REFRESH' | Env var used to force remote type refresh in dev. |
| remoteHostAllowlist | string[] | [] | Allowed remote host patterns. Supports exact hosts and *.example.com. |
| remoteAllowlistEnvVar | string | 'MF_REMOTE_ALLOWLIST' | Env var for comma-separated allowlist entries. |
| remoteAllowlistMode | 'auto' \| 'warn' \| 'error' \| 'off' | 'auto' | auto warns locally and fails closed for CI/production builds. off works only for local non-production builds and resolves to error in CI/production. |
| remoteTypeLimits | Partial<RemoteTypeLimits> | secure defaults | Overrides bounded remote declaration/ZIP download and extraction limits. |
| assetPrefix | string | - | Preset fallback asset prefix. Existing consumer output.assetPrefix has higher priority. |
| assetPrefixEnvVar | string | 'MF_ASSET_PREFIX' | Environment variable used as the next asset-prefix fallback. |
| cdnBase | string | OnePortal CDN root | Configurable CDN root used only for remote production builds with no supplied asset prefix. |
| cdnBaseEnvVar | string | 'MF_CDN_BASE' | Environment variable used to override the fallback CDN root. |
| dtsInDev | boolean | false | Enables DTS generation in dev mode. |
| dtsInclude | string[] | - | Custom DTS include paths. Overrides dtsIncludeMode. |
| dtsIncludeMode | 'all-src' \| 'exposes-only' | 'all-src' | DTS include scope when dtsInclude is not provided. |
| debug / debuge | boolean | false | Enables preset debug logging. debuge is kept for backward compatibility. |
| isHost | boolean | false | Uses host asset prefix behavior in production build. |
| mf | Record<string, unknown> | required | Module Federation options passed to the underlying plugin. |
Default Shared Dependencies
The preset shares dependencies only when the consuming project declares them in dependencies or peerDependencies.
Default shared candidates:
reactreact-domreact-router@azure/msal-reactptech-shell-sdkptech-shell-runtime@tanstack/react-queryzustandi18nextreact-i18next
User-provided mf.shared values are deep-merged over these defaults.
ptech-shell-sdk and ptech-shell-runtime are strict singletons because host
and remote applications must use one service registry and runtime context. For
stable exact dependency versions, the preset converts the runtime requirement
to a same-major compatibility range: an installed 2.7.0 provider produces
requiredVersion: '^2.7.0'. This allows a remote built against 2.7.0 to consume
a backward-compatible 2.8.x singleton supplied by the host. Existing ranges and
prerelease pins are preserved. Breaking shell contracts must use a new major.
Security Notes
- Configure
remoteHostAllowlistorMF_REMOTE_ALLOWLISTin CI/production. The defaultautomode fails the build when remotes exist and the allowlist is empty or a URL does not match.*.example.commatches subdomains, not the baseexample.com; list both when both are valid. - Remote manifests, entries, declarations, and ZIPs must use HTTPS in CI and
production. Local non-production development may use HTTP only for
localhost,127.0.0.0/8, or::1. Embedded URL credentials are rejected. - Remote manifest redirects are rejected and responses are capped at 1 MiB. Strict builds fail instead of silently continuing when a configured manifest cannot be fetched, parsed, or validated.
- Remote type fetches reject redirects and enforce these defaults: 32 MiB archive,
5 MiB single declaration, 5,000 entries, 16 MiB per entry, 128 MiB total
inflated data, 200:1 per-entry compression ratio, and 1,024-character paths.
remoteTypeLimitsmay tighten or deliberately raise a limit for a known remote. - ZIP extraction validates central and local headers before writing, rejects traversal/absolute/drive/UNC/null/ambiguous paths, duplicates, encryption, ZIP64, symlink/special-file entries, unsupported compression, CRC mismatch, and zip-bomb limits. Extraction occurs in a staging directory and swaps the target only after the complete archive succeeds.
- For inferred HTTP(S) remotes, the preset disables Module Federation's built-in archive consumer after this secure fetch. This prevents a second unbounded download/extraction path from bypassing the preset checks.
- Asset-prefix precedence is consumer
output.assetPrefix, presetassetPrefix, the configured environment variable, then the host/dev or CDN fallback. The preset never overwrites a consumer-provided prefix. - Debug output masks URL query strings to avoid leaking SAS tokens or credentials.
Build
npm run build -w ptech-preset
npm run test -w ptech-presetThe package builds src/index.ts to ESM and declaration files in dist/.
