HTML

Parcel 默认包含对 HTML 的一流支持。HTML 文件通常是您提供给 Parcel 的入口文件,所有依赖项,包括 JavaScript、CSS、图像以及指向其他页面的链接,都将从那里开始构建您的整个应用程序。

依赖项

#

Parcel 检测 HTML 中大多数对其他文件的引用(例如 <script><img><video><meta property="og:image">)并对其进行处理。这些引用被重写,以便它们链接到正确的输出文件。

文件名相对于当前 HTML 文件解析,但您也可以使用 绝对波浪号 指定符。有关详细信息,请参阅 依赖项解析

样式表

#

<link rel="stylesheet"> 元素可用于从 HTML 中引用样式表。您可以引用 CSS 文件,或任何其他编译为 CSS 的文件,例如 SASSLessStylus

index.html
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="./style.less" />
</head>
<body>
<h1>My Parcel app</h1>
</body>
</html>
style.less
h1 {
color: darkslategray;
}

有关 Parcel 如何处理 CSS 的详细信息,请参阅 CSS 文档。

脚本

#

<script> 元素可用于从 HTML 中引用脚本文件。您可以引用 JavaScript 文件,或任何其他编译为 JavaScript 的文件,例如 TypeScriptJSXCoffeeScript

index.html
<!DOCTYPE html>
<html>
<head>
<script type="module" src="app.ts" />
</head>
<body>
<h1>My Parcel app</h1>
</body>
</html>
app.ts
console.log('Hello world!')

type="module" 属性应用于指示文件是 ES 模块CommonJS 文件。如果省略,则引用文件将被视为经典脚本。有关此内容的更多信息,请参阅 经典脚本

当使用 <script type="module"> 时,如果您的某些浏览器目标不支持 ES 模块,Parcel 将自动生成 <script nomodule> 版本。有关详细信息,请参阅 差异捆绑

Parcel 还支持 <script> 元素的 asyncdefer 属性。当脚本为 async 时,它可以在运行时以任意顺序加载。因此,Parcel 将异步脚本视为“隔离的”。这意味着异步脚本不能与页面上的其他脚本共享任何依赖项,这可能会导致模块重复。因此,最好避免 async 脚本,除非在特定情况下。

defer 属性与 async(非渲染阻塞)具有类似的效果,但保证脚本按其在 HTML 文件中定义的顺序执行。当使用 <script type="module"> 时,defer 会自动启用,无需声明。

有关 <script> 元素的更多信息,请参阅 MDN 文档,有关 Parcel 如何处理 JavaScript 的详细信息,请参阅 JavaScript 文档。

图像

#

Parcel 支持通过 <img> 元素引用的图像。src 属性可用于引用图像文件。

<img src="image.jpg" alt="An image">

Parcel 还支持 srcset 属性,该属性允许引用不同大小或分辨率的图像的多个版本。

<img src="[email protected]" srcset="[email protected] 2x" alt="logo">

此外,Parcel 支持 <picture> 元素,该元素允许通过 <source> 元素提供多个备用图像,从而获得更大的灵活性。

Parcel 的 图像转换器 还可用于从单个源文件生成图像的多个版本。这是通过使用 查询参数 来提供宽度、高度和格式来转换和调整源图像的大小来完成的。

<picture>
<source type="image/webp" srcset="image.jpg?as=webp&width=400, image.jpg?as=webp&width=800 2x">
<source type="image/jpeg" srcset="image.jpg?width=400, image.jpg?width=800 2x">
<img src="image.jpg?width=400" width="400">
</picture>
#

Parcel 支持 <a> 元素从 HTML 文件链接到另一个页面。

<a href="other.html">Other page</a>

<iframe> 元素可用于将 HTML 页面嵌入到另一个页面中。

<iframe src="iframe.html"></iframe>

