external-bundle
SkillDev toolsAdd, use, or migrate a module to the external bundle system in sy-f-misc. Trigger when: user asks to reduce bundle size, move a module to external, use dynamic import for a large module, or asks about @external imports.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the external-bundle skill
What this skill tells your AI
The instructions your AI receives, as published by frostime/sy-f-misc in .agents/skills/external-bundle/SKILL.md and read by ahel’s review.
What This Skill Covers
The external bundle system lets you split large/infrequently-used modules out of the main index.js bundle. They are compiled to separate .js files under external/ and loaded at runtime via dynamic import().
Full architecture details → dev-doc
When to Use External Modules
Use external bundle for a module when all of the following are true:
- Size > ~5 KB (use
pnpm run build+ check bundle stats, or estimate from file size) - Not on the startup critical path (not imported top-level in
index.tschain) - Feature is triggered by user action, not automatically on plugin load
- Module is self-contained (doesn't depend heavily on other
src/internals)
Step-by-Step Workflow
A. Create a New External Module
-
Create the source file in
src/external/:// src/external/my-module.ts export function myFunction(input: string): string { return input.trim(); } export default class MyClass { /* ... */ }For a directory module:
src/external/my-lib/ index.ts ← entry point helpers.ts ← internal (bundled into my-lib.js) -
Register in
vite.config.ts:// ============ 配置区域 ============ const EXTERNAL_MODULES = ["sandbox", "text-edit-engine", "my-module"]; // ================================= -
Import dynamically in business code:
// In an async function const mod = await import('@external/my-module'); const result = mod.myFunction('hello'); const instance = new mod.default(); -
Verify build: Run
pnpm devorpnpm build, confirm:dev/external/my-module.js(ordist/external/) is generated- No warnings about unregistered modules in console
B. Migrate Existing Module to External
-
Move the file:
src/libs/heavy-module.ts → src/external/heavy-module.ts -
Register in
vite.config.tsEXTERNAL_MODULESarray. -
Update all import sites — replace static imports with dynamic:
// Before (static) import HeavyModule from '@/libs/heavy-module'; // After (dynamic) — must be inside async function const { default: HeavyModule } = await import('@external/heavy-module'); -
Remove old file from
src/libs/if no longer needed there. -
For TypeScript types — use
import typeat the top (safe, no runtime effect):import type { MyType } from '@external/heavy-module';
C. Use an Existing External Module
// Pattern 1: default export class
const SandboxModule = await import('@external/sandbox');
const JavaScriptSandBox = SandboxModule.default;
const instance = new JavaScriptSandBox();
await instance.init();
// Pattern 2: named exports
const { doSomething, MyClass } = await import('@external/my-module');
// Pattern 3: store module for reuse (avoid repeated imports)
let _sandboxMod: typeof import('@external/sandbox') | null = null;
async function getSandbox() {
_sandboxMod ??= await import('@external/sandbox');
return _sandboxMod;
}
Checklist Before Finishing
- Module file exists in
src/external/ - Module name added to
EXTERNAL_MODULESinvite.config.ts - All import sites use
await import('@external/...')(no static imports) -
import typeis used for type-only access if needed - Build runs without warnings about unregistered modules
- Output file appears in
dev/external/ordist/external/ - Old file removed from its original location (if migrating)
Common Mistakes
| Mistake | Effect | Fix |
|---|---|---|
import X from '@external/foo' (static) | Plugin removes it, runtime crash | Use await import(...) |
Module not in EXTERNAL_MODULES | Build warning, runtime 404 | Add to config array |
Calling import('@external/foo') at top level | CJS bundle error with top-level await | Move into async function |
External module imports from @/ (main src) | Compile error or missing reference | Copy utility or extract to npm package |
Forgot to save vite.config.ts after adding module | Module not built | Confirm the config change |
Key Files
| File | Role |
|---|---|
vite.config.ts | EXTERNAL_MODULES list + plugin setup |
vite-plugin-external-modules.ts | Plugin implementation (scan, build, transform) |
src/external/ | Source directory for all external modules |
dev/external/ / dist/external/ | Build output |
Signals
- GitHub stars
- 29
- Forks
- 6
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
external-bundle- Source
- github.com/frostime/sy-f-misc