在 Grunt 任务中读取文件名
Read filename in Grunt task
我已经将 G运行t 设置为使用 g运行t-replace,这样我就可以在几百 HTML 页中找到 div ,并将 div 中的文本替换为它所在的 HTML 文件的当前文件名。不过我不确定具体如何执行此操作。我尝试使用 window.loacation.href
但这只会在我 运行 任务时产生错误。
这是我的 Gruntfile.coffee:
module.exports = (grunt) ->
grunt.initConfig
pkg: grunt.file.readJSON "package.json"
gruntfile: "Gruntfile.coffee"
replace:
dist:
options:
patterns: [
match: "<div id'name_goes_here'></div>"
replacement: ->
"<div id'name_goes_here'>Filename: #{window.location.href}</div>"
]
usePrefix: false
files: [
expand: true
flatten: true
src: [
"src/*.html"
],
dest: "output/"
]
grunt.loadNpmTasks "grunt-replace";
grunt.registerTask "default", ["replace"];
作为旁注,我尝试将包含简单字符串的变量传递到替换字符串中,这有效并替换了所有 HTML 页面,因此 G运行任务肯定有效。而且替换是一个函数的原因是因为我计划在以后添加一些额外的东西,但现在只想让它工作。
如有任何帮助,我们将不胜感激。
编辑:更新 Gruntfile.js
中的正则表达式以处理 <div>
标签,除了 id
之外还可能包含属性。例如:
<!-- Also includes a class -->
<div id="QUUX" class="foo">...</div>
首先 grunt
在 Node.js, so calling window.location.href
will produce an error as the .html
files to be processed are not loaded into a web browser. window.location.href
is a convention of the BOM 上运行,通常只在浏览器环境中运行。
grunt-replace with standard Task configuration(s) does not provide a mechanism to obtain the filename being processed. However, as grunt-replace
is a 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: '' + fileName + ''
}]
},
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 to loop over each file found via the glob 模式 'src/*.html'
。
通过当前filePath
.
得到fileName
变量
在 forEach
语句的每个循环中,都会生成一个 Target 并添加到 config
对象中。
当退出 forEach
循环时,config
对象通过使用 grunt.config, before finally calling grunt.task.run[=54 添加到 replace
Task/Object =]
正则表达式
那么接下来的部分是做什么的?
patterns: [{
match: /(<div.*?id=\"QUUX\".*?>)[\s\S]+?(<\/div>)/g,
replacement: '' + fileName + ''
}]
match
部分使用正则表达式,进一步解释 here。它当前搜索以下实例:
<div id="QUUX">...</div>
所以,假设上面的代码片段位于一个名为 index.html
的文件中 - 那么生成的文件将显示为:
<div id="QUUX">index</div>
但是,如果在生成的文件中它应该读取(即它应该包含文件后缀 .html
):
<div id="QUUX">index.html</div>
...那么您需要更改第 34 行中 fileName
变量的赋值。 17 在 Gruntfile.js
至:
var fileName = filePath.split('/').pop();
多次匹配
要执行多个匹配,只需将另一个模式对象添加到 patterns
数组。例如:
// ...
patterns: [{
match: /(<div.*?id=\"QUUX\".*?>)[\s\S]+?(<\/div>)/g,
replacement: '' + fileName + ''
}, {
match: /(<div.*?id=\"FOOBAR\".*?>)[\s\S]+?(<\/div>)/g,
replacement: '' + fileName + ''
}]
// ...
假设正在处理的文件名为 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>
分别。
我已经将 G运行t 设置为使用 g运行t-replace,这样我就可以在几百 HTML 页中找到 div ,并将 div 中的文本替换为它所在的 HTML 文件的当前文件名。不过我不确定具体如何执行此操作。我尝试使用 window.loacation.href
但这只会在我 运行 任务时产生错误。
这是我的 Gruntfile.coffee:
module.exports = (grunt) ->
grunt.initConfig
pkg: grunt.file.readJSON "package.json"
gruntfile: "Gruntfile.coffee"
replace:
dist:
options:
patterns: [
match: "<div id'name_goes_here'></div>"
replacement: ->
"<div id'name_goes_here'>Filename: #{window.location.href}</div>"
]
usePrefix: false
files: [
expand: true
flatten: true
src: [
"src/*.html"
],
dest: "output/"
]
grunt.loadNpmTasks "grunt-replace";
grunt.registerTask "default", ["replace"];
作为旁注,我尝试将包含简单字符串的变量传递到替换字符串中,这有效并替换了所有 HTML 页面,因此 G运行任务肯定有效。而且替换是一个函数的原因是因为我计划在以后添加一些额外的东西,但现在只想让它工作。
如有任何帮助,我们将不胜感激。
编辑:更新 Gruntfile.js
中的正则表达式以处理 <div>
标签,除了 id
之外还可能包含属性。例如:
<!-- Also includes a class -->
<div id="QUUX" class="foo">...</div>
首先 grunt
在 Node.js, so calling window.location.href
will produce an error as the .html
files to be processed are not loaded into a web browser. window.location.href
is a convention of the BOM 上运行,通常只在浏览器环境中运行。
grunt-replace with standard Task configuration(s) does not provide a mechanism to obtain the filename being processed. However, as grunt-replace
is a 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: '' + fileName + ''
}]
},
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 to loop over each file found via the glob 模式'src/*.html'
。通过当前
filePath
. 得到在
forEach
语句的每个循环中,都会生成一个 Target 并添加到config
对象中。当退出
forEach
循环时,config
对象通过使用 grunt.config, before finally calling grunt.task.run[=54 添加到replace
Task/Object =]
fileName
变量
正则表达式
那么接下来的部分是做什么的?
patterns: [{
match: /(<div.*?id=\"QUUX\".*?>)[\s\S]+?(<\/div>)/g,
replacement: '' + fileName + ''
}]
match
部分使用正则表达式,进一步解释 here。它当前搜索以下实例:
<div id="QUUX">...</div>
所以,假设上面的代码片段位于一个名为 index.html
的文件中 - 那么生成的文件将显示为:
<div id="QUUX">index</div>
但是,如果在生成的文件中它应该读取(即它应该包含文件后缀 .html
):
<div id="QUUX">index.html</div>
...那么您需要更改第 34 行中 fileName
变量的赋值。 17 在 Gruntfile.js
至:
var fileName = filePath.split('/').pop();
多次匹配
要执行多个匹配,只需将另一个模式对象添加到 patterns
数组。例如:
// ...
patterns: [{
match: /(<div.*?id=\"QUUX\".*?>)[\s\S]+?(<\/div>)/g,
replacement: '' + fileName + ''
}, {
match: /(<div.*?id=\"FOOBAR\".*?>)[\s\S]+?(<\/div>)/g,
replacement: '' + fileName + ''
}]
// ...
假设正在处理的文件名为 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>
分别。