esbuild-plugin-ifdef
raw JSON → 1.0.1 verified Fri May 01 auth: no javascript
esbuild plugin for conditional compilation using `//#ifdef` comments in JavaScript and TypeScript files. Version 1.0.1 is the latest stable release. It allows developers to include or exclude code blocks based on environment variables before esbuild's tree-shaking phase. Unlike traditional `if (true)` patterns that break function scoping, this plugin removes dead code at the comment level, preserving correct scoping. It filters `process.env` prefixes automatically and supports negation with `!`. The plugin excludes `node_modules` by default for performance and security. Alternative to `esbuild-plugin-conditional` or manual define-based checks, but with a simpler preprocessor-style comment syntax.
Common errors
error TypeError: ifdef is not a function ↓
cause CommonJS require does not work with ESM-only package.
fix
Use dynamic import:
const ifdef = (await import('esbuild-plugin-ifdef')).default; or switch to ESM import. error Error: No matching define for ifdef condition 'MY_FLAG' ↓
cause The condition 'MY_FLAG' does not exist in the define object.
fix
Add
'process.env.MY_FLAG': true to the define object or use a key that exists. error Error: Plugin ifdef: baseDir '/wrong/path' does not exist ↓
cause The baseDir option points to a non-existent directory.
fix
Set baseDir to an existing directory, e.g., process.cwd() or the project root.
Warnings
gotcha The plugin strips code before esbuild parsing, so you cannot use `//#ifdef` inside already conditionally included code (e.g., inside an `if` block that might be removed). The comment must be in the original source and not in a branch that is fully removed. ↓
fix Ensure `//#ifdef` comments are in top-level or unreachable code only. Do not nest them inside JavaScript conditional statements that esbuild might evaluate.
gotcha The plugin automatically strips 'process.env.' from keys, but if your define object uses a different prefix (e.g., just 'FEATURE_X'), you must match that key in your comment exactly. ↓
fix Use the same keys as your `define` object but without 'process.env.' prefix. For example, if define = { 'process.env.FOO': true }, use `//#ifdef FOO`.
gotcha Negation syntax uses `!` before the condition: `//#ifdef !CONDITION`. It does NOT support `#ifndef`. ↓
fix Use `//#ifdef !MY_FLAG` instead of `#ifndef MY_FLAG`.
gotcha The plugin filters files using a base directory and exclude list. If your entry points are outside the base directory, the plugin may skip them silently. ↓
fix Set `baseDir` to the directory containing your entry points or adjust `exclude` to include the necessary paths.
gotcha The plugin runs on node_modules by default unless you pass an exclude list. The default exclude list includes node_modules, but if you override it, node_modules may be processed, causing slow builds or unexpected behavior. ↓
fix Always include 'node_modules' in your exclude list if using custom exclude array.
Install
npm install esbuild-plugin-ifdef yarn add esbuild-plugin-ifdef pnpm add esbuild-plugin-ifdef Imports
- ifdef wrong
const ifdef = require('esbuild-plugin-ifdef')correctimport { ifdef } from 'esbuild-plugin-ifdef' - default import wrong
import { ifdef } from 'esbuild-plugin-ifdef'correctimport ifdef from 'esbuild-plugin-ifdef' - TypeScript types wrong
import { IfdefOptions } from 'esbuild-plugin-ifdef'correctimport type { IfdefOptions } from 'esbuild-plugin-ifdef'
Quickstart
import { build } from 'esbuild';
import ifdef from 'esbuild-plugin-ifdef';
const define = {
'process.env.FEATURE_X': true,
'process.env.FEATURE_Y': false,
};
await build({
entryPoints: ['src/index.js'],
outfile: 'dist/bundle.js',
bundle: true,
plugins: [ifdef(define)],
});