用Yeoman + gulp + webpack 來管理你的前端項(xiàng)目

一. 前言

Yeoman:前端腳手架骑歹,快速搭建前端開發(fā)環(huán)境茫叭,優(yōu)化工作流~
Gulp:工程化構(gòu)建工具会烙,基于task來處理任務(wù)
Webpack:最常見的前端構(gòu)建工具残炮,類似與gulp韭赘,但不如gulp靈活,專注于代碼打包編譯

OK势就,主人公們介紹完了泉瞻,該篇主要說明三個(gè)工具的基本用法,安裝配置自己解決苞冯。

二. Yeoman

Q:
i.在寫東西的時(shí)候經(jīng)常會(huì)遇到一些重復(fù)性的操作和代碼袖牙,苦于Ctrl+c
ii.人數(shù)較多的前端團(tuán)隊(duì)10個(gè)人擁有十種代碼風(fēng)格,十種項(xiàng)目結(jié)構(gòu)舅锄,后期維護(hù)及其繁瑣

——使用Yeoman 達(dá)到One Code Style One Directory Structure

1.安裝:

$ cnpm install -g yo

2.使用:

yeoman 提供很多generator鞭达,可以直接使用

$ mkdir project-name
$ cd project-name
$ yo

按照提示選擇需要的模板就行了,這里主要說一說怎么私人訂制~~~嘻嘻

3.創(chuàng)建自己的generator

yeoman官方提供了generator-generator 來幫助我們自定義生成器皇忿,良心啊~~~

$ cnpm install -g generator-generator
$ yo generator

然后你的根目錄下就會(huì)生成如下結(jié)構(gòu):


1.png

我們需要做的就是在index.js中來創(chuàng)造我們自己的generator

 'use strict';
 const Generator = require('yeoman-generator');
 const chalk = require('chalk');
 const yosay = require('yosay');

 module.exports = class extends Generator {
 prompting() {
      // Have Yeoman greet the user.
     this.log(
     yosay(`Welcome to the tiptop ${chalk.red('generator-xy')} generator!`)
 );

const prompts = [
  {
    type: 'confirm',
    name: 'someAnswer',
    message: 'Would you like to enable this option?',
    default: true
  }
];

return this.prompt(prompts).then(props => {
  // To access props later use this.props.someAnswer;
  this.props = props;
});
}

writing() {
 this.fs.copy(
   this.templatePath('dummyfile.txt'),
   this.destinationPath('dummyfile.txt')
 );
}

install() {
  this.installDependencies();
 }
};

可以看到核心的流程是在一個(gè)繼承了generator的類當(dāng)中
其實(shí)這里generator一共提供了 initializing畴蹭,prompting,configuring鳍烁,default叨襟,writing,conflicts幔荒,install糊闽,end這幾個(gè)函數(shù)

Prompting()方法是執(zhí)行前的過渡梳玫,實(shí)現(xiàn)與用戶的交互,你可以在prompts問題集中定義一些問題墓怀,比如你叫啥汽纠,干啥,弄啥傀履,家里幾口人,人均幾畝地...........然后將用戶輸入的內(nèi)容保存在this.props中莉炉,方便以后調(diào)用钓账。

我們自己來寫一個(gè)

prompting() {
      // Have Yeoman greet the user.
     this.log(
     yosay(`Welcome to the tiptop ${chalk.red('generator-xy')} generator!`)
 );
return this.prompt([{
  type    : 'input',
  name    : 'appname',
  message : 'input your project  name',
  default : this.appname     
}
]).then((answers) => {
  this.log('appname :', answers.appname);
  this.props = answers;
})
}

在后面的方法中,我們便可以通過this.props.appname來獲取到輸入的項(xiàng)目名稱

我們在原來的基礎(chǔ)上定義一個(gè)defaults方法來生成用戶輸入的目錄

const path = require('path');
const mkdirp = require('mkdirp');

defaults () {           
if (path.basename(this.destinationPath()) !== this.props.appname) { //判斷是否存在該目錄
  this.log(
    'Your generator must be inside a folder named ' + this.props.appname + '\n' +
    'I\'ll automatically create this folder.'
  );
  mkdirp(this.props.appname); // 即 mkdir -p 創(chuàng)建該目錄
  this.destinationRoot(this.destinationPath(this.props.appname));
}
}

writing方法用來書寫創(chuàng)建工程文件的步驟
在這之前我們首先在template文件夾下創(chuàng)建一個(gè)public目錄絮宁,里面創(chuàng)建如下文件作為咱們這個(gè)初級教程的全部內(nèi)容


