用Yeoman + gulp + webpack 来管理你的前端项目

一. 前言

Yeoman:前端脚手架,快速搭建前端开发环境,优化工作流~
Gulp:工程化构建工具,基于task来处理任务
Webpack:最常见的前端构建工具,类似与gulp,但不如gulp灵活,专注于代码打包编译

OK,主人公们介绍完了,该篇主要说明三个工具的基本用法,安装配置自己解决。

二. Yeoman

Q:
i.在写东西的时候经常会遇到一些重复性的操作和代码,苦于Ctrl+c
ii.人数较多的前端团队10个人拥有十种代码风格,十种项目结构,后期维护及其繁琐

——使用Yeoman 达到One Code Style One Directory Structure

1.安装:

$ cnpm install -g yo

2.使用:

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

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

按照提示选择需要的模板就行了,这里主要说一说怎么私人订制~~~嘻嘻

3.创建自己的generator

yeoman官方提供了generator-generator 来帮助我们自定义生成器,良心啊~~~

$ cnpm install -g generator-generator
$ yo generator

然后你的根目录下就会生成如下结构:


1.png

我们需要做的就是在index.js中来创造我们自己的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();
 }
};

可以看到核心的流程是在一个继承了generator的类当中
其实这里generator一共提供了 initializing,prompting,configuring,default,writing,conflicts,install,end这几个函数

Prompting()方法是执行前的过渡,实现与用户的交互,你可以在prompts问题集中定义一些问题,比如你叫啥,干啥,弄啥,家里几口人,人均几亩地...........然后将用户输入的内容保存在this.props中,方便以后调用。

我们自己来写一个

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来获取到输入的项目名称

我们在原来的基础上定义一个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 创建该目录
  this.destinationRoot(this.destinationPath(this.props.appname));
}
}

writing方法用来书写创建工程文件的步骤
在这之前我们首先在template文件夹下创建一个public目录,里面创建如下文件作为咱们这个初级教程的全部内容


2.png

开始写writing方法

writing() {
mkdirp('css');      //创建css文件夹
mkdirp('js');      //创建js文件夹
this.fs.copy(     //调用方法将模板的内容创建到根目录
  this.templatePath('public/index.html'),       //模板文件地址 
  this.destinationPath('index.html'),          //创建在根目录
),

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(),即是用来安装我们项目依赖的

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

这里就安装一个jquery作为说明即可。
最后我们在根目录执行

 $ npm link

这样我们就可以在全局使用该generator了
然后切换到开发目录,执行

 $ yo xy

按照步骤,最后我们生成的开发目录的结构如下

3.png

然后你就可以开始编码了,so easy今后所有这种类型的项目一个命令几秒钟就可以开始愉快的编码,而且代码风格统一~~~

三. Gulp+Webpack

这里把Gulp和Webpack放到一起来说。
博主最早是只用了webpack来构建自己的项目,后来加入Gulp对其进行整合,发现配合食用,口感更佳呀
核心依然是plugin

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

这里也只是讲如何写一个初略的gulpfile.js

核心便是task,src,start,watch等api,详细说明见官网Gulp Api
基本工作流程:
i. 通过gulp.src()方法获取到我们想要处理的文件流(Vinyl filesstream),
ii. 把文件流通过pipe方法导入到gulp的插件中进行处理,比如调用concat方法合并所有css,再调用minify()压缩css。(具体插件用法,npm官网均有介绍)
iii. 把处理后的流再通过pipe方法导入到gulp.dest()中,最后把流中的内容写入到文件中

项目结构


4.png

gulpfile.js

//加载外挂:自动瞄准,无后座,锁血,大挪移.......~~~
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第一个参数为任务名,gulp task-name 即可执行对应的任务,这里需要解释的就是对于js的处理。刚才说过webpack的出口文件就是gulp的入口文件,这里我们用到了gulp-webpack包来优化。
3.在默认任务这里执行编译之前调用gulp.clean清空上一次的编译结果
4.这里使用了livereload插件,需要配置Chrome(美中不足,显然没有webpack-dev-server实在啊)
5.运行
 $ gulp
 $ gulp watch

The Relentless Pursuit of Perfection 持续更新中

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,132评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,802评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,566评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,858评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,867评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,695评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,064评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,705评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,915评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,677评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,796评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,432评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,041评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,992评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,223评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,185评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,535评论 2 343

推荐阅读更多精彩内容

  • 在现在的前端开发中,前后端分离、模块化开发、版本控制、文件合并与压缩、mock数据等等一些原本后端的思想开始...
    Charlot阅读 5,429评论 1 32
  • Pines Cheng’s Blog awesome-gulp中文版 一份gulp的资源,插件和使用实例清单, 致...
    大前端之路阅读 2,299评论 0 12
  • gulpjs是一个前端构建工具,与gruntjs相比,gulpjs无需写一大堆繁杂的配置参数,API也非常简单,学...
    井皮皮阅读 1,291评论 0 10
  • 惊叹于小学三年级学生的作品的同时,更佩服Tyger老师的提问功底。 教学到了一定阶段,教师会开始倾向于输出自己的价...
    转身2017阅读 233评论 0 0
  • 踏入社会的第一份工作,在一个化工工厂进行仪器仪表维修。这份工作是父亲拖了多层关系和后门才为我谋求到。在父辈的想法中...
    走在雨的缝中阅读 995评论 11 15