捆绑包内联
Parcel 提供了多种将一个捆绑包的编译内容内联到另一个捆绑包中的方法。
将捆绑包作为文本内联
#bundle-text:
方案可用于将捆绑包的内容作为纯文本内联。Parcel 将正常编译已解析的文件,包括捆绑所有依赖项,然后将结果作为字符串内联到父捆绑包中。
这可以用于多种场景。例如,您可以内联编译后的 CSS 捆绑包,并使用结果在运行时注入样式标签。这在需要控制样式标签插入位置的情况下可能很有用,例如插入到 Shadow DOM 根节点。
import cssText from "bundle-text:./test.css";
// 注入 <style> 标签
let style = document.createElement("style");
style.textContent = cssText;
shadowRoot.appendChild(style);
作为数据 URL 内联
#data-url:
方案允许将捆绑包作为数据 URL 内联。已解析的文件将被编译(包括所有依赖项),并转换为数据 URL。如果文件是二进制格式,它将被 base64 编码,否则将作为 URI 编码。
一个可能有用的示例是在 CSS 文件中内联小图像。
.foo {
background: url(data-url:./background.png);
}
底层实现
#bundle-text:
和 data-url:
是使用命名管道在默认 Parcel 配置中实现的。@parcel/transformer-inline-string
转换器插件将编译后的资源标记为内联,这告诉 Parcel 不要将捆绑包写入磁盘,而是将其内联到父捆绑包中。为了实现数据 URL,使用 @parcel/optimizer-data-url
优化器插件将编译后的捆绑包转换为数据 URL。
在 Parcel 配置中,它看起来像下面这样。每个管道中的 "..."
告诉 Parcel 首先运行匹配文件的正常转换器,然后运行 @parcel/transformer-inline-string
。
{
"transformers": {
"bundle-text:*": ["...", "@parcel/transformer-inline-string"],
"data-url:*": ["...", "@parcel/transformer-inline-string"]
},
"optimizers": {
"data-url:*": ["...", "@parcel/optimizer-data-url"]
}
}
您可以创建自己的命名管道,以任何您想要的方式自定义内联,重用上述插件或创建自定义插件。有关更多详细信息,请参见 Parcel 配置。
另一个可能有用的 Parcel 插件是 @parcel/transformer-inline
。与 @parcel/transformer-inline-string
类似,它将资源标记为内联,但结果不会编码为字符串。这意味着如果内联的捆绑包包含代码,它将在父捆绑包中执行,而不是向用户返回字符串。如果您有一个需要在运行时解码捆绑包的自定义插件,这可能很有用。
例如,您可能想将文件内联为 ArrayBuffer,或某种其他自定义编码。这可以使用自定义优化器插件实现,该插件对捆绑包的输出进行后处理。
import { Optimizer } from "@parcel/plugin";
import { blobToBuffer } from "@parcel/utils";
export default new Optimizer({
async optimize({ contents }) {
let buffer = await blobToBuffer(contents);
return {
contents: `new Uint8Array(${JSON.stringify(Array.from(buffer))}).buffer`,
};
},
});
现在,您可以使用新插件定义一个命名管道,并将编译后的文件导入为数组缓冲区。
有关编写自定义插件的更多详细信息,请参见插件系统文档,有关命名管道的更多信息,请参见 Parcel 配置文档。
作为 Blob URL 内联
#您可能希望将捆绑包的内容作为 Blob URL 内联,这可以传递给浏览器中的许多 Web API。可以使用 @parcel/optimizer-blob-url
插件结合 @parcel/transformer-inline
来实现这一点。默认情况下不包含这些的命名管道,因此您需要在 .parcelrc
中创建一个。
{
"extends": "@parcel/config-default",
"transformers": {
"blob-url:*": ["...", "@parcel/transformer-inline"]
},
"optimizers": {
"blob-url:*": ["...", "@parcel/optimizer-blob-url"]
}
}
不经过转换直接内联
#在 JavaScript 中,可以在不通过 Parcel 转换器的情况下内联文件的内容。这可以通过 Parcel 静态分析的 fs
Node 模块完成。可以以多种不同的编码作为字符串内联,或作为 Buffer。有关更多详细信息,请参见 Node 模拟文档。
import fs from "fs";
const sourceCode = fs.readFileSync(__dirname + "/foo.js", "utf8");
在上面的示例中,sourceCode
变量将是 foo.js
的内容,不经过编译,即原始源代码而不是捆绑结果。
与其他工具集成
#由于捆绑包内联是 Parcel 特定的功能,您需要配置 TypeScript 或 Flow 等其他工具以支持它。有关如何执行此操作的详细信息,请参见依赖解析文档中的配置其他工具部分。