skills/rspack/SKILL.md
Rspack bundler patterns for Rsbuild/Rslib config customization. Trigger: When customizing rspack config via tools.rspack, adding plugins, aliases, or Module Federation setup.
npx skillsauth add Hyperxq/modular-frontend-architecture rspackInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
rspack.config.ts in this project. All Rspack config lives inside tools.rspack callbacks within rsbuild.config.ts or rslib.config.ts.??= or ||= to safely initialize nested objects before mutating them.ui_components (NOT ui-components). MF uses the name as a JS identifier — hyphens break it.singleton: true across MF boundary to prevent duplicate Preact runtimes and hooks state corruption.IgnorePlugin) via the second argument { rspack } of the tools.rspack callback, NOT from a direct import.Need to add an alias? → tools.rspack → config.resolve.alias
Need to exclude files? → tools.rspack → rspack.IgnorePlugin
Need Module Federation? → pluginModuleFederation (Rsbuild plugin)
Need custom loader? → tools.rspack → config.module.rules
Use resolve.alias to redirect imports — e.g., swap real modules for mocks in test configs.
// rstest.config.ts or rsbuild.config.ts
import { resolve } from "path";
export default {
tools: {
rspack: (config) => {
config.resolve ||= {};
config.resolve.alias ||= {};
config.resolve.alias["some/path"] = resolve(__dirname, "mocks/mock.tsx");
return config;
},
},
};
||=guards against overwriting an existing object reference. Always do this before mutating nested fields.
Access built-in plugins from the second callback argument { rspack }.
// rslib.config.ts
export default {
lib: [ /* ... */ ],
tools: {
rspack: (config, { rspack }) => {
config.plugins ??= [];
config.plugins.push(
new rspack.IgnorePlugin({
resourceRegExp: /\.(spec|test)\.(ts|tsx|js|jsx)$/,
})
);
return config;
},
},
};
??=only initializes ifundefinedornull— safer than||=for arrays (avoids replacing an empty array[]).
Use pluginModuleFederation from @module-federation/rsbuild-plugin. This is a Rsbuild-level plugin, NOT a tools.rspack plugin.
// rsbuild.config.ts
import { pluginModuleFederation } from "@module-federation/rsbuild-plugin";
export default {
plugins: [
pluginModuleFederation({
name: "ui_components", // MUST be underscore — this becomes a JS global
exposes: {
"./Button": "./src/components/Button/index.tsx",
"./Input": "./src/components/Input/index.tsx",
},
shared: {
preact: {
singleton: true, // REQUIRED — one Preact instance across MF boundary
requiredVersion: "^10.0.0",
},
"preact/hooks": {
singleton: true,
requiredVersion: "^10.0.0",
},
},
}),
],
};
Why singleton for Preact?
If two MF modules load their own Preact, hooks (useState, useEffect) will throw or silently misbehave. singleton: true forces all remotes to share the host's Preact instance.
tools: {
rspack: (config) => {
config.module ??= {};
config.module.rules ??= [];
config.module.rules.push({
test: /\.svg$/,
type: "asset/inline",
});
return config;
},
},
Always initialize nested config paths from outermost to innermost before pushing or assigning:
// Correct
config.module ??= {};
config.module.rules ??= [];
config.module.rules.push({ /* rule */ });
// Wrong — will throw if config.module is undefined
config.module.rules.push({ /* rule */ });
rsbuild build # triggers rspack compilation under the hood
rsbuild dev # dev server with HMR via rspack
rslib build # library build via rslib → rspack
rslib inspect --verbose # print the final resolved rspack config (great for debugging)
rspack, webpack, bundler, module federation, alias, plugins, rsbuild, rslib, IgnorePlugin, tools.rspack, resolve.alias, singleton, preact, jsxImportSource
development
Rstest patterns for Rspack-native unit testing with Preact. Trigger: When writing tests with @rstest/core, testing-library/preact, or configuring rstest.config.ts.
tools
Rslib library build tool patterns for Rspack-based component libraries. Trigger: When configuring rslib.config.ts, library builds, Module Federation remotes, or dynamic entry discovery.
development
Preact 10 patterns with React-compat and Module Federation singleton setup. Trigger: When writing Preact components, hooks, types, or configuring Preact in Rsbuild/Rslib/Rstest.
tools
# Skill: playwright (project-local) Extends the global Playwright skill with project-specific setup, browser install, and MF dev server orchestration for this monorepo. --- ## Browser Installation in AI Agents (OpenCode / Claude) The MCP Playwright server looks for `chrome` at `/opt/google/chrome/chrome` by default. That binary is **not available** in this environment. ### Fix 1 — Configure MCP to use chromium (preferred, one-time) In `~/.config/opencode/opencode.json`, add `--browser chro