Remotion LabRemotion Lab
工具自訂 Webpack 設定

自訂 Webpack 設定

學習如何在 Remotion 中覆寫 Webpack 設定,啟用 MDX、TailwindCSS、SCSS、SVGR、GLSL、WebAssembly 等功能,以及在 CLI 和 Node.js API 中共用設定的最佳實踐。

Remotion 內建了自己的 Webpack 設定。你可以透過 reducer 模式覆寫它:傳入一個函式,接收現有設定並回傳新的設定。


在 CLI 渲染時覆寫設定

在你的 remotion.config.ts 設定檔中,呼叫 @remotion/cli/config 提供的 Config.overrideWebpackConfig()

// remotion.config.ts
import { Config } from "@remotion/cli/config";
 
Config.overrideWebpackConfig((currentConfiguration) => {
  return {
    ...currentConfiguration,
    module: {
      ...currentConfiguration.module,
      rules: [
        ...(currentConfiguration.module?.rules ?? []),
        // 在此加入更多 loader
      ],
    },
  };
});

提示: 使用 reducer 模式有助於型別安全、自動補全(auto-complete)、向前相容性,並保持完全的彈性 — 你可以只覆寫某個屬性,或是傳入全新的 Webpack 設定。


bundle()deploySite() 中使用

當你使用 Node.js API — bundle()(用於 SSR)或 deploySite()(用於 Lambda)時,Node.js API 不會讀取設定檔,因此你需要另外傳入 Webpack 覆寫函式。

建議將 Webpack 覆寫邏輯抽取到獨立的檔案,讓 CLI 設定與 Node.js 腳本都能共用:

// src/webpack-override.ts
import { WebpackOverrideFn } from "@remotion/bundler";
 
export const webpackOverride: WebpackOverrideFn = (currentConfiguration) => {
  return {
    ...currentConfiguration,
    // 在此加入你的覆寫設定
  };
};

在設定檔中引用:

// remotion.config.ts
import { Config } from "@remotion/cli/config";
import { webpackOverride } from "./src/webpack-override";
 
Config.overrideWebpackConfig(webpackOverride);

bundle() 中使用:

// my-script.ts
import { bundle } from "@remotion/bundler";
import { webpackOverride } from "./src/webpack-override";
 
await bundle({
  entryPoint: require.resolve("./src/index.ts"),
  webpackOverride,
});

deploySite() 中使用:

// my-script.ts
import { deploySite } from "@remotion/lambda";
import { webpackOverride } from "./src/webpack-override";
 
await deploySite({
  entryPoint: require.resolve("./src/index.ts"),
  region: "us-east-1",
  bucketName: "remotionlambda-c7fsl3d",
  options: {
    webpackOverride,
  },
  // ...其他參數
});

多個 Webpack 覆寫

若有多個覆寫需要套用,建議使用 **curry(串接)**的方式:

// remotion.config.ts
import { Config } from "@remotion/cli/config";
import { enableScss } from "@remotion/enable-scss";
import { enableTailwind } from "@remotion/tailwind-v4";
 
Config.overrideWebpackConfig((c) => enableScss(enableTailwind(c)));

從 Remotion v4.0.229 起,你也可以在設定檔中多次呼叫 Config.overrideWebpackConfig()(此方式僅限設定檔中使用):

// remotion.config.ts
import { Config } from "@remotion/cli/config";
import { enableScss } from "@remotion/enable-scss";
import { enableTailwind } from "@remotion/tailwind-v4";
 
Config.overrideWebpackConfig(enableScss);
Config.overrideWebpackConfig(enableTailwind);

實用設定片段

啟用 MDX 支援

安裝相依套件:

# npm
npm i --save-exact @mdx-js/loader @mdx-js/react
 
# pnpm
pnpm i @mdx-js/loader @mdx-js/react
 
# bun
bun i @mdx-js/loader @mdx-js/react
 
# yarn
yarn --exact add @mdx-js/loader @mdx-js/react

建立覆寫函式:

// src/enable-mdx.ts
import { WebpackOverrideFn } from "@remotion/bundler";
 
export const enableMdx: WebpackOverrideFn = (currentConfiguration) => {
  return {
    ...currentConfiguration,
    module: {
      ...currentConfiguration.module,
      rules: [
        ...(currentConfiguration.module?.rules
          ? currentConfiguration.module.rules
          : []),
        {
          test: /\.mdx?$/,
          use: [
            {
              loader: "@mdx-js/loader",
              options: {},
            },
          ],
        },
      ],
    },
  };
};

在設定檔中加入:

// remotion.config.ts
import { Config } from "@remotion/cli/config";
import { enableMdx } from "./src/enable-mdx";
 
Config.overrideWebpackConfig(enableMdx);

此外,在你的專案中建立一個宣告檔案以消除 TypeScript 錯誤:

// mdx.d.ts
declare module "*.mdx";

啟用 TailwindCSS 支援

參考 @remotion/tailwind-v4 套件的安裝說明。

啟用 SASS/SCSS 支援

最簡單的方式是使用 @remotion/enable-scss 套件,按照其文件指示安裝即可。

啟用 SVGR 支援(將 SVG 匯入為 React 元件)

安裝相依套件:

# npm
npm i --save-exact @svgr/webpack
 
# pnpm
pnpm i @svgr/webpack
 
# bun
bun i @svgr/webpack
 
# yarn
yarn --exact add @svgr/webpack

建立覆寫函式:

