How To Fix Grunt Watch Task Not Working Issue

I use grunt to construct a JS project. And I run several grunt tasks to make the JS project build process automated. But after I set up the project using grunt, I found the watch task does not work, this article will tell you how to fix it.

1. How To Fix Grunt Watch Task Not Working Issue.

  1. My project will run the grunt bower task, connect task, and watch task in order. We can see this from the Gruntfile.js configuration file.
    grunt.registerTask('default', [ 'bower', 'connect', 'watch']);
  2. When I run the command grunt in the terminal to run these grunt tasks, it shows the below output on the console.
    $ grunt
    Running "bower:flat" (bower) task
    PackageCollection add                     phaser            /Users/songzhao/Documents/WorkSpace/dev2qa.com-example-code/PythonExampleProject/js-game-engine/phaser/PhaserGruntProject/bower_components/phaser
    Package           overriding main         phaser            ./src/phaser.js
    Package           overriding dependencies phaser            {"eventemitter3":"^4.0.7","path":"^0.12.7"}
    PackageCollection add                     eventemitter3     /Users/songzhao/Documents/WorkSpace/dev2qa.com-example-code/PythonExampleProject/js-game-engine/phaser/PhaserGruntProject/bower_components/eventemitter3
    PackageCollection add                     path              /Users/songzhao/Documents/WorkSpace/dev2qa.com-example-code/PythonExampleProject/js-game-engine/phaser/PhaserGruntProject/bower_components/path
    Package           select file             phaser            /Users/songzhao/Documents/WorkSpace/dev2qa.com-example-code/PythonExampleProject/js-game-engine/phaser/PhaserGruntProject/bower_components/phaser/src/phaser.js
    
    Running "connect:target" (connect) task
    Started connect web server on http://localhost:9001
    
    Running "watch" task
    Waiting...
  3. From the above output, we can see the 3 tasks’ execution order and result.
  4. The bower task is executed first, from the below bower task configuration, it will copy the phaser.js from the bower_components/phaser folder to the scripts folder in the project root folder.
    bower: {
       flat: {
          dest: 'scripts', 
          options: {
              debugging: true 
          }
       } 
    }
  5. The connect task is executed after the bower task, it will start a local webserver that listens on the port 9001.
    connect: {
        target:{
            options: {
                port: 9001 
               }
         }
    },
  6. The watch task is executed at the end, this task will watch any js files that are saved in the src and it’s sub folders, when there are changes in these js files, the watch task will invoke the browserify task.
    watch: { 
        files: ['src/**/*.js'],
        tasks: ['browserify'], 
        options: {
            spawn: false, 
        },
    },
  7. The browserify task will make all the separated js files in the src folder into one js file and save the result js file to ‘scripts/app.js‘.
    browserify: {
        main: {
            options: {
        
                browserifyOptions: { 
          
                    debug: true
                },
                
                transform: [["babelify", { "stage": 1 }]] 
            },
    
            src: 'src/app.js',
        
            dest: 'scripts/app.js' 
        }            
    },
  8. The src/app.js is the entry point of all the other source js files, it will import other js files in the src folder. Below is the source code of the src/app.js.
    import Test from "./Test.js";
  9. Below is the Test.js file source code, it is saved in the src folder also.
    export default alert("Browserify is working as intended.");
  10. When I create the src/Test.js in the project root folder, I can not see any changes in the console output.
  11. So I close the current console and open a new console and run the command grunt –verbose again. Now I can see the grunt watch task running and watching the js files in the src folder from the console output.
    Running "watch" task
    Waiting...
    Verifying property watch exists in config...OK
    Watching src/app.js for changes.
    Watching src/Test.js for changes.
  12. When I add a new js file in the src folder, it will show that the js file is added from the console output.
    >> File "src/ABC.js" added.
  13. So when you find the grunt watch task does not work as expected, the first thing is to restart the grunt command console.
  14. But I still can not find the result scripts/app.js file as the browserify task defines.
  15. So I change some source code in the Test.js file ( add the code alert(‘Hello World’) in it ) and find the error message in the grunt console output like below.
    Watching src/Test.js for changes.
    >> File "src/Test.js" changed.
    
    Running "browserify" task
    
    Running "browserify:main" (browserify) task
    Verifying property browserify.main exists in config...OK
    Files: src/app.js -> scripts/app.js
    Options: banner="", browserifyOptions={"debug":true}, transform=[["babelify",{"stage":1}]]
    Fatal error: Cannot find module '@babel/core'
    Require stack:
    - /Users/songzhao/Documents/WorkSpace/dev2qa.com-example-code/PythonExampleProject/js-game-engine/phaser/PhaserGruntProject/node_modules/babelify/index.js
    - /Users/songzhao/Documents/WorkSpace/dev2qa.com-example-code/PythonExampleProject/js-game-engine/phaser/PhaserGruntProject/node_modules/module-deps/index.js
    - /Users/songzhao/Documents/WorkSpace/dev2qa.com-example-code/PythonExampleProject/js-game-engine/phaser/PhaserGruntProject/node_modules/browserify/index.js
    - /Users/songzhao/Documents/WorkSpace/dev2qa.com-example-code/PythonExampleProject/js-game-engine/phaser/PhaserGruntProject/node_modules/browserify-incremental/index.js
    - /Users/songzhao/Documents/WorkSpace/dev2qa.com-example-code/PythonExampleProject/js-game-engine/phaser/PhaserGruntProject/node_modules/grunt-browserify/lib/runner.js
    - /Users/songzhao/Documents/WorkSpace/dev2qa.com-example-code/PythonExampleProject/js-game-engine/phaser/PhaserGruntProject/node_modules/grunt-browserify/tasks/browserify.js
    - /Users/songzhao/Documents/WorkSpace/dev2qa.com-example-code/PythonExampleProject/js-game-engine/phaser/PhaserGruntProject/node_modules/grunt/lib/grunt/task.js
    - /Users/songzhao/Documents/WorkSpace/dev2qa.com-example-code/PythonExampleProject/js-game-engine/phaser/PhaserGruntProject/node_modules/grunt/lib/grunt.js
    - /usr/local/lib/node_modules/grunt-cli/bin/grunt
     babelify@10 requires Babel 7.x (the package '@babel/core'). If you'd like to use Babel 6.x ('babel-core'), you should install 'babelify@8'.
  16. The above error message says Fatal error: Cannot find module ‘@babel/core’.
  17. To fix this error run the command npm install @babel/core –save-dev to install the module ‘@babel/core’.
  18. Exit the grunt command console and run the command grunt –verbose to start it again, it will show the below output.
    Running "watch" task
    Waiting...
    Verifying property watch exists in config...OK
    Watching src/ABC.js for changes.
    Watching src/app.js for changes.
    Watching src/Test.js for changes.
  19. Change the content of the Test.js, I find the below output in the grunt console.
    >> File "src/Test.js" changed.
    
    Running "browserify" task
    
    Running "browserify:main" (browserify) task
    Verifying property browserify.main exists in config...OK
    Files: src/app.js -> scripts/app.js
    Options: banner="", browserifyOptions={"debug":true}, transform=[["babelify",{"stage":1}]]
    >> Error: Using removed Babel 5 option: .stage - Check out the corresponding stage-x presets http://babeljs.io/docs/plugins/#presets while parsing file: /Users/songzhao/Documents/WorkSpace/dev2qa.com-example-code/PythonExampleProject/js-game-engine/phaser/PhaserGruntProject/src/app.js
    Warning: Error running grunt-browserify.
    
  20. I google the error message >> Error: Using removed Babel 5 option: .stage – Check out the corresponding stage-x presets and find the below method to fix it.
  21. Change the browserify task definition to below because babel does not support the stage options anymore, you should use the presets option to configure it.
    // transform: [["babelify", { "stage": 1 }]]
    transform: [["babelify",  {presets: ["stage-1", "es2015"]}]]
  22. Rerun the grunt –verbose command in the terminal again, I get the error message >> Error: Cannot find module ‘babel-preset-stage-1’.
    Running "browserify:main" (browserify) task
    Verifying property browserify.main exists in config...OK
    Files: src/app.js -> scripts/app.js
    Options: banner="", browserifyOptions={"debug":true}, transform=[["babelify",{"presets":["stage-1","es2015"]}]]
    >> Error: Cannot find module 'babel-preset-stage-1'
    
  23. Run the command npm install babel-preset-stage-1 in the terminal to install the module.
  24. Exit and rerun the command grunt –verbose again, and change the Test.js file, then it will show the error message >> Error: Plugin/Preset files are not allowed to export objects, only functions like below.
    >> File "src/Test.js" changed.
    
    Running "browserify" task
    
    Running "browserify:main" (browserify) task
    Verifying property browserify.main exists in config...OK
    Files: src/app.js -> scripts/app.js
    Options: banner="", browserifyOptions={"debug":true}, transform=[["babelify",{"presets":["stage-1","es2015"]}]]
    >> Error: Plugin/Preset files are not allowed to export objects, only functions. In /Users/songzhao/Documents/WorkSpace/dev2qa.com-example-code/PythonExampleProject/js-game-engine/phaser/PhaserGruntProject/node_modules/babel-preset-stage-1/lib/index.js while parsing file: /Users/songzhao/Documents/WorkSpace/dev2qa.com-example-code/PythonExampleProject/js-game-engine/phaser/PhaserGruntProject/src/app.js
    Warning: Error running grunt-browserify.
    
  25. I have no idea, then I comment on the below code line in the gruntfile.js.
    // transform: [["babelify", { "stage": 1 }]]
    //transform: [["babelify",  {presets: ["stage-1", "es2015"]}]]
  26. After that when I rerun the grunt –verbose command, I meet another error ParseError: ‘import’ and ‘export’ may appear only with ‘sourceType: module’.
    >> File "src/Test.js" changed.
    
    Running "browserify" task
    
    Running "browserify:main" (browserify) task
    Verifying property browserify.main exists in config...OK
    Files: src/app.js -> scripts/app.js
    Options: banner="", browserifyOptions={"debug":true}
    >> /Users/songzhao/Documents/WorkSpace/dev2qa.com-example-code/PythonExampleProject/js-game-engine/phaser/PhaserGruntProject/src/app.js:1
    >> import {hello} from "./Test.js";
    >> ^
    >> ParseError: 'import' and 'export' may appear only with 'sourceType: module'
    Warning: Error running grunt-browserify.
  27. I fix this error by adding the sourceType: module option in the browserify task configuration.
    browserify: {
                main: {
                    options: {
        
                        browserifyOptions: { 
              
                            debug: true,
                            sourceType: module
                        },
     
                        // transform: [["babelify", { "stage": 1 }]]
                        //transform: [["babelify",  {presets: ["stage-1", "es2015"]}]]
                    },
    
                    src: 'src/app.js',
    
                    dest: 'scripts/app.js' 
                }            
            },
  28. Run the command grunt browserify to execute the task in the terminal to verify the error.
    $ grunt browserify
    Running "browserify:dist" (browserify) task
    Warning: Circular reference detected (.browserifyOptions.sourceType.parent.parent.exports.log.always) Use --force to continue.
    
    Aborted due to warnings.
    
  29. The above output message says the task has been aborted because of the warning message.

Leave a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.