最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • Grunt —— 最早的前端自动化构建系统

    正文概述 掘金(顽皮的雪狐七七)   2020-12-27   633

    目录

    • Grunt
      • Grunt的基本使用
        • 安装
        • 起步
        • 添加任务描述
        • 默认任务
        • 添加执行任务列表
        • 异步任务
      • Grunt标记任务失败
        • 如果任务失败如何表示?
        • 如何让后面的任务继续执行呢?
        • 异步任务如何标记失败?
      • Grunt配置选项方法 —— initConfig
      • Grunt 多目标任务
        • 如何配置多目标任务?
        • 如果在函数中拿到配置、目标和值?
      • Grunt插件的使用
        • 步骤
        • 实例
        • 常用插件
          • grunt-sass
          • grunt-babel
          • grunt-contrib-watch

    Grunt

    Grunt官网

    特点

    Grunt是最早的前端构建系统,插件生态非常的完善。由于其工作过程是基于临时文件实现的,每一步都要读写磁盘,所以构建速度相对较慢。

    Grunt的基本使用

    安装

    npm i -g grunt
    

    起步

    1. 添加一个gruntfile.js的文件,进行配置
    module.exports = grunt => {
      // 注册任务,第一个参数是任务名称,第二个参数是任务函数(当任务发生时自动执行此函数)
      grunt.registerTask('foo', () => {
        console.log('hello grunt')
      })
    }
    
    1. 命令行中执行grunt foo就可以看到执行了foo任务
    grunt foo
    
    # Running "foo" task
    # hello grunt
    
    # Done.      
    

    添加任务描述

    如果第二个参数是字符串,那么默认是任务描述

    module.exports = grunt => {
      grunt.registerTask('foo', '任务描述', () => {
        console.log('hello grunt')
      })
    }
    

    使用grunt -h可以看到

    Grunt —— 最早的前端自动化构建系统

    默认任务

    如果任务的名称叫default那么为默认任务

    module.exports = grunt => {
      grunt.registerTask('default', '任务描述', () => {
        console.log('default grunt')
      })
    }
    

    执行的时候不用添加任务名称就可以直接执行

    grunt
    
    # Running "default" task
    # default grunt
    
    # Done.
    

    添加执行任务列表

    default任务后面可以是一个数组,数组里面的元素是任务名称

    module.exports = grunt => {
      grunt.registerTask('foo', () => {
        console.log('foo grunt')
      })
    
      grunt.registerTask('bar',() => {
        console.log('bar grunt')
      })
    
      grunt.registerTask('default', ['foo', 'bar'])
    }
    

    执行的时候会按照顺序依次执行任务

    grunt
    
    # Running "foo" task
    # foo grunt
    
    # Running "bar" task
    # bar grunt
    
    # Done.
    

    异步任务

    如果在任务中写异步代码,可能会出不来

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

    这里的运行结果为空,如果要解决这个问题,需要这样写

    grunt.registerTask('async-task', function() {
        // 通过this的async方法得到一个异步方法
        const done = this.async()
        setTimeout(() => {
          console.log('async task working~')
          // 完成过后调用异步函数表示该任务已经被完成,知道done被执行,grunt才会结束
          done()
        },1000)
     })
    

    Grunt标记任务失败

    如果任务失败如何表示?

    如果在运行的时候,文件找不到了,可以标记任务为失败任务。失败任务只要返回false即可

    grunt.registerTask('bad', () => {
        console.log('bad grunt')
        return false
    })
    

    运行之后,就会抛出错误,然后后面的任务就会中断。

    grunt bad
    
    # Running "bad" task
    # bad grunt
    # Warning: Task "bad" failed. Use --force to continue.
    
    # Aborted due to warnings.
    

    如何让后面的任务继续执行呢?

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

    如果在后面添加--force参数,那么后面的任务就会继续执行

    grunt --force
    # Running "foo" task
    # foo grunt
    
    # Running "bad" task
    # bad grunt
    # Warning: Task "bad" failed. Used --force, continuing.
    
    # Running "bar" task
    # bar grunt
    
    # Done, but with warnings.
    

    异步任务如何标记失败?

    grunt.registerTask('async-task-fail', function() {
        const done = this.async()
        setTimeout(() => {
          console.log('async task fail~')
          // 执行done函数的时候,参数传false,就会标记为失败任务
          done(false)
        },1000)
    })
    

    Grunt配置选项方法 —— initConfig

    Grunttask配置都是在Gruntfile 中的 grunt.initConfig 方法中指定的。此配置主要是以任务名称命名的属性,也可以包含其他任意数据。

    // 接收一个对象,键一般与任务名保持一致
    grunt.initConfig({
        foo: 'bar'
    })
    
    grunt.registerTask('foo', () => {
        // 根据config方法获取配置,接收字符串参数,参数是配置的键
        console.log(grunt.config('foo')) //bar
    })
    

    foo也可以是个对象

    grunt.initConfig({
        foo: {
            bar: 123
        }
    })
    
    grunt.registerTask('foo', () => {
        console.log(grunt.config('foo.bar')) // 123
    })
    

    Grunt 多目标任务

    除了普通任务,Grunt还支持多目标任务,也可以理解为子任务。之后在我们实现Grunt构建任务时非常有用。

    如何配置多目标任务?

    多目标模式,可以让任务根据配置形成多个子任务

    module.exports = grunt => {
      grunt.initConfig({
      // build有两个目标任务,一个css和一个js,执行的时候两个都会执行
        build: {
        // options作为配置选项,不作为目标任务
          options: {
            foo: 'bar'
          },
          css: '1',
          js: '2'
        }
      })
      // 多目标模式有对应函数,第一个参数是任务名称,第二个参数是任务函数
      grunt.registerMultiTask('build', function() {
        console.log('build task')
      })
    }
    

    执行一下,可以看到cssjs的目标任务都执行了

    grunt build
    
    # Running "build:css" (build) task
    # build task
    
    # Running "build:js" (build) task
    # build task
    
    # Done.
    

    也可以直接运行单个目标任务

    grunt build:css
    
    # Running "build:css" (build) task
    # build task
    
    # Done.
    

    如果在函数中拿到配置、目标和值?

    • options中的东西通过this.options()方法去拿
    • 目标任务名通过this.target去拿
    • 目标任务对应的值通过this.data去拿
    grunt.registerMultiTask('build', function() {
        console.log(this.options())
        console.log(`target: ${this.target}, data: ${this.data}`)
    })
    

    执行得到

    grunt build:css
    
    # Running "build:css" (build) task
    # { foo: 'bar' }
    # target: css, data: 1
    
    # Done.
    

    如果目标任务本身也有options,则会对外面的options进行覆盖

    grunt.initConfig({
        build: {
            options: {
                foo: 'bar'
            },
            css: {
                options: {
                    foo: 'baz'
                }
            },
            js: '2'
        }
    })
    

    执行得到css目标任务的target进行了覆盖

    grunt build
    
    # Running "build:css" (build) task
    # { foo: 'baz' }
    # target: css, data: [object Object]
    
    # Running "build:js" (build) task
    # { foo: 'bar' }
    # target: js, data: 2
    
    # Done.
    

    Grunt插件的使用

    插件机制是Grunt的核心,因为很多构建任务是通用的,例如:压缩代码。
    一般我们都是通过通用的构建任务构成的。
    插件的命名规则都是grunt-contrib-<taskName>

    步骤

    • 安装插件
    • Grunt中导入插件
    • 去插件文档中配置相关的选项

    实例 —— clean插件

    clean插件用来清除我们在项目开发当中产生的临时文件

    1. 安装插件npm install grunt-contrib-clean
    2. 在文件中引用
    const { loadNpmTasks } = require("grunt")
    
    module.exports = grunt => {
      grunt.initConfig({
        clean: {
          temp: 'temp/*.txt' //清空目录,可以是单个文件路径'temp/app.js',也可以是通配符匹配路径 temp/**
    
        }
      })
      grunt.loadNpmTasks('grunt-contrib-clean')
    }
    
    1. 在命令行中执行grunt clean,就会看到temp目录下的所有txt文件被删除了。

    常用插件

    grunt-sass
    1. 安装npm i grunt-sass sass --save-dev
    2. 使用
    const { loadNpmTasks } = require("grunt")
    const sass = require('sass')
    module.exports = grunt => {
      grunt.initConfig({
        sass: {
          // 不加配置会报错,这个配置选项使我们在处理的时候使用哪个模块去处理sass的编译
          // Fatal error: The implementation option must be passed to the Sass task
          options:{
            implementation: sass,
            // 可选参数,会生成对应的sourceMap文件
            sourceMap: true
          },
          main: {
            // 键是输出路径,值是原路径
            files: {
              'css/style.css': 'scss/main.scss'
            }
          }
        }
      })
      grunt.loadNpmTasks('grunt-sass')
    }
    
    1. 执行grunt sass,可以看到sass被成功编译。
    2. 剩下的配置选项需要去官方文档中查找
    grunt-babel
    1. 安装npm i grunt-babel @babel/core @babel/preset-env
    2. 为了减少loadNpmTasks的使用,可以安装npm i load-grunt-tasks
    3. 使用
    const sass = require('sass')
    const loadGruntTasks = require('load-grunt-tasks')
    module.exports = grunt => {
      grunt.initConfig({
        babel: {
        // 最新的转换规则
          options: {
            presets: ['@babel/preset-env'],
            // 会生成对应的sourceMap文件
            sourceMap: true
          },
          main: {
            // 键是输出,值是输入
            files: {
              'dist/js/app.js': 'src/js/app.js'
            }
          }
        }
      })
      // 自动加载所有的grunt插件中的任务
      loadGruntTasks(grunt)
    }
    
    1. 执行grunt babel,可以看dist文件夹中es6的语法被成功编译。
    2. 剩下的配置选项需要去官方文档中查找
    grunt-contrib-watch

    监听文件修改并自动编译

    1. 安装npm i grunt-contrib-watch
    2. 使用
    const sass = require('sass')
    const loadGruntTasks = require('load-grunt-tasks')
    module.exports = grunt => {
      grunt.initConfig({
        // sass插件
        sass: {
          options:{
            implementation: sass,
            sourceMap: true
          },
          main: {
            files: {
              'css/style.css': 'scss/main.scss'
            }
          }
        },
        // babel插件
        babel: {
          options: {
            presets: ['@babel/preset-env'],
            sourceMap: true
          },
          main: {
            files: {
              'dist/js/app.js': 'src/js/app.js'
            }
          }
        },
        // 监听插件
        watch: {
          // 对js的任务
          js: {
            // 监听的文件路径,还有监听修改之后执行的任务名称
            files: ['src/js/*.js'],
            tasks: ['babel']
          },
          // 对css的任务
          css: {
            files: ['scss/*.scss'],
            tasks: ['sass']
          }
        }
      })
      // 自动加载所有的grunt插件中的任务
      loadGruntTasks(grunt)
    }
    
    1. 执行grunt watch,然后修改对应的文件可以看到实时改变。

    2. 由于watch执行的时候不会自动先执行sassbabel,所以需要定义一个default任务,先执行一遍之后再监听。

    //先执行sass和babel再执行watch
    grunt.registerTask('default', ['sass', 'babel', 'watch'])
    

    这个时候执行grunt即可。

    grunt      
    
    # Running "sass:main" (sass) task
    
    # Running "babel:main" (babel) task
    
    # Running "watch" task
    # Waiting...
    

    起源地下载网 » Grunt —— 最早的前端自动化构建系统

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元