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

时间:2017-02-11 19:32:21

标签: javascript node.js gruntjs

我有这个非常简单的Gruntfile,它逐行读取纯文本文件,并且应该从每一行创建一个同名的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.

Gruntfile:

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]);
    }

  });

};

1 个答案:

答案 0 :(得分:1)

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

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

注意 /n应为\r\n换行符。有关DOS与Unix行结尾之间的差异,请参阅here该行代码应为:

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'读取列表(如果文件只是您提到的纯文本,则不需要该文件为.xml问题

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

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

  4. UPDATE 更新了使用\r\n来处理DOS与Unix线路结束的答案。

    更新2

    跨平台稳健性

    在Windows上创建filenames.txt时,上述解决方案可以成功运行。但是,如果在另一个操作系统上创建filenames.txt,则由于使用的各种行结尾可能会失败,如\r\n\r\n所示,如此{ {3}}。为了确保解决方案在不同的操作系统/平台上更加健壮,那么在使用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);
            }
        });
    
    };