2.png

開始寫writing方法

writing() {
mkdirp('css');      //創(chuàng)建css文件夾
mkdirp('js');      //創(chuàng)建js文件夾
this.fs.copy(     //調(diào)用方法將模板的內(nèi)容創(chuàng)建到根目錄
  this.templatePath('public/index.html'),       //模板文件地址 
  this.destinationPath('index.html'),          //創(chuàng)建在根目錄
),

this.fs.copy(
  this.templatePath('public/index.css'),
  this.destinationPath('css/index.css')
);

this.fs.copy(
  this.templatePath('public/index.js'),
  this.destinationPath('js/index.js')
);

}

最后install方法梆暮,官方的api說的很清楚this.installDependencies(),即是用來安裝我們項(xiàng)目依賴的

install() {
  this.npmInstall(['jquery'], { 'save-dev': true });
}

這里就安裝一個(gè)jquery作為說明即可绍昂。
最后我們在根目錄執(zhí)行

 $ npm link

這樣我們就可以在全局使用該generator了
然后切換到開發(fā)目錄啦粹,執(zhí)行

 $ yo xy

按照步驟,最后我們生成的開發(fā)目錄的結(jié)構(gòu)如下

3.png

然后你就可以開始編碼了窘游,so easy今后所有這種類型的項(xiàng)目一個(gè)命令幾秒鐘就可以開始愉快的編碼唠椭,而且代碼風(fēng)格統(tǒng)一~~~

三. Gulp+Webpack

這里把Gulp和Webpack放到一起來說。
博主最早是只用了webpack來構(gòu)建自己的項(xiàng)目忍饰,后來加入Gulp對其進(jìn)行整合贪嫂,發(fā)現(xiàn)配合食用,口感更佳呀
核心依然是plugin

!Webpack出口文件即Gulp入口文件

這里也只是講如何寫一個(gè)初略的gulpfile.js

核心便是task,src,start,watch等api艾蓝,詳細(xì)說明見官網(wǎng)Gulp Api
基本工作流程:
i. 通過gulp.src()方法獲取到我們想要處理的文件流(Vinyl filesstream)力崇,
ii. 把文件流通過pipe方法導(dǎo)入到gulp的插件中進(jìn)行處理,比如調(diào)用concat方法合并所有css赢织,再調(diào)用minify()壓縮css亮靴。(具體插件用法,npm官網(wǎng)均有介紹)
iii. 把處理后的流再通過pipe方法導(dǎo)入到gulp.dest()中于置,最后把流中的內(nèi)容寫入到文件中

項(xiàng)目結(jié)構(gòu)


4.png

gulpfile.js

//加載外掛:自動(dòng)瞄準(zhǔn)茧吊,無后座,鎖血俱两,大挪移.......~~~
var gulp = require('gulp'),
minify=require('gulp-minify-css');
autoprefixer = require('gulp-autoprefixer'),
jshint = require('gulp-jshint'),
uglify = require('gulp-uglify'),
imagemin = require('gulp-imagemin'),
clean = require('gulp-clean'),
concat = require('gulp-concat'),
notify = require('gulp-notify'),
cache = require('gulp-cache'),
livereload = require('gulp-livereload'),
fileinclude = require('gulp-file-include'),
webpack = require('gulp-webpack');

gulp.task('css', function() {
gulp.src('src/css/*.css')
    .pipe(concat('main.css'))
    .pipe(minify())
    .pipe(gulp.dest('dist/css'));
})

gulp.task('scripts', function() {
return gulp.src('src/entry.js')
  .pipe(webpack( require('./webpack.config.js') ))
  .pipe(gulp.dest('dist/js'));
});

gulp.task('images', function() {
return gulp.src('src/images/**/*')
  .pipe(cache(imagemin({ optimizationLevel: 3, progressive: true, interlaced: true })))
  .pipe(gulp.dest('dist/images'))
  .pipe(notify({ message: 'Images compile complete' }));
});

gulp.task('html', function() {
return gulp.src('src/**/*.html')
  .pipe(fileinclude({
    prefix: '@@',
    basepath: '@file'
  }))
  .pipe(gulp.dest('dist/'))
  .pipe(notify({ message: 'html compile complete' }));
});

gulp.task('clean', function() {
   return gulp.src(['dist/css', 'dist/js', 'dist/images'], {read: false})
   .pipe(clean());
});

gulp.task('default', ['clean'], function() {
   gulp.start('css','scripts', 'images', 'html');
});


