gulp前端自動化構建並上傳oss

来源:https://www.cnblogs.com/huoxiao/archive/2018/10/27/9862285.html
-Advertisement-
Play Games

前言 前端自動化構建工具從最開始的grunt, gulp, fis等到現在比較流行的webpack可謂層出不窮,個人還是比較傾向於gulp,雖然有的時候會因為某個插件的配置問題頭疼很久,但不可否認gulp真的很靈活,而且個人覺得它和node結合起來比較舒服,再有對項目目錄結構的要求比較低,即使再老再 ...


前言

前端自動化構建工具從最開始的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 + '/',
                '/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);
})

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 今天使用vue 過濾器中發現一個小坑,網上查到的大都是不正確的解決方法,故分享給大家: 原錯誤代碼: 報錯: 正確代碼: 發現啥錯沒?沒錯就是filters, 註意是有s的,沒s它也不會報語法錯誤,只會再控制台輸出 過濾器解析錯誤,所以這些小坑還是很容易踩到的。 ...
  • 作者:houyanhua1 鏈接:https://blog.csdn.net/houyanhua1/article/details/79443987 來源:CSDN ...
  • 字元串對象 字元串對象是JavaScript中比較常見的一種基本數據類型,他封裝了一個字元串,並且提供了相應的方法。例如連接字元串、取字元串、分割字元串等。JavaScript中字元串是不可變的,原始的字元串值不可修改。 1.創建字元串 創建字元串有多種方法,可以使用字面值定義字元串。例如; var ...
  • 1.什麼是作用域 作用域是用於收集存儲維護變數,以及當前執行代碼聲明的變數所擁有的許可權, 例如 : function foo(a){ console.log(a); 1 }; foo(666); console.log(a); 2 此時執行該段代碼 1 -- 處列印我們得到 666 因為在函數中聲明 ...
  • 引自Flex 佈局教程:語法篇 作者: 阮一峰 日期: 2015年7月10日 鏈接:http://www.ruanyifeng.com/blog/2015/07/flex-grammar.html 作者: 阮一峰 日期: 2015年7月10日 鏈接:http://www.ruanyifeng.com ...
  • JavaScript:知識點回顧篇(一):數據類型,變數,類型轉換,函數 ...
  • //count down from 5 to 1, a useful animation. show the code to you: <!DOCTYPE html> <html> <style> #contain { width: 400px; height: 300px; overflow: h ...
  • 前言 什麼是gulp?gulp有什麼用?為什麼用gulp? gulp是前端開發的一種構建工具。 構建工具可以幫助我們工程化地開發項目,比如搭建本地伺服器、編譯CSS預處理器、保存文件後自動刷新瀏覽器而不用我們手動去刷新、多個文件合併並壓縮、壓縮圖片等。 gulp在多種構建工具中,算是簡單的了,其他構 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...