Skip to main content

Webpack 动态导入

在 Remotion 中常见的需求是从动态路径导入资源。这意味着有时您不知道应该提前导入的资源的确切路径,并且希望在运行时计算它。

这可能会成为 Webpack 中的一个意外障碍。在本页中,我们收集了一些处理动态资源的技巧。

以这种情况为例:

tsx
import { Img, useCurrentFrame } from "remotion";
 
export const DynamicImports: React.FC = () => {
const frame = useCurrentFrame();
const img = "./assets/image" + frame + ".png";
return <Img src={require(img)} />;
};
tsx
import { Img, useCurrentFrame } from "remotion";
 
export const DynamicImports: React.FC = () => {
const frame = useCurrentFrame();
const img = "./assets/image" + frame + ".png";
return <Img src={require(img)} />;
};

可能会导致:

bash
Error: 无法找到模块 './image0.png'
bash
Error: 无法找到模块 './image0.png'

即使文件存在。这是因为 Webpack 需要通过静态代码分析来确定应该捆绑哪些资源,但无法做到这一点。

推荐:使用 staticFile() 替代

我们建议将资源放在 public/ 文件夹中,并使用 staticFile() 来引用它。这种新方法不会受到潜在问题的影响。

正确编写动态表达式

虽然顶部的示例不起作用,但如果您将表达式放在 require()import() 语句中,Webpack 足够智能以使其起作用。在这种情况下,即使从未使用过该资源,Webpack 也会自动捆绑 assets/image 文件夹中的所有 .png 文件。

以下 可以 正常工作:

tsx
import { Img, useCurrentFrame } from "remotion";
 
export const DynamicImports: React.FC = () => {
const frame = useCurrentFrame();
return <Img src={require("./assets/image" + frame + ".png")} />;
};
tsx
import { Img, useCurrentFrame } from "remotion";
 
export const DynamicImports: React.FC = () => {
const frame = useCurrentFrame();
return <Img src={require("./assets/image" + frame + ".png")} />;
};

如果您想了解更多信息,请阅读Webpack 文档页面 关于此行为的内容。

在运行时导入资源

假设应该导入的资源完全未知,并且将在运行时读取,例如通过 input prop

tsx
import { getInputProps, Img } from "remotion";
 
const DynamicAsset: React.FC = () => {
const inputProps = getInputProps(); // {"imageSrc": "./assets/img0.png"}
return <Img src={require(inputProps.imageSrc as string)} />;
};
tsx
import { getInputProps, Img } from "remotion";
 
const DynamicAsset: React.FC = () => {
const inputProps = getInputProps(); // {"imageSrc": "./assets/img0.png"}
return <Img src={require(inputProps.imageSrc as string)} />;
};

这是无法工作的,因为 Webpack 不知道它必须捆绑哪些资源。因此,导入将失败。 与上述类似,您可以通过将表达式放在 require() 语句中来强制 Webpack 捆绑整个资源文件夹:

tsx
import { getInputProps, Img } from "remotion";
 
const DynamicAsset: React.FC = () => {
const inputProps = getInputProps(); // {"imageSrc": "img0.png"}
// Works!
return <Img src={require(("./assets/" + inputProps.imageSrc) as string)} />;
};
tsx
import { getInputProps, Img } from "remotion";
 
const DynamicAsset: React.FC = () => {
const inputProps = getInputProps(); // {"imageSrc": "img0.png"}
// Works!
return <Img src={require(("./assets/" + inputProps.imageSrc) as string)} />;
};

遇到困难了吗?

如果您仍然在导入资产方面遇到困难,请在Discord上联系我们或提交问题。我们很乐意听取您的意见,帮助您解决问题。