
为 Remotion 切换传统 Babel 转译remotion/babel-loader 与 replaceLoadersWithBabel 全解析【免费下载链接】remotion Make videos programmatically with React项目地址: https://gitcode.com/GitHub_Trending/re/remotionRemotion 默认使用 esbuild-loaderWebpack或 SWCRspack进行转译以获得更快的构建速度但在遇到某些依赖 Babel 插件体系的场景时需要通过兼容包remotion/babel-loader提供的replaceLoadersWithBabel()将打包器的 JavaScript/TypeScript loader 替换回 Babel。读完本文你将掌握该包的安装方式、在remotion.config.ts与 Node.jsbundle()API 两种场景下的完整配置写法并能从源码层面理解 loader 替换的实现细节、默认转译目标的差异以及仓库中现有的集成测试如何验证替换生效。一、remotion/babel-loader 是什么remotion/babel-loader是 Remotion 仓库中的一个独立子包见 packages/babel-loader/package.json其官方描述就是 Babel loader for Remotion。它的作用单一而明确向 Remotion 的打包流程注入 webpack 风格的babel-loader规则替换掉默认的 esbuild/SWC 转译。从包定义可以看到几个关键事实包版本随 Remotion 主版本发布当前仓库中为4.0.520见 packages/babel-loader/package.json它以remotion/bundler为 peerDependency导出函数replaceLoadersWithBabel()接收的类型正是remotion/bundler中的BundlerConfiguration包自身直接声明了 Babel 全家桶依赖babel/core7.29.6、babel/preset-env7.23.2、babel/preset-react7.14.5、babel/preset-typescript7.23.2、babel-loader8.2.2、react-refresh0.18.0与webpack5.105.0见 packages/babel-loader/package.json。官方文档对它的定位是兼容性包compatibility package并明确建议一般情况下不应需要这样做我们鼓励你报告默认转译器的问题见 packages/docs/docs/legacy-babel-loader.mdx。换句话说这是一条为特殊场景保留的退路而非推荐的常规配置。二、安装--save-exact 与版本对齐READMEpackages/babel-loader/README.md给出的安装命令是npm install remotion/babel-loader --save-exact这里有两个要点必须用精确版本--save-exact。README 强调安装任何remotion/remotion/*包时所有相关包版本必须对齐到同一版本需要去掉版本号前的^字符。这是因为 Remotion 各包bundler、renderer、cli 等之间通过内部协议协作版本不一致会直接导致运行时报错。官方文档在示例中另外要求用户自行安装 Babel 侧依赖以便兼容用户自己项目里的 Babel 生态# npm npm i babel-loader babel/preset-env babel/preset-react # pnpm pnpm i babel-loader babel/preset-env babel/preset-react # yarn yarn add babel-loader babel/preset-env babel/preset-react三种包管理器的命令等价见 packages/docs/docs/legacy-babel-loader.mdx。三、场景一在 remotion.config.ts 中替换 loaderRemotion 的打包器覆盖采用 reducer 风格你收到默认配置对象返回修改后的配置对象。官方文档给出的最小可用示例packages/docs/docs/legacy-babel-loader.mdximport { Config } from remotion/cli/config; import { replaceLoadersWithBabel } from remotion/babel-loader; Config.overrideBundlerConfig((currentConfiguration) { return replaceLoadersWithBabel(currentConfiguration); });这段配置放在remotion.config.ts中即可对 Studio、渲染等所有走配置文件的路径生效。replaceLoadersWithBabel 到底做了什么阅读源码 packages/babel-loader/src/index.ts 可以确认其完整行为import type {BundlerConfiguration} from remotion/bundler; const envPreset [ require.resolve(babel/preset-env), { targets: { chrome: 85, }, }, ] as const; export const replaceLoadersWithBabel Configuration extends BundlerConfiguration, ( conf: Configuration, ): Configuration { return { ...conf, module: { ...conf.module, rules: (conf.module?.rules ?? []).map((rule) { // ... 仅重写匹配 .tsx / .jsx 的规则 }), }, }; };逐条拆解它的实现逻辑只动脚本规则其余规则原样保留。函数遍历conf.module.rules逐条检查rule.test?.toString()包含.tsx的规则被替换为 TypeScript/TSX 规则包含.jsx的规则被替换为 JavaScript/JSX 规则其余规则如 CSS、字体、媒体文件规则以及 Rspack 的...占位符一律不动见 packages/babel-loader/src/index.ts。TS/TSX 规则.tsx?使用babel-loader注入的 presets/plugins 为babel/preset-envtargets固定为chrome: 85——这与 Remotion 渲染所依赖的 Chromium 环境对齐babel/preset-reactruntime: automatic即不依赖手动import React的自动 JSX 运行时babel/preset-typescriptisTSX: true, allExtensions: true让.ts与.tsx都按 TSX 语义解析pluginsbabel/plugin-proposal-class-properties并且在conf.mode development时额外注入react-refresh/babel为 Studio 的快速刷新提供 Babel 侧支持见 packages/babel-loader/src/index.ts。JS/JSX 规则.jsx?使用同一套babel-loader与preset-envpreset-react(automatic)plugins 仅保留 class properties不包含 TypeScript preset见 packages/babel-loader/src/index.ts。源码中有一条注释值得注意All modules that use require.resolve need to be added to cli/src/load-config - external arraypackages/babel-loader/src/index.ts即 loader 内部用require.resolve锁定的每个模块CLI 在加载配置文件时都必须将其标记为 external避免被提前打包。从源码结构看这是该包能在remotion.config.ts这种被 CLI 自身打包加载的场景中运行的前提。与默认配置的对比要理解替换的差异可以参考默认配置。在 packages/bundler/src/webpack-config.ts 中Webpack 路径默认使用 esbuild-loader目标同样是 Chrome 85const esbuildLoaderOptions: LoaderOptions { target: chrome85, loader: tsx, implementation: esbuild, remotionRoot, };其中.tsx?规则在 development 模式下还会追加fast-refresh/loader.js见 packages/bundler/src/webpack-config.ts。replaceLoadersWithBabel的 TSX 规则刻意将react-refresh/babel放在use数组中保持与 fast-refresh loader 相同的相对顺序源码注释 Keep the order to match babel-loader见 packages/bundler/src/webpack-config.ts保证替换后热刷新行为一致。此外bundlerOverride是在基础配置构造完成、webpackOverride之前统一应用的见 packages/bundler/src/webpack-config.ts这解释了为什么 reducer 风格收到默认配置、返回修改后配置是官方推荐写法。值得注意的是Webpack 与 Rspack 两条路径共用同一个bundlerOverrideRspack 侧默认使用内置的builtin:swc-loaderreplaceLoadersWithBabel通过相同的规则字符串匹配逻辑对其生效因此该包对两种 bundler 都是可移植portable的——这也是集成测试用 portable overrides 命名的原因。四、场景二通过 Node.js API bundle() 传覆盖函数Node.js API 不读取remotion.config.ts因此覆盖函数必须直接传入。官方文档示例packages/docs/docs/legacy-babel-loader.mdximport { bundle } from remotion/bundler; import { replaceLoadersWithBabel } from remotion/babel-loader; await bundle({ entryPoint: require.resolve(./src/index.ts), bundlerOverride: (config) replaceLoadersWithBabel(config), });文档同时指出若要把bundle()生成的目录部署到 Lambda应将其传给remotion/lambda的deploySiteFromBundle()该函数实现在 packages/lambda/src/api/deploy-site-from-bundle.ts。五、真实用法参考组合其他 overrideRemotion 的示例工程展示了一个更完整的组合写法。在 packages/example/src/webpack-override.mjs 中replaceLoadersWithBabel与 SCSS、Skia、Tailwind 的 enable 函数以及自定义 MDX loader 规则嵌套组合/** type {import(remotion/bundler).BundlerOverrideFn} */ export const bundlerOverride (currentConfiguration) { const replaced (() { if (WEBPACK_OR_ESBUILD webpack) { const {replaceLoadersWithBabel} require(/* remotion/babel-loader */); return replaceLoadersWithBabel(currentConfiguration); } return currentConfiguration; })(); return enableScss( enableSkia( enableTailwind({ ...replaced, module: { ...replaced.module, rules: [ ...(replaced.module?.rules ?? []), {test: /\.mdx?$/, use: [{loader: mdx-js/loader, options: {}}]}, ], }, resolve: { ...replaced.resolve, alias: { ...replaced.resolve.alias, lib: path.join(process.cwd(), src, lib), }, }, }), ), ); };这个例子说明了 override 组合的两条惯例每个enable*函数和replaceLoadersWithBabel都遵循展开原配置 → 局部修改 → 返回的 reducer 模式可以任意嵌套追加自定义规则时保留原有rules数组...(replaced.module?.rules ?? [])避免覆盖掉 Babel 规则或 CSS 规则。六、集成测试如何验证替换真正生效仓库中的集成测试 packages/it-tests/src/bundle/rspack-portable-overrides.test.ts 专门验证了 Babel 替换与 SCSS、Tailwind v3 的组合测试名为 SCSS, Tailwind v3, and Babel helpers work through a shared Rspack overrideconst bundlerOverride: BundlerOverrideFn (configuration) { const withHelpers replaceLoadersWithBabel( enableScss( enableTailwind(configuration, { configLocation: path.join(fixtureDirectory, tailwind.config.cjs), }), ), ); // ...收集 tsx 规则中实际生效的 loader 列表 return withHelpers; };断言部分packages/it-tests/src/bundle/rspack-portable-overrides.test.tsexpect(scriptLoaders[0]).toContain(babel-loader); expect(scriptLoaders).not.toContain(builtin:swc-loader); expect(result).toContain(BABEL_LOADER_SENTINEL);即.tsx规则的第一个 loader 必须是babel-loader、不能残留 Rspack 的builtin:swc-loader且打包产物包含 fixture 中定义的哨兵字符串。这正是判断替换是否成功的可复现验证方式——检查最终 rule 的use链与产物内容。七、适用前提与限制小结适用前提使用 Remotion 4.x本仓库版本为4.0.520且所有remotion与remotion/*包版本严格对齐生效范围Config.overrideBundlerConfig作用于走配置文件的所有路径Node.js API 必须显式传bundlerOverride对 Rspack 同样有效replaceLoadersWithBabel匹配的是规则字符串而非 Webpack 专属 loader测试证明其在 RspackSWC下也能把脚本规则替换为 Babel开发模式差异仅mode development时注入react-refresh/babelproduction 构建不会包含该插件官方立场该包是兼容性退路遇到默认 esbuild/SWC 转译问题时官方建议优先提 issue 反馈而非切换到 Babel。八、关键文件索引内容路径包 README安装说明packages/babel-loader/README.md核心实现replaceLoadersWithBabel()packages/babel-loader/src/index.ts包依赖与版本packages/babel-loader/package.json官方文档legacy-babelpackages/docs/docs/legacy-babel-loader.mdx默认 Webpack 配置与 esbuild-loaderpackages/bundler/src/webpack-config.ts组合 override 示例packages/example/src/webpack-override.mjsBabel 替换集成测试packages/it-tests/src/bundle/rspack-portable-overrides.test.tsLambda 部署入口packages/lambda/src/api/deploy-site-from-bundle.ts【免费下载链接】remotion Make videos programmatically with React项目地址: https://gitcode.com/GitHub_Trending/re/remotion创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考