虽然从 HTML 文件引用的其他资产默认情况下将在其编译后的文件名中包含 内容哈希,但通过 <a><iframe> 元素引用的文件不会。这是因为这些 URL 通常是人类可读的,并且需要随着时间的推移保持稳定的名称。捆绑包命名可以通过 命名器插件 覆盖。

视频、音频和其他资产

#

<video><audio><track><embed><object> 元素受支持。Parcel 处理引用的 URL 并将其重写为包含 内容哈希

Open Graph 和 Schema.org 元数据

#

Parcel 支持使用 <meta> 标签定义的 Open GraphTwitter CardsVKSchema.orgMicrosoft 固定网站 元数据。Parcel 处理这些元素中引用的图像和其他 URL,并将它们重写为包含 内容哈希

<meta property="og:image" content="100x100.png" />

JSON-LD

#

Parcel 支持通过 <script> 标签嵌入到 HTML 中的 JSON-LD 元数据。Parcel 处理 JSON-LD 中引用的图像和其他 URL,并将它们重写为包含 内容哈希。这是由 @parcel/transformer-jsonld 插件处理的,该插件将在需要时自动安装到您的项目中。

在此示例中,从 logo 对象引用的图像将由 Parcel 处理。

<script type="application/ld+json">
{
"@context": "http://schema.org",
"@type": "LocalBusiness",
"name": "Joe's Pizza",
"description": "Delicious pizza for over 30 years.",
"telephone": "555-111-2345",
"openingHours": "Mo,Tu,We,Th,Fr 09:00-17:00",
"logo": {
"@type": "ImageObject",
"url": "images/logo.png",
"width": 180,
"height": 120
}
}
</script>

Web 清单

#

<link rel="manifest"> 元素支持引用 Web 清单。这是一个 JSON 文件,其中包含有关应用程序的各种元数据,并允许将其安装到用户的首页或桌面。Parcel 处理此文件中 iconsscreenshots 键中引用的 URL。Web 清单可以写入 .json.webmanifest 文件。

<link rel="manifest" href="manifest.json">

内联脚本和样式

#

包含文本内容的 <script><style> 标签也像独立文件一样进行处理,生成的捆绑包被插入回 HTML 文件中。脚本标签上的 type="module" 属性的工作方式与上面描述的外部脚本相同。但是,如果您的某些浏览器目标不支持 ES 模块,Parcel 将仅将内联脚本编译为非模块脚本,并且不会输出 <script type="module">,以保持生成的 HTML 小巧。

index.html
<!DOCTYPE html>
<html>
<body>
<style>
@import "./style.scss";
</style>
<script type="module">
import value from "./other.ts";
console.log(value);
</script>
</body>
</html>

注意:谨慎使用此功能,因为大型内联脚本/样式可能会对(感知到的)加载速度产生不利影响。

内联 style 属性

#

可以在任何 HTML 元素上使用 style 属性来定义 CSS 样式。Parcel 将处理内联 CSS,并将结果插入回 style 属性中。这包括遵循引用的 URL(如背景图像),以及为您的目标浏览器转换现代 CSS。

<div style="background: url(background.jpg)">Hello!</div>

内联 SVG

#

Parcel 支持 HTML 中的 内联 SVG。通过 <image> 元素引用的图像和通过 <use> 元素引用的依赖项受支持,并且 SVG 中的内联脚本和样式也按上述方式处理。

<!DOCTYPE html>
<html>
<body>
<svg xmlns:xlink="http://www.w3.org/1999/xlink">
<rect x="10" y="10" width="50" height="50" fill="red" />
<use xlink:href="icon.svg"/>
</svg>
</body>
</html>

并行脚本和样式

#

当引用脚本或样式时,Parcel 有时需要将另一个依赖文件插入到编译后的 HTML 文件中。例如,当引用导入 CSS 文件的 JavaScript 文件时,Parcel 将在 <head> 中插入一个 <link> 元素,以与 JavaScript 并行加载此样式表。

index.html
<!DOCTYPE html>
<html>
<head>
<script type="module" src="app.js"></script>
</head>
<body>
<div id="root"></div>
</body>
</html>
app.js
import './app.css';

