摘要:通過本文,我們將學(xué)習(xí)如何使用來改變開發(fā)流程,從而使開發(fā)更加快速高效。中文網(wǎng)站詳細(xì)入門教程使用是基于的,需要要安裝為了確保依賴環(huán)境正確,我們先執(zhí)行幾個(gè)簡(jiǎn)單的命令檢查。詳盡使用參見官方文檔,中文文檔項(xiàng)目地址
為了UED前端團(tuán)隊(duì)更好的協(xié)作開發(fā)同時(shí)提高項(xiàng)目編碼質(zhì)量,我們需要將Web前端使用工程化方式構(gòu)建;
目前需要一些簡(jiǎn)單的功能:
1. 壓縮HTML 2. 檢查JS 3. 編譯SASS 4. 壓縮圖片 5. 壓縮CSS 6. 壓縮JS 7. 雪碧圖制作 8. 靜態(tài)服務(wù)器 9. 代理解決跨域 10. 打包項(xiàng)目
目前最知名的構(gòu)建工具: Gulp、Grunt、NPM + Webpack;
grunt是前端工程化的先驅(qū) gulp更自然基于流的方式連接任務(wù) Webpack最年輕,擅長用于依賴管理,配置稍較復(fù)雜
PC端項(xiàng)目,我們推薦使用Gulp,Gulp基于nodejs中stream,工作流,效率更好語法更自然,不需要編寫復(fù)雜的配置文件
演示項(xiàng)目
順手一下,star或者fork初識(shí) gulp
簡(jiǎn)介
gulp是前端開發(fā)過程中對(duì)代碼進(jìn)行構(gòu)建的工具,是自動(dòng)化項(xiàng)目的構(gòu)建利器;她不僅能對(duì)網(wǎng)站資源進(jìn)行優(yōu)化,而且在開發(fā)過程中很多重復(fù)的任務(wù)能夠使用正確的工具自動(dòng)完成;使用她,我們不僅可以很愉快的編寫代碼,而且大大提高我們的工作效率。
gulp是基于Nodejs的自動(dòng)任務(wù)運(yùn)行器, 她能自動(dòng)化地完成 javascript/coffee/sass/less/html/image/css 等文件的的測(cè)試、檢查、合并、壓縮、格式化、瀏覽器自動(dòng)刷新、部署文件生成,并監(jiān)聽文件在改動(dòng)后重復(fù)指定的這些步驟。在實(shí)現(xiàn)上,她借鑒了Unix操作系統(tǒng)的管道(pipe)思想,前一級(jí)的輸出,直接變成后一級(jí)的輸入,使得在操作上非常簡(jiǎn)單。通過本文,我們將學(xué)習(xí)如何使用Gulp來改變開發(fā)流程,從而使開發(fā)更加快速高效。
gulp 和 grunt 非常類似,但相比于 grunt 的頻繁 IO 操作,gulp 的流操作,能更快地更便捷地完成構(gòu)建工作。
Gulp 中文網(wǎng)站
gulp詳細(xì)入門教程
Gulp使用Gulp是基于 Node.js的,需要要安裝 Node.js
為了確保依賴環(huán)境正確,我們先執(zhí)行幾個(gè)簡(jiǎn)單的命令檢查。
node -v
Node是一個(gè)基于Chrome JavaScript V8引擎建立的一個(gè)解釋器
檢測(cè)Node是否已經(jīng)安裝,如果正確安裝的話你會(huì)看到所安裝的Node的版本號(hào)
接下來看看npm,它是 node 的包管理工具,可以利用它安裝 gulp 所需的包
npm -v
這同樣能得到npm的版本號(hào),裝 Node 時(shí)已經(jīng)自動(dòng)安裝了npm
npm介紹
npm install -g gulp 全局安裝 gulp gulp -v 得到gulp的版本號(hào),確認(rèn)安裝成功
基礎(chǔ)安裝結(jié)束
選裝cnpm因?yàn)閚pm安裝插件是從國外服務(wù)器下載,受網(wǎng)絡(luò)影響大,這里建議使用cnpm
npm install -g cnpm --registry=https://registry.npm.taobao.orgcmd命令小技巧
創(chuàng)建空文件夾 mkdir name name是文件夾名稱 創(chuàng)建空文件 cd.> name.txt 刪除文件夾 rd/s/q name name是文件夾名稱 (物理刪除) tree命令 tree /f 顯示樹形結(jié)構(gòu) tree /f > tree.txt 導(dǎo)出目錄集合功能
HTML組件化和壓縮
編譯Sass和壓縮css
檢查Javascript
編譯es6語法
壓縮Javascript
無損壓縮圖片
雪碧圖制作
創(chuàng)建靜態(tài)服務(wù)器
設(shè)置代理解決跨域
打包項(xiàng)目且生成壓縮包
結(jié)合webpack使用(選用)
項(xiàng)目目錄結(jié)構(gòu)│ .babelrc │ .eslintignore // eslint文件過濾 │ .eslintrc // eslint語法檢查 │ .gitignore // git文件過濾 │ config.js // 路徑配置文件 │ gulpfile.js // gulp配置文件 │ package.json // 依賴模塊json文件,npm install會(huì)安裝項(xiàng)目所有的依賴模塊 │ README.MD // 項(xiàng)目說明 │ webpack.config.js // webpack配置文件 │ ├─build // 發(fā)布環(huán)境 和 預(yù)覽環(huán)境 | ├─node_modules // 依賴模塊包目錄 │ └─src // 開發(fā)環(huán)境項(xiàng)目 │ index.html // 啟動(dòng)默認(rèn)頁面 │ ├─assets // 靜態(tài)資源 │ ├─css // 樣式文件 │ ├─images // 圖片文件 │ ├─js // js文件 │ └─lib // 插件文件 │ └─page // 頁面文件gulpfile配置文件 常用的插件
gulp-sass: sass的編譯 gulp-autoprefixer: 自動(dòng)添加css前綴 gulp-minify-css: 壓縮css一行 gulp-uglify: 壓縮js代碼 gulp-notify: 加控制臺(tái)文字描述用的 gulp-clean: 清理文件 gulp-file-include: include 文件用 gulp-imagemin: 圖片壓縮 imagemin-pngquant: 圖片無損壓縮 gulp-cache: 檢測(cè)文件是否更改 gulp-zip: 自動(dòng)打包并按時(shí)間重命名 gulp-htmlmin: 壓縮html merge-stream: 合并多個(gè) stream gulp-util: 打印日志 log gulp-plumber: 監(jiān)控錯(cuò)誤 gulp-babel: 編譯ES6 gulp-if: 條件判斷 gulp-sequence: 順序執(zhí)行 gulp-eslint: 代碼風(fēng)格檢測(cè)工具 del: 刪除文件制作雪碧圖 (支持同時(shí)制作多個(gè))
規(guī)定如下
在src/assets/image中,sprite是作為需要制作雪碧圖的文件夾
在sprite文件夾下,必須新建一個(gè)文件夾,例如user文件夾,me文件,存放你的圖標(biāo)
執(zhí)行g(shù)ulp sprites任務(wù)
任務(wù)完成,在src/assets/image中就會(huì)生成一個(gè)icon文件夾,里面就是生成的雪碧圖,在src/assets/css會(huì)生成雪碧圖的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 };; } /** * * 支持多個(gè)文件夾編譯生成雪碧圖 * 雪碧圖制作規(guī)定要求 * 在images文件夾下icon文件夾,新建一個(gè)文件夾就可以 * */ 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, // 保存合并后對(duì)于css樣式的地址 padding: 10, // 合并時(shí)兩個(gè)圖片的間距 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+";"+ // "} "); // }); // return arr.join(""); // } })) .pipe(gulp.dest("src/assets/")); }) } /* 生成雪碧圖 */ gulp.task("sprites", function () { // 執(zhí)行任務(wù) csssPrites(); });gulpfile.js內(nèi)容
/** * gulp 自動(dòng)化構(gòu)建工具 * 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"); // 自動(dòng)添加css前綴 var minifycss = require("gulp-minify-css"); // 壓縮css一行 var uglify = require("gulp-uglify"); // 壓縮js代碼 var notify = require("gulp-notify"); // 加控制臺(tái)文字描述用的 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"); // 檢測(cè)文件是否更改 var zip = require("gulp-zip"); // 自動(dòng)打包并按時(shí)間重命名 var htmlmin = require("gulp-htmlmin"); // 壓縮html var mergeStream = require("merge-stream"); // 合并多個(gè) stream var gutil = require("gulp-util"); // 打印日志 log var plumber = require("gulp-plumber"); // 監(jiān)控錯(cuò)誤 var babel = require("gulp-babel"); // 編譯ES6 var gulpif = require("gulp-if"); // 條件判斷 var minimist = require("minimist"); var gulpSequence = require("gulp-sequence"); // 順序執(zhí)行 var eslint = require("gulp-eslint"); // 代碼風(fēng)格檢測(cè)工具 var del = require("del"); // 刪除文件 var spritesmith = require("gulp.spritesmith"); // 生成雪碧圖 https://github.com/twolfson/gulp.spritesmith // 結(jié)合webpack var webpack = require("gulp-webpack"); var webpackConfig = require("./webpack.config.js"); // 靜態(tài)服務(wù)器和代理請(qǐng)求 var url = require("url"); var proxy = require("proxy-middleware"); var browserSync = require("browser-sync"); var reload = browserSync.reload; // 代理請(qǐng)求 / 端口設(shè)置 / 編譯路徑 var config = require("./config.js"); // 區(qū)分開發(fā)和生產(chǎn)環(huán)境 var knownOptions = { string: "env", default: { env: process.env.NODE_ENV || "development" } }; var options = minimist(process.argv.slice(2), knownOptions); /** * 開發(fā)環(huán)境和生產(chǎn)環(huán)境 * 先清空原先文件夾,在執(zhí)行編譯或者打包 * * @param {any} cb 回調(diào) */ var cnEnvironment = function(cb) { // 先執(zhí)行清空文件夾內(nèi)容 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(" "))); // 執(zhí)行項(xiàng)目打包 gulpSequence([ "htmlmin", "cssmin", "images", "jsmin", "libmin" ], function() { gutil.log(gutil.colors.green("Message:Compile finished!")); // 執(zhí)行回調(diào) cb && cb(); }); }); } /** * 錯(cuò)誤輸出 * * @param {any} error */ var onError = function(error){ var title = error.plugin + " " + error.name; var msg = error.message; var errContent = msg.replace(/ /g, "A "); // replace to `A`, ` ` 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 };; } /** * * 支持多個(gè)文件夾編譯生成雪碧圖 * 雪碧圖制作規(guī)定要求 * 在images文件夾下icon文件夾,新建一個(gè)文件夾就可以 * */ 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, // 保存合并后對(duì)于css樣式的地址 padding: 10, // 合并時(shí)兩個(gè)圖片的間距 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+";"+ // "} "); // }); // return arr.join(""); // } })) .pipe(gulp.dest("src/assets/")); }) } /* html 打包*/ gulp.task("htmlmin", function() { var optionsSet = { removeComments: true, // 清除HTML注釋 collapseWhitespace: true, // 壓縮HTML collapseBooleanAttributes: true, // 省略布爾屬性的值 ==> removeEmptyAttributes: false, // 刪除所有空格作屬性值 ==> removeScriptTypeAttributes: false, // 刪除