欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

gulp前端自动化构建并上传oss

程序员文章站 2022-06-16 23:12:39
前言 前端自动化构建工具从最开始的grunt, gulp, fis等到现在比较流行的webpack可谓层出不穷,个人还是比较倾向于gulp,虽然有的时候会因为某个插件的配置问题头疼很久,但不可否认gulp真的很灵活,而且个人觉得它和node结合起来比较舒服,再有对项目目录结构的要求比较低,即使再老再 ......

前言

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

项目目录

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

gulp前端自动化构建并上传oss

初始化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 + '/',
                '/public/static/': params().domain + '/',
                '/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);
})