zoukankan      html  css  js  c++  java
  • gulp前端自动化构建并上传oss

    前言

    前端自动化构建工具从最开始的grunt, gulp, fis等到现在比较流行的webpack可谓层出不穷,个人还是比较倾向于gulp,虽然有的时候会因为某个插件的配置问题头疼很久,但不可否认gulp真的很灵活,而且个人觉得它和node结合起来比较舒服,再有对项目目录结构的要求比较低,即使再老再乱的项目也可以通过它进行整理和自动化构建。这里用本公司的一个老项目举例子。

    项目目录

    因为是老项目,各种资源的引用乱七八糟,首先花费大量时间把项目中所有静态资源全部整理至新的目录中,并且把原来项目中的路径全部替换掉。现在新的静态资源目录为项目根目录Public下,如下图:

    初始化npm

    安装node,完了继续npm init,下一步下一步生成package.json,里面包含了我们项目所需要的各种模块的依赖和基本信息。这里拿我的package.json举例:

    {
      "name": "test",
      "version": "1.0.0",
      "description": "test web gulp",
      "main": "gulpfile.js",
      "dependencies": {
        "gulp": "^3.9.1",
        "gulp-clean-css": "^3.9.0",
        "gulp-concat": "^2.6.0",
        "gulp-csso": "^1.1.0",
        "gulp-filter": "^4.0.0",
        "gulp-jshint": "^2.0.0",
        "gulp-minify-html": "^1.0.6",
        "gulp-rename": "^1.2.2",
        "gulp-rev-collector": "^1.2.2",
        "gulp-zip": "^4.0.0",
        "jshint": "^2.9.5"
      },
      "devDependencies": {
        "arr-flatten": "^1.1.0",
        "array-differ": "^1.0.0",
        "array-uniq": "^1.0.3",
        "beeper": "^1.1.1",
        "dateformat": "^2.2.0",
        "expand-range": "^2.0.0",
        "expand-tilde": "^2.0.2",
        "extend-shallow": "^2.0.1",
        "gulp-aliyun-oss": "^0.1.1",
        "gulp-clean": "^0.3.2",
        "gulp-make-css-url-version": "0.0.13",
        "gulp-minify-css": "^1.2.4",
        "gulp-replace": "^1.0.0",
        "gulp-rev": "^7.1.2",
        "gulp-uglify": "^1.5.4",
        "has-gulplog": "^0.1.0",
        "lodash": "^3.0.0",
        "lodash._reescape": "^3.0.0",
        "lodash._reevaluate": "^3.0.0",
        "lodash._reinterpolate": "^3.0.0",
        "lodash.assignwith": "^4.2.0",
        "lodash.template": "^4.4.0",
        "multipipe": "^0.1.2",
        "object-assign": "^3.0.0",
        "parse-filepath": "^1.0.1",
        "repeat-element": "^1.1.2",
        "replace-ext": "^0.0.1",
        "run-sequence": "^1.2.2",
        "through2": "^2.0.0",
        "vinyl": "^0.5.0"
      },
      "scripts": {
        "test": "echo "Error: no test specified" && exit 1"
      },
      "author": "hxj",
      "license": "ISC"
    }

    安装依赖

    这个没什么说的,安装相应功能的gulp插件,npm install package(安装的包名,如:gulp) —save-dev然后回车。

    这里有一个很多人一直弄不明白的问题,就是为什么有时候加-save, 有时候加--save-dev,那么他们的区别到底是什么:

      —save-dev(也可以缩写成-D)输出的会出现在devDependencies,代表着是开发调试时的依赖,等到项目真正发布的时候不会真正出现在项目中。

      —save(也可以缩写成-S)输出的会出现在dependencies,代表着是发布后的依赖,等到项目真正发布的时候会真正出现在项目中,缺少它们项目会运行不了。 

    构建gulp任务

    这里直接贴代码,构建出来的静态文件全部上传到阿里云oss,因为公司项目是用jenkins部署的,所以在jenkins中会专门有一个shell脚本用来执行gulp构建任务:

    #!/bin/bash
    if [ -f gulpfile.js ] ; then
        /usr/bin/gulp buildBeta
    else
        echo "未找到gulpfile.js"
        exit 1
    fi
    
    #!/bin/bash
    tar czf ROOT.tar.gz *

    完整代码:

    var gulp = require("gulp");
    var runSequence = require('run-sequence'); // 按顺序逐个同步地运行 Gulp 任务
    var oss = require('gulp-aliyun-oss'); // 阿里云上传文件
    var cssmin = require('gulp-minify-css'); // 压缩css文件
    var uglify = require('gulp-uglify'); //js压缩
    var rev = require('gulp-rev'); // 为静态文件随机添加一串hash值, 解决cdn缓存问题
    var clean = require('gulp-clean'); // 删除文件及文件夹
    var revCollector = require('gulp-rev-collector'); //gulp-rev的插件 ,用于html模板更改引用路径
    
    // 配置开发环境, 默认为测试环境
    var ENV = "beta";
    var config = {
        beta: {
            accessKeyId: '******',
            accessKeySecret: '******',
            region: '******',
            bucket: '******',
            prefix: 'www/',
            domain: '//www.beta.example.com/www/'
        },
        prod: {
            accessKeyId: '******',
            accessKeySecret: '******',
            region: '******',
            bucket: '******',
            prefix: 'www/',
            domain: '//www.example.com/www/'
        }
    }
    
    // 配置输入输出路径
    var path = {
        base: "Public/static",
        input: {
            html: "app/Tpl/**/*.html",
            css: "Public/static/styles/**/*.css",
            js: "Public/static/script/**/*.js",
            images: "Public/static/images/**/*",
        },
        output: "Public/target"
    }
    
    function params() {
        return (ENV == 'prod') ? config.prod : config.beta;
    }
    
    // 压缩图片
    gulp.task('imgmin', function() {
        return gulp.src(path.input.images, { base: path.base })
            .pipe(rev())
            .pipe(gulp.dest(path.output))
            .pipe(rev.manifest())
            .pipe(gulp.dest(path.output + "/rev/images"));
    });
    
    // 压缩css
    gulp.task('cssmin', function() {
        return gulp.src(path.input.css, { base: path.base })
            .pipe(cssmin({
                advanced: false, //类型:Boolean 默认:true [是否开启高级优化(合并选择器等)]
                compatibility: 'ie7', //保留ie7及以下兼容写法 类型:String 默认:''or'*' [启用兼容模式; 'ie7':IE7兼容模式,'ie8':IE8兼容模式,'*':IE9+兼容模式]
                keepBreaks: false, //类型:Boolean 默认:false [是否保留换行]
                keepSpecialComments: '*'
                //保留所有特殊前缀 当你用autoprefixer生成的浏览器前缀,如果不加这个参数,有可能将会删除你的部分前缀
            }))
            .pipe(rev())
            .pipe(gulp.dest(path.output))
            .pipe(rev.manifest())
            .pipe(gulp.dest(path.output + "/rev/styles"));
    });
    
    // 压缩js
    gulp.task('jsmin', function() {
        return gulp.src(path.input.js, { base: path.base })
            .pipe(uglify({
                mangle: true,
                compress: true
            }))
            .pipe(rev())
            .pipe(gulp.dest(path.output))
            .pipe(rev.manifest())
            .pipe(gulp.dest(path.output + "/rev/script"));
    });
    
    // css中的引用资源路径替换
    gulp.task('replaceImgPath', function() {
        return gulp.src(
                [
                    path.output + "/rev/images/*.json",
                    path.output + "/styles/**/*.css"
                ]
            )
            .pipe(revCollector({
                replaceReved: true // 用来说明模板中已经被替换的文件是否还能再被替换,默认是false
            }))
            .pipe(gulp.dest(path.output + "/styles"));
    });
    
    // 上传静态文件到oss
    gulp.task('uploadOss', function(cb) {
        var options = {
            accessKeyId: params().accessKeyId,
            accessKeySecret: params().accessKeySecret,
            region: params().region,
            bucket: params().bucket,
            prefix: params().prefix,
            ossOpt: {
                headers: {
                    'Cache-Control': 'no-cache'
                }
            }
        };
    
        return gulp.src(['./Public/target/**/*', '!Public/target/rev/**/*']).pipe(oss(options));
    })
    
    /**
     * 页面模版资源路径替换
     */
    gulp.task('replaceHtml', function() {
        return gulp.src([
                path.output + "/rev/**/*.json",
                path.input.html
            ])
            .pipe(revCollector({
                replaceReved: true,
                dirReplacements: {
                    '/Public/static/': params().domain + '/',
                }
            }))
            .pipe(gulp.dest('./app/Tpl/'));
    });
    
    /**
     * 删除输出目录
     */
    gulp.task('del', function() {
        return gulp.src([path.output], { read: false }).pipe(clean());
    });
    
    //构建
    gulp.task('buildBeta', function(done) {
        ENV = "beta";
        runSequence(
            ['imgmin'],
            ['cssmin'],
            ['jsmin'],
            ['replaceImgPath'],
            ['uploadOss'],
            ['replaceHtml'],
            ['del'],
            done);
    })
    gulp.task('buildProd', function(done) {
        ENV = "prod";
        runSequence(
            ['imgmin'],
            ['cssmin'],
            ['jsmin'],
            ['replaceImgPath'],
            ['uploadOss'],
            ['replaceHtml'],
            ['del'],
            done);
    })
  • 相关阅读:
    2013-1-17 打开/关闭默认共享的命令
    2013-1-1遍历文件夹,改名文件
    2012-07-02 无边框最大化窗体
    2012-04-12 工具箱中添加自定义控件的方法
    2012-4-2 通过MdiParent设置窗体最前
    2012-2-7列举及终止进程
    python with as 以上这段代码执行完毕后,就算在处理过程中出问题了,文件 f 总是会关闭。
    终于好了 ipython 里执行dos命令 显示结果却显示在kernel界面里 搞定了
    Win7开启远程桌面
    哪位有方法把 dd/mm/yyyy的字符串 格式化成yyyy-mm-dd
  • 原文地址:https://www.cnblogs.com/huoxiao/p/9862285.html
Copyright © 2011-2022 走看看