esbuild-plugin-file-path-extensions
raw JSON → 2.1.4 verified Mon Apr 27 auth: no javascript
This esbuild plugin automatically adds file extensions to import/export specifiers in bundled JavaScript output, addressing the common requirement for explicit extensions when targeting Node.js ESM or other environments that enforce extension inclusion. Version 2.1.4 (npm) requires Node >=14 and npm >=7. It ships with TypeScript types and has zero runtime dependencies. Unlike manual post-processing or bundler-agnostic solutions, this integrates directly as an esbuild plugin, offering fine-grained control over which extension (.js, .mjs, .cjs) to append based on the build target. The plugin handles dynamic imports, re-exports, and preserves URL imports. It sees active maintenance with regular updates aligned to esbuild API changes.
Common errors
error TypeError: filePathExtensions is not a function ↓
cause Using a named import instead of default import (common mistake after v2 breaking change).
fix
Change to:
import filePathExtensions from 'esbuild-plugin-file-path-extensions' error Error: Cannot find module 'esbuild-plugin-file-path-extensions' ↓
cause Project is in a CommonJS module scope and tries to require() the package, which is ESM-only.
fix
Switch your project to ESM (type: module in package.json) or use dynamic import:
const filePathExtensions = (await import('esbuild-plugin-file-path-extensions')).default; error No matching files found: ... The plugin worked but no import paths were rewritten ↓
cause The inFileExtension does not match the actual extension used in import statements, or the outFileExtension matches the original extension.
fix
Set inFileExtension to match the file extensions in your source (e.g., '.ts') and outFileExtension to the desired output extension (e.g., '.mjs').
Warnings
gotcha The plugin only processes files that are part of the esbuild build; it does not transform external dependencies unless they are bundled. ↓
fix Ensure all files requiring extension rewriting are included in the build via entryPoints or resolve extensions.
gotcha If you set outFileExtension to the same as the original extension (e.g., .ts --> .ts), no changes occur. This is intentional but may confuse users expecting transformation. ↓
fix Use distinct extensions like .ts -> .mjs or .ts -> .js for actual effect.
breaking Version 2.0.0 changed the default export from a named export to a default export. Old imports using named import will break. ↓
fix Change `import { filePathExtensions } from 'esbuild-plugin-file-path-extensions'` to `import filePathExtensions from 'esbuild-plugin-file-path-extensions'`.
gotcha The plugin does not handle bare specifiers (e.g., 'lodash') – only relative/absolute imports with explicit extensions. ↓
fix Use esbuild's `alias` or `external` settings for bare specifiers.
Install
npm install esbuild-plugin-file-path-extensions yarn add esbuild-plugin-file-path-extensions pnpm add esbuild-plugin-file-path-extensions Imports
- default (the plugin function) wrong
const filePathExtensions = require('esbuild-plugin-file-path-extensions')correctimport filePathExtensions from 'esbuild-plugin-file-path-extensions' - Plugin type (TypeScript) wrong
import { filePathExtensions } from 'esbuild-plugin-file-path-extensions'correctimport type { Plugin } from 'esbuild' import filePathExtensions from 'esbuild-plugin-file-path-extensions' - Calling the function wrong
new filePathExtensions()correctfilePathExtensions({ inFileExtension: '.ts', outFileExtension: '.mjs' })
Quickstart
import * as esbuild from 'esbuild';
import filePathExtensions from 'esbuild-plugin-file-path-extensions';
await esbuild.build({
entryPoints: ['src/index.ts'],
outdir: 'dist',
bundle: true,
format: 'esm',
platform: 'node',
target: 'node14',
plugins: [
filePathExtensions({
inFileExtension: '.ts',
outFileExtension: '.mjs'
})
]
});
console.log('Build complete with .mjs extensions added to imports/outputs.');