[前端自动化]grunt的简单使用

前言

现在前端自动化已经是家常便饭,各种工具也是层出不穷,grunt、gulp、webpack是应用最广的三种工具,虽然grunt看似已垂垂老矣,但是以前写的很多项目一直用的就是grunt,温故方能知新,这里把grunt的基本操作再记录一下。

grunt常用插件

开始使用grunt很简单,在项目的根目录中添加两份文件:package.json 和 Gruntfile.js。npm安装模块和插件的操作就不细说了,主要是在Gruntfile.js中填写配置代码。代码目录结构如下:

代码目录

然后我们就来介绍最常用的几个插件:

合并:grunt-contrib-concat

合并代码是我们最需要的一个功能了,当项目变大并且模块很多的时候,就拿我们这个angular的单页应用项目来说,index页面会有一列的js代码,如下图所示:

js引用

我们需要将这些js合并为一个文件,大大减少网络请求数量因此来提升性能。grunt-contrib-concat完美胜任,下面我们来看看基本配置用法:

module.exports = function(grunt) {
    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),
        concat: {
            allInOne: {
                src: ['src/js/*.js'],
                dest: 'dest/js/<%= pkg.name %>.js'
            }         
        }
    });

    grunt.loadNpmTasks('grunt-contrib-concat');

    grunt.registerTask('default', ['concat']);
};

将src/js中所有js文件合并为一个js,放在dest/js目录下,名字为package.json中项目name。这时候项目目录中就会出现一个dest的文件夹,如下所示:

concat

压缩:grunt-contrib-uglify

合并文件后,体积仍然比较大,上线之前要将代码压缩,因此我们接着将上一步合并后的代码压缩,这里就需要用到grunt-contrib-uglify插件。仍然直接上配置代码:

module.exports = function(grunt) {
    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),
        concat: {
            allOne: {
                src: ['src/js/*.js'],
                dest: 'dest/js/<%= pkg.name %>.js'
            }         
        },
        uglify: {
            buildrelease: {
                options: {
                    report: "min" //输出压缩率
                },
                files: [{
                    expand: true, 
                    cwd: 'dest/js', //js目录
                    src: '**/*.js', //所有js文件
                    dest: 'dest/js', //输出到此目录下
                    ext: '.min.js' //指定扩展名
                }]
            }
        }
    });

    grunt.loadNpmTasks('grunt-contrib-uglify');
    grunt.loadNpmTasks('grunt-contrib-concat');

    grunt.registerTask('default', ['concat', 'uglify:buildrelease']);
};

这里我将concat后的js文件仍然输出到当前目录dest/js下,如下图所示:

urglify

引用替换:grunt-usemin(grunt-contrib-copy,grunt-contrib-clean)

使用上面两个插件合并压缩后,每次都需要手动去html页面中修改引用路径,这并不是我们想要的结果,并且直接在源版本上修改也不利于测试与发布,因此首先我们需要用到grunt-contrib-copy插件,将源代码copy一份,然后在副本上进行压缩合并,这样无论是全部压缩还是部分压缩就比较灵活了,copy之后就可以使用grunt-usemin插件了,usemin是一个多任务插件,它包括两个任务,useminPrepare和usemin。
useminPrepare用来检测html页面中的脚本块,包括脚本文件的源路径,目的路径,从而更新后续需要使用到的Grunt任务的配置信息,如前面使用的concat,uglify。useminPrepare只是分析文件,获取文件及路径信息,不更新内容。HTML中的脚本块如下:

block

而usemin则进行文件引用替换,将源文件中的文件块替换为压缩文件。useminPrepare已经帮助我们自动配置了concat,uglify针对的源文件以及目的文件的路径信息,因此就无需再手动配置concat和uglify任务了。配置代码如下

module.exports = function(grunt) {
    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),
        clean: {
            src: 'build/'
        },
        useminPrepare: {
            html: 'build/index.html',
            options: {
                dest: 'build'
            }
        },
        uglify: {
            buildrelease: {
                options: {
                    report: "min" //输出压缩率
                }
            }
        },
        usemin: {
            html: 'build/index.html',
            options: {
                dest: 'build'
            }
        },
        copy: {
            html: {
                files: [{
                    expand: true,
                    cwd: 'src',
                    src: '**/*',
                    dest: 'build/'
                }]
            }
        }
    });

    grunt.loadNpmTasks('grunt-contrib-clean');
    grunt.loadNpmTasks('grunt-contrib-copy');
    grunt.loadNpmTasks('grunt-contrib-uglify');
    grunt.loadNpmTasks('grunt-contrib-concat');
    grunt.loadNpmTasks('grunt-usemin');

    grunt.registerTask('default', ['clean', 'copy', 'useminPrepare', 'concat', 'uglify', 'usemin']);
};

上面又引入了一个clean插件,每次构建时候先清除build目录,这样build目录就是我们打包后的要的结果了。目录结构如下:

build

总结

以上就是grunt最基本的使用方法,为了简单方便,插件的很多配置并没有介绍与使用,可以在此基础上查看官方文档使用更强的功能即可。项目代码使用的是大漠穷秋的angular实战的一个Demo,也是我入门angular的资料,需要注意的是打包angular项目时候要保证严格的依赖注入风格,否则合并后会报错的。

参考资料

  1. 中文官网
  2. usemin使用
原文地址:https://www.cnblogs.com/lijie33402/p/6237462.html