天天看點

使用gulp快速開發靜态頁

前言

如今我們開發web網頁的方式主要有幾種,使用

vue-cli、create-react-app、webpack、不借助建構工具

等實作單頁或多頁網站。“工欲善其事,必先利其器”,前三種方式無疑能滿足我們開發網頁的絕大部分需求,但在某些情況下,比如前後端不分離(jsp、php、tpl等嵌套後端語言的方式),以及單純地開發一些靜态頁(活動頁、幫助手冊等),使用gulp搭建一個輕量級的前端開發環境是一個選擇。

gulp相對上手簡單,有經驗的前端也都比較熟悉,這裡不打算一步步地介紹gulp開發環境的搭建,而是分享一下實際使用gulp的代碼及思路。

實作哪些功能

使用gulp的目的是實作自動化建構,提升開發效率、代碼品質,是以有以下一些目标。

  1. 壓縮html、css、js、圖檔
  2. 編譯ES6、less/scss
  3. 補全css字首
  4. px轉rem
  5. 靜态資源緩存控制
  6. 靜态伺服器
  7. 代碼檢查

實際上gulp能做到的還有更多,不過出于開發靜态頁的目的,這裡隻羅列了一些常用功能。

代碼

基本目錄如下

使用gulp快速開發靜态頁

gulpfile.js主要代碼

靜态伺服器
gulp.task('server', done => {
    connect.server({
        root: 'dist',//根目錄
        livereload: true,//自動更新
        port: 9090//端口
    })
    done();
});
           
壓縮html
gulp.task('html', function () {
    return gulp.src('src/*.html')
        .pipe(htmlmin({ collapseWhitespace: true }))
        .pipe(gulp.dest('dist'))
        .pipe(connect.reload())
})
           
編譯并壓縮css
gulp.task('css', done => {
    var processors = [px2rem({ remUnit: 100 })];

    gulp.src('src/less/**/*.less')   //擷取所有less檔案路徑
        .pipe(less())           //執行less
        .pipe(autoprefixer({//補全字首
            overrideBrowserslist: [
                "Android 4.1",
                "iOS 7.1",
                "Chrome > 31",
                "ff > 31",
                "ie >= 8"
            ]
        }))
        .pipe(postcss(processors))//px轉rem tips: 如果某個px不轉換,可使用大寫代替,類似1PX
        .pipe(minifyCss())
        .pipe(gulp.dest('dist/css'))
        .pipe(connect.reload())

    done();
});
           
編譯并壓縮js
gulp.task('js', function () {
    return gulp.src('src/js/**/*.js')
        //.pipe(jshint())//檢查代碼
        .pipe(babel({//編譯ES6
            presets: ['@babel/env']
        }))
        .pipe(uglify())//壓縮js
        .pipe(gulp.dest('dist/js'))
        .pipe(connect.reload())
})
           
壓縮圖檔
gulp.task('images', function () {
    return gulp.src('src/images/**/*.+(png|jpg|jpeg|gif|svg)')
        .pipe(imagemin())
        .pipe(gulp.dest('dist/images'))
});
           
監控檔案變化
gulp.task('watcher', done => { //監聽變化
    gulp.watch('src/*.html', gulp.series('html'));
    gulp.watch('src/less/**/*.less', gulp.series('css'));
    gulp.watch('src/js/**/*.js', gulp.series('js'));
    gulp.watch('src/images/**/*', gulp.series('images'));

    done();
})
           
生成帶hash值的檔案名及路徑

這裡還使用了

gulp-rev-delete-original

删除舊檔案。

gulp.task("hash", done => {
    gulp
        .src("dist/**")
        .pipe(
            RevAll.revision({
                dontRenameFile: [/\.html$/]
            })
        )
        .pipe(revdel({
            exclude: function (file) {
                if (/\.html$/.test(file.name)) {
                    return true; //if you want to exclude the file from being deleted
                }
            }
        }))
        .pipe(gulp.dest("dist"))

    done();
});
           
gulp指令

打開本地伺服器,以及打封包件。

// 初始化
gulp.task('init', gulp.series('clean', gulp.parallel('html', 'css', 'js', 'images')));
// 開發
gulp.task('default', gulp.series('init', 'server', 'watcher'));
// 打包
gulp.task('build', gulp.series('hash'));
           

可以看出上面的代碼比較簡單,因為初衷是做一些簡單的靜态頁,是以并沒有做得比較複雜,監控檔案變化編譯至dist目錄,再由gulp-rev-all生成hash檔案名。

前後端不分離的情況

這裡需要區分前後端不分離的情況,由于公司的技術不更新,或者需要維護老項目,就要應付前後端不分離的場景。比如頁面是jsp、php檔案,這時靜态頁跟實際頁面并沒有直接對應關系,每次gulp打包後,gulp-rev-all會重新生成帶hash的檔案和路徑,并且不支援

test.css?v=123

這種方式,這樣全部手動複制到項目目錄并不實際,隻能放棄gulp-rev-all(

build

),并且移除代碼壓縮。

值得一提的是,前後端不分離可以用後端語言進行資源的緩存控制,例如使用php讀取檔案的修改日期來做版本号。

function autoVersion($file) {  
    if( file_exists($_SERVER['DOCUMENT_ROOT'].$file) ) {  
        $ver = filemtime($_SERVER['DOCUMENT_ROOT'] . $file);  
    } else {  
        $ver = 1;  
    }  
    return $file .'?v=' .$ver;  
}  
           

此外,應對前後端不分離應該還有一種解決方案,借助建構工具直接生成後端所需的模闆檔案(如index.tpl),這裡暫不讨論。

最後

這些是根據工作經驗總結出來的,雖然當下使用或基于webpack開發單頁是主流,但在某些覆寫不到的場景下進行一些梳理還是有必要的。

源碼位址:gulp-util,另外附上一個webpack多頁腳手架webpack-multiple-entry,這是作者fork别人的項目來修改的,比較簡單實用,感興趣的小夥伴可以參考下。