我的比價推崇先後端分離的開發方式,你們夥各司其職,只需經過 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
點擊:這裏查看完整代碼
首先介紹下安裝依賴,明確有哪些task:
/** * 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'));