gulp 作为前端构建项目的一个工具, 自己理解 gulp 主要方面的作用:
1. 构建本地服务器
2. 快速构建项目
3. 对代码进行压缩合并, 使代码简洁, 减少频繁的请求工作
gulp 学习地址: gulp 中文网: http://www.gulpjs.com.cn/
一 gulp 安装
1.1 全局安装 gulp, 前提是必须安装了 node.js/npm;
npm install --global gulp
1.2 作为项目的开发依赖(需要在项目目录下)
npm install --save-dev gulp
1.3 根据自己的项目需求, 安装其他开发依赖
npm install gulp-connect gulp-concat gulp-uglify --save-dev
1.4 在项目根目录创建一个名为 gulpfile.js 文件, 看项目需要依赖哪些开发项, 进行依赖注入在 gulpfile.js 中, 并创建 gulp 任务
- var gulp=require('gulp');
- var connnect=require('gulp-connect');
- ......
- gulp.task('kathie',function(){
- // 此任务要做的事情
- });
- gulp.task('default',['kathie']);// 默认执行的任务
1.5 在项目跟目录创建一个 package.json 的文件, 这个文件是一个严格的 json 文件主要是项目的配置文件其中很多属性可以通过 npm-config 来生成主要信息有以下其中除了 devDependencies 之外, 可以通过 npm init 来配置; devDependencies 依赖的插件需要通过 npm install gulp-connect --save-dev 来安装
1.6 package.json 配置详解: http://www.cnblogs.com/tzyy/p/5193811.html#_h1_27
[图片]
二 npm 中的开发依赖项学习
2.1 gulp-connect: run a webserver 具体用法:
- //1. 引入插件:
- var gulp = require('gulp');
- var connect = require('gulp-connect');
- //2. 创建 watch 任务去检测 html 文件, 其定义了一个当 html 改动之后, 去调用一个 gulp 的 task
- gulp.task('watch',
- function() {
- gulp.watch(['./www/.html'], ['html']);
- })
- //3. 使用 connect 启动一个 web 服务器
- gulp.task('connect',
- function() {
- connect.server({
- root: "www",
- livereload: true,
- //port:8090, 可以更改本地默认端口号
- //host:'gulp.dev'
- });
- });
- //4. 加载 www 中的一个主页面
- gulp.task('html',
- function() {
- gulp.src('./www/.html').pipe(connect.reload());
- });
- //5. 设置默认任务
- gulp.task('default', ['connect', 'watch']);
- //6. 不要关闭 dos 命令行, 如果没有修改端口号, 直接浏览器输入 http://localhost:8080
- 2.2 browser - sync:
启动一个本地服务器, 配置启动页面; 同时修改代码之后能自动刷新页面, 免按 F5;
browser-sync 与 gulp 一起使用方法
- //1. 引入插件:
- var browserSync=require('browser-sync').create();
- //2. 创建任务, 并使用 browserSync 创建服务器
- gulp.task('serve',function(){
- browserSync.init({
- server:{
- basedir : './' // 初始化项目根目录为./
- },
- files:[
- 'www/CSS/*.css',
- 'www/*/.js',
- 'www/*/.html',
- 'www/img/',
- 'www/fonts/'
- ]
- });
- gulp.watch(['./www/*.html'],['html']);
- gulp.watch("www/**/*.html").on("change",browserSync.reload);
- //3.watch 这个 api 是监控当前文件发生变化时触发的任务; 这里是当 html 文档发生变化时, 浏览器会自动 reload
- });
以下为案例:
- // 引入 gulpgulp 插件以及 browser-sync
- var gulp = require('gulp'),
- browserSync = require('browser-sync').create(),
- less = require('gulp-less');
- // 创建一个新的 gulp 任务
- gulp.task('serve',['less'],function(){
- // 初始化项目跟目录为'./'(也可以使用代理 proxy: "yourlocal.dev")
- browserSync.init({
- server: './'
- });
- // 创建 gulp 监听器, 监听 less 文件的变化, 自动执行'less'任务, 编译 less 并生成 css 文件
- gulp.watch('./less/.less', ['less']).on('change', function(event){
- console.log('File' + event.path + 'was' + event.type + ', running tasks...');
- });
- // 监听 html 文件的变化, 自动重新载入
- gulp.watch('./.html').on('change', browserSync.reload);
- });
- // 创建自动编译 less 的任务, 这边需要 return stream 以保证 browserSync.reload 在正确的时机调用
- gulp.task('less', function(){
- return gulp.src('./less/*.less')
- .pipe(less())
- .pipe(gulp.dest('./css'))
- .pipe(browserSync.stream());
- });
- // 默认启动的 gulp 任务数组['serve']
- gulp.task('default', ['serve']);
- 2.3 gulp-rev and gulp-rev-collector
目的是对 css 和 js 文件命名进行加密处理; 同时在对应的 html 中的路径进行更新
- var gulp = require('gulp');
- var concat = require('gulp-concat'); //- 多个文件合并为一个;
- var minifyCss = require('gulp-minify-css'); //- 压缩 CSS 为一行;
- var rev = require('gulp-rev'); //- 对文件名加 MD5 后缀
- var revCollector = require('gulp-rev-collector'); //- 路径替换
- gulp.task('cssConcat',
- function() { //- 创建一个名为 concat 的 task
- gulp.src('www/css/*.css') //- 需要处理的 css 文件, 放到一个字符串数组里
- .pipe(minifyCss()) //- 压缩处理成一行
- .pipe(rev()) //- 文件名加 MD5 后缀
- .pipe(gulp.dest('dist/css')) //- 输出文件本地
- .pipe(rev.manifest()) //- 生成一个 rev-manifest.json
- .pipe(gulp.dest('./rev')); //- 将 rev-manifest.json 保存到 rev 目录内
- });
- gulp.task('rev', ['cssConcat'],
- function() {
- console.log(111) gulp.src(['./rev/rev-manifest.json', 'dist/index.html'])
- //- 读取 rev-manifest.json 文件以及需要进行 css 名替换的文件
- .pipe(revCollector()) //- 执行文件内 css 名的替换
- .pipe(gulp.dest('dist')); //- 替换后的文件输出的目录
- });
- gulp.task('default', ['rev']);
这里踩的坑:
2.3.1 第一个坑: 只能对同名的 css 或者 js 文件进行 md5 加密, 然后进行替换对于先拷贝再修改名再加密的情况, html 中的引用无法更新
我存在的问题:
源文件 www/index.html 中引用的是 < link rel="stylesheet" href="css/bootstrap.css">
对 css 进行了拷贝, 再 rename 并加密
- gulp.task('cssConcat',function(){
- return gulp.src('www/css/*.css')
- .pipe(minifyCss({ // 先对源文件进行压缩
- keepSpecialComments: 0
- }))
- .pipe(rename({
- extname: '.min.css' // 再重命名
- }))
- .pipe(rev()) // 再加密
- .pipe(gulp.dest('dist/css')) // 输出到 dist 文件中
- .pipe(rev.manifest())
- .pipe(gulp.dest('./rev')); // 将 rev-manifest.json 文件放到 rev 文件夹
- });
此时 dist 中的 css 文件名是 bootstrap-87we8fuiehfjhdj.min.css
但拷贝过来的 html 中的 css 文件还是 < link rel="stylesheet" href="css/bootstrap.css">
尽管此时生产了 rev-manifest.json 文件; 但还是无法替换 html 中的 css 引用名称
解决办法: 不要先对其 rename 注释掉. pipe(rename({ extname: '.min.css' }))
2.3.2 第二个坑: 目前不能同时对 css 和 js 进行加密后面的会覆盖掉前面的 rev-manifest.json 文件
[图片]
[图片]
如图: 这样 rev-manifest.json 文件只有对 js 的加密的文件; 没有 css 的
解决办法:
在网上看到可以使用. pipe(rev.manifest({ merge: true })), 但实际操作过了, 不行;
目前的解决办法就是将 css 和 js 分别备份到 rev 存两个文件夹; 一个 css; 一个 js 如下:
[图片]
2.4 gulp-uglify
对 js 进行压缩; 这里踩的坑 ----- 对 js 进行压缩之后, 启动项目, 发现报错
原因: gulpfile.js 必须是严格模式的第一行必须写 use strict 所以压缩的文件也必须按照严格模式来写所以 angular 中的写法都必须定义变量采用严格模式:
angular.module('app',[]).controller('myCtrl',function($scope){})---- 这个写法是错误的, 必须变成加中括号, 定义变量:
angular.module('app',[]).controller('myCtrl',['$scope',function($scope){}])-- 正确写法
如果不使用严格模式的写法; 针对 angularJs 的 js 文件; 也可以使用 gulp-ng-annotate 插件此插件的作用是: 使用 ng-annotate 进行 angular 模块依赖自动注入, 引入模块自动加[], 防止被混淆
2.5 gulp-dom-src and gulp-cheerio
gulp-dom-src 可以对 html 中的 script 和 link 进行操作
eg:-- 这样可以直接操作 index.html 中的 script 和 link 的引用文件
[图片]
因为我们要复制一个 dist 文件出来, 对原有的 www 的文件不要做变更; 所以我们还是不是直接对 index.html 中的文件进行操作
gulp-cheerio 有点强大; 他可以帮忙我们操作 html 中的 dom 元素; 我们在合并了 jscss 之后, 要修改 index.html 中的引用文件; 可以直接使用 gulp-cheerio 进行操作; 其使用的还是 jq 中的方法
eg:
[图片]
如上; 可以使用 append()进行插入; 但因为 append()只是插入到当前元素内部最后一个; 害怕位置不一样的话导致引用效果不一样的话, 我们可以变更引用的位置如:
$('<link rel="stylesheet"href="css/bootstrap.min.css">').insertBefore('head>style');
还有一个坑需要注意下: index.html 中引用的文件是有顺序的, 合并的时候是否需要按照顺序来合并?
普通的只使用 gulp-src 目前就是按照文件的顺序 (在文件夹中的首字母排序) 进行合并的; 这样访问页面有错误;
使用 gulp-src(['a.js','b.js','c.js']).pipe(concat())可以实现按照自己想要的顺序进行排序, 这样 js 依赖就不会出错;
看网上有介绍 gulp-order 可以进行排序; 实验了下, 不能按照自己想要的顺序进行排序至于为什么不能排序; 以后再研究
2.6 gulp-src
gulp-src 中匹配对应的文件; 可使用正则
排除 kaifanla.js 的写法如下:
- gulp.src(['www/js/*.js','!kaifanla.js']);
- 2.7 gulp-ng-html2js
gulp-ng-html2js 是对 angularjs 中的 templates html 片段整合成 js 文件; angular 项目的混淆作用
用法步骤如下:
先复制 index.html 和 aaa.js 文件到 dist 文件;
合并外部 js 文件到 dist---all.min.js 文件;
使用 ng-html2js 插件, 对 tpl 中的 html 文档进行整合
- gulp.task('html2js', function () {
- return gulp.src("www/tpl/*.html")// 原路径
- .pipe(html2js({
- moduleName: "template"
- }))//html 模板转 js 文件
- .pipe(concat("templates.js"))// 合并
- // .pipe(uglify({compress:false}))// 压缩
- .pipe(gulp.dest("dist/js/"));// 目标路径
- });
这样 dist 的目录是这样的:
[图片]
修改 index.html 中文件的引用为:
- <script src="js/libs.min.js"></script>
- <script src="js/aaa.js"></script>
- <script src="js/templates.js"></script>
接下来修改 aaa.js 文件:
第一处: 因为 templates.js 中的 module 为 template; 所以 aaa.js 中的 module 就要依赖 template
[图片]
第二处: 修改路由
[图片]
按照如上的这个方法; 找到 templates.js 中查看 a,b 分别代表什么; 将 aaa.js 中的路由都替换成 a
[图片]
[图片]
[图片]
来源: http://www.qdfuns.com/article/22227/d6ab196cd08feb899d167bc35caa514c.html