编辑:更新了Gruntfile.js 中的正则表达式以处理<div> 标记,这些标记可能还包括除了id 之外的属性。例如:
<!-- Also includes a class -->
<div id="QUUX" class="foo">...</div>
首先grunt 在Node.js 上运行,因此调用window.location.href 将产生错误,因为要处理的.html 文件未加载到Web 浏览器中。 window.location.href 是 BOM 的约定,通常仅适用于浏览器环境。
grunt-replace 使用标准任务配置不提供获取正在处理的文件名的机制。但是,由于grunt-replace 是一个multi-task 插件,因此可以通过使用自定义函数来动态创建replace 任务对象来满足您的要求。
下面展示了如何实现这一点:
Gruntfile.js
module.exports = function (grunt) {
grunt.initConfig( {
replace: {} // <-- // Intentionally empty, will be generated dynamically.
});
/**
* Helper function dynamically creates config object for `replace` Task.
* We dynamically generate this to obtain the filename and use that for
* the `replacement` value.
*/
function replaceHtml() {
var glob = 'src/*.html',
config = {};
grunt.file.expand({ filter: 'isFile' }, glob).forEach(function (filePath) {
var fileName = filePath.split('/').pop().split('.')[0];
config[fileName] = {
options: {
usePrefix: false,
patterns: [{
// Regex pattern explained here: https://regex101.com/r/uJVMOI/3
match: /(<div.*?id=\"QUUX\".*?>)[\s\S]+?(<\/div>)/g,
replacement: '$1' + fileName + '$2'
}]
},
files: [{
expand: true,
flatten: true,
src: filePath,
dest: 'output/'
}]
}
});
grunt.config('replace', config);
grunt.task.run(['replace']);
}
grunt.loadNpmTasks('grunt-replace');
grunt.registerTask("default", replaceHtml);
};
备注
replace 任务的配置故意设置为空对象。
replaceHtml 函数利用grunt.file.expand 循环遍历通过glob 模式'src/*.html' 找到的每个文件。
fileName变量是通过当前filePath获取的。
在forEach 语句的每个循环期间,会生成一个Target 并将其添加到config 对象中。
退出forEach循环时,config对象通过使用grunt.config添加到replace任务/对象,然后最终调用grunt.task.run
正则表达式
那么接下来的部分在做什么呢?
patterns: [{
match: /(<div.*?id=\"QUUX\".*?>)[\s\S]+?(<\/div>)/g,
replacement: '$1' + fileName + '$2'
}]
match 部分使用正则表达式,在here 中有进一步的解释。它目前搜索以下实例:
<div id="QUUX">...</div>
所以,假设上面的 sn-p 位于一个名为 index.html 的文件中 - 然后生成的文件将显示为:
<div id="QUUX">index</div>
但是,如果在结果文件中它应该读取(即它应该包含文件后缀.html):
<div id="QUUX">index.html</div>
...那么您需要在第 1 行更改 fileName 变量的赋值。 17 在Gruntfile.js 到:
var fileName = filePath.split('/').pop();
多个匹配
要执行多个匹配,只需将另一个模式对象添加到 patterns 数组。例如:
// ...
patterns: [{
match: /(<div.*?id=\"QUUX\".*?>)[\s\S]+?(<\/div>)/g,
replacement: '$1' + fileName + '$2'
}, {
match: /(<div.*?id=\"FOOBAR\".*?>)[\s\S]+?(<\/div>)/g,
replacement: '$1' + fileName + '$2'
}]
// ...
假设正在处理的文件名为hello-world.html - 那么上面的示例将替换任何实例
<div class="foo" id="QUUX">...</div>
或
<div id="FOOBAR" class="foo">...</div>
与
<div class="foo" id="QUUX">hello-world</div>
和
<div id="FOOBAR" class="foo">hello-world</div>
分别。