# @bonniernews/atlas-html-stream 中文文档

规范地址：https://npmcn.com/package/%40bonniernews/atlas-html-stream/

版本：2\.0\.1
npm 元数据更新时间：2026-08-26T12:06:43.498Z
中文译文更新时间：2026-11-08T10:58:50.402Z
软件包许可：Apache-2\.0

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40bonniernews/atlas-html-stream
原文对照：https://npmcn.com/package/%40bonniernews/atlas-html-stream/?lang=original
项目主页：https://github.com/BonnierNews/atlas-html-stream#readme
源码仓库：https://github.com/BonnierNews/atlas-html-stream

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：18.6 kB，6 个文件
- 模块格式：CommonJS
- TypeScript 类型：未声明
- Node.js 要求：\>=10\.1\.0
- 运行依赖：0 个
- 首次发布：2021-08-26T07:38:18.398Z
- 最新版本发布：2021-12-21T10:56:59.302Z
- 近 30 天下载量：2466（2026-10-09 至 2026-11-07，npm 官方下载统计）
- 已发布版本数：4（近 12 个月 0 个）

## 中文简介

一个超快的html-parser流输出标记,文本和关闭节点.

## 安装

```sh
npm install @bonniernews/atlas-html-stream
```

也可以使用：`pnpm add @bonniernews/atlas-html-stream`、`yarn add @bonniernews/atlas-html-stream`、`bun add @bonniernews/atlas-html-stream`

## README

# 地图集-html-流

