external
- Type:
string | RegExp | (string | RegExp)[] | ((id: string, parentId: string | undefined, isResolved: boolean) => NullValue<boolean>) - Optional: Yes ✅
Specifies which modules should be treated as external and not bundled. External modules will be left as import statements in the output.
Examples
String pattern
export default {
external: 'react',
};Regular expression
export default {
external: /node_modules/,
};Array of patterns
export default {
external: ['react', 'react-dom', /^lodash/],
};In-depth
⚠️ Don't use function unless you have to
Using the function form has significant performance overhead because Rolldown is written in Rust and must call JavaScript functions from Rust for every module in your dependency graph.
Performance Impact:
- Each module triggers a Rust-to-JS call
- Cross-language call overhead is high
- Can significantly slow down builds in large projects
Use static patterns when possible:
// ❌ Avoid: Function with performance overhead
export default {
external: (id) => {
return !id.startsWith('.') && !id.startsWith('/');
},
};
// ✅ Prefer: Static pattern (much faster)
export default {
external: [
'react',
'react-dom',
'vue',
/^lodash/,
/^@mui/,
],
};When to use function:
- You need truly dynamic logic based on
parentIdorisResolved - The logic cannot be expressed with static patterns
- You're okay with the performance trade-off
⚠️ Don't use /node_modules/ to match npm packages
Using /node_modules/ to externalize npm packages is problematic because Rolldown matches module IDs twice during resolution.
Example with import Vue from 'vue':
First match (unresolved ID):
'vue'- Pattern
/node_modules/does NOT match - This is the bare package name
- Pattern
Second match (resolved ID):
'/path/to/project/node_modules/vue/dist/vue.runtime.esm-bundler.js'- Pattern
/node_modules/DOES match - This is the full resolved file path
- Pattern
The Problem:
Since the pattern only matches on the resolved ID, Rolldown generates imports with absolute paths:
// ❌ Bad result: Absolute path in output
import Vue from '/Users/somebody/project/node_modules/vue/dist/vue.runtime.esm-bundler.js';This breaks portability and doesn't work as intended.
Better alternatives:
- Use exact package names
export default defineConfig({
external: ['vue', 'react', 'react-dom'],
});- Use package name patterns
export default {
external: [/^vue/, /^react/, /^@mui/],
};- Match bare identifiers
Pattern (visualize) to match all bare module IDs (not starting with . or /):
export default {
external: /^[^./]/,
};