Subchapter 8.26
references/option-shims.mdMarkdown5 KBView on GitHub
Shims provide small pieces of code that bridge the gap between CommonJS (CJS) and ECMAScript Modules (ESM), enabling cross-module-system compatibility.
With shims: true, adds CommonJS variables to ESM:
__dirname - Current directory path__filename - Current file pathAlways added when using require in ESM on Node.js:
require function via createRequire(import.meta.url)Always added to CommonJS output:
import.meta.urlimport.meta.dirnameimport.meta.filenametsdown --shimsexport default defineConfig({
entry: ['src/index.ts'],
format: ['esm'],
shims: true,
})Source:
console.log(__dirname)
console.log(__filename)Output (shims: true):
import { fileURLToPath } from 'node:url'
import { dirname } from 'node:path'
const __filename = fileURLToPath(import.meta.url)
const __dirname = dirname(__filename)
console.log(__dirname)
console.log(__filename)Source:
const mod = require('some-module')Output (automatic on Node.js):
import { createRequire } from 'node:module'
const require = createRequire(import.meta.url)
const mod = require('some-module')Source:
console.log(import.meta.url)
console.log(import.meta.dirname)Output (automatic):
const import_meta = {
url: require('url').pathToFileURL(__filename).toString(),
dirname: __dirname,
filename: __filename
}
console.log(import_meta.url)
console.log(import_meta.dirname)export default defineConfig({
entry: ['src/cli.ts'],
format: ['esm'],
platform: 'node',
shims: true, // Add __dirname, __filename
})export default defineConfig({
entry: ['src/index.ts'],
format: ['esm', 'cjs'],
platform: 'node',
shims: true, // ESM gets __dirname/__filename
// CJS gets import.meta.* (automatic)
})export default defineConfig({
entry: ['src/server.ts'],
format: ['esm'],
platform: 'node',
shims: true,
deps: {
neverBundle: [/.*/], // External all deps
},
})// Source code
import { readFileSync } from 'fs'
import { join } from 'path'
// Read file relative to current module
const content = readFileSync(join(__dirname, 'data.json'), 'utf-8')// tsdown config
export default defineConfig({
entry: ['src/index.ts'],
format: ['esm'],
shims: true, // Enables __dirname
})__dirname or __filenameimport.meta.urlShims add minimal runtime overhead:
// Added to output when shims enabled
import { fileURLToPath } from 'node:url'
import { dirname } from 'node:path'
const __filename = fileURLToPath(import.meta.url)
const __dirname = dirname(__filename)If __dirname or __filename are not used, they’re automatically removed during bundling (no overhead).
export default defineConfig({
platform: 'node',
format: ['esm'],
shims: true, // Recommended for Node.js
})require shim added automatically__dirname and __filename available with shims: trueexport default defineConfig({
platform: 'browser',
format: ['esm'],
shims: false, // Not needed for browser
})export default defineConfig({
platform: 'neutral',
format: ['esm'],
shims: false, // Avoid platform-specific code
})# Enable shims
tsdown --shims
# ESM with shims for Node.js
tsdown --format esm --platform node --shims
# Dual format with shims
tsdown --format esm --format cjs --shimsEnable shims:
export default defineConfig({
shims: true,
})Automatic on Node.js platform. If not working:
export default defineConfig({
platform: 'node', // Ensure Node.js platform
})Automatic - no configuration needed. If still failing, check output format:
export default defineConfig({
format: ['cjs'], // Shims added automatically
})shims: true for CLIs and serversrequire in ESMimport.meta.* always available in CJS