[![Built latest](https://github.com/BonnierNews/atlas-html-stream/actions/workflows/build-latest.yaml/badge.svg)](https://github.com/BonnierNews/atlas-html-stream/actions/workflows/build-latest.yaml)

叉子为 [地图集-html-流](https://github.com/atlassubbed/atlas-html-stream) 它是一个超快的html-parser流 输出标记, 文本和关闭节点。 见 `CHANGELOG.md` 用于在分叉中引入的更改.

* * *

## 安装

```
npm install --save @bonniernews/atlas-html-stream
```

## 为什么

我不喜欢 htmlparser2 的流 API , 我想要一个 html 解析器,在默认情况下 连接文本节点的白空间。 我还想看看能不能写一个更快的解析器.

## 业绩

#### htmlparser 基准标记

以下基准是用我的本地机器 [htmlparser 基准标记](https://github.com/AndreasMadsen/htmlparser-benchmark)下调更好 :

```
atlas-html-stream: 4.91208 ms/file ± 6.08846
htmlparser2: 7.06549 ms/file ± 5.09643
```

我只测试了htmlparser2,因为它是最快的以流为基础的剖析器. 这个基准使用两个解析器的流出界面.

#### 内存使用量

一个简单的解析器需要身体在内存中,如果您的 HTML 非常大,则可能打破游戏. 这个解析器是一个流, 并且从使用块数据中受益 。 基本的想法是跟踪当前块 以及从上一个块溢出到当前块的任何东西。 例如,考虑以下两个块:

1.  `"first data chunk <di"`
2.  `"v>second chunk</div>"`

当解析器用第一个块完成时,它会认识到它需要坚持 `"<di"` 而只会冲出 `"first chunk "` 从记忆。 当解析器用第二块完成后,它会冲出记忆中的一切,因为不再有一个待决的节点.

## 实例

使用这个解析器很容易 `extends` 流界面 - 您只需要管道或写入 HTML 并听 `"data"` 事件:

### 有管道

建议使用流界面,因为它允许您消耗一定数量的内存(无论HTML大小):

```javascript
const { createReadStream } = require("fs");
const HtmlParser = require("@bonniernews/atlas-html-stream");
const myHtmlFile = createReadStream("./index.html");

myHtmlFile.pipe(new HtmlParser()).on("data", ({name, data, text}) => {
  if (text){
    // is a text node
    console.log(text);
  } else if (name && data){
    // is an opening tag with potential attributes
    console.log(name, data)
  } else {
    // is a closing tag
    console.log(name)
  }
}).on("end", () => {
  console.log("parsed all html")
})

```

### 无管道

除非您负担得起您的 HTML 完全存在于内存中,否则不推荐此选项 。 首先,我们将写一个小助手来取出流线界面:

```javascript
// helpers.js
const HtmlParser = require("@bonniernews/atlas-html-stream");
const parser = new HtmlParser();

const parseHtml = html => {
  const nodes = [];
  parser.on("data", data => nodes.push(data))
  parser.write(html)
  // resets the parser back to vanilla state
  parser.reset();
  return nodes;
}

module.exports = { parseHtml };
```

接下来,我们将使用我们的助手来分析我们的内幕html文件:

```javascript
const { readFileSync } = require("fs");
const { parseHtml } = require("./helpers");
const file = readFileSync("./index.html");
const nodes = parseHtml(file);
// do what you want with the parsed nodes.
```

### 注释、脚本和样式节点

上面的例子表明API是多么的微不足道,应该如此. 注释,脚本和样式节点被作为正则节点处理,因为它们发出打开和关闭标记. 主要的区别在于,这些节点内部的内容被作为单一的原始文本节点来对待,没有白空-collaps. 简而言之,让我们用我们的 `parseHtml` 帮助器在以下实例中的功能 :

#### 脚本/样式标签

```javascript
...
const scriptNodes = parseHtml(`
  <script src="./script.js">
    const myVar = 5;
  </script>
`);
scriptNodes.forEach(n => console.log(n))
// { name: 'script', data: { src: './script.js' } }
// { text: '\n    const myVar = 5;\n  ' }
// { name: 'script' }
```

样式标记的处理方式相同,但 `name` 属性的值为 `"style"`。 。 。 .

#### 注释标签

同样,这些也得到了同样的对待.

```javascript
const commentNodes = parseHtml(`
  <!--
    this is
    a comment
  -->
`)
commentNodes.forEach(n => console.log(n));
// { name: '!--', data: {} }
// { text: ' \n    this is \n    a comment \n  ' }
// { name: '!--' }
```

### 保持空白空间

默认情况下,解析器会将所有非标注/样式/comment 白空降为单个空格,如果您正在刮取并不在乎白空格,则白空格是有用的. 在某些情况下,你需要白空间。 你可以通过一个 `preserveWS` 选项到构造器,它将迫使解析器保留它在文本节点中找到的所有空白:

```javascript
const nodes = parseHtml(`
  This is some text

      <b>
        Hola
          </b>
`)
nodes.forEach(n => console.log(n));
// { text: "\n  This is some text\n\n      " }
// { name: "b", data: {} }
// { text: " \n        Hola\n          " }
// { name: "b" }
// { text: "  \n" }
```

然后,如果需要更具体化的话,可以处理节点。 请注意,这个例子不使用流线接口来简化,但是流线接口被高度推荐:

`myFile.pipe(new HtmlParser({preserveWS: true})).pipe(myTransform).on("data", node => {...})`

`myTransform` 可以有条件地检查文本节点,然后逐一处理.

## 待办事宜

#### `parseHtml` 帮助者

应否 `parseHtml` 除此包外, 还要导出 `HtmlParser`使用 `parseHtml` 在流媒体界面上不建议使用,但它似乎是对html字符串需要存在内存的情况的有效帮助.

#### 还要快

我想让这个东西更快。 解析本身需要了解 `3.5 ms/file` (使用时) [htmlparser 基准标记](https://github.com/AndreasMadsen/htmlparser-benchmark)在我的电话机上 将节点推为 `data` 增加40%左右的处理时间 `4.9 ms/file` - 这是无法避免的,因为我们 _请求_ 流媒体界面.

这个 `SeqMatcher` 减慢此解析器( 检查注释, 脚本和样式节点); 可能有一个更快的方法来处理这些特殊的节点 .

正在打开 `state` 首先是解析器,可能比先切换当前字符要快,但我还没有测试后者。 主要想法是,尽量减少每项指令所需的数量 `[state, char]` 根据每一对的概率 若为 `[TEXT, !whitespace]` 在“ 典型” html 中, 概率最高, 那么我们希望这对 需要最少的指令。 换句话说, `sum_i(probabilityOfPair_i*numSteps_i)` 应尽量减少.

我想是美国崩溃了 `SCRIPT`, (中文(简体) ), `STYLE` 财务报告和审定财务报表 `COMMENT` 变成单一状态 `SPECIAL` 可能会提高性能 而不是污染空间 `SeqMatchers` 每个人一开始都可以按需创建,无论哪个 `SPECIAL` 节点,我们正在解析, 把它们储存在一长串 以防我们看到相同的 `SPECIAL` 又是节点.

#### 动态解析器想法

什么定义了“典型的”html文档? 一组解析“ 典型” html 文档的指令对于“ 非典型” html 文档可能较慢, 其差异很大 `probabilityOfPair_i` 分发。 如果解析器可以利用当前文档的对子分布来动态地改变其飞行时的状况呢? 例如,如果我们被原始文本所压倒,那么检查状态会更快 `TEXT` 先说 或者,如果我们的文件几乎 _没有_ 原始文本,如果状态是 `TEXT` 最后一个 虽然动态剖析器听起来很有趣,但如果它增加了一吨间接费用,就可能不值得执行.

## 说明

#### 大文本节点

由于解析器在内存中一直等待节点的数据,一个大的文本节点会引发内存问题. 在绝大多数情况下,你不会碰到比块本身更大的文本节点。 如果这成为问题,可修改解析器以接受 `maxTextSize` 用于块块单个文本节点的参数。 现在,这是一个极端的边缘案件,没有处理.

#### 文档类型

道克类型节点作为任何其他节点处理. 投入 `"<!DOCTYPE html>"` 将产生以下数据事件: `{name: "!DOCTYPE", data: {html: ""}}`

#### 无值的属性

没有值的标记属性不被特殊处理;一个没有值的密钥会在节点的数据字段中有一个空字符串值. 我可以执行 `true` 作为默认值,但这似乎是可以很容易地由呼叫者完成的.

## 常见问题

### @bonniernews/atlas-html-stream 是什么？

一个超快的html-parser流输出标记,文本和关闭节点\.

### 如何安装 @bonniernews/atlas-html-stream？

在项目目录运行 npm install @bonniernews/atlas-html-stream，或使用 pnpm add / yarn add / bun add。

### @bonniernews/atlas-html-stream 支持 TypeScript 吗？

该包的 package\.json 没有声明类型入口。需要类型提示时，可以在 npm 上查找社区维护的 @types/bonniernews\_\_atlas-html-stream 是否存在。

### @bonniernews/atlas-html-stream 支持 ESM 还是 CommonJS？

以 CommonJS 形式发布，可以直接 require\(\)；在 ES Module 项目中也可以用 import 引入（Node\.js 会把 module\.exports 作为默认导出）。

### @bonniernews/atlas-html-stream 需要什么版本的 Node\.js？

package\.json 的 engines 字段要求 Node\.js \>=10\.1\.0。版本不符时 npm 默认只给出警告，开启 engine-strict 后会拒绝安装。

### @bonniernews/atlas-html-stream 可以商用吗？

@bonniernews/atlas-html-stream 使用 Apache-2\.0 许可。宽松许可：允许商业使用、修改和再分发，并附带明确的专利授权；分发时需保留许可与 NOTICE 文件，修改过的文件要注明改动。以上为概括，不构成法律意见，请以许可原文为准。

### @bonniernews/atlas-html-stream 的下载量有多少？

根据 npm 官方下载统计，@bonniernews/atlas-html-stream 在 2026/10/09 – 2026/11/07 这 30 天内被下载 2,466 次，日均约 82 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入，适合横向比较热度，不能直接等同于使用人数。

### @bonniernews/atlas-html-stream 还在维护吗？

最新版本 2\.0\.1 发布于 2021/12/21（4 年前）；至今共发布 4 个版本，其中过去 12 个月发布了 0 个；首次发布于 2021/08/26。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

