基本使用

初始化项目

  1. yarn init -y

安装 grunt 包

  1. yarn add grunt

创建 gruntfile 文件

  1. code gruntfile.js

定义 grunt 任务

  1. // Grunt 的入口文件
  2. // 用于定义一些需要 Grunt 自动执行的任务
  3. // 需要导出一个函数,该函数接收一个 grunt 的形参,内部提供一些创建任务的 API
  4. module.exports = grunt => {
  5. grunt.registerTask('foo', () => {
  6. console.log('hello grunt');
  7. });
  8. }

执行 foo 任务,任务可以存在多个

yarn grunt foo

任务描述信息,registerTask 第二个参数

// Grunt 的入口文件
// 用于定义一些需要 Grunt 自动执行的任务
// 需要导出一个函数,该函数接收一个 grunt 的形参,内部提供一些创建任务的 API

module.exports = grunt => {
  grunt.registerTask('foo', () => {
    console.log('hello grunt');
  });
  grunt.registerTask('bar', '任务描述', () => {
    console.log('other task~');
  });
}
yarn grunt --help

如果注册任务的名称为 default,那么运行任务时,就不需要写任务抿成

// Grunt 的入口文件
// 用于定义一些需要 Grunt 自动执行的任务
// 需要导出一个函数,该函数接收一个 grunt 的形参,内部提供一些创建任务的 API

module.exports = grunt => {
  grunt.registerTask('foo', () => {
    console.log('hello grunt');
  });
  grunt.registerTask('bar', '任务描述', () => {
    console.log('other task~');
  });
  grunt.registerTask('default', () => {
    console.log('default task~');
  });
}
yarn grunt

default 一般用来依次执行其他任务

module.exports = grunt => {
  grunt.registerTask('foo', () => {
    console.log('hello grunt');
  });
  grunt.registerTask('bar', '任务描述', () => {
    console.log('other task~');
  });
  // grunt.registerTask('default', () => {
  //   console.log('default task~');
  // });

  grunt.registerTask('default', ['foo', 'bar']);
}
yarn grunt

grunt 异步任务

grunt.registerTask('async-task', function () {
  const done = this.async();

  setTimeout(() => {
    console.log('async task working~');
    done();
  }, 1000);
});
yarn grunt async-task

标记任务失败

return false 即可标记为任务失败

module.exports = grunt => {
  grunt.registerTask('bad', () => {
    console.log('bad working~');
    return false;
  });
  grunt.registerTask('foo', () => {
    console.log('foo working~');
  });
  grunt.registerTask('default', ['bad', 'foo']);
}

任务失败后,后续任务不会执行。我们可以通过 —force 强制后续任务继续执行。

yarn grunt --force

异步任务也可以标记失败,使用 done(false)

grunt.registerTask('bad-async', function () {
  const done = this.async();

  setTimeout(() => {
    done(false);
  }, 1000);
});

配置方法

module.exports = grunt => {
  grunt.initConfig({
    foo: {
      bar: 123
    }
  });

  grunt.registerTask('foo', () => {
    console.log(grunt.config('foo'));
    console.log(grunt.config('foo.bar'));
  });
}
yarn grunt foo

多目标任务

module.exports = grunt => {
  grunt.initConfig({
    build: {
      options: {
        foo: 'bar'
      },
      css: {
        options: {
          foo: 'baz'
        }
      },
      js: '2'
    }
  });

  // 多目标模式,可以让任务根据配置形成多个子任务
  grunt.registerMultiTask('build', function () {
    console.log('build task');
    console.log(this.options());
    console.log(`target: ${ this.target }, data: ${ this.data }`)
  });
}

运行目标任务

yarn grunt build

运行指定目标任务

yarn grunt build:css

插件使用

插件机制时 Grunt 机制的核心。很多构建任务都是通用的,所有由很多预设插件,插件内部封装了通用的构建任务。

一般来说,我们的构建过程都是由通用的构建任务组成。

安装 grunt-contrib-clean

yarn add grunt-contrib-clean
module.exports = grunt => {
  grunt.initConfig({
    clean: {
      temp: 'temp/app.js'
    }
  });
  grunt.loadNpmTasks('grunt-contrib-clean');
}
yarn grunt clean

通配符配置

module.exports = grunt => {
  grunt.initConfig({
    clean: {
      temp: 'temp/*.txt'
    }
  });
  grunt.loadNpmTasks('grunt-contrib-clean');
}
module.exports = grunt => {
  grunt.initConfig({
    clean: {
      // 清除所有子目录以及子目录下的文件
      temp: 'temp/**'
    }
  });
  grunt.loadNpmTasks('grunt-contrib-clean');
}

使用 Grunt 插件

  • 找到可使用插件,进行安装
  • 加载插件任务(loadNpmTasks)
  • initConfig 中为任务增加配置选项

常用插件

grunt-sass

yarn add grunt-sass sass --dev
const sass = require('sass');

module.exports = grunt => {
  grunt.initConfig({
    sass: {
      options: {
        sourceMap: true,
        implementation: sass
      },
      main: {
        files: {
          'dist/css/main.css': 'src/scss/main.scss'
        }
      }
    }
  });
  grunt.loadNpmTasks('grunt-sass');
}
yarn grunt sass

grunt-babel

新特性支持,代码转化

yarn add grunt-babel @babel/core @babel/preset-env --dev

减少 loadNpmTasks 使用

yarn add load-grunt-tasks --dev
const sass = require('sass');
const loadGruntTasks = require('load-grunt-tasks');

module.exports = grunt => {
  grunt.initConfig({
    sass: {
      options: {
        sourceMap: true,
        implementation: sass
      },
      main: {
        files: {
          'dist/css/main.css': 'src/scss/main.scss'
        }
      }
    },
    babel: {
      options: {
        sourceMap: true,
        presets: ['@babel/preset-env']
      },
      main: {
        files: {
          'dist/js/app.js': 'src/js/app.js'
        }
      }
    }
  });

  // grunt.loadNpmTasks('grunt-sass');
  loadGruntTasks(grunt); // 自动加载所有的 grunt 插件任务
}
yarn grunt babel

grunt-contrib-watch

yarn add grunt-contrib-watch --dev
const sass = require('sass');
const loadGruntTasks = require('load-grunt-tasks');

module.exports = grunt => {
  grunt.initConfig({
    sass: {
      options: {
        sourceMap: true,
        implementation: sass
      },
      main: {
        files: {
          'dist/css/main.css': 'src/scss/main.scss'
        }
      }
    },
    babel: {
      options: {
        sourceMap: true,
        presets: ['@babel/preset-env']
      },
      main: {
        files: {
          'dist/js/app.js': 'src/js/app.js'
        }
      }
    },
    watch: {
      js: {
        files: ['src/js/*.js'],
        tasks: ['babel']
      },
      css: {
        files: ['src/scss/*.scss'],
        tasks: ['sass']
      },
    }
  });

  loadGruntTasks(grunt); // 自动加载所有的 grunt 插件任务

  grunt.registerTask('default', ['sass', 'babel', 'watch']);
}
yarn grunt