Aurelia:完整性检查模板 html?
Aurelia: sanity check template html?
我最近问为什么 在 Aurelia 的模板系统中;这是因为自闭元素无效 html。
然而,今天我又犯了同样的错误(这次是小部件),我一直在摸不着头脑,为什么内容丢失了。
问题:在gulp任务中是否可以清理Aurelia模板html?
我试过使用:
gulp-htmlhint
: 无法在自闭元素上出错
gulp-htmllint
: 无法配置;使用默认设置,它会因错误而爆炸。
gulp-html5-lint
:看起来不可配置,它讨厌 aurelia 的属性。
鉴于还没有人回答;我提出 "Better than nothing (maybe)"™ 解决方案。
var gulp = require('gulp');
var gutil = require('gulp-util');
var voidTags = [
'area', 'base', 'br', 'col', 'embed', 'hr',
'img', 'input', 'keygen', 'link', 'meta',
'param', 'source', 'track', 'wbr'];
var checkSelfClose = function () {
function sanitize(file, cb) {
var dirty = String(file.contents);
var matches = dirty.match(/(?:\<[\/\\-\"\'!() a-z=.]+\/\>)/g);
var customTags = [];
if(matches && matches.length > 0)
{
matches.forEach((match)=>{
var tag = match.match(/[a-z\-]+/)[0];
if(voidTags.indexOf(tag) < 0)
customTags.push(tag);
});
};
if(customTags.length > 0)
gutil.log('WARNING', 'found ' + customTags.length + " non-void self-closed tags in",
file.path.substring(file.cwd.length, file.path.Length),
"tags:", customTags
);
cb(null, file);
}
return require('event-stream').map(sanitize);
}
gulp.task('build-html', function () {
return gulp.src('source/**/*.html')
.pipe(checkSelfClose())
.pipe(gulp.dest('output'));
});
测试:
<template bindable="items">
<require from="./menu-bar.css" />
<custom-element/>
<custom-element click.delegate="subitem.execute()" repeat.for="item of items" />
<custom-element-moo></custom-element-moo>
<br>
<br/>
<div id="blahblah"/>
<button class="dropbtn"/>
</template>
gulp 输出:
[更新]
将其留在这里是因为它是一种快速、肮脏且无依赖性的检查自关闭标签的方法;确实回答了这个问题,可能会有用。
我们可以用 parse5 解决查找和报告 self-closing 元素的问题。它有一个应该非常健壮的 SAXParser class(parse5 符合 html5 标准)。解析器在找到 start-tags 后引发一个事件,该事件包含一个关于找到的标签是否自行关闭的布尔值。
var parser = new SAXParser();
parser.on("startTag", (name, attrs, selfClosing)=>{
if(selfClosing){
//check if name is void, if not report error
}
});
parser.push(html);
为了利用此功能,我设置了一个项目,可用于帮助使用上述方法清理 html。开发的 lint 工具能够 运行 一系列规则,收集任何错误并将它们 return 作为 Promise。然后可以将此报告给用户。
原版Html/Templates
template-lint 构成 tool-set 的基础。它由 Linter 和一些基本规则组成:
- SelfClose - 确保 non-void 元素不会 self-close
- 解析器 - returns 未闭合或 ill-matched 元素的错误,在解析期间捕获
gulp-template-lint 是 template-lint 的 gulp 包装器,可以像这样使用:
var gulp = require('gulp');
var linter = require('gulp-template-lint');
gulp.task('build-html', function () {
return gulp.src(['source/**/*.html'])
.pipe(linter())
.pipe(gulp.dest('output'));
});
例子
给出以下 html:
<template>
<custom-element/>
<svg>
<rect/>
</svg>
<div>
<div>
</div>
</template>
产生:
注意:self-closed <rect/>
不会产生错误。 svg 元素包含 xml 并且规则可以根据范围进行区分。
Aurelia 模板
我最初制作了 aurelia-template-lint,但决定将可重用(aurelia 之外的)组件拆分为 template-lint。虽然两者目前是分开的,但我会在适当的时候让 aurelia-template-lint 扩展到 template-lint。目前有一些 proof-of-concept 条规则:
- SelfClose - 确保 non-void 元素不会 self-close
- 解析器 - returns 未闭合或 ill-matched 元素的错误,在解析期间捕获
- 模板 - 确保根是一个模板元素,并且存在的模板元素不超过一个
- RouterView - 不允许 router-view 元素包含内容元素
- 要求 - 确保要求元素具有 'from' 属性
有一个 gulp 包装器可以通过以下方式安装:
npm install gulp-aurelia-template-lint
并在 gulp 构建中使用:
var linter = require('gulp-aurelia-template-lint');
gulp.task('lint-template-html', function () {
return gulp.src('**/*.html')
.pipe(linter())
.pipe(gulp.dest('output'));
});
这将使用默认的规则集。
例子
使用以下 ill-formed aurelia 模板进行简单测试:
<link/>
<template bindable="items">
<require from="foo"/>
<require frm="foo"/>
<br/>
<div></div>
<router-view>
<div/>
</router-view>
</template>
<template>
</template>
输出:
改进
需要做很多改进;例如,有几种方法可以在不使用 <template>
标签的情况下定义原始模板。 Aurelia 还引入了很多可以清理的特定属性。
我最近问为什么
然而,今天我又犯了同样的错误(这次是小部件),我一直在摸不着头脑,为什么内容丢失了。
问题:在gulp任务中是否可以清理Aurelia模板html?
我试过使用:
gulp-htmlhint
: 无法在自闭元素上出错gulp-htmllint
: 无法配置;使用默认设置,它会因错误而爆炸。gulp-html5-lint
:看起来不可配置,它讨厌 aurelia 的属性。
鉴于还没有人回答;我提出 "Better than nothing (maybe)"™ 解决方案。
var gulp = require('gulp');
var gutil = require('gulp-util');
var voidTags = [
'area', 'base', 'br', 'col', 'embed', 'hr',
'img', 'input', 'keygen', 'link', 'meta',
'param', 'source', 'track', 'wbr'];
var checkSelfClose = function () {
function sanitize(file, cb) {
var dirty = String(file.contents);
var matches = dirty.match(/(?:\<[\/\\-\"\'!() a-z=.]+\/\>)/g);
var customTags = [];
if(matches && matches.length > 0)
{
matches.forEach((match)=>{
var tag = match.match(/[a-z\-]+/)[0];
if(voidTags.indexOf(tag) < 0)
customTags.push(tag);
});
};
if(customTags.length > 0)
gutil.log('WARNING', 'found ' + customTags.length + " non-void self-closed tags in",
file.path.substring(file.cwd.length, file.path.Length),
"tags:", customTags
);
cb(null, file);
}
return require('event-stream').map(sanitize);
}
gulp.task('build-html', function () {
return gulp.src('source/**/*.html')
.pipe(checkSelfClose())
.pipe(gulp.dest('output'));
});
测试:
<template bindable="items">
<require from="./menu-bar.css" />
<custom-element/>
<custom-element click.delegate="subitem.execute()" repeat.for="item of items" />
<custom-element-moo></custom-element-moo>
<br>
<br/>
<div id="blahblah"/>
<button class="dropbtn"/>
</template>
gulp 输出:
[更新]
将其留在这里是因为它是一种快速、肮脏且无依赖性的检查自关闭标签的方法;确实回答了这个问题,可能会有用。
我们可以用 parse5 解决查找和报告 self-closing 元素的问题。它有一个应该非常健壮的 SAXParser class(parse5 符合 html5 标准)。解析器在找到 start-tags 后引发一个事件,该事件包含一个关于找到的标签是否自行关闭的布尔值。
var parser = new SAXParser();
parser.on("startTag", (name, attrs, selfClosing)=>{
if(selfClosing){
//check if name is void, if not report error
}
});
parser.push(html);
为了利用此功能,我设置了一个项目,可用于帮助使用上述方法清理 html。开发的 lint 工具能够 运行 一系列规则,收集任何错误并将它们 return 作为 Promise。然后可以将此报告给用户。
原版Html/Templates
template-lint 构成 tool-set 的基础。它由 Linter 和一些基本规则组成:
- SelfClose - 确保 non-void 元素不会 self-close
- 解析器 - returns 未闭合或 ill-matched 元素的错误,在解析期间捕获
gulp-template-lint 是 template-lint 的 gulp 包装器,可以像这样使用:
var gulp = require('gulp');
var linter = require('gulp-template-lint');
gulp.task('build-html', function () {
return gulp.src(['source/**/*.html'])
.pipe(linter())
.pipe(gulp.dest('output'));
});
例子
给出以下 html:
<template>
<custom-element/>
<svg>
<rect/>
</svg>
<div>
<div>
</div>
</template>
产生:
注意:self-closed <rect/>
不会产生错误。 svg 元素包含 xml 并且规则可以根据范围进行区分。
Aurelia 模板
我最初制作了 aurelia-template-lint,但决定将可重用(aurelia 之外的)组件拆分为 template-lint。虽然两者目前是分开的,但我会在适当的时候让 aurelia-template-lint 扩展到 template-lint。目前有一些 proof-of-concept 条规则:
- SelfClose - 确保 non-void 元素不会 self-close
- 解析器 - returns 未闭合或 ill-matched 元素的错误,在解析期间捕获
- 模板 - 确保根是一个模板元素,并且存在的模板元素不超过一个
- RouterView - 不允许 router-view 元素包含内容元素
- 要求 - 确保要求元素具有 'from' 属性
有一个 gulp 包装器可以通过以下方式安装:
npm install gulp-aurelia-template-lint
并在 gulp 构建中使用:
var linter = require('gulp-aurelia-template-lint');
gulp.task('lint-template-html', function () {
return gulp.src('**/*.html')
.pipe(linter())
.pipe(gulp.dest('output'));
});
这将使用默认的规则集。
例子
使用以下 ill-formed aurelia 模板进行简单测试:
<link/>
<template bindable="items">
<require from="foo"/>
<require frm="foo"/>
<br/>
<div></div>
<router-view>
<div/>
</router-view>
</template>
<template>
</template>
输出:
改进
需要做很多改进;例如,有几种方法可以在不使用 <template>
标签的情况下定义原始模板。 Aurelia 还引入了很多可以清理的特定属性。