You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何仅用Babel在构建时编译模板字符串(不使用Webpack)

问题

我使用Babel(不搭配Webpack)转译ES6代码,希望在构建阶段直接计算代码中的模板字面量,注入版本号。代码中有如下导入语句:

const Component = React.lazy(() => import(`projectVersion${__VERSION__}/FooBar`))

我尝试了babel-plugin-inline-replace-variables、babel-plugin-transform-inline-environment-variables等插件,但编译后的代码会保留字符串拼接逻辑:

var Component = /*#__PURE__*/_react.default.lazy(function () {
  return Promise.resolve("projectVersion".concat("1", "/FooBar")).then(function (s) {
    return _interopRequireWildcard(require(s));
  });
});

这会导致运行时报错:Critical dependency: the request of a dependency is an expression。我需要的是版本号直接合并为固定字符串的编译结果,类似:

const Component = /* #__PURE__*/_react.default.lazy(() => Promise.resolve().then(() => _interopRequireWildcard(require('projectVersion1/FooBar'))))

补充信息:

  • 构建命令:babel src --out-dir build
  • 当前Babel配置:
module.exports = api => {
  api.cache(true)

  return {
    presets: [
      ['@babel/preset-env', {
        corejs: 3,
        targets: '> 0.25%, not dead',
        useBuiltIns: 'usage',
      }],
      ['@babel/preset-react', {
        runtime: 'automatic',
      }],
      '@babel/preset-typescript',
    ],
    plugins: [],
  }
}
解决方案

要让Babel在语法转换阶段就完全合并模板字面量为固定字符串,需要使用能直接替换并拼接完整字符串的插件,而非仅替换变量、保留拼接逻辑的工具。以下是两种可行方案:

方案一:使用babel-plugin-preprocessor

  1. 安装插件:
npm install babel-plugin-preprocessor --save-dev
  1. 修改Babel配置,添加插件并配置版本变量:
module.exports = api => {
  api.cache(true)

  return {
    presets: [
      ['@babel/preset-env', {
        corejs: 3,
        targets: '> 0.25%, not dead',
        useBuiltIns: 'usage',
      }],
      ['@babel/preset-react', {
        runtime: 'automatic',
      }],
      '@babel/preset-typescript',
    ],
    plugins: [
      ['babel-plugin-preprocessor', {
        macros: {
          __VERSION__: process.env.VERSION || '1' // 可直接写死版本,或从环境变量读取
        }
      }]
    ],
  }
}
  1. 运行构建命令(若用环境变量传版本,需先设置):
# Linux/macOS
VERSION=1 babel src --out-dir build

# Windows(PowerShell)
$env:VERSION='1'; babel src --out-dir build

该插件会在语法解析阶段直接合并模板字面量为完整字符串,编译后即可得到固定的require('projectVersion1/FooBar')形式。

方案二:自定义极简Babel插件

若不想额外安装依赖,可编写一个简单的自定义插件处理版本替换:

  1. 在项目根目录创建babel-plugin-replace-version.js:
module.exports = function({ types: t }) {
  return {
    visitor: {
      TemplateLiteral(path) {
        // 检查模板字面量是否包含__VERSION__标识符
        const hasVersion = path.node.expressions.some(expr => 
          t.isIdentifier(expr) && expr.name === '__VERSION__'
        );
        if (!hasVersion) return;

        // 获取版本号(可从环境变量或配置读取)
        const version = process.env.VERSION || '1';
        // 拼接所有模板片段与版本号
        const fullString = path.node.quasis.reduce((str, quasi, index) => {
          return str + quasi.value.cooked + (index < path.node.expressions.length ? version : '');
        }, '');
        
        // 将模板字面量替换为字符串字面量
        path.replaceWith(t.stringLiteral(fullString));
      }
    }
  };
};
  1. 修改Babel配置引入自定义插件:
module.exports = api => {
  api.cache(true)

  return {
    presets: [
      ['@babel/preset-env', {
        corejs: 3,
        targets: '> 0.25%, not dead',
        useBuiltIns: 'usage',
      }],
      ['@babel/preset-react', {
        runtime: 'automatic',
      }],
      '@babel/preset-typescript',
    ],
    plugins: [
      './babel-plugin-replace-version.js'
    ],
  }
}
  1. 设置环境变量后运行构建命令,即可得到期望的编译结果。

内容的提问来源于stack exchange,提问作者Patrick

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 10:20:33