gulp.task('watch', function() {

   gulp.watch('src/css/**/*.css', ['css']);

   gulp.watch('src/js/**/*.js', ['scripts']);

   gulp.watch('src/images/**/*', ['images']);

   gulp.watch('src/**/*.html', ['html']) ;

   livereload.listen();
   gulp.watch(['dist/**']).on('change', livereload.changed);

});
1.插件的話按需自取饱狂,這里我用的插件是包含了處理所有文件的∠懿剩可以酌情增減
2.gulp.task第一個(gè)參數(shù)為任務(wù)名休讳,gulp task-name 即可執(zhí)行對應(yīng)的任務(wù),這里需要解釋的就是對于js的處理尿孔。剛才說過webpack的出口文件就是gulp的入口文件俊柔,這里我們用到了gulp-webpack包來優(yōu)化筹麸。
3.在默認(rèn)任務(wù)這里執(zhí)行編譯之前調(diào)用gulp.clean清空上一次的編譯結(jié)果
4.這里使用了livereload插件,需要配置Chrome(美中不足雏婶,顯然沒有webpack-dev-server實(shí)在拔锔稀)
5.運(yùn)行
 $ gulp
 $ gulp watch

The Relentless Pursuit of Perfection 持續(xù)更新中

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市留晚,隨后出現(xiàn)的幾起案子酵紫,更是在濱河造成了極大的恐慌,老刑警劉巖错维,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件奖地,死亡現(xiàn)場離奇詭異,居然都是意外死亡赋焕,警方通過查閱死者的電腦和手機(jī)参歹,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來隆判,“玉大人犬庇,你說我怎么就攤上這事∏揉郑” “怎么了臭挽?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長飒炎。 經(jīng)常有香客問我埋哟,道長,這世上最難降的妖魔是什么郎汪? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任赤赊,我火速辦了婚禮,結(jié)果婚禮上煞赢,老公的妹妹穿的比我還像新娘抛计。我一直安慰自己,他們只是感情好照筑,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布吹截。 她就那樣靜靜地躺著,像睡著了一般凝危。 火紅的嫁衣襯著肌膚如雪波俄。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天蛾默,我揣著相機(jī)與錄音懦铺,去河邊找鬼。 笑死支鸡,一個(gè)胖子當(dāng)著我的面吹牛冬念,可吹牛的內(nèi)容都是我干的趁窃。 我是一名探鬼主播,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼急前,長吁一口氣:“原來是場噩夢啊……” “哼醒陆!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起裆针,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤刨摩,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后据块,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體码邻,經(jīng)...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年另假,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片怕犁。...
    茶點(diǎn)故事閱讀 40,040評論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡边篮,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出奏甫,到底是詐尸還是另有隱情戈轿,我是刑警寧澤,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布阵子,位于F島的核電站思杯,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏挠进。R本人自食惡果不足惜色乾,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望领突。 院中可真熱鬧暖璧,春花似錦、人聲如沸君旦。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽金砍。三九已至局蚀,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間恕稠,已是汗流浹背琅绅。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留谱俭,地道東北人奉件。 一個(gè)月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓宵蛀,卻偏偏與公主長得像,于是被迫代替她去往敵國和親县貌。 傳聞我的和親對象是個(gè)殘疾皇子术陶,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,979評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 在現(xiàn)在的前端開發(fā)中,前后端分離煤痕、模塊化開發(fā)梧宫、版本控制、文件合并與壓縮摆碉、mock數(shù)據(jù)等等一些原本后端的思想開始...
    Charlot閱讀 5,443評論 1 32
  • Pines Cheng’s Blog awesome-gulp中文版 一份gulp的資源塘匣,插件和使用實(shí)例清單, 致...
    大前端之路閱讀 2,304評論 0 12
  • gulpjs是一個(gè)前端構(gòu)建工具巷帝,與gruntjs相比忌卤,gulpjs無需寫一大堆繁雜的配置參數(shù),API也非常簡單楞泼,學(xué)...
    井皮皮閱讀 1,298評論 0 10
  • 驚嘆于小學(xué)三年級學(xué)生的作品的同時(shí)驰徊,更佩服Tyger老師的提問功底。 教學(xué)到了一定階段堕阔,教師會(huì)開始傾向于輸出自己的價(jià)...
    轉(zhuǎn)身2017閱讀 239評論 0 0
  • 踏入社會(huì)的第一份工作棍厂,在一個(gè)化工工廠進(jìn)行儀器儀表維修。這份工作是父親拖了多層關(guān)系和后門才為我謀求到超陆。在父輩的想法中...
    走在雨的縫中閱讀 1,004評論 11 15