Grunt:获取错误的行号

时间:2015-12-23 15:25:16

标签: javascript node.js gruntjs

我正在使用Grunt和node.js,并试图让Grunt告诉我它在Gruntfile.js中发现错误的位置。似乎很奇怪,默认情况下它不会这样做。

对于grunt watch,我收到此错误:

Loading "Gruntfile.js" tasks...ERROR
>> SyntaxError: Unexpected string
Warning: Task "watch" not found. Use --force to continue.

我真的很想知道意外字符串在哪一行,但我无法让Grunt告诉我。

当我尝试grunt watch --stack时,它会显示节点文件的整个node.js堆栈跟踪,但不是Gruntfile.js中错误的来源。

按照this answer的建议,将grunt.option('stack', true);添加到Gruntfile.js的顶部,无效。

我的Gruntfile.js:

var path_dev = 'app/assets/_dev';
var path_live = 'app/assets'; 
var url_dev = '//assets.domain.dev/_dev';

module.exports = function (grunt) {
    grunt.option('stack', true);
    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),
        banner: '/*!\n' +
                '* <%= pkg.name %> - v<%= pkg.version %> - <%= grunt.template.today("yyyy-mm-dd") %> - Copyright <%= grunt.template.today("yyyy") %> \n' +
                '* @author <%= pkg.author %>\n' +
                '*/',

        path_dev: path_dev,
        path_live: path_live,
        url_dev: url_dev,

        clean: {
            build: {
                src: [
                    '<%= path_live %>/css/',
                    '<%= path_live %>/js/'
                ]
            }
        },

        concat: {
            options: {
                separator: ';'
            },
            build: {
                src: [
                    '<%= path_dev %>/js/core/jquery.min.js',
                    '<%= path_dev %>/js/core/bootstrap.min.js',
                    '<%= path_dev %>/js/core/jquery.slimscroll.min.js',
                    '<%= path_dev %>/js/core/jquery.scrollLock.min.js',
                    '<%= path_dev %>/js/core/jquery.appear.min.js',
                    '<%= path_dev %>/js/core/jquery.countTo.min.js',
                    '<%= path_dev %>/js/core/jquery.placeholder.min.js',
                    '<%= path_dev %>/js/core/js.cookie.min.js',
                    '<%= path_dev %>/js/main.js'
                ],
                dest: '<%= path_live %>/js/global.js'
            }
        },

        uglify: {
            options: {
                banner: '<%= banner %>'
            },
            build: {
                files: {
                    '<%= path_live %>/js/global.js': ['<%= path_live %>/js/global.js']
                }
            }
        },

        copy: {
            build: {
                files: [
                    {
                        expand: true,
                        cwd: '<%= path_dev %>/css/',
                        src: 'bootstrap.min.css',
                        dest: '<%= path_live %>/css/'
                    },
                    {
                        expand: true,
                        cwd: '<%= path_dev %>/fonts/',
                        src: '**',
                        dest: '<%= path_live %>/fonts/'
                    },
                    {
                        expand: true,
                        cwd: '<%= path_dev %>/img/',
                        src: '**',
                        dest: '<%= path_live %>/img/'
                    },
                    {
                        expand: true,
                        cwd: '<%= path_dev %>/js/plugins/',
                        src: '**',
                        dest: '<%= path_live %>/js/plugins/'
                    }
                ]
            }
        }
    });

    var tasks_to_watch = [];
    var less = {}; 
    var watch = {};


    //less:build
    less['build'] = {
        options: {
            compress: true,
            yuicompress: true,
            optimization: 2,
        },
        files: {}
    };
    less['build']['files'][path_live+'/css/global.css'] = path_dev'/less/main.less';
    less['build']['files'][path_live+'/css/apps/**/*.css'] = path_dev'/less/apps/**/*.less';


    //less:dev_main
    less['dev_main'] = {
        options: {
            sourceMap: true,
            sourceMapURL: url_dev+'/css/global.css.map',
        },
        files: {}
    };
    less['dev_main']['files'][path_dev+'/css/global.css'] = path_dev'/less/main.less'; 

    tasks_to_watch.push('less:dev_main');



    //less:(dynamically find .less files)
    grunt.file.recurse(path_dev+'/less/apps/', function(abspath, rootdir, subdir, filename) {

        if(filename.match(/\.less$/g)){
            var name = filename.substring(0, filename.lastIndexOf('.'));
            var thisurl = url_dev+'/css/apps/app/'+name+'.css';
            var thispath = path_dev+'/css/apps/app/'+name+'.css';

            less[name] = {
                options: {
                    sourceMap: true, 
                    sourceMapURL: thisurl+'.map',
                }, 
                files: {}
            };
            less[name]['files'][thispath] = abspath;
            tasks_to_watch.push('less:'+name);
        }
    }); //grunt.file.recurse()


    watch = {
        styles: {
            files: [path_dev+'/less/**/*.less'],
            tasks: tasks_to_watch,
            options: {
                nospawn: true
            }
        }
    };

    //now repurpose the array to contain all tasks, so we can register them all below
    tasks_to_watch.push('less:build');
    tasks_to_watch.push('watch');

    //load tasks
    grunt.loadNpmTasks('grunt-contrib-watch');
    grunt.loadNpmTasks('grunt-contrib-less');
    grunt.loadNpmTasks('grunt-contrib-clean');
    grunt.loadNpmTasks('grunt-contrib-concat');
    grunt.loadNpmTasks('grunt-contrib-uglify');
    grunt.loadNpmTasks('grunt-contrib-copy');

    grunt.config('less', less);
    grunt.config('watch', watch);

    //register tasks
    grunt.registerTask('default', tasks_to_watch);
    grunt.registerTask('build', ['clean:build', 'less:build', 'concat:build', 'uglify:build', 'copy:build']);
};

1 个答案:

答案 0 :(得分:1)

问题出在行上:104,105和116,您在+之后错过了加号path_dev

less['build']['files'][path_live+'/css/global.css'] = path_dev+'/less/main.less';

请你解决其他问题。