Skip to main content

Remotion 代码的即时编译

如果你已经将 Remotion 组件生成成字符串(例如 使用 LLMs),你可以在浏览器中编译它以显示实时预览。

🌐 If you have generated a Remotion component as a string (for example using LLMs), you can compile it in the browser to display a live preview.

const code = `
const MyComponent = () => {
  return <div style={{fontSize: 100}}>Hello</div>;
};
`;

要使此可执行文件,首先使用 @babel/standalone 进行转译:

🌐 To make this executable, first transpile it with @babel/standalone:

import * as Babel from '@babel/standalone';

const transpiled = Babel.transform(code, {
  presets: ['react', 'typescript'],
});

转译后,结果是这个字符串:

🌐 After transpilation, the result is this string:

'const MyComponent = () => { return React.createElement("div", {style: {fontSize: 100}}, "Hello"); };';

使用 JavaScript 的 Function 构造函数将字符串转换为真正的函数:

🌐 Use JavaScript's Function constructor to turn the string into a real function:

const createComponent = new Function('React', `${transpiled.code}\nreturn MyComponent;`);

这创建了一个等同于以下内容的函数:

🌐 This creates a function equivalent to:

function createComponent(React) {
  const MyComponent = () => { return React.createElement("div", ...); };

  return MyComponent;
}

调用此函数并传入实际的 React 库可以使组件可用。
组件代码被封装在内部,并且依赖(在此例中仅是 React)作为参数传入。

🌐 Calling this function and passing the actual React library makes the component available.
The component code is wrapped inside, and dependencies (in this case just React) are passed in as arguments.

const Component = createComponent(React);

添加 Remotion API

🌐 Adding Remotion APIs

仅仅使用 React 对动画来说是不够的。 Remotion 组件需要访问像 useCurrentFrame()<AbsoluteFill> 这样的 API。这些 API 的注入方式相同。

🌐 Just React won't be enough for animations.
Remotion components need access to APIs like useCurrentFrame() and <AbsoluteFill>. These are injected the same way.

代码中使用的所有 API 必须明确传入。

🌐 All APIs used within the code must be explicitly passed in.

这里有一个包含几个 Remotion API 的示例:

🌐 Here's an example with a few Remotion APIs:

import {AbsoluteFill, useCurrentFrame, spring} from 'remotion';

const createComponent = new Function('React', 'AbsoluteFill', 'useCurrentFrame', 'spring', `${transpiled.code}\nreturn MyComponent;`);

const Component = createComponent(React, AbsoluteFill, useCurrentFrame, spring);

每个参数名称都会在执行的代码中变成一个可用的变量。

🌐 Each parameter name becomes an available variable inside the executed code.

处理导入语句

🌐 Handling Import Statements

AI 生成的代码通常包括导入语句。 由于 API 是通过 Function 构造函数手动注入的,因此需要去掉这些导入语句:

🌐 AI-generated code typically includes import statements.
Since APIs are injected manually via the Function constructor, these imports need to be stripped:

// AI generates this:
import {useCurrentFrame, AbsoluteFill} from 'remotion';

export const MyComposition = () => {
  const frame = useCurrentFrame();
  return <AbsoluteFill>...</AbsoluteFill>;
};

导入部分已被移除,只提取了组件主体:

🌐 The imports are removed and just the component body is extracted:

// Step 1: Remove imports (these are injected manually)
const codeWithoutImports = code.replace(/^import\s+.*$/gm, '').trim();

// Step 2: Extract component body from "export const X = () => { ... };"
const match = codeWithoutImports.match(/export\s+const\s+\w+\s*=\s*\(\s*\)\s*=>\s*\{([\s\S]*)\};?\s*$/);
const componentBody = match ? match[1].trim() : codeWithoutImports;

// Step 3: Wrap it back into a component
const wrappedSource = `const DynamicComponent = () => {\n${componentBody}\n};`;

完整示例

🌐 Complete Example

在此示例中,React 组件由 <Player> 组件编译并渲染。

🌐 In this example, a React component is compiled and rendered by the <Player> component.

Preview.tsx
import {Player} from '@remotion/player'; import {useCompilation} from './use-compilation'; export const Preview: React.FC<{code: string}> = ({code}) => { const {Component, error} = useCompilation(code); if (error) { return <div style={{color: 'red'}}>Error: {error}</div>; } if (!Component) { return null; } return <Player component={Component} durationInFrames={150} fps={30} compositionWidth={1920} compositionHeight={1080} controls />; };

安全

🌐 Security

请注意,这段代码在浏览器的全局作用域中运行。它可以访问所有全局变量和函数。

🌐 Note that this code runs in the global scope of the browser.
It can access all global variables and functions.

对于生产应用,考虑在沙箱化的 <iframe> 中运行代码,并设置内容安全策略。
这超出了本指南的范围。

🌐 For production applications, consider running the code in a sandboxed <iframe>, and setting a content security policy.
This is outside the scope of this guide.

另请参阅

🌐 See Also