grunt的安装与使用

 

野猪侠咕噜

Grunt是基于Node.js的javascript项目构建工具。它的工作就是运行你所设定的批处理任务。其实去年这个时候我已经开始用上grunt,这篇文章是给师弟师妹们学习之用。现阶段利用github几乎必须学会使用grunt,因为大多数javascript项目都用该工具进行项目管理,不用grunt连登堂入室都做不到。

一.安装及使用流程

1)首先确定无论你是什么系统(windows、linux、macOS),系统里面都已经装好了nodejs。可通过在命令行输入npm -v或者node -v查看版本,来确定nodejs是否安装,没有就去nodejs.org上面去下载安装。

2)在全局中安装grunt客户端:在命令行输入 client npm install -g grunt-cli按回车。

说明:grunt有二个部分:服务器端(grunt)和客户端(grunt-cli)。grunt-cil的任务很简单:允许在命令行中输入grunt, 调用与Gruntfile.js在同一目录中的grunt服务器端程序。所以安装grunt-cli并不等于安装了grunt!每个要使用grunt的工程目录下还要安装grunt服务端版本,具体请看步骤4的说明。

3)找一个大牛们的工程耍耍,例如github上的angularjs,或者bootstrap,git clone到自己的测试文件夹下。

4)在目标工程项目中安装grunt服务器端:打开命令行,切到该工程的根目录,输入npm install按回车。

说明:grunt是基于nodejs的项目构建工具,因此使用npm包管理工具安装即可。一般而言,grunt 和 grunt 插件都会在这些项目根目录下的package.json文件中定义。这样就可以通过一个命令将当前项目依赖的模块安装完毕。(如果grunt没有在项目的package.json文件中定义,则无法执行之后的grunt命令,需要使用npm install grunt命令安装grunt服务器端)

事实上,对于每个项目,都要执行相似的工作,从而对每个项目生成其特定的grunt版本。这是很正常的,因为不同项目可能需要不同的grunt模块,或者同一个模块的不同版本,故而一个项目一个grunt服务是最好的结果。

5)执行grunt批处理功能:在命令行输入grunt按回车。之后会按gruntfile.js中预定义的批处理命令生成各种文件。看看命令行的提示,以及目录中多了什么文件。OK,到这里你已经学会怎么用grunt了。

二. package.json文件的书写

虽然我们已经会使用grunt执行命令,但是还不会写这些命令。学会使用grunt进行批处理的关键是学会写package.json和gruntfile.js这两个文件。package.json是定义依赖包的目录文件,而gruntfile.js是批处理命令文件。package.json比较简单,上github多看几个大牛工程的package.json就知道怎么写了。考虑到初学者看到太大段的文字可能看不懂,我这里提供一个简短的例子,来自于robin项目:

{
  "name": "robin_zycj",
  "version": "1.0.0",
  "devDependencies": {
    "grunt": "~0.4.1",
    "grunt-contrib-clean": "0.4.0",
    "grunt-contrib-compress": "0.4.1",
    "grunt-contrib-concat": "~0.2.0",
    "grunt-contrib-connect": "0.1.2",
    "grunt-contrib-copy": "~0.5.0",
    "grunt-contrib-csslint": "~0.1.1",
    "grunt-contrib-cssmin": "~0.5.0",
    "grunt-contrib-imagemin": "~0.1.2",
    "grunt-contrib-less": "~0.11.1",
    "grunt-contrib-uglify": "~0.2.0",
    "grunt-css": ">0.0.0",
    "grunt-string-replace": "^0.2.7"
  }
}

grunt及grunt的插件都定义在devDenpendencies属性中。其中grunt-contrib系列插件都是由grunt主团队维护的。每个插件之后定义的是其版本号:如果只是“0.1.2”这样的数字,表示只安装这个版本。如果加了波浪号~,表示允许该插件自动升级。根据需求选择版本。

三. gruntfile.js文件的书写

