【问题标题】:Grunt watch warning: EPERM, operation not permittedGrunt watch 警告:EPERM,不允许操作
【发布时间】:2014-01-03 11:53:39
【问题描述】:

我对 gruntjs 和 grunt-contrib-watch 插件有一个非常烦人的问题。一段时间后,我无法定义,可能是半小时或两个小时的工作(它是随机的)控制台吐出这个错误:

Running "watch" task
Waiting...Warning: EPERM, operation not permitted 'C:\dev\project\app\index.html~RF97bf99.TMP'

它重复了大约 50 次,接下来是:

Warning: An error occurred while processing a template (An error occurred while processing a templat
e (Maximum call stack size exceeded).).
Warning: An error occurred while processing a template (An error occurred while processing a templat
e (An error occurred while processing a template (Maximum call stack size exceeded).).).
Warning: An error occurred while processing a template (An error occurred while processing a templat
e (An error occurred while processing a template (An error occurred while processing a template (Max
imum call stack size exceeded).).).).
Warning: An error occurred while processing a template (An error occurred while processing a templat
e (An error occurred while processing a template (An error occurred while processing a template (An
error occurred while processing a template (Maximum call stack size exceeded).).).).).

我的 Grunfile.js:

'use strict';

module.exports = function (grunt) {

    // Load all grunt tasks
    require('load-grunt-tasks')(grunt);
    // Show elapsed time at the end
    require('time-grunt')(grunt);

    grunt.initConfig({
        // Project settings
        project: {
            app: 'app',
            dist: 'dist'
        },
        bootstrap: {
            src: 'bower_components/sass-bootstrap',
            pkg: grunt.file.readJSON('bower_components/sass-bootstrap/package.json'),
            banner: '/*!\n' +
                    ' * Bootstrap v<%= bootstrap.pkg.version %> by @fat and @mdo\n' +
                    ' * Copyright <%= grunt.template.today("yyyy") %> <%= bootstrap.pkg.author %>\n' +
                    ' * Licensed under <%= _.pluck(bootstrap.pkg.licenses, "url").join(", ") %>\n' +
                    ' *\n' +
                    ' * Designed and built with all the love in the world by @mdo and @fat.\n' +
                    ' */\n\n',
            jqueryCheck: 'if (typeof jQuery === "undefined") { throw new Error("Bootstrap requires jQuery") }\n\n'
        },
        watch: {
            sass: {
                files: ['<%= project.app %>/sass/{,*/}*.scss'],
                tasks: ['sass:dev', 'autoprefixer'],
                options: {
                    spawn: false,
                    livereload: true
                },
            },
            js: {
                files: [
                    '<%= project.app %>/js/{,*/}*.js',
                    '!<%= project.app %>/js/vendor/{,*/}*.js',
                    '!<%= project.app %>/js/plugins/{,*/}*.js'
                ],
                options: {
                    livereload: true
                }
            },
            livereload: {
                options: {
                    livereload: '<%= connect.options.livereload %>'
                },
                files: [
                    '<%= project.app %>/{,*/}*.html',
                    '<%= project.app %>/css/{,*/}*.css',
                    '<%= project.app %>/images/{,*/}*.{gif,jpeg,jpg,png,svg,webp}'
                ]
            }
        },
        connect: {
            options: {
                port: 9000,
                livereload: 35729,
                // Change this to '0.0.0.0' to access the server from outside
                hostname: 'localhost'
            },
            livereload: {
                options: {
                    open: true,
                    base: '<%= project.app %>'
                }
            },
            dist: {
                options: {
                    open: true,
                    base: '<%= project.dist %>',
                    livereload: false
                }
            }
        },
        sass: {
            options: {
                includePaths: ['<%= bootstrap.src %>/lib/']
            },
            dev: {
                files: {
                    '<%= project.app %>/css/app.css': '<%= project.app %>/sass/app.scss'
                }
            },
            dist: {
                files: {
                    '<%= project.app %>/css/app.css': '<%= project.app %>/sass/app.scss'
                }
            }
        },
        autoprefixer: {
            options: {
                browsers: ['last 2 version']
            },
            dist: {
                files: [{
                    expand: true,
                    cwd: '<%= project.app %>/css/',
                    src: '{,*/}*.css',
                    dest: '<%= project.app %>/css/'
                }]
            }
        },
        concat: {
            options: {
                nonull: true,
                separator: '\n\n'
            },
            bootstrap: {
                options: {
                    banner: '<%= bootstrap.banner %><%= bootstrap.jqueryCheck %>'
                },
                src: [
                    '<%= bootstrap.src %>/js/transition.js',
                    // '<%= bootstrap.src %>/js/alert.js',
                    // '<%= bootstrap.src %>/js/button.js',
                    // '<%= bootstrap.src %>/js/carousel.js',
                    '<%= bootstrap.src %>/js/collapse.js',
                    '<%= bootstrap.src %>/js/dropdown.js',
                    // '<%= bootstrap.src %>/js/modal.js',
                    // '<%= bootstrap.src %>/js/tooltip.js',
                    // '<%= bootstrap.src %>/js/popover.js',
                    // '<%= bootstrap.src %>/js/scrollspy.js',
                    // '<%= bootstrap.src %>/js/tab.js',
                    // '<%= bootstrap.src %>/js/affix.js'
                ],
                dest: '<%= project.app %>/js/plugins/bootstrap.js'
            },
            plugins: {
                files: {
                    '<%= project.app %>/js/plugins.js': ['<%= project.app %>/js/plugins/bootstrap.min.js', '<%= project.app %>/js/plugins/*.min.js']
                }
            }
        },
        uglify: {
            bootstrap: {
                options: {
                    banner: '<%= bootstrap.banner %>'
                },
                files: {
                    '<%= project.app %>/js/plugins/bootstrap.min.js': '<%= concat.bootstrap.dest %>'
                }
            },
            all: {
                options: {
                    preserveComments: 'some',
                    report: 'min'
                },
                files: [{
                    expand: true,
                    cwd: '<%= project.app %>/js/',
                    src: ['*.js', '!plugins.js'],
                    ext: '.min.js',
                    dest: '<%= project.app %>/js/'
                }]
            }
        },
        cssmin: {
            options: {
                report: 'min'
            },
            dist: {
                expand: true,
                cwd: '<%= project.app %>/css/',
                src: ['*.css', '!*.min.css'],
                dest: '<%= cssmin.dist.cwd %>',
                ext: '.min.css'
            }
        },
        imagemin: {
            dist: {
                files: [{
                    expand: true,
                    cwd: '<%= project.app %>/img',
                    src: ['{,*/}*.{gif,jpeg,jpg,png}'],
                    dest: '<%= project.dist %>/img'
                }]
            }
        }
    });

    // Register tasks
    // ==================================================

    // Run local server
    grunt.registerTask('serve', function (target) {
        if (target === 'dist') {
            return grunt.task.run(['build', 'connect:dist:keepalive']);
        }

        grunt.task.run([
            'connect:livereload',
            'watch'
        ]);
    });

    // Build JS
    grunt.registerTask('build-js', [
        'concat:bootstrap',
        'uglify',
        'concat:plugins'
    ]);

    // Build CSS
    grunt.registerTask('build-css', [
        'sass:dist',
        'autoprefixer',
        'cssmin'
    ]);

    // Minify images
    grunt.registerTask('test', ['imagemin']);

    // grunt.registerTask('default', ['']);

};

