zoukankan      html  css  js  c++  java
  • 自动化构建 -- 一篇文章带你了解Grunt

    Grunt怎么使用?

    Grunt算是最早的一款前端构建系统了,Grunt的插件生态非常的完善

    安装Grunt

    yarn add grunt

    安装完成后在项目根目录添加Grunt的入口文件gruntfile.js

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

    Grunt 任务注册

    Grunt 使用接口registerTask来注册任务

    
    module.exports=grunt=>{
      // 注册任务
      grunt.registerTask('foo',()=>{
        console.log('hello grunt~')
      })
      // 注册默认任务
      grunt.registerTask('default',()=>{
        console.log('default task~')
      })
    }
    

    执行grunt任务

    yarn grunt bar

    执行结果如下:

    默认任务不需要指定任务名

    yarn grunt

    执行结果如下:

    Grunt的Default任务

    一般注册default任务来映射其它任务

    // default的任务的第二个参数传入一个数组,数组中是要执行的其它的任务,执行default任务会依次执行数组中的任务
    grunt.registerTask('default',['foo','bar'])
    

    此时运行default任务结果如下图所示:

    Grunt 的异步任务

    Grunt默认使用同步模式,要使用异步操作,需要在任务中使用this.async() 来得到一个回调函数,并在异步操作完成后执行此回调,不然异步操作不会得到执行,此任务的回调函数不能是箭头函数

    grunt.registerTask('async-task', function(){
      const done=this.async()
        setTimeout(()=>{
            console.log('async task working...')
            done()
    
        },1000)
    })
    

    Grunt标记任务失败

    任务失败时,需要在任务中返回false来标记任务失败,执行多个任务时,当有任务失败了,后续任务就不会再执行了,可以根据提示添加force参数来让任务保持继续执行

    grunt.registerTask('badtask',()=>{
        console.log('badtask working')
        return false
    })
    grunt.registerTask('default',['foo','badtask','bar'])
    

    运行default失败的任务结果如下:

    从图中可以看到,foo任务执行了,但bar任务没有任务

    尝试添加--force强制不打断执行:

    此时bar任务也执行了

    Grunt 标记异步任务的失败

    异步任务不能像同步任务一样直接返回false,需要在this.async()中传入参数false

    grunt.registerTask('async-badtask',function(){
        const done=this.async()
        setTimeout(() => {
            console.log('async bad')
            done(false)
        }, 1000);
    })
    

    Grunt 的配置选项

    Grunt 提供一个API叫initConfig,用来添加一些配置选项,选项名一般与任务名保持一致,选项值可以是值,也可以是对象,具体看代码:

    grunt.initConfig({
        foo:'bar',
        objtest:{
            prop1:1232,
            objprop:{
                foo:'111'
            }
        }
    })
    grunt.registerTask('objtest',()=>{
        // 配置选项为对象时可以通过"."语法拿到子属性
        console.log(grunt.config('objtest.objprop.foo'))
    })
    grunt.registerTask('foo',()=>{
        console.log(grunt.config('foo'))
    })
    grunt.registerTask('default',['foo','objtest'])
    })
    

    运行结果如下:

    Grunt 的多目标任务

    Grunt注册的任务可以根据配置形成多个子任务

    为任务配置多个目标:

    grunt.initConfig({
        // 为multiTask任务配置的多个目标
        multiTask:{
            css:'1',
            js:'2'
        }
    })
    

    注册多目标任务:

    //使用registerMultiTask注册多目标任务
    grunt.registerMultiTask('multiTask',function(){
        // 可以通过this.target拿到目标的名称,this.data拿到目标的数据
        console.log(`target:${this.target},data:${this.data}`)
    })
    

    multiTask 运行结果:

    从上图可以看到多个目标都被执行了,当我们只想执行指定目标时,通过冒号+目标名来执行指定的目标

    注意:多目标任务不会对配置选项中的options进行执行,如下所示:

    // initConfig中的配置选项
    grunt.initConfig({
        multiTask:{
            options:{
                foo:'bar',
            },
            css:'1',
            js:'2'
        }
    })
    grunt.registerMultiTask('multiTask',function(){
        console.log(`target:${this.target},data:${this.data}`)
    })
    

    执行multiTask任务结果:

    可以看出,options中的配置没有对应的执行输出

    配置的目标中也有options时,会覆盖外层的options的对应属性

    grunt.initConfig({
      multiTask:{
          options:{
              foo:'bar',
          },
          css:{
              options:{
                  // 当执行css目标时,此foo会覆盖外层foo
                  foo:'baz'
              }
          },
          js:'2'
      }
    })
    grunt.registerMultiTask('multiTask',function(){
      console.log(this.options())
    })
    

    执行multiTask结果:

    css对应输出{foo:baz}
    js对应输出{foo:bar}

    grunt-contrib-clean插件 删除文件

    • Grunt的插件多数都是以grunt-contrib-的形式来名称的,比如grunt-contrib-clean就等于是clean任务,执行的时候只需要执行类似yarn grunt clean就可以了,同时它的配置选项名也只需要写clean就可以了

    • grunt-contrib-clean插件用于清除文件,其是一个多目标任务,需要对其配置多目标选项,不然会执行会产生错误提示

    • 安装grunt-contrib-clean插件

    yarn add grunt-contrib-clean

    • 加载任务
    grunt.initConfig({
      clean:{
          // 表示将会删除temp目录中的app.js文件
          // 除了单文件外,还可以批量删除文件,
          // 使用temp/*.txt来删除temp目录下以所有的txt文件
          // 使用temp/** 来删除temp目录以及temp里面的所有内容
          temp:'temp/app.js'
      }
    })
    grunt.loadNpmTasks('grunt-contrib-clean')
    
    • 执行任务

    yarn grunt clean

    grunt-sass插件处理sass

    • 安装依赖

    yarn add grunt-sass sass --dev

    • 配置目标
    const sass=require('sass')
    module.exports=grunt=>{
      grunt.initConfig({
        sass:{
          options:{
            sourceMap:true,
            implementation:sass
            // 更多选项可以到grunt-sass的官方仓库查看
          },
           main:{
            files:{
              'dist/css/main.css':'src/scss/main.scss'
            }
          }
        }
      })
      grunt.loadNpmTasks('grunt-sass')
    }
    
    

    load-grunt-tasks 插件自动加载

    加载grunt插件的npm包,我们可以使用grunt.loadNpmTasks('插件名')来加载插件,当插件很多时,其实不需要每个插件都手动加载一遍,可以使用grunt提供的loadGruntTasks方法,这个方法可以自动的为我们加载需要的插件

    只需要将grunt对象传入作为参数就可以了:loadGruntTasks(grunt)

    grunt-babel 编译es6语法

    • 安装依赖

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

    • 配置目标
    const loadGruntTasks=require('load-grunt-tasks')
    module.exports=grunt=>{
      grunt.initConfig({
        babel:{
            options:{
                sourceMap:true,
                presets:['@babel/preset-env']
            },
            main:{
                files:{
                    'dist/js/app.js':'src/js/app.js'
                }
            }
        }
      })
      loadGruntTasks(grunt) //自动加载所有的grunt插件中的任务
    }
    
    

    grunt-contrib-watch监听文件变化

    • 安装:yarn add grunt-contrib-watch --dev

    • 目标配置

    const loadGruntTasks=require('load-grunt-tasks')
    module.exports=grunt=>{
      grunt.initConfig({
        watch:{
          js:{
              // 监听的文件
              files:['src/js/*.js'],
              // 文件发生改变时需要执行的任务
              tasks:['babel']
          },
          css:{
              // 监听的文件
              files:['src/scss/*.scss'],
              // 文件发生改变时需要执行的任务
              tasks:['sass']
          }
        }
      })
      loadGruntTasks(grunt) //自动加载所有的grunt插件中的任务
      // 因为watch任务只在目标文件发生变动时才会执行相关任务,若要一开始就执行相关任务,可以为相关任务做一个映射,使watch监听开始前就先执行一遍相关任务
      grunt.registerTask('default',['sass','babel','watch'])
    }
    

    运行yarn grunt就可以开启watch监听了

  • 相关阅读:
    uni-app之预加载和取消预加载(仅支持APP和H5)——uni.preloadPage、uni.unPreloadPage
    JavaScript 之数组对象(Array)
    【2019csp模拟】文件列表
    【2019csp模拟】两段子序列
    B. 【普转提七联测 Day 6】载重
    C.【普转提七联测 Day 6】分数
    A. 【普转提七联测 Day 6】石头
    struct和class的区别
    TagHelper中获取当前Url
    为什么要使用 Taghelper (标记助手)
  • 原文地址:https://www.cnblogs.com/MissSage/p/14899473.html
Copyright © 2011-2022 走看看