{"id":15478,"library":"preval.macro","title":"preval.macro: Build-Time Code Evaluation","description":"preval.macro is a Babel macro designed to pre-evaluate code at build-time, embedding the results directly into the JavaScript bundle. It leverages `babel-plugin-preval` under the hood, offering a streamlined way to achieve static code evaluation without direct Babel plugin configuration, thanks to its integration with `babel-plugin-macros`. The current stable version is 5.0.0. This package is particularly useful for tasks like inlining static file contents, injecting environment variables known at build time, or pre-calculating complex values, thereby reducing runtime computations and potentially optimizing bundle size. Its release cadence is generally aligned with updates to the broader Babel ecosystem and its upstream dependencies, `babel-plugin-preval` and `babel-plugin-macros`.","status":"active","version":"5.0.0","language":"javascript","source_language":"en","source_url":"https://github.com/kentcdodds/preval.macro","tags":["javascript","babel-macros","babel-plugin-macros"],"install":[{"cmd":"npm install preval.macro","lang":"bash","label":"npm"},{"cmd":"yarn add preval.macro","lang":"bash","label":"yarn"},{"cmd":"pnpm add preval.macro","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"preval.macro is a macro that relies on babel-plugin-macros to function. It must be installed and configured as a devDependency.","package":"babel-plugin-macros","optional":false}],"imports":[{"note":"This is a default import. Attempting to destructure it will fail, as `preval.macro` exports a default function that expects a tagged template literal.","wrong":"import { preval } from 'preval.macro'","symbol":"preval","correct":"import preval from 'preval.macro'"},{"note":"For CommonJS environments, use the default require pattern. The macro itself evaluates at build time via Babel, so the runtime import merely serves as a marker.","wrong":"const { preval } = require('preval.macro')","symbol":"preval (CommonJS)","correct":"const preval = require('preval.macro')"},{"note":"The core usage involves a tagged template literal. The content within the backticks (` `) is executed as a Node.js module during the build process, and its `module.exports` value is then embedded.","wrong":"preval('module.exports = \"some_value\"')","symbol":"Code Block (Tagged Template Literal)","correct":"preval`module.exports = 'some_value'`"}],"quickstart":{"code":"/*\n  1. Install dependencies:\n  npm install --save-dev @babel/cli @babel/core babel-plugin-macros preval.macro\n\n  2. Create `.babelrc.js` in your project root:\n  module.exports = {\n    plugins: ['macros'],\n  };\n\n  3. Create `src/index.js`:\n*/\n\nimport preval from 'preval.macro';\n\n// Pre-evaluate a simple arithmetic expression during build\nconst sum = preval`module.exports = 10 + 20`;\nconsole.log('The sum is:', sum); // During build, 'sum' becomes 30\n\n// Pre-evaluate and embed an environment variable (e.g., BUILD_ID=abc)\n// To see this in action, run Babel with an environment variable:\n// BUILD_ID=123 babel src --out-dir dist\nconst buildId = preval`module.exports = process.env.BUILD_ID || 'N/A'`;\nconsole.log('Build ID:', buildId); // 'buildId' becomes '123' at build time\n\n// Read a file at build-time and embed its content\n// Create a file `src/data.txt` with content: 'Hello Preval World!'\nconst fileContent = preval`\n  const fs = require('fs');\n  const path = require('path');\n  module.exports = fs.readFileSync(path.resolve(__dirname, 'data.txt'), 'utf8');\n`;\nconsole.log('File Content:', fileContent); // 'fileContent' becomes 'Hello Preval World!'\n\n/*\n  4. Create `src/data.txt` in the same directory as `src/index.js`\n     with content: `Hello Preval World!`\n\n  5. Compile with Babel from your project root:\n  BUILD_ID=123 babel src --out-dir dist\n\n  6. Run the compiled output:\n  node dist/index.js\n  // Expected output:\n  // The sum is: 30\n  // Build ID: 123\n  // File Content: Hello Preval World!\n*/","lang":"javascript","description":"Demonstrates how to use `preval.macro` to evaluate arithmetic expressions, inject environment variables, and read file contents at build-time, embedding the results directly into the output JavaScript bundle."},"warnings":[{"fix":"Ensure that any code within `preval` blocks is Node.js-compatible and does not rely on browser-specific globals or runtime contexts. The environment is akin to running a standard Node.js script.","message":"`preval.macro` operates at build-time, meaning the code inside the tagged template literal is executed by Node.js during your Babel compilation step, not in the browser or Node.js runtime. This implies browser-specific globals like `window` or DOM APIs are unavailable within preval'd code.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Always ensure `babel-plugin-macros` is installed and configured correctly in your Babel configuration (e.g., `.babelrc.js` or `babel.config.js`). Refer to the official `babel-plugin-macros` documentation for the latest setup instructions, especially after major Babel upgrades.","message":"Older versions of `babel-plugin-macros` (and indirectly `preval.macro`) might behave differently or require specific configuration. As the Babel ecosystem evolves, ensure your `babel-plugin-macros` setup is current.","severity":"breaking","affected_versions":">=3.0.0"},{"fix":"Always trigger a full build process whenever the external data sources consumed by `preval` (such as environment variables or static files) are updated to ensure the latest values are embedded.","message":"The values generated by `preval.macro` are hardcoded into your bundle at compile time. If the source of these values (e.g., environment variables, static files) changes after compilation, your application will continue to use the stale, embedded data.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Use `preval.macro` judiciously for static, small-to-medium data points. For very large assets, dynamic data, or performance-critical I/O, consider traditional runtime fetching or build processes that generate separate asset files.","message":"Executing complex or I/O-heavy operations (e.g., reading very large files, extensive computations) within `preval` can significantly increase your build times. Overuse can also lead to larger bundle sizes if substantial data structures or files are embedded directly.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-04-21T00:00:00.000Z","next_check":"2026-07-20T00:00:00.000Z","problems":[{"fix":"Install `babel-plugin-macros` as a `devDependency` (`npm install --save-dev babel-plugin-macros`) and add it to your Babel configuration (e.g., `plugins: ['macros']` in `.babelrc.js` or `babel.config.js`).","cause":"The `babel-plugin-macros` plugin is not installed or incorrectly configured in your Babel setup, preventing the macro from being processed.","error":"ReferenceError: preval is not defined"},{"fix":"Ensure `preval` is used as a tagged template literal: `preval`module.exports = 'your_value'`.","cause":"Attempting to call `preval` as a regular function (e.g., `preval('some code')`) or passing arguments directly, instead of using it as a tagged template literal.","error":"TypeError: preval is not a function"},{"fix":"Verify that the file path is correct and accessible relative to the file containing the `preval` macro during the build process. Use `path.resolve(__dirname, 'your-file.txt')` for more robust, absolute path resolution.","cause":"A file path referenced within the `preval` tagged template literal (e.g., using `fs.readFileSync`) is incorrect or the specified file does not exist at the time the Babel build process runs.","error":"Error: ENOENT: no such file or directory, open '/path/to/your/file.txt'"},{"fix":"Use the default import for `preval`: `import preval from 'preval.macro'` for ESM or `const preval = require('preval.macro')` for CommonJS.","cause":"Incorrectly using destructuring for the `preval` import or require, e.g., `import { preval } from 'preval.macro'`.","error":"SyntaxError: Unexpected token '{'"}],"ecosystem":"npm"}