// src/enable-svgr.ts
import { WebpackOverrideFn } from "@remotion/bundler";
 
export const enableSvgr: WebpackOverrideFn = (currentConfiguration) => {
  return {
    ...currentConfiguration,
    module: {
      ...currentConfiguration.module,
      rules: [
        {
          test: /\.svg$/i,
          issuer: /\.[jt]sx?$/,
          resourceQuery: { not: [/url/] }, // 排除 *.svg?url 的情況
          use: ["@svgr/webpack"],
        },
        ...(currentConfiguration.module?.rules ?? []).map((r) => {
          if (!r) {
            return r;
          }
          if (r === "...") {
            return r;
          }
          if (!r.test?.toString().includes("svg")) {
            return r;
          }
          return {
            ...r,
            // 移除 Remotion 將 SVG 作為 URL 載入的設定
            test: new RegExp(
              r.test.toString().replace(/svg\|/g, "").slice(1, -1)
            ),
          };
        }),
      ],
    },
  };
};

在設定檔中加入:

// remotion.config.ts
import { Config } from "@remotion/cli/config";
import { enableSvgr } from "./src/enable-svgr";
 
Config.overrideWebpackConfig(enableSvgr);

記得重新啟動 Remotion Studio 讓變更生效。

啟用 GLSL 著色器匯入支援

安裝相依套件:

# npm
npm i --save-exact glsl-shader-loader glslify glslify-import-loader raw-loader
 
# pnpm
pnpm i glsl-shader-loader glslify glslify-import-loader raw-loader
 
# bun
bun i glsl-shader-loader glslify glslify-import-loader raw-loader
 
# yarn
yarn --exact add glsl-shader-loader glslify glslify-import-loader raw-loader

建立覆寫函式:

// src/enable-glsl.ts
import { WebpackOverrideFn } from "@remotion/bundler";
 
export const enableGlsl: WebpackOverrideFn = (currentConfiguration) => {
  return {
    ...currentConfiguration,
    module: {
      ...currentConfiguration.module,
      rules: [
        ...(currentConfiguration.module?.rules
          ? currentConfiguration.module.rules
          : []),
        {
          test: /\.(glsl|vs|fs|vert|frag)$/,
          exclude: /node_modules/,
          use: ["glslify-import-loader", "raw-loader", "glslify-loader"],
        },
      ],
    },
  };
};

在設定檔中加入:

// remotion.config.ts
import { Config } from "@remotion/cli/config";
import { enableGlsl } from "./src/enable-glsl";
 
Config.overrideWebpackConfig(enableGlsl);

在你的入口點(例如 src/index.ts)加入型別宣告:

declare module "*.glsl" {
  const value: string;
  export default value;
}

完成後,刪除 Webpack 快取並重新啟動 Remotion Studio:

rm -rf node_modules/.cache

啟用 WebAssembly 支援

Webpack 支援兩種 WebAssembly 模式:同步非同步。建議兩種都測試,選擇適合你使用的 WASM 函式庫的那一種。

同步模式:

// remotion.config.ts
import { Config } from "@remotion/cli/config";
 
Config.overrideWebpackConfig((conf) => {
  return {
    ...conf,
    experiments: {
      syncWebAssembly: true,
    },
  };
});

注意: 由於 Webpack 不允許在主 chunk 中使用同步 WebAssembly,你很可能需要使用 lazyComponent 而非 component 來宣告你的 Composition。

非同步模式:

// remotion.config.ts
import { Config } from "@remotion/cli/config";
 
Config.overrideWebpackConfig((conf) => {
  return {
    ...conf,
    experiments: {
      asyncWebAssembly: true,
    },
  };
});

啟用後,清除 Webpack 快取:

rm -rf node_modules/.cache

重新啟動後,你就可以使用 import 語句來匯入 .wasm 檔案。記得同樣將 Webpack 覆寫函式加入到你的 Node.js API 呼叫中。

修改 @jsxImportSource

// remotion.config.ts
import { Config } from "@remotion/cli/config";
 
Config.overrideWebpackConfig((config) => {
  return {
    ...config,
    module: {
      ...config.module,
      rules: config.module?.rules?.map((rule) => {
        // @ts-expect-error
        if (!rule?.use) {
          return rule;
        }
        return {
          // @ts-expect-error
          ...rule,
          // @ts-expect-error
          use: rule?.use.map((use) => {
            if (!use?.loader?.includes("esbuild")) {
              return use;
            }
            return {
              ...use,
              options: {
                ...use.options,
                jsxImportSource: "react",
              },
            };
          }),
        };
      }),
    },
  };
});

其他進階設定

  • 使用舊版 Babel Loader: 請參考「使用舊版 Babel 轉譯」文件。
  • 啟用 TypeScript 路徑別名: 請參考「TypeScript 別名」文件。

自訂設定檔位置

你可以在執行 CLI 指令時透過 --config 旗標指定自訂的設定檔位置:

npx remotion render --config=./my-custom-config.ts

remotion.config.ts 中匯入 ES Modules

此功能從 Remotion v4.0.117 起提供。

設定檔在 CommonJS 環境中執行。若要匯入 ES Modules,可以傳入非同步函式給 Config.overrideWebpackConfig()

// remotion.config.ts
import { Config } from "@remotion/cli/config";
 
Config.overrideWebpackConfig(async (currentConfiguration) => {
  const { enableSass } = await import("./src/enable-sass");
  return enableSass(currentConfiguration);
});

相關資源