@eyeo/snippets

中文文档
2.18.0发布于 2026/10/23GPL-3.0-onlyES Module零依赖近 30 天下载 7244

eye/o snippets for Ads blocker

原始使用文档
文档目录11 节
  1. Snippets in a nutshell
  2. How to use this module
  3. How to reach our files directly after releases
  4. XPath 3.1 Support
  5. Used Third-Party Libraries
  6. Module Structure
  7. Architectural Overview
  8. Local development
  9. Tool versions (optional)
  10. Pre-commit hooks
  11. About Releases

@eyeo/snippets

This module goal is to provide a pre-bundled, pre-tested, and pre-optimized version of all snippets used in various mobile, or desktop, Ads blockers.

Snippets in a nutshell

Each snippet is represented as a filter text, defined through #$# syntax, followed by the snippet name and zero, one, or more arguments separated by a space or, when spaces are part of the argument, included in quotes.

! logs 1 2 3 in the console
evilsite.com#$#log 1 2 3

Multiple snippets can be executed per single filter by using a semicolon ; in between calls.

! logs 1 2 then 3 4 5 in the console
evilsite.com#$#log 1 2; log 3 4 5

The two kind of snippets

Snippets can run either as content script, which is a separate environment that replicates the DOM but never interferes with the JS that is running on the user page (and vice-versa), or as injected script that runs on the page among 3rd party and regular site's JS code.

The former kind is called isolated, because it runs sandboxed through the Web extension API, while the latter kind is called main, or injected, because it requires evaluation within the rest of the code that runs in the page, hence it's literally injected into such page.

Some snippet might be just an utility and, as such, be available in both the main and the isolated worlds. The way this snippet gets executed, and its possible side effects, remain confined within the isolated or main "world" it runs into.

How to use this module

This module currently provides the following exports:

  • @eyeo/snippets which includes both isolated and main, aliased also as injected, export names
  • @eyeo/snippets/isolated which includes only the isolated export
  • @eyeo/snippets/main, aliased as @eyeo/snippets/injected too, which includes only the main export
  • @eyeo/all which exports all snippets, as single callback for those environments where the isolated world is not supported, but standard ESM is used

Accordingly to the project needs, this module can be used in various ways.

How to reach our files directly after releases

Please always check our releases page and feel free to use URLs that point at our released branches, via https://gitlab.com/eyeo/snippets/-/raw/RELEASE_VERSION/dist/YOUR_FILE_HERE.js, where RELEASE_VERSION can be v0.5.0 or others, and YOUR_FILE_HERE is:

  • for Chromium based products, we have an ISOLATED world first artifact, reachable through this module's isolated-first.jst file
  • for WebKit based products, we a MAIN it all artifact, reachable through this module's snippets.js file

Both main.js and isolated.js are also there for possible testing purpose, containing the same code other files have.

Their source code is the exact same available in the webext folder and its source files.

XPath 3.1 Support

With the release of snippets module version 0.8.0, we introduced a new snippet called hide-if-matches-xpath3 that allows using XPath 3.1 functions to target ads. As XPath 3.1 is not supported natively by the browsers, the snippet requires injecting a dependency into the isolated context to work properly. This dependency is automatically injected using existing mechanisms for web extensions, if you are using eyeo's Web Extension Ad Blocking Toolkit. For Chromium based products, the dependency injection logic will be supported by eyeo Browser Ad-Filtering Solution .

As a Chromium-based product, if you are using the @eyeo/snippets module as a standalone library you would need to actively opt-in to be able to use the hide-if-matches-xpath3 snippet. You can keep using the isolated-first.jst artifact without any changes to your existing build steps. isolated-first.jst does not include hide-if-matches-xpath3 snippet but it will keep being supported. If you want to include the hide-if-matches-xpath3 snippet you would need to do two steps. First you would need to use isolated-first-all.jst artifact instead. Secondly you would need to implement the dependency injection logic so that the required dependencies are included before the snippet runs. You can do this by injecting the dependencies.jst artifact into the page and calling the dependency function: hideIfMatchesXPath3Dependency(). The snippet should work as expected after that.

Used Third-Party Libraries

Module Structure

The source folder contains all the files used to create artifacts in both dist folder and webext folder.

The former contains files used by 3rd party, non Web Extension related, projects, while the webext folder contains both optimized and source version of the files, so that it is possible to eventually offer a debugging mode instead of a production one.

Architectural Overview

This module is used by both Web Extensions and 3rd party partners and, even if the source code is always the same, these are different targets.

This section would like to explain, on a high level, the difference among these folders.

Webext

This folder contains all exports defined as ECMAScript standard module (aka ESM) within the package.json file.

Both main and isolated exports are pure functions that can get passed to the Manifest v3 scripting API.

These functions have been augmented like a read-only Map via a .has(snippetName) and .get(snipetName) where:

  • .has(...) returns true if the snippets is known for that specific world (either MAIN or ISOLATED)
  • .get(...) returns either null or a callback that is used as dependency for that very specific script

