zoukankan      html  css  js  c++  java
  • Grunt实现前端自动化

    定义:个人认为,前端自动化就是便捷地将开发代码迅速转化为发布代码的过程。

    意义:一般来说,开发代码不会直接部署上线运行,小型项目倒问题不大,但对于大型项目来说,要考虑到服务器的压力以及保密的等原因,需要将代码的体积最小化,减少请求数量,对代码进行混淆和压缩,如果手动完成这个过程,会比较繁琐。

    主要用到的技术:Grunt(首先要安装Node.js环境,安装好Node.js环境相当于安装好了npm,在项目建设过程中就是用npm下载各个JS库的)

    范例步骤:

    一、先看看整个项目文件结构(假定我们已经实现了src以及image文件夹下的所有内容

    这个项目实现的功能是随机显示一个颜色作为网页背景,并随机显示一个0~100的数字。

    传统的网页项目只会有名为src和image文件夹下的内容(忽略名为concat的两个文件夹以及文件夹下的内容,这两个文件夹只是在生成过程中的一个副产品^_^),真正部署时用到的是名为dist以及image的文件夹。

    我的HTML文件是这样的,引用了两个js文件和一个css文件:

    <!DOCTYPE html>
    <html>
    <head>
        <title>Grunt--前端自动化</title>
        <!-- build:css css/App.min.css -->
        <link rel="stylesheet" type="text/css" href="css/index.css">
        <!-- endbuild -->
    </head>
    <body>
        <a>Grunt--前端自动化</a>
        <!-- build:js js/App.min.js -->
        <script type="text/javascript" src="node_modules/jquery/dist/jquery.min.js"></script>
        <script type="text/javascript" src="js/index.js"></script>
        <!-- endbuild -->
    </body>
    </html>

    二、定义项目相关信息(package.json)

    {
      "name": "App",
      "version": "1.0.0",
      "description": "Grunt Page",
      "main": "index.js",
      "scripts": {
        "test": "echo "Error: no test specified" && exit 1"
      },
      "author": "Mandy","devDependencies": {
        "grunt": "^1.0.1",
        "grunt-contrib-clean": "^1.1.0",
        "grunt-contrib-concat": "^1.0.1",
        "grunt-contrib-copy": "^1.0.0",
        "grunt-contrib-csslint": "^2.0.0",
        "grunt-contrib-cssmin": "^2.2.0",
        "grunt-contrib-jshint": "^1.1.0",
        "grunt-contrib-uglify": "^3.0.1",
        "grunt-contrib-watch": "^1.0.0",
        "grunt-usemin": "^3.1.1",
        "jquery": "^3.2.1"
      },
      "dependencies": {
        "grunt": "^1.0.1",
        "grunt-contrib-clean": "^1.1.0",
        "grunt-contrib-concat": "^1.0.1",
        "grunt-contrib-copy": "^1.0.0",
        "grunt-contrib-csslint": "^2.0.0",
        "grunt-contrib-cssmin": "^2.2.0",
        "grunt-contrib-jshint": "^1.1.0",
        "grunt-contrib-uglify": "^3.0.1",
        "grunt-contrib-watch": "^1.0.0",
        "grunt-usemin": "^3.1.1",
    "jquery": "^3.2.1"
     } }

    package.json文件会描述这个npm包的所有相关信息,包括作者、简介、包依赖、构建等信息,格式是严格的JSON格式。

    所展示的这个文件依次定义了npm包名、版本号、描述、入口文件、脚本说明对象、作者、只在开发时需要的依赖包、当前包所需的依赖包,当然这个文件还可有别的参数,具体可以参考这里或者这里

    ps:之所以处处与npm相关,是因为基于grunt其实等于基于npm,而npm本身就是为了开发者开发各种JS库所诞生的“包管理工具”。

    如果一开始项目没有这个文件,可以通过控制台执行npm init,然后根据提示一步一步生成这个文件。

    其中dependencies下的条目其实都不是手打的,其实是可以自动生成的,具体看下一步。

    三、安装依赖包(我所理解的JS库,或许理解有误,正确称呼应为依赖包)

    安装Grunt:控制台执行npm install grunt --save-dev

    后面这个--save-dev参数就是生成前面dependencies下内容的关键,如果是--save-dev,就会保存到devDependencies,如果是--save,就会保存到dependencies。

    依此类推,安装clean(清空文件夹)、concat(合并文件)、csslint(CSS语法检查)、jshint(JS语法检查)、cssmin(压缩CSS)、uglify(混淆压缩JS)、copy(复制文件)、useminPrepare(usemin的准备)、usemin(使用压缩后的文件)、watch(检测文件变化)。

    npm install grunt-contrib-concat --save-dev
    npm install grunt-contrib-csslint --save-dev
    npm install grunt-contrib-cssmin --save-dev
    npm install grunt-contrib-jshint --save-dev
    npm install grunt-contrib-uglify --save-dev
    npm install grunt-contrib-watch --save-dev
    npm install grunt-usemin --save-dev
    npm install grunt-contrib-copy --save-dev
    npm install grunt-contrib-clean --save-dev

     安装完之后node_modules文件夹下就会出现截图中所出现的依赖包了。

    四、创建Gruntfile.js文件

    module.exports = function(grunt){
        //初始化grunt 配置
        grunt.initConfig({
     
            //获取package.json的信息,也就是后面pkg变量的来源
            pkg: grunt.file.readJSON('package.json'),
    
            // 各插件的配置信息
            clean:{
                src:"dist/"
            },
    
            concat: {
                options:{
                    stripBanners:true, // 合并时允许输出头部信息
                    banner:'/*!<%= pkg.name %> - <%= pkg.version %>-'+'<%=grunt.template.today("yyyy-mm-dd") %> */'
                },
                cssConcat:{
                    src:['src/css/*.css'],
                    dest:'src/css/concat/<%= pkg.name %> - <%= pkg.version %>.css' // dest 是目的地输出
                },
                jsConcat:{
                    src:[
                        'node_modules/jquery/dist/jquery.min.js',
                        'src/js/index.js'
                    ],
                    dest:'src/js/concat/<%=pkg.name %> - <%= pkg.version %>.js'
                }
            },
     
            csslint:{
                options:{
                    csslintrc:'.csslint'
                },
                build:['src/css/*.css']
     
            },
    
            jshint:{
                options:{
                    jshintrc:'.jshint'
                },
                build:['Gruntfile.js','src/js/*.js']
            },
    
            cssmin:{
                options:{
                    stripBanners:true, // 合并时允许输出头部信息
                    banner:'/*!<%= pkg.name %> - <%= pkg.version %>-'+'<%=grunt.template.today("yyyy-mm-dd") %> */
    '
                },
                build:{
                    src:'src/css/concat/<%=pkg.name %> - <%=pkg.version %>.css',// 压缩是要压缩合并了的
                    dest:'dist/css/<%= pkg.name %>.min.css' // dest 是目的地输出
                }
            },
            uglify:{
                options:{
                    stripBanners:true, // 合并时允许输出头部信息
                    banner:'/*!<%= pkg.name %> - <%= pkg.version %>-'+'<%=grunt.template.today("yyyy-mm-dd") %> */
    '
                },
                build:{
                    src:'src/js/concat/<%=pkg.name %> - <%=pkg.version %>.js',// 压缩是要压缩合并了的
                    dest:'dist/js/<%= pkg.name %>.min.js' // dest 是目的地输出
                }
            },
            copy:{
                html:{
                    src:'src/index.html',
                    dest:'dist/index.html'
                }
            },
            useminPrepare:{
                html:'index.html',
                options:{
                    dest:'dist'
                }
            },
            usemin:{
                html:['dist/index.html'],
                js:['dist/js/20170711 - 1.0.0.min.js'],
                css:['dist/css/20170711 - 1.0.0.min.css']
            },
    
            //watch自动化
            watch:{
                build:{
                    files:['src/js/*.js','src/css/*.css'],
                    tasks:['concat','cssmin','uglify'],
                    options:{spawn:false}
                }
            }
     
        });
        // 告诉grunt我们将使用插件
        grunt.loadNpmTasks('grunt-contrib-clean');
        grunt.loadNpmTasks('grunt-contrib-concat');
        grunt.loadNpmTasks('grunt-contrib-cssmin');
        grunt.loadNpmTasks('grunt-contrib-uglify');
        grunt.loadNpmTasks('grunt-contrib-jshint');
        grunt.loadNpmTasks('grunt-contrib-csslint');
        grunt.loadNpmTasks('grunt-contrib-watch');
        grunt.loadNpmTasks('grunt-contrib-copy');
        grunt.loadNpmTasks('grunt-usemin');
        // 告诉grunt当我们在终端输入grunt时需要做些什么
        // 先进行语法检查,如果没有问题,再合并,再压缩
        grunt.registerTask('default',
            [
            'clean',
            'concat',
            // 'csslint',
            // 'jshint',
            'cssmin',
            'uglify',
            'copy',
            'useminPrepare',
            'usemin',
            'watch'
            ]
        );
    };

    这个文件的存在是为了定义当我们在控制台执行grunt的时候所要执行的操作。

    initConfig是针对各个功能模块的具体配置

    loadNpmTasks是加载完成任务所需的模块

    registerTask是定义一个任务的执行过程(当然它不仅仅只能这样做,还可以有更多功能和更多写法,暂且这样认为吧)

    五、执行

    在控制台中执行grunt命令,执行到以下效果时,说明代码已经生成完毕了。

    此时我们可以看到dist文件夹出现在了项目中,接下来我们就只需要将dist文件夹和image文件夹拷贝到服务器上就可以运行了。

    生成后的项目只依赖于一个css文件和一个js文件(image文件夹其实我并没有用到),而打开这两个文件,我们会发现css和js代码都已经被压缩成了一行。

    HTML文件也变成了这样:

    <!DOCTYPE html>
    <html>
    <head>
        <title>Grunt--前端自动化</title>
        <link rel="stylesheet" href="css/App.min.css">
    </head>
    <body>
        <a>Grunt--前端自动化</a>
        <script src="js/App.min.js"></script>
    </body>
    </html>

    原本依赖的两个js也自动合并成了一个js —— 这里要隆重地说一说这个卡住我好久的问题!!!

    一开始我的HTML并没有变化,说明usemin并没有起到效果?于是我为了解决这个问题找了很多资料,期间查找无果搁置了一段时间。

    这几天才知道,原来是HTML文件中相应的JS或者CSS引用应该用<!-- build:js js/App.min.js --><!-- endbuild -->和<!-- build:css css/App.min.css --><!-- endbuild -->这样的一个注释括起来,之后usemin才可以正常运作。

    其实官方文档已经提到过这个,但是由于是用英文Blocks来描述的,半天反应不过来是指这样的东西。。

    没留意里面贴出的代码段,也没想到居然一个注释都能有这样的功能。。

  • 相关阅读:
    csv 中 数值被自动转换成科学计数法 的问题 excel打开后数字用科学计数法显示且低位变0的解决方法
    java 随机数 优惠码 生成 随机字串
    JSF primefaces session view expired 会话失效后页面跳转
    primefaces 查询 点击按钮 加载 动画 ajax loader
    时间戳 时区 java mysql
    JBoss 系列十四:JBoss7/WildFly如何加载外部的文件或properties文件
    MQTT 消息 发布 订阅
    mosquitt win32
    Hibernate JPA实体继承的映射(一) 概述
    wildfly jboss 优化配置
  • 原文地址:https://www.cnblogs.com/bettyling/p/7241021.html
Copyright © 2011-2022 走看看