SVG
SVG 是一种基于 XML 的矢量 2D 图形格式,支持交互性和动画。Parcel 包含对 SVG 的支持,作为单独的文件,嵌入在 HTML 中,或作为 JSX 导入到 JavaScript 文件中。
依赖项
#Parcel 检测 SVG 中大多数对其他文件的引用(例如 <script>
、<image>
和 <use>
)并对其进行处理。这些引用被重写,以便它们链接到正确的输出文件。
文件名相对于当前 SVG 文件解析,但您也可以使用 绝对 和 波浪号 指定符。有关详细信息,请参阅 依赖解析。
样式表
#可以通过 SVG 文档中的 xml-stylesheet
处理指令引用外部样式表。您可以引用 CSS 文件,或任何编译为 CSS 的其他文件,例如 SASS、Less 或 Stylus。
<?xml-stylesheet href="style.css" ?>
<svg viewBox="0 0 240 20" xmlns="http://www.w3.org/2000/svg">
<text>Red text</text>
</svg>
text {
fill: red;
}
有关 Parcel 如何处理 CSS 的详细信息,请参阅 CSS 文档。
脚本
#<script>
元素可用于从 SVG 引用脚本文件。您可以引用 JavaScript 文件,或任何编译为 JavaScript 的其他文件,例如 TypeScript、JSX 或 CoffeeScript。
type="module"
属性应用于指示文件是 ES 模块 或 CommonJS 文件。如果省略,则引用的文件将被视为经典脚本。有关此的更多信息,请参阅 经典脚本。ES 模块尚未在 SVG 中得到原生支持,因此 Parcel 将所有 JavaScript 编译为经典脚本,即使它们是作为模块编写的。
注意:SVG 使用 href
属性而不是 src
属性用于 <script>
元素。
<svg viewBox="0 0 240 80" xmlns="http://www.w3.org/2000/svg">
<circle cx="50" cy="50" r="50" fill="red" />
<script type="module" href="interactions.js" />
</svg>
let circle = document.querySelector('circle');
circle.addEventListener('click', () => {
circle.setAttribute('fill', 'blue');
});
有关 <script>
元素的更多信息,请参阅 MDN 文档,有关 Parcel 如何处理 JavaScript 的详细信息,请参阅 JavaScript 文档。
图像
#可以使用 <image>
元素将光栅图像或其他 SVG 嵌入 SVG 文件中。Parcel 识别 href
和 xlink:href
属性。
<image href="image.jpg" width="100" height="50" />
Parcel 的图像转换器还可以通过使用 查询参数 来调整图像大小和转换图像。
<image href="image.jpg?as=webp" width="100" height="50" />
注意:通过 <image>
元素引用的 SVG 不会加载外部资源(如样式表、字体和其他图像),并且脚本和交互性被禁用。
有关 Parcel 如何处理图像的详细信息,请参阅 图像 文档。
链接
#SVG 文件可以使用 <a>
元素链接到其他网页或文件。Parcel 支持 href
和 xlink:href
属性。
<a href="circle.html">
<circle cx="50" cy="40" r="35" />
</a>
虽然从 SVG 文件引用的其他资产默认情况下将在其编译后的文件名中包含 内容哈希,但 <a>
元素引用的文件不会。这是因为这些 URL 通常是人类可读的,并且需要随着时间的推移保持稳定的名称。捆绑包命名可以通过 命名器插件 覆盖。
外部引用
#Parcel 支持通过许多其他元素上的 href
和 xlink:href
属性进行外部引用。有关详细信息,请参阅 MDN 文档。
<use href="fox.svg#path" stroke="red" />
<text>
<textPath href="fox.svg#path">
Quick brown fox jumps over the lazy dog.
</textPath>
</text>
还支持通过 url()
函数在表示属性(如 fill
、stroke
、clip-path
以及许多其他属性)中引用的外部资源。
<circle
cx="50" cy="40" r="35"
fill="url(external.svg#gradient)" />
内联脚本和样式
#<script>
和 <style>
标记的文本内容也像独立文件一样进行处理,生成的捆绑包被插入回 SVG 文件中。使用 type="module"
属性(如上所述)来启用从内联脚本导入其他模块。
<svg viewBox="0 0 240 80" xmlns="http://www.w3.org/2000/svg">
<circle cx="50" cy="50" r="50" />
<style>
@import './style.scss';
</style>
<script type="module">
import {setup} from './interactions.ts';
let circle = document.querySelector('circle');
setup(circle);
</script>
</svg>
$fill: blue;
circle {
fill: $fill;
}
export function setup(element: SVGElement) {
element.addEventListener('click', () => {
element.setAttribute('fill', 'red');
});
}
通过 @import
引用的 CSS 文件,以及通过 import
引用的 JavaScript 将被捆绑到编译后的 SVG 文件中。有关如何引用外部文件,请参阅 样式表 和 脚本。
内联 style
属性
#可以使用任何 SVG 元素上的 style
属性来定义 CSS 样式。Parcel 将处理内联 CSS,并将结果插入回 style
属性中。这包括遵循引用的 URL,以及为目标浏览器转换现代 CSS。
<circle
cx="50" cy="40" r="35"
style="fill: url(external.svg#gradient)" />
HTML 中的 SVG
#HTML 中的 SVG 可以作为外部文件引用,也可以直接嵌入到 HTML 文档中。
外部 SVG
#可以通过多种方式从 HTML 引用 SVG 文件。最简单的方法是使用 <img>
元素,并使用 src
属性引用 SVG 文件。Parcel 将遵循引用并处理 SVG 及其所有依赖项。
<img src="logo.svg" alt="logo" />
如果您的 SVG 是静态的,这种方法非常有效。如果 SVG 引用外部资源(如其他 SVG、图像、字体、样式表或脚本),或包含任何交互性,则它将不起作用。您也不能通过 HTML 页面中的 CSS 更改 SVG 的样式,也不能使用 JavaScript 操作 SVG 的 DOM,并且 SVG 中的任何文本都无法被用户选中。
可以使用 <object>
元素将外部 SVG 嵌入 HTML,并启用外部引用、脚本、交互性和文本选择。使用 data
属性引用 SVG 文件。
<object data="interactive.svg" title="Interactive SVG"></object>
这也允许您通过 <object>
元素上的 getSVGDocument()
方法访问 SVG DOM。
let object = document.querySelector('object');
let svg = object.getSVGDocument();
let circle = svg.querySelector('circle');
circle.setAttribute('fill', 'red');
但是,使用 <object>
元素嵌入的 SVG 无法通过 HTML 页面上的 CSS 进行样式化。
内联 SVG
#SVG 可以直接内联到 HTML 中,而不是作为单独的文件引用。这允许 HTML 页面上的 CSS 对 SVG 元素进行样式化。Parcel 以与 SVG 位于单独文件中相同的方式支持嵌入式 SVG 中的外部引用。
<!DOCTYPE html>
<html>
<body>
<svg width="100" height="100">
<circle cx="50" cy="50" r="50" />
</svg>
<style>
circle {
fill: blue;
}
circle:hover {
fill: green;
}
</style>
</body>
</html>
CSS 中的 SVG
#可以使用 url()
函数从 CSS 文件引用 SVG。与 <img>
元素一样,背景图像中的 SVG 不支持外部资源(如样式表),并且脚本和交互性被禁用。
.logo {
background: url('logo.svg');
}
您还可以使用数据 URL 将小型 SVG 嵌入 CSS 文件中。使用 data-url:
方案执行此操作,Parcel 将构建 SVG 并将结果内联到编译后的 CSS 中。有关详细信息,请参阅 包内联。
.logo {
background: url('data-url:logo.svg');
}
JavaScript 中的 SVG
#SVG 文件可以作为外部 URL 从 JavaScript 引用,也可以作为字符串内联,或者转换为 JSX 以在 React 等框架中渲染。
URL 引用
#Parcel 支持使用 URL
构造函数引用 SVG 文件。此示例使用结果使用 JSX 渲染 <img>
元素。这与上面 外部 SVG 中描述的方式相同。如果 SVG 是交互式的或具有外部资源,您可以使用 <object>
元素。
const logo = new URL('logo.svg', import.meta.url);
export function Logo() {
return <img src={logo} alt="logo" />;
}
有关详细信息,请参阅 JavaScript 文档中的 URL 依赖项。
作为字符串内联
#SVG 可以通过使用 bundle-text:
方案导入它来作为字符串内联到 JavaScript 中。
import svg from 'bundle-text:./logo.svg';
let logo = document.createElement('div');
logo.innerHTML = svg;
document.body.appendChild(logo);
有关详细信息,请参阅 包内联。
作为 React 组件导入
#@parcel/transformer-svg-react
插件可用于将 SVG 文件作为 React 组件导入。这使用 SVGR 将 SVG 文件转换为 JSX。它还使用 SVGO 优化 SVG 以减小文件大小。
此插件未包含在默认的 Parcel 配置中,因此您需要安装它并将其添加到您的 .parcelrc
中。
yarn add @parcel/transformer-svg-react --dev
您可以配置您的 .parcelrc
将所有 SVG 转换为 JSX,或者使用命名管道来创建一个 URL 方案,您可以从 JavaScript 导入语句中引用它。这种方法允许从 JavaScript 引用的 SVG 文件被转换为 JSX,但其他地方引用的 SVG 保持为 SVG 文件。使用 "..."
语法在将 SVG 转换为 JSX 之前先运行默认的 SVG 转换器。
{
"extends": "@parcel/config-default",
"transformers": {
"jsx:*.svg": ["...", "@parcel/transformer-svg-react"]
}
}
import Icon from "jsx:./icon.svg";
export const App = () => <Icon />;
生产
#在生产模式下,Parcel 包含优化以减小代码的文件大小。有关此工作原理的详细信息,请参阅 生产。
缩小
#在生产模式下,Parcel 会自动缩小您的代码以减小捆绑包的文件大小。默认情况下,Parcel 使用 SVGO 执行 SVG 缩小。
要配置 SVGO,您可以在项目根目录中创建一个 svgo.config.json
文件。要查看 SVGO 的所有可用配置选项,请参阅 官方文档。
{
"plugins": [
{
"name": "preset-default",
"params": {
"overrides": {
"inlineStyles": false
}
}
}
]
}
注意:svgo.config.js
、svgo.config.mjs
和 svgo.config.cjs
也支持基于 JavaScript 的配置,但在可能的情况下应避免使用,因为它会降低 Parcel 缓存的有效性。请改用基于 JSON 的配置格式。