webpack-add-noopener-plugin
v1.0.1
Published
A webpack plugin that automatically adds rel="noopener" to all <a> tags with target="_blank"
Maintainers
Readme
webpack-add-noopener-plugin
简体中文
一个 Webpack 插件,自动为所有带有 target="_blank" 的 <a> 标签添加 rel="noopener" 属性,提高网站安全性。
- 适用场景:需要在构建阶段统一为 HTML 中的外链添加
rel="noopener",避免遗漏。 - 支持:Webpack 4 / 5,完整 HTML 或仅 body 片段的 HTML。
为什么需要这个插件?
当使用 target="_blank" 打开新标签页时,新页面可以通过 window.opener 访问原页面,这可能导致安全风险。添加 rel="noopener" 可以防止这种行为。
特色
- ✅ 自动检测并处理所有
target="_blank"的<a>标签 - ✅ 智能合并已有
rel值,不重复添加noopener - ✅ 支持多种 HTML 产物(完整文档或仅 body 内容)
- ✅ 兼容 Webpack 4 / 5,零额外依赖(仅使用 cheerio 解析)
- ✅ 可通过
verbose查看详细处理日志
安装
npm install --save-dev webpack-add-noopener-plugin或使用 yarn:
yarn add --dev webpack-add-noopener-plugin使用方法
基本用法
在 webpack.config.js 中引入并配置插件:
const AddNoopenerPlugin = require('webpack-add-noopener-plugin');
module.exports = {
// ... 其他配置
plugins: [
new AddNoopenerPlugin()
]
};配置选项
new AddNoopenerPlugin({
verbose: true, // 是否在控制台输出处理信息,默认 false
extensions: ['.html'] // 要处理的文件扩展名数组,默认 ['.html']
})选项说明
verbose (boolean, 默认:
false)- 设置为
true时,会在控制台输出处理的文件和处理数量
- 设置为
extensions (string[], 默认:
['.html'])- 指定要处理的文件扩展名数组
- 例如:
['.html', '.htm']
示例
- 最简配置:见
example/webpack.config.js - HTML 示例:见
example/src/index.html - 本地快速体验:
pnpm install # 或 npm install / yarn
pnpm test # 确认单测通过
pnpm exec webpack --config example/webpack.config.js构建后在 example/dist/index.html 中可以看到自动添加的 rel="noopener"。
工作原理(简述)
- 在
emit钩子阶段读取输出资源。 - 使用 cheerio 解析 HTML,定位
target="_blank"的<a>标签。 - 如果缺少
noopener,则追加到rel属性。 - 将更新后的内容写回构建产物。
处理前后对比
处理前:
<a href="https://example.com" target="_blank">链接</a>
<a href="https://example.com" target="_blank" rel="nofollow">链接</a>
<a href="https://example.com" target="_blank" rel="noopener">链接</a>处理后:
<a href="https://example.com" target="_blank" rel="noopener">链接</a>
<a href="https://example.com" target="_blank" rel="nofollow noopener">链接</a>
<a href="https://example.com" target="_blank" rel="noopener">链接</a>测试
运行测试:
npm test运行测试并生成覆盖率报告:
npm run test:coverage发布到 npm 与 GitHub
- 更新版本号:
npm version <patch|minor|major>(会自动打 tag)。 - 更新
CHANGELOG.md:记录本次变更。 - 验证质量:
npm test(如有需要可补充npm run test:coverage)。 - 发布到 npm:
npm publish(确保已登录并拥有发布权限)。 - 推送到 GitHub:
git push origin main --tags(或对应分支)。
发布前可执行以下自检:
- README 示例能否跑通(
example/中构建一次)。 peerDependencies/engines是否符合预期。- 打包体积是否仅包含
files声明的内容(npm pack --dry-run可查看)。
兼容性
- Node.js >= 12.0.0
- Webpack >= 4.0.0
许可证
MIT
贡献
欢迎提交 Issue 和 Pull Request!
更新日志
1.0.0
- 初始版本
- 支持自动添加
rel="noopener"到<a target="_blank">标签 - 支持自定义文件扩展名
- 支持 verbose 模式
English
webpack-add-noopener-plugin is a Webpack plugin that automatically adds rel="noopener" to all <a> tags with target="_blank", improving the security of your site.
- Use case: Enforce
rel="noopener"for external links at build time, so you don't miss any. - Supported: Webpack 4 / 5, both full HTML documents and body-only HTML fragments.
Why this plugin?
When you open a new tab with target="_blank", the new page can access the original page via window.opener, which may introduce security risks such as tabnabbing. Adding rel="noopener" prevents this behavior.
Features
- ✅ Automatically finds and processes all
<a>tags withtarget="_blank" - ✅ Smart merge of existing
relvalues without adding duplicatednoopener - ✅ Works with different kinds of HTML output (full document or body-only)
- ✅ Compatible with Webpack 4 / 5, with only
cheerioas HTML parser - ✅ Optional verbose logging for debugging
Installation
npm install --save-dev webpack-add-noopener-pluginor with yarn:
yarn add --dev webpack-add-noopener-pluginUsage
Basic usage
In your webpack.config.js:
const AddNoopenerPlugin = require('webpack-add-noopener-plugin');
module.exports = {
// ... other config
plugins: [
new AddNoopenerPlugin()
]
};Options
new AddNoopenerPlugin({
verbose: true, // whether to log detailed info, default false
extensions: ['.html'] // file extensions to process, default ['.html']
})Option details
verbose (boolean, default:
false)- When
true, prints processed file names and processed anchor count to the console.
- When
extensions (string[], default:
['.html'])- File extensions to process.
- Example:
['.html', '.htm']
Examples
- Minimal config: see
example/webpack.config.js - HTML example: see
example/src/index.html - Try it locally:
pnpm install # or npm install / yarn
pnpm test # run tests
pnpm exec webpack --config example/webpack.config.jsAfter the build, open example/dist/index.html and you will see rel="noopener" has been added automatically.
How it works
- Reads emitted assets in the
emithook. - Parses HTML with
cheerioand locates<a>tags withtarget="_blank". - If
noopeneris missing fromrel, it is appended. - Writes the updated content back to the corresponding asset.
Before & after
Before:
<a href="https://example.com" target="_blank">Link</a>
<a href="https://example.com" target="_blank" rel="nofollow">Link</a>
<a href="https://example.com" target="_blank" rel="noopener">Link</a>After:
<a href="https://example.com" target="_blank" rel="noopener">Link</a>
<a href="https://example.com" target="_blank" rel="nofollow noopener">Link</a>
<a href="https://example.com" target="_blank" rel="noopener">Link</a>Running tests
npm testGenerate coverage:
npm run test:coveragePublish to npm & GitHub
- Bump version:
npm version <patch|minor|major>(this also creates a git tag). - Update
CHANGELOG.mdto describe changes. - Ensure tests pass:
npm test(andnpm run test:coverageif needed). - Publish to npm:
npm publish(make sure you are logged in and have permission). - Push to GitHub:
git push origin main --tags(or your main branch).
Pre-publish checklist:
- Try the example in
example/to ensure the README instructions work. - Check
peerDependenciesandenginesinpackage.json. - Confirm published files via
npm pack --dry-run(should include only what you expect).
Compatibility
- Node.js >= 12.0.0
- Webpack >= 4.0.0
License
MIT
Contributing
Issues and PRs are welcome!
Changelog
1.0.0
- Initial release
- Support automatic adding
rel="noopener"to<a target="_blank">tags - Support custom file extensions
- Support verbose mode
