爲了UED前端團隊更好的協做開發同時提升項目編碼質量,咱們須要將Web前端使用工程化方式構建;javascript
目前須要一些簡單的功能:css
1. 壓縮HTML 2. 檢查JS 3. 編譯SASS 4. 壓縮圖片 5. 壓縮CSS 6. 壓縮JS 7. 雪碧圖製做 8. 靜態服務器 9. 代理解決跨域 10. 打包項目
目前最知名的構建工具: Gulp、Grunt、NPM + Webpack;html
grunt是前端工程化的先驅 gulp更天然基於流的方式鏈接任務 Webpack最年輕,擅長用於依賴管理,配置稍較複雜
PC端項目,咱們推薦使用Gulp,Gulp基於nodejs中stream,工做流,效率更好語法更天然,不須要編寫複雜的配置文件前端
演示項目java
順手一下,star或者fork
簡介node
gulp是前端開發過程當中對代碼進行構建的工具,是自動化項目的構建利器;她不只能對網站資源進行優化,並且在開發過程當中不少重複的任務可以使用正確的工具自動完成;使用她,咱們不只能夠很愉快的編寫代碼,並且大大提升咱們的工做效率。android
gulp是基於Nodejs的自動任務運行器, 她能自動化地完成 javascript/coffee/sass/less/html/image/css 等文件的的測試、檢查、合併、壓縮、格式化、瀏覽器自動刷新、部署文件生成,並監聽文件在改動後重復指定的這些步驟。在實現上,她借鑑了Unix操做系統的管道(pipe)思想,前一級的輸出,直接變成後一級的輸入,使得在操做上很是簡單。經過本文,咱們將學習如何使用Gulp來改變開發流程,從而使開發更加快速高效。webpack
gulp 和 grunt 很是相似,但相比於 grunt 的頻繁 IO 操做,gulp 的流操做,能更快地更便捷地完成構建工做。ios
Gulp 中文網站git
Gulp是基於 Node.js的,須要要安裝 Node.js
爲了確保依賴環境正確,咱們先執行幾個簡單的命令檢查。
node -v
Node是一個基於Chrome JavaScript V8引擎創建的一個解釋器
檢測Node是否已經安裝,若是正確安裝的話你會看到所安裝的Node的版本號
接下來看看npm,它是 node 的包管理工具,能夠利用它安裝 gulp 所需的包
npm -v
這一樣能獲得npm的版本號,裝 Node 時已經自動安裝了npm
npm介紹
npm install -g gulp 全局安裝 gulp gulp -v 獲得gulp的版本號,確認安裝成功
基礎安裝結束
由於npm安裝插件是從國外服務器下載,受網絡影響大,這裏建議使用cnpm
npm install -g cnpm --registry=https://registry.npm.taobao.org
建立空文件夾 mkdir name name是文件夾名稱 建立空文件 cd.> name.txt 刪除文件夾 rd/s/q name name是文件夾名稱 (物理刪除) tree命令 tree /f 顯示樹形結構 tree /f > tree.txt 導出目錄
HTML組件化和壓縮
編譯Sass和壓縮css
檢查Javascript
編譯es6語法
壓縮Javascript
無損壓縮圖片
雪碧圖製做
建立靜態服務器
設置代理解決跨域
打包項目且生成壓縮包
結合webpack使用(選用)
│ .babelrc │ .eslintignore // eslint文件過濾 │ .eslintrc // eslint語法檢查 │ .gitignore // git文件過濾 │ config.js // 路徑配置文件 │ gulpfile.js // gulp配置文件 │ package.json // 依賴模塊json文件,npm install會安裝項目全部的依賴模塊 │ README.MD // 項目說明 │ webpack.config.js // webpack配置文件 │ ├─build // 發佈環境 和 預覽環境 | ├─node_modules // 依賴模塊包目錄 │ └─src // 開發環境項目 │ index.html // 啓動默認頁面 │ ├─assets // 靜態資源 │ ├─css // 樣式文件 │ ├─images // 圖片文件 │ ├─js // js文件 │ └─lib // 插件文件 │ └─page // 頁面文件
gulp-sass: sass的編譯 gulp-autoprefixer: 自動添加css前綴 gulp-minify-css: 壓縮css一行 gulp-uglify: 壓縮js代碼 gulp-notify: 加控制檯文字描述用的 gulp-clean: 清理文件 gulp-file-include: include 文件用 gulp-imagemin: 圖片壓縮 imagemin-pngquant: 圖片無損壓縮 gulp-cache: 檢測文件是否更改 gulp-zip: 自動打包並按時間重命名 gulp-htmlmin: 壓縮html merge-stream: 合併多個 stream gulp-util: 打印日誌 log gulp-plumber: 監控錯誤 gulp-babel: 編譯ES6 gulp-if: 條件判斷 gulp-sequence: 順序執行 gulp-eslint: 代碼風格檢測工具 del: 刪除文件
規定以下
在src/assets/image中,sprite是做爲須要製做雪碧圖的文件夾
在sprite文件夾下,必須新建一個文件夾,例如user文件夾,me文件,存放你的圖標
執行gulp sprites任務
任務完成,在src/assets/image中就會生成一個icon文件夾,裏面就是生成的雪碧圖,在src/assets/css會生成雪碧圖的scss樣式文件
var srcDir = path.resolve(process.cwd(), config.sprite); /** * 獲取獲取文件名字和路徑 * @returns */ var iconFolder = function() { var filesSrc = []; // 文件路徑 var filesName = []; // 文件名字 // 遍歷獲取文件名字和路徑 fs.readdirSync(srcDir).forEach(function(file, i){ var reg = /\.(png|jpg|gif|ico)/g; var isImg = file.match(reg); // 判讀是 file.indexOf('sprite') != -1 if(!isImg){ filesName.push(file); filesSrc.push(path.resolve(srcDir, file, '*.{png,jpg}')); } }); // 返回文件名字和路徑 return { 'name': filesName, 'src' : filesSrc };; } /** * * 支持多個文件夾編譯生成雪碧圖 * 雪碧圖製做規定要求 * 在images文件夾下icon文件夾,新建一個文件夾就能夠 * */ var csssPrites = function() { var folder = iconFolder(); var folderName = folder.name; var folderSrc = folder.src; folderSrc.forEach(function (item, i) { var imgName = `images/icon/icon_${folderName[i]}.png`; var cssName = `css/icon_${folderName[i]}.scss`; return gulp.src(item) // 須要合併的圖片地址 .pipe(spritesmith({ imgName: imgName, // 保存合併後圖片的地址 cssName: cssName, // 保存合併後對於css樣式的地址 padding: 10, // 合併時兩個圖片的間距 algorithm: 'binary-tree', // 註釋1 cssTemplate: './cssTemplate.tpl' // 模板 // cssTemplate: function (data) { // var arr=[]; // data.sprites.forEach(function (sprite) { // arr.push(".icon-"+sprite.name+ // "{" + // "background-image: url('"+sprite.escaped_image+"');"+ // "background-position: "+sprite.px.offset_x+"px "+sprite.px.offset_y+"px;"+ // "width:"+sprite.px.width+";"+ // "height:"+sprite.px.height+";"+ // "}\n"); // }); // return arr.join(""); // } })) .pipe(gulp.dest('src/assets/')); }) } /* 生成雪碧圖 */ gulp.task('sprites', function () { // 執行任務 csssPrites(); });
/** * gulp 自動化構建工具 * gulpfile.js 配置文件 * */ var fs = require('fs'); var path = require('path'); var gulp = require('gulp'); var sass = require('gulp-sass'); // sass的編譯 var autoprefixer = require('gulp-autoprefixer'); // 自動添加css前綴 var minifycss = require('gulp-minify-css'); // 壓縮css一行 var uglify = require('gulp-uglify'); // 壓縮js代碼 var notify = require('gulp-notify'); // 加控制檯文字描述用的 var clean = require('gulp-clean'); // 清理文件 var fileinclude = require('gulp-file-include'); // include 文件用 var imagemin = require('gulp-imagemin'); // 圖片壓縮 var pngquant = require('imagemin-pngquant'); // 圖片無損壓縮 var cache = require('gulp-cache'); // 檢測文件是否更改 var zip = require('gulp-zip'); // 自動打包並按時間重命名 var htmlmin = require('gulp-htmlmin'); // 壓縮html var mergeStream = require('merge-stream'); // 合併多個 stream var gutil = require('gulp-util'); // 打印日誌 log var plumber = require('gulp-plumber'); // 監控錯誤 var babel = require('gulp-babel'); // 編譯ES6 var gulpif = require('gulp-if'); // 條件判斷 var minimist = require('minimist'); var gulpSequence = require('gulp-sequence'); // 順序執行 var eslint = require('gulp-eslint'); // 代碼風格檢測工具 var del = require('del'); // 刪除文件 var spritesmith = require('gulp.spritesmith'); // 生成雪碧圖 https://github.com/twolfson/gulp.spritesmith // 結合webpack var webpack = require('gulp-webpack'); var webpackConfig = require('./webpack.config.js'); // 靜態服務器和代理請求 var url = require('url'); var proxy = require('proxy-middleware'); var browserSync = require('browser-sync'); var reload = browserSync.reload; // 代理請求 / 端口設置 / 編譯路徑 var config = require('./config.js'); // 區分開發和生產環境 var knownOptions = { string: 'env', default: { env: process.env.NODE_ENV || 'development' } }; var options = minimist(process.argv.slice(2), knownOptions); /** * 開發環境和生產環境 * 先清空原先文件夾,在執行編譯或者打包 * * @param {any} cb 回調 */ var cnEnvironment = function(cb) { // 先執行清空文件夾內容 del(config.rootBuild).then(paths => { // 通知信息 gutil.log(gutil.colors.green('Message:Delete complete!')); gutil.log(gutil.colors.green('Message:Deleted files and folders:', paths.join('\n'))); // 執行項目打包 gulpSequence([ 'htmlmin', 'cssmin', 'images', 'jsmin', 'libmin' ], function() { gutil.log(gutil.colors.green('Message:Compile finished!')); // 執行回調 cb && cb(); }); }); } /** * 錯誤輸出 * * @param {any} error */ var onError = function(error){ var title = error.plugin + ' ' + error.name; var msg = error.message; var errContent = msg.replace(/\n/g, '\\A '); // replace to `\A`, `\n` is not allowed in css content // system notification notify.onError({ title: title, message: errContent, sound: true })(error); // prevent gulp process exit this.emit('end'); }; var srcDir = path.resolve(process.cwd(), config.sprite); /** * 獲取獲取文件名字和路徑 * @returns */ var iconFolder = function() { var filesSrc = []; // 文件路徑 var filesName = []; // 文件名字 // 遍歷獲取文件名字和路徑 fs.readdirSync(srcDir).forEach(function(file, i){ var reg = /\.(png|jpg|gif|ico)/g; var isImg = file.match(reg); // 判讀是 file.indexOf('sprite') != -1 if(!isImg){ filesName.push(file); filesSrc.push(path.resolve(srcDir, file, '*.{png,jpg}')); } }); // 返回文件名字和路徑 return { 'name': filesName, 'src' : filesSrc };; } /** * * 支持多個文件夾編譯生成雪碧圖 * 雪碧圖製做規定要求 * 在images文件夾下icon文件夾,新建一個文件夾就能夠 * */ var csssPrites = function() { var folder = iconFolder(); var folderName = folder.name; var folderSrc = folder.src; folderSrc.forEach(function (item, i) { var imgName = `images/icon/icon_${folderName[i]}.png`; var cssName = `css/icon_${folderName[i]}.scss`; return gulp.src(item) // 須要合併的圖片地址 .pipe(spritesmith({ imgName: imgName, // 保存合併後圖片的地址 cssName: cssName, // 保存合併後對於css樣式的地址 padding: 10, // 合併時兩個圖片的間距 algorithm: 'binary-tree', // 註釋1 cssTemplate: './cssTemplate.tpl' // 模板 // cssTemplate: function (data) { // var arr=[]; // data.sprites.forEach(function (sprite) { // arr.push(".icon-"+sprite.name+ // "{" + // "background-image: url('"+sprite.escaped_image+"');"+ // "background-position: "+sprite.px.offset_x+"px "+sprite.px.offset_y+"px;"+ // "width:"+sprite.px.width+";"+ // "height:"+sprite.px.height+";"+ // "}\n"); // }); // return arr.join(""); // } })) .pipe(gulp.dest('src/assets/')); }) } /* html 打包*/ gulp.task('htmlmin', function() { var optionsSet = { removeComments: true, // 清除HTML註釋 collapseWhitespace: true, // 壓縮HTML collapseBooleanAttributes: true, // 省略布爾屬性的值 <input checked="true"/> ==> <input /> removeEmptyAttributes: false, // 刪除全部空格做屬性值 <input id="" /> ==> <input /> removeScriptTypeAttributes: false, // 刪除<script>的type="text/javascript" removeStyleLinkTypeAttributes: false, // 刪除<style>和<link>的type="text/css" minifyJS: true, // 壓縮頁面JS minifyCSS: true // 壓縮頁面CSS }; return gulp .src([config.dev.html, '!*.tpl'], { base: config.rootDev }) .pipe(plumber(onError)) .pipe(fileinclude({ prefix: '@@', basepath: '@file' })) .pipe(gulpif(options.env === 'production', htmlmin(optionsSet))) .pipe(gulp.dest(config.build.html)) .pipe(reload({ stream: true })); }); /* css 壓縮 */ gulp.task('cssmin', function() { var AUTOPREFIXER_BROWSERS = [ 'last 6 version', 'ie >= 6', 'ie_mob >= 10', 'ff >= 30', 'chrome >= 34', 'safari >= 7', 'opera >= 23', 'ios >= 7', 'android >= 4.0', 'bb >= 10' ]; return gulp .src(config.dev.css) .pipe(plumber(onError)) .pipe(sass()) // .pipe(sass().on('error', sass.logError)) .pipe(autoprefixer(AUTOPREFIXER_BROWSERS)) .pipe(gulpif(options.env === 'production', minifycss())) .pipe(gulp.dest(config.build.css)) .pipe(reload({ stream: true })); }); /* eslint 語法檢查 */ gulp.task('eslint', function() { return gulp .src([config.dev.js, '!node_modules/**']) .pipe(plumber(onError)) .pipe(eslint({ configFle: './.eslintrc' })) .pipe(eslint.format()) .pipe(eslint.failAfterError()); }) /* js 壓縮 */ gulp.task('jsmin', ['eslint'], function() { var jsmin = gulp .src([config.dev.js, '!node_modules/**']) .pipe(plumber(onError)) .pipe(babel({ presets: ['es2015'], plugins: [ // es2015 - based off of v6.3.13 // https://github.com/babel/babel/tree/master/packages require('babel-plugin-transform-es2015-object-super'), require('babel-plugin-syntax-export-extensions'), require('babel-plugin-transform-object-assign'), require('babel-plugin-transform-es3-member-expression-literals'), require('babel-plugin-transform-es3-property-literals'), [require('babel-plugin-transform-es2015-classes'), { loose: true }], [require('babel-plugin-transform-regenerator'), { async: false, asyncGenerators: false }], ] })) // .pipe(webpack( webpackConfig )) .pipe(gulpif(options.env === 'production', uglify())) // 僅在生產環境時候進行壓縮 .pipe(gulp.dest(config.build.js)) .pipe(reload({ stream: true })); return mergeStream(jsmin); }); /* js 插件 */ gulp.task('libmin', function() { // lib 插件 return gulp .src(config.dev.lib) .pipe(plumber(onError)) .pipe(gulp.dest(config.build.lib)) .pipe(reload({ stream: true })); }); /* webpack */ gulp.task('webpack', function() { webpackConfig.refreshEntry(); return gulp .src([config.dev.js]) .pipe(webpack(webpackConfig)) .pipe(gulp.dest(config.build.js)); }); /* images 壓縮 */ gulp.task('images', () => { return gulp .src(config.dev.image) .pipe(plumber(onError)) .pipe(cache(imagemin({ progressive: true, svgoPlugins: [{ removeViewBox: false }], use: [pngquant()] }))) .pipe(gulp.dest(config.build.image)) .pipe(reload({ stream: true })); }); /* 生成雪碧圖 */ gulp.task('sprites', function () { // 執行任務 csssPrites(); }); /* clean 清除*/ gulp.task('clean', function() { // return gulp // .src(config.rootBuild, { read: false }) // .pipe(clean()) // .pipe(notify({ message: 'Clean task complete' })); del(config.rootBuild).then(paths => { console.log('Deleted files and folders:\n', paths.join('\n')); }); }); /* zip 壓縮包 */ gulp.task('zip', function() { /** * 補零 * @param {any} i * @returns */ function checkTime(i) { if (i < 10) { i = '0' + i; } return i; } var d = new Date(); var year = d.getFullYear(); var month = checkTime(d.getMonth() + 1); var day = checkTime(d.getDate()); var hour = checkTime(d.getHours()); var minute = checkTime(d.getMinutes()); var time = String(year) + String(month) + String(day) + String(hour) + String(minute); var build = 'build-' + time + '.zip'; return gulp .src(config.build.zip) .pipe(plumber(onError)) .pipe(zip(build)) .pipe(gulp.dest(config.rootZip)) .pipe(notify({ message: 'Zip task complete' })); }); /* watch 文件 */ gulp.task('watch', function() { // 看守全部.tpl文件 gulp.watch(config.dev.tpl, ['htmlmin']) // 看守全部.html文件 gulp.watch(config.dev.html, ['htmlmin']) // 看守全部.scss文件 gulp.watch(config.dev.scss, ['cssmin']) // 看守全部.js文件 gulp.watch(config.dev.js, ['jsmin']) // 看守全部js插件文件 gulp.watch(config.dev.lib, ['libmin']) // 看守全部圖片文件 gulp.watch(config.dev.image, ['images']) // 看守全部雪碧圖 gulp.watch(config.dev.image, ['sprites']) }); /* server 服務器 */ gulp.task('server', function() { cnEnvironment(function(){ gutil.log(gutil.colors.green('啓動本地服務器')); gutil.log(gutil.colors.green('代理請求地址:' + config.proxyTable.target)); gutil.log(gutil.colors.green('代理請求項目:' + config.proxyTable.inner)); var proxyOptions = url.parse(config.proxyTable.target + config.proxyTable.inner); proxyOptions.route = config.proxyTable.inner; browserSync.init({ // 初始化 BrowserSync injectChanges: true, // 插入更改 files: [ '*.html', '*.css', '*.js' ], // 監聽文件類型來自動刷新 server: { baseDir: config.rootBuild, // 目錄位置 middleware: [proxy(proxyOptions)] // 代理設置 }, ghostMode: { // 是否開啓多端同步 click: true, // 同步點擊 scroll: true // 同步滾動 }, logPrefix: 'browserSync in gulp', // 再控制檯打印前綴 browser: ["chrome"], //運行後自動打開的;瀏覽器 (不填默認則是系統設置的默認瀏覽器) open: true, // 自動打開瀏覽器 port: config.port // 使用端口 }); // 監聽watch gulp.start('watch'); }); }); /* build 打包項目 */ gulp.task('build', function() { cnEnvironment(function(){ gulp.start('zip', function(){ gutil.log(gutil.colors.green('Message:Project package is complete')); }); }) }); /* 任務命令 */ gulp.task('default', function() { gutil.log(gutil.colors.green('開發環境: npm run dev 或者 gulp server')); gutil.log(gutil.colors.green('打包項目: npm run build 或者 gulp build --env production')); gutil.log(gutil.colors.green('刪除文件夾: gulp clean')); gutil.log(gutil.colors.green('編譯js代碼: gulp jsmin')); gutil.log(gutil.colors.green('編譯css代碼: gulp cssmin')); gutil.log(gutil.colors.green('編譯html代碼: gulp htmlmin')); gutil.log(gutil.colors.green('編譯圖片壓縮: gulp images')); gutil.log(gutil.colors.green('監聽全部文件: gulp watch')); });
開發環境: npm run dev 或者 gulp server 打包項目: npm run build 或者 gulp build --env production 刪除文件夾: gulp clean 編譯js代碼: gulp jsmin 編譯css代碼: gulp cssmin 編譯html代碼: gulp htmlmin 編譯圖片壓縮: gulp images 監聽全部文件: gulp watch
ESLint
爲何使用ESLint
使用使用 ESLint 工具和代碼風格檢測工具,則能夠輔助編碼規範執行,有效控制代碼質量。
git clone git@github.com:vincentSea/gulp-demo.git