年后,前端林宥嘉走了,一个满口广普的93年小孩儿。有点伤感,曾经在下班之后聊过几次,通常都是他教我写代码,帮我找bug。有几个瞬间,我突然有了无数动力学前端,因为想变得像他一样厉害。同样刚刚毕业,这是我心里学霸的模样,可又是个很有意思的人。
最近因为项目重新翻出了gulp,发现好久不用又忘记了。总是这样,学了忘忘了学,脑容量让人堪忧。
之前从“林宥嘉”的主页里看到一篇很好的用于gulp入门的翻译,以下内容完全是用代码重现了整个过程,聊表怀念:Gulp新手入门教程。
安装gulp
安装gulp之前,先安装node.js,点这里。然后使用 npm install
命令安装gulp1
sudo npm install gulp -g
npm install
从字面意义上来看就是安装,安装什么呢?你可以想象远程有个地方存着好多js库,npm install
的意义就是从这个库里下载你需要的js代码。而在gulp当中,你需要的js库被称作“插件”或“包”。
只要知道插件的名称,就可以通过npm install
下载到本地,如果你不知道插件的名称,可以在npmjs里进行查找。例如,你想下载编译scss文件的插件,就可以在终端输入
1 | $ npm install sass |
sass就是插件的名称。
因为npm install
安装插件是从国外服务器下载,常常会受到网络限制。阿里就提供了一个npm镜像库,把库从国外同步到了国内,10分钟从npmjs.org同步一次。安装后将命令改为cnpm install
即可。
被下载的插件被存放在node_modules
文件夹对应的模块名文件夹中。引用方式由<script src="node_modules/gulp"></script>
变成了在gulpfile.js
文件的require
,默认路径是node_modules/
:
1 | var gulp = require('gulp'); |
创建gulp项目
1 | $ npm init |
npm init
执行后,创建package.json文件,package.json文件包含项目相关信息。
1 | { |
执行命令,局部安装依赖包。
1 | npm install gulp --save-dev |
使用--save-dev
会在package.json文件中添加依赖信息。查看package.json文件,会发现devDependencies字段多了一行信息,这就是我们刚刚添加的依赖。
1 | "devDependencies": { |
依赖的作用在于,当执行npm install
时,会安装devDependencies下的所有插件。这一功能在多人协作开发当中是非常有用的。
目录结构
除了node_modules
和package.json
可以通过命令生成,其他目录结构是需要手动创建的。通常情况下,目录结构如下
1 | ├── app/ |
在这个结构当中,app
文件夹为开发目录,源文件都在这个文件夹下。dist
文件夹用来存放生产环境的文件。gulpfile.js
是最重要的一个文件,它是gulp项目的配置文件,下文讲到的所有代码都写在这个文件中。
第一个gulp项目
在创建好的gulpfile.js
文件中写入以下内容
1 | var gulp = require('gulp'); |
第一行代码引用了需要的gulp包。gulp.task('hello',...)
自定义了一个名叫“hello”的任务,任务的内容就是输出Hello World!
。
在命令行中执行
1 | $ gulp hello |
控制台输出Hello World!
,这就是我们写的第一个gulp项目。
通过使用不同的插件,可以对文件进行操作,比如编译scss文件。
1 | gulp.task('task-name', function () { |
gulp 执行预处理
首先,安装 gulp-sass 插件
1 | $ npm install gulp-sass --save-dev |
gulpfile.js文件:
1 | var sass = require('gulp'); |
这样,当我们编辑并保存style.scss文件以后,在控制台执行
1 | $ gulp sass |
就会在app/css目录下生成编译好的style.css文件。
Node中的通配符
通配符,用于对文件名和文件路径进行匹配,一种匹配模式可以匹配多个文件。
常用的几种如下:
- *.scss:*号匹配当前目录任意文件,所以这里*.scss匹配当前目录下所有scss文件
- **/*.scss:匹配当前目录及其子目录下的所有scss文件。
- !not-me.scss:!号移除匹配的文件,这里将移除not-me.scss
- *.+(scss|sass):+号后面会跟着圆括号,里面的元素用|分割,匹配多个选项。这里将匹配scss和sass文件。
如果写了多个scss文件,可以利用通配符实现多个文件同时编译。例如:
1 | gulp.task('sass', function() { |
这样,app/scss
目录及其子目录下的所有scss文件都会编译到app/css
目录下。语法如下:
1 | // Gulp watch syntax |
监听Sass文件
改造一下上面的例子:
1 | gulp.task('watch', function(){ |
如果我们修改了app/scss
文件夹下的scss文件,就会执行名叫’sass’的任务。
Browser Sync 自动刷新
参考文档:Browsersync + Gulp.js 说明文档
在刚刚完成的任务中,我们实现了自动编译scss文件的功能。可是编译之后要刷新浏览器才能看到效果,我想保存一下就自动刷新浏览器,这样开发起来就更方便了。这时我们就用到了 Browser Sync。
安装插件
1 | $ npm install browser-sync --save-dev |
创建 Browser Sync 任务,并设定根目录的位置。
1 | // 静态服务器 |
Browser Sync 需要一个应用场景,对,就是编译sass。我们希望编译scss文件后刷新浏览器,所以在任务完成后我们调用 BrowserSync 的reload()
方法。
1 | // scss编译后的css将注入到浏览器里实现更新 |
要实现同步刷新就要通过 gulp watch 来调用 BrowserSync 的 reload 方法,由于我们已经在 sass 任务中调用了 reload 方法,所以只需要在 watch 之前执行 browserSync 和 sass 任务即可。
1 | gulp.task('watch', ['array', 'of', 'tasks', 'to', 'complete','before', 'watch'], function (){ |
根据上述语法,更新代码。
1 | gulp.task('watch', ['browserSync', 'sass'], function (){ |
当在命令行中执行 $ gulp watch
以后,会发现浏览器自动打开 localhost:3000 页面,也就是起了本地服务。之前一直搞不懂怎么用 gulp 起本地服务,原来利用 gulp 起服务需要引入服务器插件,有关服务器的插件有很多个,Browser Sync 就是其中之一。
当我们修改背景色的颜色时,只要保存一下,浏览器自动就会生效。是不是很神奇?
不仅如此,它还能在不同的浏览器不同的设备上同步所有页面上的操作。假如我同时打开两个窗口,我在其中一个进行鼠标滚动时,另一个浏览器窗口也会跟着一起滚动。开始不知道这个功能的时候,我把本地地址发给设计走查,出现了页面自己动的灵异现象,活活吓了我一跳。
除了监测 scss 文件的修改,我们还可以加入 HTML 文件和 js 文件的监测,一旦有任何修改都会立即更新。
1 | gulp.task('watch', ['browserSync', 'sass'], function (){ |
组合 Gulp 任务
上面我们是这样定义任务的
1 | gulp.task('watch', ['browserSync', 'sass'], function() { |
但是 Gulp 会同时触发[]中的事件。而通常情况下,我们希望 [] 中是按我们书写的顺序执行任务的,所以就要用到 RunSequence。
1 | $ npm install run-sequence --save-dev |
用法如下:
1 | var runSequence = require('run-sequence'); |
执行 task-name 时,Gulp 会按照顺序执行 task-one, task-two, task-thre。RunSequence也允许你同时执行多个任务。
1 | gulp.task('default', function (callback) { |
如果你的任务名字叫做 default,那么只需要输入 gulp 命令即可执行。
优化CSS和JavaScript文件
通过压缩,拼接文件,减少 HTTP 请求。gulp-useref
插件可以很好地实现这个功能。
1 | $ npm install gulp-useref --save-dev |
假如我们有以下 js 文件需要合并
1 | <body> |
合并的语法如下
1 | <!-- build:<type> <path> --> |
在我们这个例子里,只要将需要打包的文件外层加上两行代码,就可以输出到 js 文件夹下的 main.min.js 文件中了。
1 | <!--build:js js/main.min.js --> |
gulpfile.js
通过一个 useref 任务,把生成的文件保存到 dist/js/main.min.js 里。这样,在新生成的 dist/.html文件中,引用也将变成一行 <script src="js/main.min.js"></script>
1 | gulp.task('useref', function(){ |
合并以后用 gulp-uglify
插件进行压缩。
安装
1 | $ npm install gulp-uglify --save-dev |
使用
1 | var uglify = require('gulp-uglify'); |
gulp-useref
同样可以应用在 css 上,只不过压缩插件要变为 gulp-minify-css
。我们还要使用 gulp-if 来做不同处理。
1 | var gulpIf = require('gulp-if'); |
总结
上面的的内容搭建了一个基本的 Gulp 工作流。另外还有一些常用的插件,同样摘自Gulp新手入门教程
开发过程:
使用 Autoprefixer,你不再需要写CSS浏览器内核前缀
增加 Sourcemaps,让你更方便的调试 Sass, coffeescript
使用 sprity 创建精灵图
gulp-changed 只允许通过修改的文件
Babel 或 Traceur 写ES6
Browserify , webpack , jspm 模块化 JavaScript
Handlebars ,Swing 模块化 HTML
require-dir 分割 gulpfile 成多个文件
gulp-moderinizr 自动生成Modernizr脚本
优化:
unCSS 移除多余的CSS
CSSO 更深入地优化CSS
Critical 生成行内CSS
附
第一次录屏,觉得挺有意思的。
软件是 licecap,下载链接:http://www.cockos.com/licecap/