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>红色文字</text>
</svg>
text {
fill: red;
}
有关 Parcel 如何处理 CSS 的详细信息,请参见 CSS 文档。
脚本
#可以在 SVG 中使用 <script>
元素引用脚本文件。您可以引用 JavaScript 文件,或任何可编译为 JavaScript 的文件,如 TypeScript、JSX 或 CoffeeScript。
应使用 type="module"
属性来指示文件是 ES 模块或 CommonJS 文件。如果省略,则引用的文件被视为经典脚本。有关详细信息,请参见经典脚本。SVG 中尚不原生支持 ES 模块,因此 Parcel 会将所有 JavaScript 编译为经典脚本,即使是以模块形式编写的。
note:SVG 在 <script>
元素中使用 href
属性,而不是 src
属性。
<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" />
note:通过 <image>
元素引用的 SVG 不会加载外部资源,如样式表、字体和其他图像,并且脚本和交互性被禁用。
有关 Parcel 如何处理图像的详细信息,请参见图像文档。
链接
#可以使用 <a>
元素在 SVG 文件中链接到其他网页或文件。Parcel 支持 href
和 xlink:href
属性。
<a href="circle.html">
<circle cx="50" cy="40" r="35" />
</a>
虽然默认情况下,从 SVG 文件引用的其他资源将在其编译后的文件名中包含内容哈希,但通过 <a>
元素引用的文件不会。这是因为这些 URL 通常是人类可读的,并且需要随时间保持稳定的名称。可以通过 Namer 插件覆盖捆绑包命名。
外部引用
#Parcel 支持在许多其他元素上通过 href
和 xlink:href
属性进行外部引用。更多详细信息请参见 MDN 文档。
<use href="fox.svg#path" stroke="red" />
<text>
<textPath href="fox.svg#path">
快速的棕色狐狸跳过了懒惰的狗。
</textPath>
</text>
在 fill
、stroke
、clip-path
等展示属性中通过 url()
函数引用的外部资源也受支持。
<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>
元素在 HTML 中嵌入外部 SVG,并启用外部引用、脚本、交互性和文本选择。使用 data
属性引用 SVG 文件。
<object data="interactive.svg" title="交互式 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>
SVG in CSS
#SVG can be referenced from CSS files using the url()
function. As with the <img>
element, SVGs in background images do not support external resources such as stylesheets, and scripting and interactivity is disabled.
.logo {
background: url("logo.svg");
}
You can also embed small SVGs in a CSS file using data URLs. Use the data-url:
scheme to do this, and Parcel will build the SVG and inline the result into the compiled CSS. See Bundle inlining for more details.
.logo {
background: url("data-url:logo.svg");
}
SVG in JavaScript
#SVG files can either be referenced as an external URL from JavaScript, inlined as a string, or converted to JSX for rendering in a framework like React.
URL references
#Parcel supports referencing SVG files using the URL
constructor. This example uses the result to render an <img>
element using JSX. This works the same way as described in External SVG above. You can use an <object>
element instead if the SVG is interactive or has external resources.
const logo = new URL('logo.svg', import.meta.url);
export function Logo() {
return <img src={logo} alt="logo" />;
}
See URL dependencies in the JavaScript docs for more details.
Inlining as a string
#SVG can be inlined as a string in JavaScript by importing it using the bundle-text:
scheme.
import svg from 'bundle-text:./logo.svg';
let logo = document.createElement('div');
logo.innerHTML = svg;
document.body.appendChild(logo);
See Bundle inlining for more details.
Importing as a React component
#The @parcel/transformer-svg-jsx
plugin can be used to import an SVG file as a React component. This transforms SVG into JSX, and optimizes it for file size. It's compatible with SVGR.
This plugin is not included in the default Parcel config, so you'll need to install it and add it to your .parcelrc
.
yarn add @parcel/transformer-svg-jsx --dev
You can either configure your .parcelrc
to convert all SVGs to JSX, or use a named pipeline to create a URL scheme that you can reference from a JavaScript import statement. This approach allows SVG files referenced from JavaScript to be converted to JSX, but SVGs referenced elsewhere to be kept as SVG files. Use the "..."
syntax to run the default SVG transformer first before converting the SVG to JSX.
{
"extends": "@parcel/config-default",
"transformers": {
"jsx:*.svg": ["...", "@parcel/transformer-svg-jsx"],
"jsx:*": ["..."]
}
}
import Icon from "jsx:./icon.svg";
export const App = () => <Icon />;
SVG to JSX can be configured in a .svgrrc
file, following the options documented by SVGR.
Note: Some options such as custom templates are not supported by @parcel/transformer-svg-jsx
. If these are needed, use @parcel/transformer-svg-react
instead, which uses SVGR instead of Parcel's Rust-based replacement.
Production
#In production mode, Parcel includes optimizations to reduce the file size of your code. See Production for more details about how this works.
Minification
#In production mode, Parcel automatically minifies your code to reduce the file sizes of your bundles. By default, Parcel uses oxvg to perform SVG minification, which is compatible with SVGO. To configure it, create a svgo.config.json
file in your project root directory. To see all the available configuration options for SVGO, see the official documentation.
{
"plugins": [
{
"name": "preset-default",
"params": {
"overrides": {
"inlineStyles": false
}
}
}
]
}
Note: svgo.config.js
, svgo.config.mjs
, and svgo.config.cjs
are also supported for JavaScript-based configuration, but should be avoided when possible because it reduces the effectiveness of Parcel's caching. Use a JSON based configuration format instead.
Previous versions of Parcel used SVGO as the default SVG minifier. To continue using SVGO instead of Parcel's builtin SVG minifier, you can use the @parcel/optimizer-svgo
plugin in your .parcelrc
. See Plugins for more information.