postcss - Postcss 8 插件:如何避免循环进入声明函数?
问题描述
您好 postcss 专家!
我正在将旧插件更新为 postCSS 8 API,但遇到了一些问题。
这个简单的 postCSS 插件陷入了一个无限循环:
module.exports = (options = {}) => {
return {
postcssPlugin: 'postcss-failing-plugin',
Declaration(decl) {
if (decl.prop.startsWith('--')) {
decl.prop = decl.prop.replace(/^--/, `--prefix-`);
}
},
};
};
module.exports.postcss = true;
文档提到了这种行为:
插件将重新访问您更改或添加的所有节点。如果您要更改任何子级,插件也会重新访问父级。只有
Once
并且OnceExit
不会再次调用。 写一个插件
但没有什么可以避免的。
如何在Declaration
不进行无限循环的情况下编辑值?
解决方案
您可能会反复向已添加前缀的自定义属性声明添加前缀,从而导致声明访问者无限运行。
您可以使用否定前瞻断言 (?!)
来匹配不以特定自定义属性前缀开头的自定义属性,即^--(?!prefix-)
.
const matcher = /^--(?!prefix-)/
const replacement = '--prefix-'
const ensure = value => value.replace(matcher, replacement)
// these _should not_ receive a new prefix
ensure('foo') // "foo"
ensure('prefix-foo') // "prefix-foo"
ensure('--prefix-foo') // "--prefix-foo"
// these _should_ receive a new prefixed
ensure('--foo') // "--prefix-foo"
ensure('--prefixable-foo') // "--prefix-prefixable-foo"
如适用于您的示例
module.exports = (options = {}) => {
return {
postcssPlugin: 'postcss-failing-plugin',
Declaration(decl) {
/** Matches a `--` property not beginning with `--prefix-`. */
const match = /^--(?!prefix-)/
if (match.test(decl.prop)) {
decl.prop = decl.prop.replace(match, `--prefix-`);
}
},
};
};
module.exports.postcss = true;
推荐阅读
- rest - 使用 Bitbucket REST API 时出现 curl 错误
- c# - EF Core 更新导航属性但 FK 隐藏属性未更新
- html - HTML&CSS + Twitter Bootstrap:左侧的任何表单元素和右侧的按钮(行部分)
- httpclientfactory - 在 .Net Core 2.1 类库中使用 HttpClientFactory
- c++ - gtk_text_buffer_create_tag 创建警告:“GtkTextTag”没有名为“\u0004”的属性
- javascript - VueJS多个嵌套路由不由路由器视图呈现
- docker - 使用 supervisord 在 docker 中生成 JSON 格式的 celery 日志
- docker - Docker compose 生成匿名卷而不是现有的命名卷
- dialogflow-es - 在 Dialogflow 中是否可以进行手动聊天?
- amazon-web-services - 如何从 S3 存储桶中的文件夹中删除带有后缀的图像