Coding With Fun
Home Docker Django Node.js Articles Python pip guide FAQ Policy

Gruntfile instance


May 25, 2021 Grunt



Gruntfile instance

Here's a simple analysis of a Gruntfile case, which can also be used as an example:

module.exports = function(grunt) {

  grunt.initConfig({
    jshint: {
      files: ['Gruntfile.js', 'src/**/*.js', 'test/**/*.js'],
      options: {
        globals: {
          jQuery: true
        }
      }
    },
    watch: {
      files: ['<%= jshint.files %>'],
      tasks: ['jshint']
    }
  });

  grunt.loadNpmTasks('grunt-contrib-jshint');
  grunt.loadNpmTasks('grunt-contrib-watch');

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

};

At the bottom of the page is the full content of this Gruntfile instance, and if you read this article in order, you can follow us step by step through each part of the file. We'll use the following 5 Grunt plug-ins:

The first part is the "wrapper" function, which contains the entire Grunt configuration information.

module.exports = function(grunt) {
}

In this function, we can initialize the configuration object:

grunt.initConfig({
});

The project configuration information can then be read from the package.json file and stored in the pkg property. This gives us access to the properties listed in the package.json file, as follows:

pkg: grunt.file.readJSON('package.json')

So far we can see the following configuration:

module.exports = function(grunt) {
  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json')
  });
};

Now we can define the appropriate configuration for each of our tasks (define the task configurations we define for the project one by one), and then each task's configuration object is a property of the Grunt configuration object (that is, the configuration object accepted by grunt.initConfig, and the property name is the same as the task name). S o the "concat" task is the "concat" key (property) in our configuration object. Here's the configuration object for my "concat" task.

concat: {
  options: {
    // 定义一个用于插入合并输出文件之间的字符
    separator: ';'
  },
  dist: {
    // 将要被合并的文件
    src: ['src/**/*.js'],
    // 合并后的JS文件的存放位置
    dest: 'dist/<%= pkg.name %>.js'
  }
}

Notice how I refer to the name attribute in the JSON file (that is, the profile we introduced at the top of the configuration object). H ere I use pkg.name to access the package.json file information that we just introduced and stored in the pkg property, which will be parsed into a JavaScript object. Grunt comes with a simple template engine for outputing configuration objects (in this case, configuration objects in package.json) property values, where I have the concat task merge all the files that exist in the src/directory ending in .js, then store them in the dist directory and name them after the project name.

Now let's configure the uglify plug-in, which is used to compress (minify) JavaScript files:

uglify: {
  options: {
    // 此处定义的banner注释将插入到输出文件的顶部
    banner: '/*! <%= pkg.name %> <%= grunt.template.today("dd-mm-yyyy") %> */\n'
  },
  dist: {
    files: {
      'dist/<%= pkg.name %>.min.js': ['<%= concat.dist.dest %>']
    }
  }
}

Here we have uglify create a JavaScript file in the dist/directory that contains the results of the compression. Note that here I'm using the .lt;%-concat.dist.dest.gt;, so uglify automatically compresses the files generated in the concat task.

The QUnit plug-in is very simple to set up. You just need to give it the location of the file used for the test run, note that QUnit here is running on the HTML file.

qunit: {
  files: ['test/**/*.html']
},

The configuration of the JSHint plug-in is also simple:

jshint: {
  // define the files to lint
  files: ['gruntfile.js', 'src/**/*.js', 'test/**/*.js'],
  // configure JSHint (documented at http://www.jshint.com/docs/)
  options: {
      // more options here if you want to override JSHint defaults
    globals: {
      jQuery: true,
      console: true,
      module: true
    }
  }
}

JSHint only needs an array of files (that is, the array of files you need to detect), followed by an options object (which is used to override the default detection rules provided by JSHint). Y ou can view the full documentation at the JSHint Official Documentation site. If you're happy to use the default configurations provided by JSHint, you don't need to redefine them in Gruntfile.

Finally, let's look at the watch plug-in:

watch: {
  files: ['<%= jshint.files %>'],
  tasks: ['jshint', 'qunit']
}

You can run this task using grunt watch on the command line. When it detects a change in any file you specify (here I use the same file that needs to be detected in the JSHint task), it performs the specified task in the order you specify (here I specify the jshint and qunit tasks).

Finally, we'll load the required Grunt plug-in. They should all be installed by npm.

grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-contrib-qunit');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-concat');

Finally, some task is set. The most important thing is the default task:

// 在命令行上输入"grunt test",test task就会被执行。
grunt.registerTask('test', ['jshint', 'qunit']);

// 只需在命令行上输入"grunt",就会执行default task
grunt.registerTask('default', ['jshint', 'qunit', 'concat', 'uglify']);

Here's the final Gruntfile file:

module.exports = function(grunt) {

  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    concat: {
      options: {
        separator: ';'
      },
      dist: {
        src: ['src/**/*.js'],
        dest: 'dist/<%= pkg.name %>.js'
      }
    },
    uglify: {
      options: {
        banner: '/*! <%= pkg.name %> <%= grunt.template.today("dd-mm-yyyy") %> */\n'
      },
      dist: {
        files: {
          'dist/<%= pkg.name %>.min.js': ['<%= concat.dist.dest %>']
        }
      }
    },
    qunit: {
      files: ['test/**/*.html']
    },
    jshint: {
      files: ['Gruntfile.js', 'src/**/*.js', 'test/**/*.js'],
      options: {
        //这里是覆盖JSHint默认配置的选项
        globals: {
          jQuery: true,
          console: true,
          module: true,
          document: true
        }
      }
    },
    watch: {
      files: ['<%= jshint.files %>'],
      tasks: ['jshint', 'qunit']
    }
  });

  grunt.loadNpmTasks('grunt-contrib-uglify');
  grunt.loadNpmTasks('grunt-contrib-jshint');
  grunt.loadNpmTasks('grunt-contrib-qunit');
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-contrib-concat');

  grunt.registerTask('test', ['jshint', 'qunit']);

  grunt.registerTask('default', ['jshint', 'qunit', 'concat', 'uglify']);

};