This approach gives us the ability to execute the minimum amount of code whenever such snippet is not needed for that specific page, as dependencies can indeed be quite big (in this case a stripped version of the TensorFlow Library + a binary model).

These callbacks are usually not used, nor needed, by other 3rd party snippets' consumers.

Dist

This folder contains files that can be embedded directly as part of any HTML page and executed right away through surrounding text:

// example of distFileContent source code
// distFileContent = readFileSync("dist/snippets.js")
// distFileContent = readFileSync("dist/isolated-first.jst")
page.evaluate(`(${distFileContent})(...${JSON.stringify([env, ...snippets])})`);

In the snippets.js case we have all snippets except the ML one embedded into a single callback, and all snippets run in the MAIN world.

The isolated-first.jst file instead executes right away any ISOLATED snippet and, if there's anything in the MAIN world to execute too, it contains itself some logic to append a script on the user page that runs MAIN world snippets right after, still passing along the very same arguments it received through [env, ...snippets] serialization.

The .jst extension means JS Template and it's been chosen because otherwise some toolchain might try to automatically minify such file and, because its content is not referenced anyway as that's just a callback that's not even executed right away, the minifier could decide to entirely drop its content.

We came up with a template extension to avoid minifiers embedded in toolchains (i.e. Android) to actually break our code once injected.

Other files in the dist folder offer, like it is for the webext one, full source code alternatives or any other possible alternative as just isolated.js or main.js could be.

Plase note these files in the dist folder are not exported as module but are used through release tags as explained in the previous session.

Local development

Install the build tooling and build the artifacts:

npm install
npm run build

npm run build regenerates dist/ and webext/ and then runs the tests. npm test runs the tests on their own.

Tool versions (optional)

Node and pre-commit versions are pinned in mise.toml. Install mise and run mise install in the repository root to get them, or install the same versions yourself.

Pre-commit hooks

The repository uses pre-commit to run the same security scanners locally that run in CI (semgrep and gitleaks). Install pre-commit, then enable the hooks once:

pre-commit install

The hooks then run automatically on every commit. To run them on demand against the whole repository:

pre-commit run --all-files

About Releases

We try to follow official guidance from GitLab through the following steps:

  1. be sure the internal source code and repository points at the release code we'd like to ship as module
  2. from main, run the release preparation script:
    ./prepare-release.sh [major|minor|patch] [path-to-abp-snippets/source]
    
    The script automates the following steps (and pauses at step 5 for manual intervention):
    • creates branch vX.X.X
    • bumps the version in package.json without creating a tag
    • imports source code files from the provided abp-snippets/source path (optional; can be run manually afterwards with npm run build.assets <path>)
    • pauses so you can make any manual changes if needed, such as:
      • registering new snippets in bundle/main.js (main context) or bundle/isolated.js (isolated context)
      • updating files outside of source
    • runs npm run build to create the artifacts
    • commits everything with message @eyeo/snippets vX.X.X
    • pushes the branch with git push --set-upstream origin vX.X.X
  3. when reviewing the MR, ignore dist, webext, and source — these will always differ
  4. in GitLab create a descriptive release MR using the release template
  5. once reviewed and approved, merge the release branch into main squashing commits without deleting the branch
  6. after merge, trigger manually the release job in the pipeline: it will take care of publishing the tags and create the gitLab release
  7. if the publishing command fails in the CI: checkout main, pull and if you are sure you have access rights and a 2FA protected account run:
    • npm login
    • npm publish

版本与发布记录

@eyeo/snippets 共发布 62 个版本,首次发布于 2022/03/30;过去 12 个月发布了 17 个版本。

版本发布日期距今
2.18.0latest2026/10/2321 天前
2.17.02026/10/121 个月前
2.16.02026/09/102 个月前
2.15.02026/08/172 个月前
2.14.02026/08/073 个月前
2.13.02026/07/144 个月前

关于 @eyeo/snippets 的常见问题

@eyeo/snippets 是什么?

eye/o snippets for Ads blocker

如何安装 @eyeo/snippets?

在项目目录运行 npm install @eyeo/snippets,或使用 pnpm add / yarn add / bun add。

@eyeo/snippets 支持 TypeScript 吗?

该包的 package.json 没有声明类型入口。需要类型提示时,可以在 npm 上查找社区维护的 @types/eyeo__snippets 是否存在。

@eyeo/snippets 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@eyeo/snippets 可以商用吗?

@eyeo/snippets 使用 GPL-3.0-only 许可。强 Copyleft:分发包含该代码的软件时,整个作品需以 GPL-3.0 兼容许可开源,并附带专利与反锁定条款。仅内部使用不触发此义务。以上为概括,不构成法律意见,请以许可原文为准。

@eyeo/snippets 的下载量有多少?

根据 npm 官方下载统计,@eyeo/snippets 在 2026/10/14 – 2026/11/12 这 30 天内被下载 7,244 次,日均约 241 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@eyeo/snippets 还在维护吗?

最新版本 2.18.0 发布于 2026/10/23(21 天前);至今共发布 62 个版本,其中过去 12 个月发布了 17 个;首次发布于 2022/03/30。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。