Babel Plugin Codegen
Babel-plugin-codegen is a build-time code generation utility for JavaScript and TypeScript projects, currently at stable version 4.1.5. It enables developers to execute synchronous Node.js code during the Babel compilation step, replacing sections of source code with the string output of that execution. Unlike `babel-plugin-preval`, which replaces values, `babel-plugin-codegen` replaces entire code blocks by transforming the generated string into an Abstract Syntax Tree (AST) node. It can be used directly as a Babel plugin or integrated via `babel-plugin-macros` for a more flexible, macro-style API, supporting template literals, special `codegen:` import comments, and `codegen.require()` calls. The package has a slow release cadence, with the last update in September 2021, suggesting a maintenance phase focusing on stability and bug fixes rather than active feature development. This tool is particularly useful for generating boilerplate, adapting to environmental configurations, or consolidating dynamic code into static bundles during the build process, reducing runtime overhead.
Common errors
-
ReferenceError: codegen is not defined
cause The `codegen` template tag or `codegen.require` was used, but the `babel-plugin-codegen/macro` is not active, or the main `babel-plugin-codegen` is not configured.fixIf using the macro, install `babel-plugin-macros` (`npm i -D babel-plugin-macros`) and add it to your Babel configuration's `plugins` array. If using the plugin directly, ensure 'babel-plugin-codegen' is in your Babel plugins. -
Error: Cannot find module './some-code.js'
cause File system operations like `require.resolve()` or `fs.readFileSync()` within the codegen script are executed at *build time* from the Node.js context where Babel runs, not relative to the source file.fixUse absolute paths or resolve paths relative to `__dirname` within your codegen script (e.g., `path.resolve(__dirname, './some-code.js')`) to ensure correct file resolution from the Babel execution context. -
SyntaxError: Unexpected token 'export' (or 'import')
cause The code generated by the `codegen` script produces module syntax (e.g., `export` or `import`) that is incompatible with the module system of the file it's inserted into, or with subsequent Babel transforms.fixEnsure the *output* string from your codegen script produces valid JavaScript/TypeScript for its final insertion context. If the target file is an ESM module, the codegen script should output ESM syntax (`export ...`). Verify your Babel presets handle the generated module syntax correctly.
Warnings
- breaking Version 4.0.0 dropped support for Node.js 8. Projects using this version or newer must run on Node.js 10 or higher.
- breaking Starting with version 3.0.0, `babel-plugin-codegen` no longer transpiles the code that is being generated. The code produced by your codegen script must be valid for your target environment, or you must transpile it ahead of time.
- gotcha All code executed by `babel-plugin-codegen` must run synchronously. Asynchronous operations (e.g., `async/await`, Promises) are not supported within the codegen script itself.
- gotcha Code run by `babel-plugin-codegen` is executed in a non-sandboxed Node.js environment. Be cautious when using third-party scripts or untrusted input, as they could execute arbitrary code with the same privileges as your build process.
- gotcha When using `babel-plugin-codegen/macro`, `babel-plugin-macros` must be explicitly installed and configured in your Babel setup, otherwise the `codegen` macro syntax will not be recognized.
Install
-
npm install babel-plugin-codegen -
yarn add babel-plugin-codegen -
pnpm add babel-plugin-codegen
Imports
- codegen
const codegen = require('babel-plugin-codegen/macro');import codegen from 'babel-plugin-codegen/macro';
- GeneratedModule
import GeneratedModule from './path/to/script.js';
import GeneratedModule from 'codegen:./path/to/script.js';
- Babel Plugin Configuration
module.exports = { plugins: ['babel-plugin-codegen'] };
Quickstart
{
"// babel.config.js": "",
"module.exports": "{\n plugins: [\n 'babel-plugin-macros', // Required to use `codegen/macro`\n // Alternatively, 'babel-plugin-codegen' if not using the macro\n ],\n presets: [\n '@babel/preset-typescript',\n ['@babel/preset-env', { targets: { node: 'current' } }],\n ],\n};",
"// src/dynamic-data.ts": "",
"export const GREETING = \"Hello from codegen!\";\nexport function getCurrentTime(): string {\n return new Date().toLocaleTimeString();\n}\n",
"// src/index.ts": "",
"import codegen from 'babel-plugin-codegen/macro';\nimport * as path from 'path';\n\n// This entire `codegen` block will be replaced at build time\n// with the content of `src/dynamic-data.ts`.\ncodegen`\n const fs = require('fs');\n const pathToCode = path.resolve(__dirname, './dynamic-data.ts');\n const fileContent = fs.readFileSync(pathToCode, 'utf8');\n // The script's module.exports becomes the replacement code.\n module.exports = fileContent;\n`;\n\n// After Babel processing, the above codegen block is replaced, and\n// these generated exports become directly available in the file.\nconsole.log(GREETING); // "Hello from codegen!"\nconsole.log(`Current time generated: ${getCurrentTime()}`);\n\n// To compile and run:\n// 1. npm install --save-dev @babel/cli @babel/core @babel/preset-env @babel/preset-typescript babel-plugin-codegen babel-plugin-macros\n// 2. npx babel src/index.ts --out-file dist/index.js --extensions ".ts"\n// 3. node dist/index.js"
}