这个gruntfile.js中定义的是grunt的批处理命令。根据需求不同、所用插件不同,差别很大,所以不能一概而论。这里我只给出一个我以前自动处理robin项目前端文件的gruntfile.js,并添加了些注释作为参考。

module.exports = function (grunt) {
    // 给grunt新建些设置
    grunt.initConfig({
        //首先把目录拷贝到指定位置
        copy: {
            main: {
                files: [
                    // 拷贝整个目录
                    {expand: true, cwd: '../views/zoro/', src: ['**'], dest: 'zoro/'},
                    // 拷贝全部图片文件夹到指定目录
                    {expand: true, flatten: false, cwd: '../views/zoro/module/download/css/images/', src: ['**'], dest: 'zoro/module/cssmin/images/'},
                    {expand: true, flatten: false, cwd: '../views/zoro/module/files/css/images/', src: ['**'], dest: 'zoro/module/cssmin/images/'},
                    {expand: true, flatten: false, cwd: '../views/zoro/module/platform/css/images/', src: ['**'], dest: 'zoro/module/cssmin/images/'},
                    {expand: true, flatten: false, cwd: '../views/zoro/module/robin/cssv2/images/', src: ['**'], dest: 'zoro/module/cssmin/images/'},
                ]
            },
        },

        //对一些文件进行字符串替换工作,这样做是为了避免修改主版本代码的情况下生成新代码
        'string-replace': {
            robin: {
                files: {
                    'zoro/module/robin/robin.js': '../views/zoro/module/robin/robin.js',
                },
                options: {
                    replacements: [
                        {
                            pattern: "require('less');",
                            replacement: ''
                        },
                        {
                            pattern: 'require("module/robin/cssv2/robin.less");',
                            replacement: 'require("module/cssmin/all.min.css");'
                        }
                    ]
                }
            },
            init: {
                files: {
                    'zoro/init.js': '../views/zoro/init.js',
                },
                options: {
                    replacements: [
                        {
                            pattern: "'less' :            'core/less',",
                            replacement: ''
                        },
                        {
                            pattern: ",preload : ['core/plugin-less']",
                            replacement: ''
                        }
                    ]
                }
            },
            download: {
                files: {
                    'zoro/download.php': '../views/zoro/download.php',
                },
                options: {
                    replacements: [
                        {
                            pattern: '<link rel="stylesheet/less" type="text/css" href="/application/views/zoro/module/main/css/base.less">',
                            replacement: '<link rel="stylesheet" type="text/css" href="/application/views/zoro/module/cssmin/all.min.css">'
                        },
                        {
                            pattern: '<link rel="stylesheet/less" type="text/css" href="/application/views/zoro/module/robin/cssv2/reset.less">',
                            replacement: ''
                        },
                        {
                            pattern: '<link rel="stylesheet/less" type="text/css" href="/application/views/zoro/module/robin/cssv2/robin.less">',
                            replacement: ''
                        },
                        {
                            pattern: '<link rel="stylesheet/less" type="text/css" href="/application/views/zoro/module/download/css/styles.less">',
                            replacement: ''
                        },
                        {
                            pattern: '<script src="/application/views/zoro/core/less.js" type="text/javascript"></script>',
                            replacement: ''
                        }
                    ]
                }
            },
            others: {
                files: {
                    'zoro/module/circles/circles.js': '../views/zoro/module/circles/circles.js',
                    'zoro/module/files/files.js': '../views/zoro/module/files/files.js',
                    'zoro/module/files/files_sync.js': '../views/zoro/module/files/files_sync.js',
                    'zoro/module/files/receives.js': '../views/zoro/module/files/receives.js',
                    'zoro/module/files/recycles.js': '../views/zoro/module/files/recycles.js',
                    'zoro/module/platform/platform.js': '../views/zoro/module/platform/platform.js',
                },
                options: {
                    replacements: [
                        {
                            pattern: 'require("module/circles/css/circle.less");',
                            replacement: ''
                        },
                        {
                            pattern: 'require("module/files/css/file.less");',
                            replacement: ''
                        },
                        {
                            pattern: 'require("module/files/css/recycle.less");',
                            replacement: ''
                        },
                        {
                            pattern: 'require("module/files/css/share.less");',
                            replacement: ''
                        },
                        {
                            pattern: 'require("module/files/css/receive.less");',
                            replacement: ''
                        },
                        {
                            pattern: 'require("module/files/css/linkman.less");',
                            replacement: ''
                        },
                        {
                            pattern: 'require("module/platform/css/platform.less");',
                            replacement: ''
                        }
                    ]
                }
            }
        },

        //解码less
        less: {
            development: {
                options: {
                    compress: true,
                },
                files: {
                    "zoro/module/main/css/base.css": "../views/zoro/module/main/css/base.less",

                    "zoro/module/robin/css/reset.css": "../views/zoro/module/robin/css/reset.less",
                    "zoro/module/robin/css/robin.css": "../views/zoro/module/robin/css/robin.less",
                    "zoro/module/robin/cssv2/reset.css": "../views/zoro/module/robin/cssv2/reset.less",
                    "zoro/module/robin/cssv2/robin.css": "../views/zoro/module/robin/cssv2/robin.less",

                    "zoro/module/files/css/file.css": "../views/zoro/module/files/css/file.less",
                    "zoro/module/files/css/linkman.css": "../views/zoro/module/files/css/linkman.less",
                    "zoro/module/files/css/receive.css": "../views/zoro/module/files/css/receive.less",
                    "zoro/module/files/css/recycle.css": "../views/zoro/module/files/css/recycle.less",
                    "zoro/module/files/css/share.css": "../views/zoro/module/files/css/share.less",

                    "zoro/module/platform/css/platform.css": "../views/zoro/module/platform/css/platform.less",

                    "zoro/module/download/css/styles.css": "../views/zoro/module/download/css/styles.less",
                }
            }
        },
        //把解码好的css文件组合压缩成一个文件,cssmin是CSS压缩工具
        cssmin: {
            add_banner: {
                options: {
                    banner: '/* 10 in one, view gruntfile.js */'
                },
                files: {
                    'zoro/module/cssmin/all.min.css': [
                        // "zoro/module/main/css/base.css",
                        // "zoro/module/robin/cssv2/reset.css",
                        "zoro/module/robin/cssv2/robin.css",
                        "zoro/module/files/css/file.css",
                        "zoro/module/files/css/linkman.css",
                        "zoro/module/files/css/receive.css",
                        "zoro/module/files/css/recycle.css",
                        "zoro/module/files/css/share.css",
                        "zoro/module/platform/css/platform.css",
                        "zoro/module/download/css/styles.css"
                    ]   
                }
            }
        },
        //uglify是js压缩工具
        uglify: {
            options: {
                mangle: false, //不混淆变量名
                preserveComments: 'all', //不删除注释,还可以为 false(删除全部注释),some(保留@preserve @license @cc_on等注释)
                banner: '/*! <%= grunt.template.today("yyyy-mm-dd") %> */\n'//添加banner
            },
            buildall: {//按原文件结构压缩js文件夹内所有JS文件
                files: [
                    {
                        expand: true,
                        src: 'zoro/module/**/*.js',//所有js文件
                        dest: ''//生成的文件就输出到原目录下
                    }
                ]
            },
        }
    });
    // 载入插件
    grunt.loadNpmTasks('grunt-contrib-copy');
    grunt.loadNpmTasks('grunt-string-replace');
    grunt.loadNpmTasks('grunt-contrib-less');
    grunt.loadNpmTasks('grunt-contrib-cssmin');
    grunt.loadNpmTasks('grunt-contrib-uglify');
    // 默认任务
    grunt.registerTask('default', ['copy', 'string-replace', 'less', 'cssmin', 'uglify']);
};