gulp 搭建我的工做流:文件注入、熱啓動、跨域

我的比價推崇先後端分離的開發方式,你們夥各司其職,只需經過 API 進行交流,不只避免了溝通上的成本,更提高了開發效率。而在前端開發工做中,許多需求和問題是類似的,因此咱們的開發模式每每是雷同的,是否可以總結出一套通用的模式呢?css

(備份一個webpack的中文網站:https://angular.cn/docs/ts/latest/guide/webpack.html)html

平常前端開發的處境

一、 開發流程類似前端

​ 前端開發工做包含哪些?html、css、js,對應的工程目錄也類似,每次從新建立都要耗費一些時間。node

二、 需求更改頻繁webpack

​ 開發們都推崇兩個字「複用」,那麼是什麼阻礙了代碼的複用?答:產品經理的需求變動。雖然有些搞笑的成分,但毋庸置疑,前端開發中需求頻繁更改是很是常見的,咱們可不想由於一條樣式修改而找遍全部文件。git

三、 如何跨域es6

​ 如何跨域是每一個前端必須面對的,最優的解決方案是服務器的反向代理來實現,而多數前端都沒有這方面的經驗。幸虧,在開發環境中,咱們能夠利用 node 或者 gulp 來解決跨域問題。github

​ 以前個人一篇博客介紹了利用node.js進行跨域訪問:http://www.cnblogs.com/fayin/p/6628150.htmlweb

​ 今天,我將介紹用gulp搭建工做流,並帶來第二種前端跨域的方式。json

點擊:這裏查看完整代碼

gulp 搭建工做流

首先介紹下安裝依賴,明確有哪些task:

  • gulp-load-plugins:用來加載插件,避免咱們再頭部聲明一堆插件,作到想用就用
  • less:用於編譯 .less文件
  • autoprefixer:自動添加css前綴
  • babel:es6 編譯成 es5
  • uglify:JS壓縮
  • minify:CSS壓縮
  • rename:重命名
  • sourcemaps:資源映射
  • concat:合併文件
  • del:刪除文件、文件夾
  • inject:文件注入
  • notify:提示信息
  • browser-sync:熱啓動
  • http-proxy-middleware:配合browser-sync進行跨域
  • changed:只有發生了改變的文件才能進入流中
  • sequence:讓task按順序完成
  • rev:添加MD5
  • watch:監聽文件變化

gulpfile.js

/**
 * gulp mask list
 *
 * gulp-load-plugins
 *
 * babel, less, uglify, browser-sync, del, autoprefixer, concat, minifyCss, rename
 * sourcemaps, inject, notify
 *
 */

const APIURL = 'http://192.168.1.30:6760';
const ISPROXY = false;

const DEV_PRO = false;


const
    fs   = require('fs'),
    path = require('path'),
    gulp = require('gulp'),
    gulpLoadPlugins = require('gulp-load-plugins'),
    del = require('del'),
    browserSync = require('browser-sync').create(),
    reload = browserSync.reload,
    plugins = gulpLoadPlugins(),
    sequence = require('gulp-sequence'),
    gulpCopy = require('gulp-file-copy'),
    proxy = require('http-proxy-middleware'),
    fileinclude = require('gulp-file-include'),
    pngquant = require('imagemin-pngquant'),
    mozjpeg = require('imagemin-mozjpeg'),
    merge = require('merge-stream');

const DIST = 'dist',
    SRC = 'dist';

const getFolders = (dir)=> {
    return fs.readdirSync(dir)
        .filter((file)=> {
            return fs.statSync(path.join(dir, file)).isDirectory();
        })
};
const getError = function(err) {
    console.log(err.toString());
    this.emit('end');
};


gulp.task('clean', function () {
   return del(['dist/**/*'])
});

gulp.task('clean-css', function () {
    return del(['dist/css/**/*.*'])
});

gulp.task('clean-js', function () {
    return del(['dist/js/*.*'])
});

gulp.task('include', function () {
   return gulp.src('src/*.html')
       .pipe(plugins.changed(DIST))
       .pipe(fileinclude({
           prefix: '@@',
           basepath: '@file'
       }))
       .pipe(plugins.debug({title: '文件引入:'}))
       .pipe(gulp.dest('dist'))
});


gulp.task('css', ()=> {
    let commonStyle = gulp.src('src/less/*.less',{base: 'src/less'})
        .pipe(plugins.changed(DIST, {extension: '.css'}))
        //.pipe(plugins.watch('src/less/*.less'))
        .pipe(plugins.sourcemaps.init())
        .pipe(plugins.less())
        .on('error', getError)
        .pipe(plugins.autoprefixer({
            browsers: ['last 4 version','Android >= 4.0'],
            cascade: true,
            remove: true
        }))
        .pipe(plugins.concat('common.css'))
        .pipe(plugins.minifyCss())
        .pipe(plugins.rename({suffix: '.min'}))
        //.pipe(plugins.rev())    // 添加md5
        .pipe(plugins.sourcemaps.write('.'))
        .pipe(plugins.debug({title: '編譯css:'}))
        .pipe(gulp.dest('dist/css'))
        .pipe(browserSync.stream({match: '**/*.css'}));
    // .pipe(gulp.rev.manifest())
    // .pipe(gulp.dest('dist/rev'))
    let lessPath = 'src/less';
    let folders = getFolders(lessPath);

    let folderStyle = folders.map((folder)=> {
        let newPath = path.join(lessPath, folder, '/*.less');
        return gulp.src(newPath)
            .pipe(plugins.changed(DIST, {extension: '.css'}))
            //.pipe(plugins.watch(newPath))
            .pipe(plugins.sourcemaps.init())
            .pipe(plugins.less())
            .pipe(plugins.autoprefixer({
                browsers: ['last 4 version','Android >= 4.0'],
                cascade: true,
                remove: true
            }))
            .pipe(plugins.concat(folder+'.css'))
            .pipe(plugins.minifyCss())
            .pipe(plugins.rename({suffix: '.min'}))
            //.pipe(plugins.rev())    // 添加md5
            .pipe(plugins.sourcemaps.write('.'))
            .pipe(plugins.debug({title: '編譯foldercss:'}))
            .pipe(gulp.dest('dist/css/'+folder))
            .pipe(browserSync.stream({match: '**/*.css'}));
    });
    return merge(commonStyle, folderStyle);
});

gulp.task('es6ToEs5', function () {
    return gulp.src('src/js/**/*.js')
        .pipe(plugins.changed(DIST, {extension: '.js'}))
        .pipe(plugins.sourcemaps.init())
        .pipe(plugins.babel({
            presets: ['es2015']
        }))
        .on('error', getError)
        //.pipe(plugins.concat('main.js'))
        .pipe(plugins.uglify())
        .pipe(plugins.rename({suffix: '.min'}))
        //.pipe(plugins.rev())
        .pipe(plugins.sourcemaps.write('.'))
        .pipe(plugins.debug({title: '編譯js:'}))
        .pipe(gulp.dest('dist/js'))
        .pipe(browserSync.stream({match: '**/*.js'}));
});

gulp.task('rev',['css'],function() {
    return gulp.src(['dist/rev/rev-manifest.json','dist/*.html'])  //獲取rev-manifest.json和要替換的html文件
        .pipe(plugins.revCollector({
            replaceReved: true      //根據rev-manifest.json的規則替換html裏的路徑,因爲替換是根據rev-manifest.json規則來的,因此必定要先生成這個文件再進行替換
        }))
        .pipe(gulp.dest('dist'))
        .pipe(browserSync.stream({match: '**/*.css'}));
        //.pipe(plugins.notify('md5 success!!!!'))
});


gulp.task('copy', function () {
    let start = 'src/lib/*.*',
        start2 = 'src/images/**/*.*';
    let copyLib = gulp.src(start)
        .pipe(plugins.changed(DIST))
        .pipe(gulpCopy('dist/lib', {
            start: 'src/lib'
        }));

    let copyImages = gulp.src(start2)
        .pipe(plugins.changed(DIST))
        .pipe(plugins.imagemin(
            [pngquant(), mozjpeg()],
            {verbose: true}
        ))
        .pipe(gulp.dest('dist/images'));
    return merge(copyLib, copyImages)
});

gulp.task('injectFile', function () {
   let target = ['src/*.html','!src/_head.html'],
       target2 = ['dist/lib/*.js', 'dist/js/*.js', 'dist/css/*.css'],
       sources = gulp.src(target2, {'read': false});
   return gulp.src(target)
       .pipe(plugins.changed(DIST))
       .pipe(fileinclude({
           prefix: '@@',
           basepath: '@file'
       }))
       .pipe(plugins.inject(sources, {relative: true}))
       .pipe(plugins.debug({title: '注入:'}))
       .pipe(gulp.dest('dist'))
       .pipe(browserSync.stream({match: '**/*.html'}));
       //.pipe(plugins.notify('inject success'))
});

gulp.task('watch-css', function (callback) {
    sequence('rev', 'injectFile', callback)
});

gulp.task('watch-js', function (callback) {
    sequence('es6ToEs5', 'injectFile', callback)
});

gulp.task('del-maps', function () {
    return del(['dist/**/*.map']);
});

gulp.task('html-watch', ['injectFile'], function (done) {
    browserSync.reload();
    done();
});

gulp.task('server', function() {
    const aipProxy = proxy('/api', {
        target: APIURL,
        changeOrigin: true,
        ws: true
    });

    if (!ISPROXY) {
        browserSync.init({
            // files:'**',
            server: {
                baseDir: './'
            }
        });
    }else {
        browserSync.init({
            server: {
                baseDir: './',
                middleware: [aipProxy]
            }
        });
    }

    gulp.watch(['src/*.html'], ['injectFile']);
    gulp.watch(['src/images/**/*.*'], ['copy']);
    gulp.watch(['src/less/**/*'], ['watch-css']);
    gulp.watch(['src/js/**/*.js', 'src/lib/*.*'], ['watch-js']);
    gulp.watch(['dist/*.html']).on('change', browserSync.reload);
    gulp.watch(['src/**/**'])
        .on('change', function (event) {
            if(event.type == 'deleted') {
                let _path = event.path,
                    cssPath = _path.replace(/src\\less/, 'dist\\css');
                console.log(cssPath);
                if(path.extname(_path) === '.less') {
                    del(path.dirname(cssPath)+'/*.*');
                    sequence('rev', 'injectFile');
                }else {
                    del(_path.replace(/src/, 'dist'))
                }

            }
        })
        .on('error', function (err) {
            console.log(err)
        });
    //browserSync.watch('./src/**/*.*').on('change',reload);
    //browserSync.watch('./dist/**/*').on('change',reload);
});

gulp.task('dev', sequence('clean', ['rev', 'es6ToEs5','copy'], 'injectFile', 'server'));


gulp.task('build-pro', sequence('clean',['rev', 'es6ToEs5', 'copy'],'injectFile', 'del-maps'));

目錄

相關文章
相關標籤/搜索