Output Directory
Configure where Packem writes your built files and assets
Output Directory
The output directory determines where Packem writes your built files, assets, and generated code. Proper configuration ensures your build artifacts are organized and accessible.
Basic Configuration
Default Directory
By default, Packem outputs to the dist directory:
export default defineConfig({
// Uses 'dist' by default
})Custom Directory
export default defineConfig({
rollup: {
output: {
dir: 'build' // Custom output directory
}
}
})Multiple Directories
export default defineConfig({
rollup: {
output: [
{ format: 'esm', dir: 'dist/esm' },
{ format: 'cjs', dir: 'dist/cjs' },
{ format: 'iife', dir: 'dist/browser' }
]
}
})Directory Structure
Flat Structure
export default defineConfig({
rollup: {
output: {
dir: 'dist',
// All files in root
entryFileNames: '[name].js',
chunkFileNames: '[name].js',
assetFileNames: '[name].[ext]'
}
}
})Organized Structure
export default defineConfig({
rollup: {
output: {
dir: 'dist',
// Organized by type
entryFileNames: 'js/[name].js',
chunkFileNames: 'chunks/[name]-[hash].js',
assetFileNames: 'assets/[name]-[hash].[ext]'
}
}
})Format-Based Structure
export default defineConfig({
rollup: {
output: [
{
format: 'esm',
dir: 'dist/esm',
entryFileNames: '[name].mjs'
},
{
format: 'cjs',
dir: 'dist/cjs',
entryFileNames: '[name].cjs'
}
]
}
})File Naming Patterns
Entry Files
export default defineConfig({
rollup: {
output: {
dir: 'dist',
entryFileNames: (chunkInfo) => {
// Custom naming logic
if (chunkInfo.name === 'index') {
return 'main.js'
}
return '[name]-[hash].js'
}
}
}
})Chunk Files
export default defineConfig({
rollup: {
output: {
dir: 'dist',
chunkFileNames: 'chunks/[name]-[hash].js'
}
}
})Asset Files
export default defineConfig({
rollup: {
output: {
dir: 'dist',
assetFileNames: (assetInfo) => {
const extType = assetInfo.name.split('.').pop()
if (/png|jpe?g|svg|gif|tiff|bmp|ico/i.test(extType)) {
return 'images/[name]-[hash].[ext]'
}
if (/css|scss|sass|less|styl/i.test(extType)) {
return 'styles/[name]-[hash].[ext]'
}
return 'assets/[name]-[hash].[ext]'
}
}
}
})Package.json Integration
Automatic Directory Detection
{
"main": "./lib/index.js",
"module": "./esm/index.js",
"exports": {
".": {
"import": "./esm/index.js",
"require": "./lib/index.js"
}
}
}export default defineConfig({
// Automatically uses 'lib' and 'esm' directories
rollup: {
output: [
{ format: 'cjs', dir: 'lib' },
{ format: 'esm', dir: 'esm' }
]
}
})Custom Export Paths
{
"exports": {
".": {
"import": "./dist/modern/index.mjs",
"require": "./dist/legacy/index.cjs"
}
}
}export default defineConfig({
rollup: {
output: [
{ format: 'esm', dir: 'dist/modern' },
{ format: 'cjs', dir: 'dist/legacy' }
]
}
})Directory Cleaning
Automatic Cleaning
export default defineConfig({
clean: true, // Clean output directory before build
rollup: {
output: {
dir: 'dist'
}
}
})Selective Cleaning
export default defineConfig({
clean: ['dist/**/*.js', 'dist/**/*.css'], // Clean specific patterns
rollup: {
output: {
dir: 'dist'
}
}
})Custom Cleaning
export default defineConfig({
hooks: {
'build:before': async () => {
const { rimraf } = await import('rimraf')
await rimraf('dist')
}
},
rollup: {
output: {
dir: 'dist'
}
}
})Asset Handling
Static Assets
export default defineConfig({
rollup: {
output: {
dir: 'dist',
assetFileNames: 'assets/[name]-[hash].[ext]'
},
plugins: [
// Copy static assets
copy({
targets: [
{ src: 'public/*', dest: 'dist' }
]
})
]
}
})CSS Assets
export default defineConfig({
rollup: {
output: {
dir: 'dist',
assetFileNames: (assetInfo) => {
if (assetInfo.name?.endsWith('.css')) {
return 'styles/[name]-[hash].[ext]'
}
return 'assets/[name]-[hash].[ext]'
}
}
}
})Image Assets
export default defineConfig({
rollup: {
output: {
dir: 'dist',
assetFileNames: (assetInfo) => {
const imageExts = ['png', 'jpg', 'jpeg', 'gif', 'svg', 'webp']
const ext = assetInfo.name?.split('.').pop()?.toLowerCase()
if (imageExts.includes(ext)) {
return 'images/[name]-[hash].[ext]'
}
return 'assets/[name]-[hash].[ext]'
}
}
}
})Monorepo Configuration
Package-Specific Directories
// packages/ui/packem.config.ts
export default defineConfig({
rollup: {
output: {
dir: 'dist',
entryFileNames: '[name].js'
}
}
})
// packages/utils/packem.config.ts
export default defineConfig({
rollup: {
output: {
dir: 'lib', // Different directory per package
entryFileNames: '[name].js'
}
}
})Shared Output Directory
export default defineConfig({
rollup: {
output: {
dir: '../../dist/packages/my-package',
entryFileNames: '[name].js'
}
}
})Development vs Production
Environment-Specific Directories
export default defineConfig({
rollup: {
output: {
dir: process.env.NODE_ENV === 'production' ? 'dist' : 'dev',
entryFileNames: '[name].js'
}
}
})Development Server
export default defineConfig({
rollup: {
output: {
dir: 'dev',
sourcemap: true,
entryFileNames: '[name].js'
}
},
server: {
static: 'dev' // Serve from output directory
}
})Advanced Patterns
Dynamic Directory Names
export default defineConfig({
rollup: {
output: {
dir: `dist/${process.env.BUILD_TARGET || 'default'}`,
entryFileNames: '[name].js'
}
}
})Conditional Outputs
export default defineConfig({
rollup: {
output: process.env.DUAL_PACKAGE ? [
{ format: 'esm', dir: 'dist/esm' },
{ format: 'cjs', dir: 'dist/cjs' }
] : {
format: 'esm',
dir: 'dist'
}
}
})Platform-Specific Directories
export default defineConfig({
rollup: {
output: [
{
format: 'esm',
dir: 'dist/node',
platform: 'node'
},
{
format: 'esm',
dir: 'dist/browser',
platform: 'browser'
}
]
}
})Directory Permissions
Setting Permissions
export default defineConfig({
hooks: {
'build:after': async () => {
const { chmod } = await import('fs/promises')
await chmod('dist', 0o755)
}
},
rollup: {
output: {
dir: 'dist'
}
}
})Ownership
export default defineConfig({
hooks: {
'build:after': async () => {
const { chown } = await import('fs/promises')
const { getuid, getgid } = await import('process')
await chown('dist', getuid(), getgid())
}
}
})Troubleshooting
Directory Not Found
Ensure the output directory exists or can be created.
export default defineConfig({
hooks: {
'build:before': async () => {
const { mkdir } = await import('fs/promises')
await mkdir('dist', { recursive: true })
}
}
})Permission Errors
export default defineConfig({
hooks: {
'build:before': async () => {
const { access, constants } = await import('fs/promises')
try {
await access('dist', constants.W_OK)
} catch {
throw new Error('Output directory is not writable')
}
}
}
})Path Conflicts
export default defineConfig({
rollup: {
output: {
dir: 'dist',
// Avoid conflicts with reserved names
entryFileNames: (chunkInfo) => {
const reserved = ['index', 'main', 'lib']
if (reserved.includes(chunkInfo.name)) {
return `${chunkInfo.name}-bundle.js`
}
return '[name].js'
}
}
}
})Performance Considerations
SSD Optimization
export default defineConfig({
rollup: {
output: {
dir: 'dist',
// Optimize for SSD performance
compact: true,
generatedCode: {
preset: 'es2015'
}
}
}
})Network Drives
export default defineConfig({
rollup: {
output: {
dir: process.env.CI ? '/tmp/dist' : 'dist', // Use local storage in CI
entryFileNames: '[name].js'
}
}
})Large Files
export default defineConfig({
rollup: {
output: {
dir: 'dist',
// Split large chunks
maxParallelFileOps: 5,
chunkFileNames: 'chunks/[name]-[hash].js'
}
}
})Related Options
- Output Format - Configure output formats
- Entry - Configure entry points
- Assets - Handle static assets
- Clean - Clean output directories