質問

I've set up a grunt file to automate some of my tasks. I've also split up my watch task into smaller subtasks, to prevent it becoming one monolithic watch task.

The individual tasks each used to run perfectly fine, but now it seems that watch is missing some filechanges as they occur. For example, it'll detect a change in my scss and compile that. But it'll miss the subsequent change in the compiled css, and skip the autoprefix and ftp-deploy.

How can I correct this? Do I need to use a debouncedelay, is my watch spawn setting wrong, or is there something else going wrong?

module.exports = function(grunt) {

  // Load all grunt tasks matching the `grunt-*` pattern
  require('load-grunt-tasks')(grunt);

  // All configuration goes here 
  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),

    // Template strings for directories
    dirs: {
      // Dev
      dev_js: 'js',
      dev_css: 'css',
      dev_scss: 'scss',
      dev_js_authored: '<%= dirs.dev_js %>/authored',
      dev_js_libs: '<%= dirs.dev_js %>/libs',
      dev_js_build: '<%= dirs.dev_js %>/build',
      dev_css_build: '<%= dirs.dev_css %>/build',
      // Production
      prod_server_root: '/wp-content/themes',
      prod_current_theme: '<%= dirs.prod_server_root %>/themename',
      prod_css: '<%= dirs.prod_current_theme %>/css'
    },

    // Template strings for ftp
    ftp_cred: {
      prod_host: 'ip-here',
      prod_auth: 'auth-here'
    },

    // Concatenate
    concat: {   
      js: {
        src: [
          '<%= dirs.dev_js_libs %>/*.js',
          '<%= dirs.dev_js_authored %>/*.js'
        ],
        dest: '<%= dirs.dev_js_build %>/production.js'
      }
    },

    // Minify
    uglify: {
      js: {
        src: '<%= dirs.dev_js_build %>/production.js',
        dest: '<%= dirs.dev_js_build %>/production.min.js'
      }
    },

    // Sass
    sass: {
      compile: {
        options: {
          style: 'compressed'
        },
        files: {
          'css/build/unprefixed.min.css': 'scss/global.scss'
        }
      }
    },

    // Autoprefixer
    autoprefixer: {
      prefix: {
        single_file: {
         src: '<%= dirs.dev_css_build %>/unprefixed.min.css',
         dest: '<%= dirs.dev_css_build %>/production.min.css'
        }
      }
    },

    // FTP
    'ftp-deploy': {
      css: {
        build: {
          auth: {
            host: '<%= ftp_cred.prod_host %>',
            port: 21,
            authKey: '<%= ftp_cred.prod_auth %>'
          },
          src: '<%= dirs.dev_css %>',
          dest: '<%= dirs.prod_css %>',
          exclusions: ['<%= dirs.dev_css_build %>/unprefixed.min.css']
        }        
      }
    },

    // Watch
    watch: {
      scripts_concat: {
        files: ['<%= dirs.dev_js_authored %>/*.js','<%= dirs.dev_js_libs %>/*.js'],
        tasks: ['concat:js']
      },
      scripts_min: {
        files: ['<%= dirs.dev_js_build %>/production.js'],
        tasks: ['uglify:js']
      },
      scss_compile: {
        files: ['<%= dirs.dev_scss %>/**/*.scss'],
        tasks: ['sass:compile']
      },
      css_prefix: {
        files: ['<%= dirs.dev_css_build %>/unprefixed.min.css'],
        tasks: ['autoprefixer:prefix']
      },
      ftp_css: {
        files: ['<%= dirs.dev_css_build %>/production.min.css'],
        tasks: ['ftp-deploy:css']
      },
      livereload: {
        options: { livereload: true },
        files: ['<%= dirs.dev_css_build %>/production.min.css','<%= dirs.dev_js_build %>/production.min.js']
      }
    }

  });

  // Load required plugins
  require('load-grunt-tasks')(grunt);

  // Define what to do at which command
  grunt.registerTask('default', ['watch']);

};
役に立ちましたか?

解決 2

Ok, so I found the mistake (which was a mixup in the folders that I was watching and outputting files to). In the end I changed the watch section to a smaller collection of meaningful task chains, like so:

watch: {
  js_prod: {
    files: ['<%= dirs.dev_js_authored %>/*.js','<%= dirs.dev_js_libs %>/*.js'],
    tasks: ['concat:js','uglify:js','ftp-deploy:js_prod','clean:temp_js']
  },
  js_standalone: {
    files: ['<%= dirs.dev_js_standalone %>/*.js'],
    tasks: ['ftp-deploy:js_standalone']
  },
  css_prod: {
    files: ['<%= dirs.dev_scss %>/**/*.scss'],
    tasks: ['sass:compile','autoprefixer:prefix','ftp-deploy:css_prod']
  },
  css_ie: {
    files: ['<%= dirs.dev_css_ie %>/*.css','!<%= dirs.dev_css_ie %>/*.min.css'],
    tasks: ['cssmin:ie','ftp-deploy:css_ie','clean:temp_css_ie']
  },
  livereload: {
    options: { livereload: true },
    files: [
      '<%= dirs.dev_css %>/**/*.css',
      '<%= dirs.dev_js_build %>/production.min.js',
      '<%= dirs.dev_js_standalone %>/*.js']
  }
}

This works fine, and I have no more problems with watch tasks not picking up changes, since I won't be working simultaneously in any of the areas they're watching.

他のヒント

If you run grunt watch:scss_compile, the ftp_css task won't be running and therefore the changes to the production.min.css won't trigger the ftp deployment...

So what you probably want is to run two watch tasks simultaneously, with the help of grunt-concurrent

concurrent: {
    options: {
        logConcurrentOutput: true
    },
    css: {
        tasks: ["watch:scss_compile", "watch:ftp_css"]
    }
}

Then:

grunt.registerTask(["concurrent:css"]); // add this task to your default task

Have a look at the reference for more details: How to run two grunt watch tasks simultaneously

I would, however, separate the watch task into two blocks: js and css, as I assume all css-related tasks would have to run upon changes anyway. I would do something like:

  css: {
    files: ['<%= dirs.dev_scss %>/**/*.scss'],
    tasks: ['sass:compile', 'autoprefixer:prefix', 'ftp-deploy:css', 'watch:livereload']
  },
  livereload: {
    options: { livereload: true },
    files: [
        '<%= dirs.dev_css_build %>/production.min.css',
        '<%= dirs.dev_js_build %>/production.min.js'
    ]
  }
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top