package.json(所有依赖都是最新的):

{
  "name": "project",
  "version": "0.0.0",
  "dependencies": {},
  "devDependencies": {
    "load-grunt-tasks": "~0.2.1",
    "time-grunt": "~0.2.6",
    "grunt": "~0.4.2",
    "grunt-contrib-watch": "~0.5.3",
    "grunt-contrib-connect": "~0.6.0",
    "grunt-autoprefixer": "~0.6.3",
    "grunt-contrib-concat": "~0.3.0",
    "grunt-contrib-uglify": "~0.2.7",
    "grunt-contrib-cssmin": "~0.7.0",
    "grunt-sass": "~0.9.0",
    "jpegtran-bin": "~0.2.0",
    "grunt-contrib-imagemin": "~0.4.0"
  }
}

我使用的是 Windows 7 32 位、gruntjs v.0.4.2、nodejs v0.10.22。任何想法可能导致此问题?我将如何解决它?非常感谢。

【问题讨论】:

    标签: gruntjs grunt-contrib-watch


    【解决方案1】:

    我遇到了类似的问题“EPERM,不允许操作...”,这是因为我没有以管理员模式打开 CMD。 所以右键单击CMD并以管理员身份运行。 这解决了我的错误。

    【讨论】:

    • 我刚刚在 Linux Mint 上遇到了同样的问题。使用 sudo 运行 grunt 任务。
    • 这很可能是公认的答案,对我来说效果很好并解决了我的问题。谢谢
    • 事实证明,如果文件的文件权限为 rwx---r-x 并且管理员是组所有者,则无论您的管理员是否是管理员,grunt 都会拒绝您的访问。
    • 使用超级用户权限运行任何错误都是灾难的根源。
    【解决方案2】:

    我不熟悉这个问题,但我认为这可能与您在 Gruntfile.js 上使用通配符的方式有关。一位同事曾经抱怨说,他的watch 任务需要花费大量时间来运行,每次最多 3-4 分钟。他使用的语法是:

    /css/{,*/}*.css
    

    我没有这个问题,所以在让他的Gruntfile.js 更像我的时候,我们发现使用:

    /css/**/*.css
    

    ...解决了整个问题!他的所有任务都在不到 10 秒内完成。

    我已对您的Gruntfile.js 进行了更改,您可能想使用diff 工具将我的版本与您的版本进行比较,看看有什么变化。

    我还强烈建议在您的项目中使用jshintJavaScript 进行lint,特别是Gruntfile.js 和任何其他对Grunt 重要的配置文件,您可能已从Gruntfile.js 中分离出来。 An example here(查看同一个项目了解更多细节)。

    'use strict';
    
    module.exports = function (grunt) {
    
        // Load all grunt tasks
        require('load-grunt-tasks')(grunt);
        // Show elapsed time at the end
        require('time-grunt')(grunt);
    
        grunt.initConfig({
            // Project settings
            project: {
                app: 'app',
                dist: 'dist'
            },
            bootstrap: {
                src: 'bower_components/sass-bootstrap',
                pkg: grunt.file.readJSON('bower_components/sass-bootstrap/package.json'),
                banner: '/*!\n' +
                        ' * Bootstrap v<%= bootstrap.pkg.version %> by @fat and @mdo\n' +
                        ' * Copyright <%= grunt.template.today("yyyy") %> <%= bootstrap.pkg.author %>\n' +
                        ' * Licensed under <%= _.pluck(bootstrap.pkg.licenses, "url").join(", ") %>\n' +
                        ' *\n' +
                        ' * Designed and built with all the love in the world by @mdo and @fat.\n' +
                        ' */\n\n',
                jqueryCheck: 'if (typeof jQuery === "undefined") { throw new Error("Bootstrap requires jQuery") }\n\n'
            },
            watch: {
                sass: {
                    files: ['<%= project.app %>/sass/**/*.scss'],
                    tasks: ['sass:dev', 'autoprefixer'],
                    options: {
                        spawn: false,
                        livereload: true
                    },
                },
                js: {
                    files: [
                        '<%= project.app %>/js/**/*.js',
                        '!<%= project.app %>/js/vendor/**/*.js',
                        '!<%= project.app %>/js/plugins/**/*.js'
                    ],
                    options: {
                        livereload: true
                    }
                },
                livereload: {
                    options: {
                        livereload: '<%= connect.options.livereload %>'
                    },
                    files: [
                        '<%= project.app %>/**/*.html',
                        '<%= project.app %>/css/**/*.css',
                        '<%= project.app %>/images/**/*.{gif,jpeg,jpg,png,svg,webp}'
                    ]
                }
            },
            connect: {
                options: {
                    port: 9000,
                    livereload: 35729,
                    // Change this to '0.0.0.0' to access the server from outside
                    hostname: 'localhost'
                },
                livereload: {
                    options: {
                        open: true,
                        base: '<%= project.app %>'
                    }
                },
                dist: {
                    options: {
                        open: true,
                        base: '<%= project.dist %>',
                        livereload: false
                    }
                }
            },
            sass: {
                options: {
                    includePaths: ['<%= bootstrap.src %>/lib/']
                },
                dev: {
                    files: {
                        '<%= project.app %>/css/app.css': '<%= project.app %>/sass/app.scss'
                    }
                },
                dist: {
                    files: {
                        '<%= project.app %>/css/app.css': '<%= project.app %>/sass/app.scss'
                    }
                }
            },
            autoprefixer: {
                options: {
                    browsers: ['last 2 version']
                },
                dist: {
                    files: [{
                        expand: true,
                        cwd: '<%= project.app %>/css',
                        src: '/**/*.css',
                        dest: '<%= project.app %>/css'
                    }]
                }
            },
            concat: {
                options: {
                    nonull: true,
                    separator: '\n\n'
                },
                bootstrap: {
                    options: {
                        banner: '<%= bootstrap.banner %><%= bootstrap.jqueryCheck %>'
                    },
                    src: [
                        '<%= bootstrap.src %>/js/transition.js',
                        // '<%= bootstrap.src %>/js/alert.js',
                        // '<%= bootstrap.src %>/js/button.js',
                        // '<%= bootstrap.src %>/js/carousel.js',
                        '<%= bootstrap.src %>/js/collapse.js',
                        '<%= bootstrap.src %>/js/dropdown.js'
                        // '<%= bootstrap.src %>/js/modal.js',
                        // '<%= bootstrap.src %>/js/tooltip.js',
                        // '<%= bootstrap.src %>/js/popover.js',
                        // '<%= bootstrap.src %>/js/scrollspy.js',
                        // '<%= bootstrap.src %>/js/tab.js',
                        // '<%= bootstrap.src %>/js/affix.js'
                    ],
                    dest: '<%= project.app %>/js/plugins/bootstrap.js'
                },
                plugins: {
                    files: {
                        '<%= project.app %>/js/plugins.js': ['<%= project.app %>/js/plugins/bootstrap.min.js', '<%= project.app %>/js/plugins/*.min.js']
                    }
                }
            },
            uglify: {
                bootstrap: {
                    options: {
                        banner: '<%= bootstrap.banner %>'
                    },
                    files: {
                        '<%= project.app %>/js/plugins/bootstrap.min.js': '<%= concat.bootstrap.dest %>'
                    }
                },
                all: {
                    options: {
                        preserveComments: 'some',
                        report: 'min'
                    },
                    files: [{
                        expand: true,
                        cwd: '<%= project.app %>/js/',
                        src: ['*.js', '!plugins.js'],
                        ext: '.min.js',
                        dest: '<%= project.app %>/js/'
                    }]
                }
            },
            cssmin: {
                options: {
                    report: 'min'
                },
                dist: {
                    expand: true,
                    cwd: '<%= project.app %>/css/',
                    src: ['*.css', '!*.min.css'],
                    dest: '<%= cssmin.dist.cwd %>',
                    ext: '.min.css'
                }
            },
            imagemin: {
                dist: {
                    files: [{
                        expand: true,
                        cwd: '<%= project.app %>/img',
                        src: ['/**/*.{gif,jpeg,jpg,png}'],
                        dest: '<%= project.dist %>/img'
                    }]
                }
            }
        });
    
        // Register tasks
        // ==================================================
    
        // Run local server
        grunt.registerTask('serve', function (target) {
            if (target === 'dist') {
                return grunt.task.run(['build', 'connect:dist:keepalive']);
            }
    
            grunt.task.run([
                'connect:livereload',
                'watch'
            ]);
        });
    
        // Build JS
        grunt.registerTask('build-js', [
            'concat:bootstrap',
            'uglify',
            'concat:plugins'
        ]);
    
        // Build CSS
        grunt.registerTask('build-css', [
            'sass:dist',
            'autoprefixer',
            'cssmin'
        ]);
    
        // Minify images
        grunt.registerTask('test', ['imagemin']);
    
        // grunt.registerTask('default', ['']);
    
    };
    

    【讨论】:

      【解决方案3】:

      在 linux 上,更改目录权限

      $ sudo chmod -R 777 name_directory
      

      【讨论】:

        猜你喜欢
        • 2017-01-07
        • 2021-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-10-20
        相关资源
        最近更新 更多