每次在本地新建自己的测试demo时,都需要新建各种的folder和拷贝一些基础代码。感觉组内内部的脚手架使用起来有些繁琐,于是打算根据自己的编码习惯,写一个简单的仅用于测试或者练习demo的脚手架借此深入学习一下gulp。在此做个记录。
Gulp快速入门
首先确保本地已安装node.js
和npm
然后通过npm
全局安装gulp
$ npm install -g gulp
根据不同项目的要求,可选择适合的gulp
插件进行后续开发。如果项目的要求基本相似(如小型的活动运营H5,平台页面等)可建立自己的脚手架工具以便于后续快速开发。
搭建脚手架
1、首先在项目根目录下通过命令行安装项目依赖
$ npm install --save-dev gulp
2、在项目根目录下新建文件gulpfile.js
。要想完成相关插件的配置,首先需要了解gulp
相关方法
gulp
只有五个方法:task
run
watch
src
dest
task
这个API用来创建任务,在命令行下可以输入gulp test
来执行test
的任务。run
这个API用来运行任务watch
这个API用来监听任务。src
这个API设置需要处理的文件的路径,可以是多个文件以数组的形式[main.scss,vender.scss]
,也可以是正则表达式/*/ .scss
。dest
这个API设置生成文件的路径,一个任务可以有多个生成路径,一个可以输出未压缩的版本,另一个可以输出压缩后的版本。其实整个
gulp
的配置文件,基本上都是在做一些任务的配置,比如创建任务,监听任务等等。
基于脚手架进行开发
1、拷贝package.json
和gulpfile.js
到相印项目根目录下,使用以下命令安装各插件
$ npm install
2、在根目录下键入相印命令进行所需的操作,如
$ gulp
基本设定
先大致地梳理一遍我们想要的功能和一些前提的设定。
1、脚手架自动化工具基于Gulp
2、基本的Task
- 初始化目录结构
- 初始化Index文件结构(迭代时可考虑基于Mobile OR PC)
- Sass自动编译
- CSS AutoPrefixer
- 监听文件,自动刷新
- 合并雪碧图
编写自己的Gulpfile.js
有了上面的基本约束后,现在建立自己的gulpfile
文件,这里会详细记录每一个task
的配置和使用。
首先把package.json
和gulpfile.js
建立起来
使用 npm init
初始化package.json
(可一直按回车,或填写一些基本信息)。使用 npm install --save-dev gulp
使用gulp
作为项目依赖
安装所需插件以及gulpfile.js
的task
配置
初始化目录与文件
首先需要初始化目录结构,这里使用fs-extra
fs-extra contains methods that aren't included in the vanilla Node.js fs package. Such as mkdir -p, cp -r, and rm -rf.
使用以下命令进行安装 (后续的插件安装不再赘述,大家可从npmjs处查找相印的安装以及Api
)
npm install --save fs-extra
先看一眼我们需要生成的目录结构
├── dist # 编译后的文件
├── html
└── index.html # home
├── css
├── js
└── img
├── src
├── img
├── sprite
├── pics
├── js
└── sass
└── style.scss
├── psd
写入gulpfile.js
var gulp = require('gulp');
// 引入组件
var path = require('path'), // node自带组件
fse = require('fs-extra'); // 通过npm下载
// 获取当前文件路径
var PWD = process.env.PWD || process.cwd(); // 兼容windows
gulp.task('init', function() {
var dirs = ['dist','dist/html','dist/css','dist/img','dist/js','src','src/sass','src/js','src/img','src/pic','src/sprite','psd'];
dirs.forEach(function (item,index) {
// 使用mkdirSync方法新建文件夹
fse.mkdirSync(path.join(PWD + '/'+ item));
})
// 往index里写入的基本内容
var template = '<!DOCTYPE html><html lang="zh-CN"><head><meta charset="utf-8"/><meta name="viewport" content="width=device-width,initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no"/><title></title><meta name="apple-touch-fullscreen" content="yes" /><meta name="format-detection" content="telephone=no" /><meta name="apple-mobile-web-app-capable" content="yes" /><meta name="apple-mobile-web-app-status-bar-style" content="black" /></head><body></body></html>';
fse.writeFileSync(path.join(PWD + '/dist/html/index.html'), template);
fse.writeFileSync(path.join(PWD + '/src/sass/style.scss'), '@charset "utf-8";');
})
此时运行$ gulp init
发现目录已经生成完成了。再对index.html
里的内容用编辑器的插件格式化一下,进入下一步。
编译.sass
以及为某些属性添加适当的前缀
添加对sass
编译的支持 安装插件gulp-sass
。在gulpfile
写入
// 编译sass
var sass = require('gulp-sass');
gulp.task('sass', function () {
return gulp
// 在src/sass目录下匹配所有的.scss文件
.src('src/sass/**/*.scss')
// 基于一些配置项 运行sass()命令
.pipe(sass({
errLogToConsole: true,
outputStyle: 'expanded'
}).on('error', sass.logError))
// 输出css
.pipe(gulp.dest('dist/css'));
});
这时候在命令行敲入$ gulp sass
发现已经跑起来了,但是存在两个问题
- 每次修改完
sass
文件后都需要输入命令 - 若
sass
有书写错误会直接退出gulp
监听
这两个问题我们放到最后再一起解决。
下面来为我们写的css
的某些不兼容属性添加前缀。这里用到了插件gulp-autoprefixer
,看一眼代码。其实都大同小异,大致的内容可在npmjs内查找到。
var autoprefix = require('gulp-autoprefixer');
gulp.task('autoprefixer', function () {
return gulp.src('dist/css/**/*.css')
.pipe(autoprefixer({
browsers: ['ios 5','android 2.3'],
cascade: false
}))
.pipe(gulp.dest('dist/css'));
});
下面测试一下,在scss
写入一个css3
属性
perspective: 500;
输入命令 $ gulp autoprefixer
发现文件没有更改。原因是sass文件还未被编译,这时候需要先敲一遍$ gulp sass
编译。这时会发现css
已经被添加了相印的后缀了
添加对雪碧图的支持
看了一下比较火的插件gulp.spritesmith
,发现它不支持生成多张雪碧图。这里使用的是gulp.spritesmith-multi
。看一眼代码
var spritesmith = require('gulp.spritesmith-multi')
gulp.task('sprite', function () {
return gulp.src('src/sprite/**/*.png')
.pipe(spritesmith())
.on('error', function (err) {
console.log(err)
})
.pipe(gulp.dest('dist/img'))
})
键入命令 $ gulp sprite
发现已经可以根据不同的sprite文件夹生成不同的雪碧图。
这里把生成的雪碧图和css
文件都输出到同一个文件夹里,不利于构建清晰的项目结构和后期维护。使用merge
将其分别导出到不同的文件夹中。并且我希望所有的sprite.scss
可以合并成一个.scss
文件。使用插件gulp-concat
看一眼代码
var spritesmith = require('gulp.spritesmith-multi'),
merge = require('merge-stream'),
concat = require('gulp-concat');
gulp.task('sprite', function () {
var spriteData = gulp.src('src/sprite/**/*.png')
.pipe(spritesmith({
spritesmith: function (options, sprite) {
options.cssName = sprite + '.scss';
options.cssSpritesheetName = sprite;
}
}));
var imgStream = spriteData.img
.pipe(gulp.dest('dist/img'))
var cssStream = spriteData.css
.pipe(concat('sprite.scss'))
.pipe(gulp.dest('src/sass'))
// Return a merged stream to handle both `end` events
return merge(imgStream, cssStream)
})
现在生成的文件就是这样啦
开启服务器以及监听编译
终于到配置的最后一步了,我们的想法是当sass、js、html有所更改时都执行相印的命令。
如 自动压缩、合并文件、添加前缀、刷新浏览器
这里选用browser-sync
同时我想当sass、sprite等文件改变时自动执行所需的task,使用watch
命令对文件进行监听。话不多说,还是看源码。
//=======================
// 服务器 + 监听
//=======================
var browserSync = require('browser-sync').create();
gulp.task('default', function() {
// 监听重载文件
var files = [
'dist/html/**/*.html',
'dist/css/**/*.css',
'src/js/**/*.js',
'src/sprite/**/*.png'
]
browserSync.init(files, {
server: {
baseDir: "./",
directory: true
},
open: 'external',
startPath: "dist/html/"
});
// 监听编译文件
gulp.watch("dist/html/**/*.html").on('change', browserSync.reload);
gulp.watch("src/sass/**/*.scss", ['sass']);
gulp.watch("src/sprite/**/*.png", ['sprite']);
gulp.watch("dist/css/**/*.css", ['autoprefixer']);
});
到这里我们就完成一个小型的1.0版本脚手架搭建啦~!
在命令行输入 $ gulp
这时我们的项目已经妥妥地跑起来了。
一些小问题的解决和脚手架的迭代,会在后续文章解决。
传送带>>> 基于gulp的前端脚手架(二)
感谢阅读^^
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。