let app = document.createElement('div');
app.className = 'app';
app.textContent = 'My Parcel app!';
root.appendChild(app);
app.css
.app {
background: red;
}

编译后的 HTML

<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" src="app.f8e9c6.css">
<script type="module" src="app.26fce9.js"></script>
</head>
<body>
<div id="root"></div>
</body>
</html>

这也可能发生在脚本中。例如,如果两个页面依赖于同一个 JavaScript 库(例如 React 或 Lodash),它可能会被拆分为自己的捆绑包并单独加载。Parcel 将在编译后的 HTML 中插入一个 <script> 标签,以与该“共享捆绑包”并行加载。有关详细信息,请参阅 代码拆分

PostHTML

#

PostHTML 是一种使用插件转换 HTML 的工具。您可以通过使用以下名称之一创建配置文件来配置 PostHTML:.posthtmlrc(JSON,强烈推荐)、.posthtmlrc.js.posthtmlrc.mjs.posthtmlrc.cjsposthtml.config.jsposthtml.config.mjsposthtml.config.cjs

在您的应用程序中安装插件

yarn add posthtml-doctype --dev

然后,创建一个配置文件

.posthtmlrc
{
"plugins": {
"posthtml-doctype": { "doctype": "HTML 5" }
}
}

插件在 plugins 对象中作为键指定,选项使用对象值定义。如果插件没有选项,只需将其设置为一个空对象即可。

此示例使用 posthtml-include 来内联另一个 HTML 文件。

.posthtmlrc
{
"plugins": {
"posthtml-include": {}
}
}
index.html
<html>
<head>
<title>Home</title>
</head>
<body>
<include src="header.html"></include>
<main>My content</main>
</body>
</html>
header.html
<header>This is my header</header>

posthtml.config.js

#

对于某些需要将函数作为配置选项传递的插件,或者为了根据 process.env.NODE_ENV 设置插件,您需要使用 posthtml.config.js 文件进行配置,而不是 .posthtmlrc

注意:应尽可能避免使用 JavaScript 配置文件。这些会导致 Parcel 的缓存效率降低,这意味着每次重新启动 Parcel 时,您的所有 HTML 文件都将重新编译。为了避免这种情况,请改用基于 JSON 的配置格式(例如 .posthtmlrc)。

此示例使用 posthtml-shorten 通过自定义缩短函数来缩短 URL。

yarn add posthtml-shorten --dev
posthtml.config.js
module.exports = {
plugins: {
"posthtml-shorten": {
shortener: {
process: function (url) {
return new Promise((resolve, reject) => {
resolve(url.replace(".html", ""));
});
},
},
tag: ["a"], // Allowed tags for URL shortening
attribute: ["href"], // Attributes to replace on the elements
},
},
};
index.html
<html>
<head>
<title>Home</title>
</head>
<body>
<a href="http://example.com/test.html">Example</a>
</body>
</html>

生产环境

#

在生产环境中,Parcel 会包含优化措施来减小代码文件的大小。有关此工作原理的更多详细信息,请参阅 生产环境

压缩

#

在生产环境中,Parcel 会自动压缩代码以减小捆绑包的文件大小。默认情况下,Parcel 使用 htmlnano 来执行 HTML 压缩。要配置 htmlnano,您可以在项目根目录中创建一个 .htmlnanorc.htmlnanorc.json 文件。

例如,要保留 HTML 注释

.htmlnanorc
{
"removeComments": false
}

或者不压缩 SVG 元素。

.htmlnanorc
{
"minifySvg": false
}

注意.htmlnanorc.js.htmlnanorc.mjs.htmlnanorc.cjshtmlnano.config.jshtmlnano.config.mjshtmlnano.config.cjs 也支持基于 JavaScript 的配置,但应尽可能避免使用,因为这会降低 Parcel 缓存的有效性。请改用基于 JSON 的配置格式。