Grunt 只会创建一个文件,不会创建多个

Grunt will only create one file, not multiples

我有一个非常简单的 G运行tfile,它逐行读取一个纯文本文件,并且应该从每一行创建一个同名的 html 文件(即: eng_product_100x100.html) 但它只适用于文件中的一行,而不适用于多行。

这是尝试使用多行 运行 时的控制台响应:

Running tasks: createProducts

Running "createProducts" task
Writing product/eng/eng_product_100x100.html
eng_product_200x200.html
eng_product_300x300.html
eng_product_400x400.html...ERROR
Warning: Unable to write "product/eng/eng_product_100x100.html
eng_product_200x200.html
eng_product_300x300.html
eng_product_400x400.html" file (Error code: ENOENT). Use --force to continue.

Aborted due to warnings.

G运行t文件:

module.exports = function(grunt) {

  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json')
  });

  grunt.registerTask('createProducts', 'Create product banners', function() {
    this.async();

    var fs = require('fs');
    var fileName = 'filenames.xml';

    var str = fs.readFileSync(fileName, 'utf8');
    var arr = str.split('/n');
    for (i in arr){
      grunt.file.write(arr[i].split('_')[1]+'/'+arr[i].split('_')[0]+'/'+arr[i], 'test');
      console.log(arr[i]);
    }

  });

};

您的 Gruntfile.js 几乎是正确的。它不能使用多行的原因是代码行阅读:

var arr = str.split('/n');

注意 对于换行符,/n 应该是 \r\n。请参阅 here 以了解 DOS 与 Unix 行尾之间的差异该行代码应为:

var arr = str.split('\r\n');

Gruntfile.js

这是 Gruntfile.js 的完整更正版本,包括一些重构:

module.exports = function(grunt) {

    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json')
    });

    grunt.registerTask('createProducts', 'Create product banners', function() {
        this.async();

        var fs = require('fs'),
            fileNameList = 'filenames.txt',
            str = fs.readFileSync(fileNameList, 'utf8'),
            arr = str.split('\r\n');

        for (var i in arr) {
            var newFilePath = arr[i].split('_')[1] + '/' + arr[i].split('_')[0] + '/' + arr[i] + '.html';
            grunt.file.write(newFilePath, '<html></html>');
            console.log('Created file: ' + newFilePath);
        }
    });

};

重构后的显着变化是:

  1. 它从 filenames.txt 而不是 'filenames.xml' 读取列表(如果文件只是您问题中提到的纯文本。

  2. 添加了一个名为 newFilePath 的新变量,因为它清楚地表明了所有 arr[i].split() 等真正创建的内容。

  3. '.html' 添加到 newFilePath 变量,以便生成的文件包含 .html 后缀。


UPDATE 更新答案以利用 \r\n 处理 DOS 与 Unix 行尾。


更新 2

跨平台稳健性

在 Windows 上创建 filenames.txt 时,上述解决方案成功运行。但是,如果 filenames.txt 在另一个 OS 上创建,它可能会失败,因为使用了各种行尾,\r\n\r\n 作为在此 answer 中进行了解释。为了确保解决方案在不同的 OS/platforms 中更加稳健,那么在使用 split() 来制作数组之前,有必要检查使用了哪个行结尾。

下面展示了如何实现 (注意:为了解释目的,要点故意冗长,可能应该重构):

module.exports = function(grunt) {

    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json')
    });

    grunt.registerTask('createProducts', 'Create product banners', function() {
        this.async();

        var fs = require('fs'),
            fileNameList = 'filenames.txt',
            str = fs.readFileSync(fileNameList, 'utf8'),
            arr = [];

        // Warn if filename.txt does not include any text.
        if (!str) {
            console.warn('Error: ' + fileNameList + ' is empty');
            process.exit(1);
        }

        // Check which line ending is used before splitting.
        if (str.indexOf('\r\n') !== -1) { // CR + LF - filenames.txt was created on Windows.
            arr = str.split('\r\n');
        } else if (str.indexOf('\n') !== -1) { // LF - filenames.txt was created on Unix/Mac OS X.
            arr = str.split('\n');
        } else if (str.indexOf('\r') !== -1) { // CR - filenames.txt was created on Mac OS before X.
            arr = str.split('\r');
        } else { // Only one line exists in filenames.txt
            arr.push(str);
        }

        for (var i in arr) {
            var newFilePath = arr[i].split('_')[1] + '/' + arr[i].split('_')[0] + '/' + arr[i];
            grunt.file.write(newFilePath, '<html></html>');
            console.log('Created file: ' + newFilePath);
        }
    });

};