Gulp探究折腾之路(I).docx
Gulp折腾之初探折腾之战略上的藐视回过头看Gulp的折腾历程,使用还是非常简易的。初步入门资料可参考这 里。所以战略上一定要藐视"她";当然战术上要给予足够的重视。毕竟要依赖 她以及其他各种插件and编辑器等实现前端工程化,组件化,模块化,便捷化 是一个蛮复杂的过程。总之,折腾伊始需要自信就好,折腾过程带着耐心就 好。譬如,想借助gulp压缩美化下js代码,写如下代码于gulpfile.js即可:var gulp 二 require ('gulp'),uglify = require('gulp-uglify');var gNeedDealJsFile =js' ; /javascrip 代码存放路径var outPut = /build/”; 指定输出文件存放目录 gulp, task, scripts', function() return gulp, src(gNeedDealJsFile) .pipe(uglifyO) , pipe (rename( suffix: '.min' ).pipe (gulp, dest(outPut); );在gulpfile.js同级目录运行gulp scripts即可;PS:当然前提是您已经安装了 nodejs ,并且使用npm安装了代码中需要的插件gulp和gulp-uglify与本 地。名叫gulp-concat的模块,找到这个模块后把该的目录链接到 -/work/*/gulpTest/node_modules/gulp-concat 这个目录上来。如此,在 此工程小工程中的gulpfile.js中也可以加以使用了。当然,npm link也支持多 个参数:npm link gulp gulp-concat gulp-rename gulp-uglify gulp-minify-css gulp-jshint gulp-cachedPS:这样使用时,需要注意忽略掉node_modules目录下的js/css代码, gulp.src参数数组中可以加入!node_modules/*/*. +(js|css)'以过滤之。注:即便使用 npm link 感觉也不是一个特别简洁的方案。并且在使用的时候还 遇到了些许问题:之前有提问于segmentFaultgulp如何管理多工程?以及 V2EX gulp如何管理多工程;热心码友也提出了一些可行的建议,比方:配置 多个task ,或者采用fbi ,或者采用nodejs中的NODE_PATHnodejs中的 NODE_PATH等等;此处有待进一步学习&折腾&择决;(如有简洁方案,欢求指 点,拜谢)。gulp-util幸之助幸亏有gulp-util之协助:在折腾的过程中,难免不会出现奇奇怪怪的问题; 然而gulp本身的报错提示机制真心让新手的我蛋蛋的忧伤:比方在折腾的过 程中压缩JS代码就出现Uglify throws Parse error;可是提示却幸好stackoverflowllglify throws Parse error一个问答中,大牛给予了明灯般 的指导:引入gulp-util;原话如下:uglify will parse the script content before minifying it. I suspect that one ofthe browserify source maps are being included in the stream down to uglify. Anyway to find the problem you can use gulp-util zs log method to handle uglify' s exceptions. Example:. var gulpUtil = requireCgulp-util'); gulp.taskCscripts', function(). .pipe(sourcemaps.init(loadMaps: true) ,pipe(uglify().on('error', gulplltil.log) / notice the error event here .pipe(sourcemaps.write('./') .pipe(gulp.dest('./web/js'););实时刷新页面gulp-livereload 模块gulp-1 ivereload模块用于自动刷新浏览器,反映出源码的最新变化。它除了 模块以外,还需要在浏览器中安装插件,用来配合源码变化。LiveReload结合了浏览器扩展(包括Chrome extension ),在发现文件被修 改时会实时更新网页。它可以和gulp-watch插件或者前面描述的gulp- watch()函数一起使用。下面有一个gulp-livereload仓库中的README文件 提到的例子:var gulp = require。gulp'), less = require。gulp-less'), livereload = require(' gulp-livereload'), watch = require (? gulp-watch');gulp. task(,less,, function() gulp. src(' less/*. less,) , pipe (watch () pipe (less ().pipe (gulp, dest (' css,).pipe (livereload(); );这会监听到所有与less/*.less相匹配的文件的变化。一旦监测到变化,就会生 成css并保存,然后重新加载网页.BrowserSync安装BrowserSync您可以选择从Node.js的包管理(NPM )库中 安装 BrowserSynco翻开一终端窗口 ,运行以下命令:npm install -g browser-sync您告诉包管理器下载BrowserSync文件,并在全局下安装它们,您可以在所有 工程(任何目录)中使用。当然您也可以结合gulpjs或gruntjs构建工具来使用,在您需要构建的工程里 运行下面的命令:npm install -save-dev browser-sync启动BrowserSync静态网站如果您想要监听.css文件,您需要使用服务器模 式。BrowserSync将启动一个小型服务器,并提供一个URL来查看您的网 站。/ -files 路径是相对于运行该命令的工程(目录)browser-sync start -server -files css/*.css如果您需要监听多个类型的文件,您只需要用逗号隔开。例如我们再加入一个html文件/ -files路径是相对于运行该命令的工程(目录)browser-sync start 一一server 一一files css/*css, *.html/如果你的文件层级比拟深,您可以考虑使用*(表示任意目录)匹配,任意目录下 任意.css或.html文件。browser-sync start 一一server 一一files */*css,注:在该文件下运行命令,默认需要启动网站文件:index.htmL 动态网站如果您已经有其他本地服务器环境PHP或类似的,您需要使用例模式。BrowserSync将通过代理URL(localhost:3000)来查看您的网站。/主机名可以是ip或域名browser-sync start -proxy 主机名 css/*. css在本地创立了一个PHP服务器环境,并通过绑定B来访问本地 服务器,使用以下命令方式,Browsersync将提供一个新的地址 localhost:3000来访问B ,并监听其css目录下的所有css文 件。browser-sync start 一一proxy ''BrowserSync. cn,z css/*. css参考博文:BrowserSync ,迅捷从免F5开始。注:使用的时候纯路径比方"B"尚好着,然而地址后面带一堆 参数时候,就会遇到些问题;暂时还未搞明白以解决之,特注之,待弄懂!前端组件html模板化(gulptlp2mod)摒弃了 gulp.runQgulp的API很简单z常用的也就几个:watch, task, dest, src ;目前已经摒弃T run方法。创立Default Task:注册缺省任务gulp, task(' default,, function() gulp. run C jshint,, ' scripts,);gulp. watch(workspace, function() gulp. run(' jshint,, ' scripts,);) );gulp.runQ has been deprecated. Use task dependencies or gulp.watch task triggering instead.可以根据 gulp.task(namef deps, fn)特性写法替代之。deps : (Array)一个包含任务列表的数组,这些任务会在你当前任务运行之前完成。注意:你的任务是否在这些前置依赖的任务完成之前运行了 ?请一定要确保你所依赖的任务列表中的任 务都使用了正确的异步执行方式:使用一个callback ,或者返回一个promise或streamo 创立 Default Task:注册缺省任务 gulp.task('default'z 'jshint', 'scripts', 'watch');折腾 gulp.srcQGulp使用node-glob来从你指定的glob里面获取文件,这里列举下面的例子来阐述,方便大家理解:js/app.js精确匹配文件js/jM仅匹配js目录下的所有后缀为.js的文件js:js匹配js目录及其子目录下 所有后缀为.js的文件!js/app.js从匹配结果中排除js/app.js ,这种方法在你想要匹配除了特殊文件之外 的所有文件时非常管用*.+(js|css)匹配根目录下所有后缀为.js或者.css的文件止矽卜,Gulp也有很多其 他的特征,但并不常用。如果你想了解更多的特征,请查看Minimatch文档。js目录下包含了压缩和未压缩的JavaScript文件,现在我们想要创立一个任务 来压缩还没有被压缩的文件,我们需要先匹配目录下所有的JavaScript文件,然后排除后缀为.min.js的文件:gulp, src(' js/*/* js',! js/*/* min. js,)使用 gulp-jshint()好吧,不同帮派,不同侠士,对于代码的输出是不一致的。而这JS又没像Py 那般天生带有美丽的基因。即便出了 jshint这样的好利器,然,也得考虑下兼顾团队已有的Style。所以,这里配置得纠结下微说Gulp之gulp-jshintogulp. task(,lint,, function() truereturn gulp, src(workspace)truetrue. pipe (jshint ()truetrue. pipe(jshint. reporter(,YOUR_REPOTER_HERE,););这reporter使用"default"的话,就会采用默认蛮严格的检查手段。为了能够规范而不失灵活的搀起JS ,在使用JShint之时,过滤掉哪些不合时宜的写法(如下写法就可以不留情的规避之),就得斟酌下咯。列举些常见不推荐的写法,运行时提醒如下:Missing semicolon. (W033) 丧失分号'lack' is better written in dot notation 推荐 xx.lack 写法,而不是 xx lack7 You might be leaking a variable (disX) here. (W不是不推荐连等写法: 比方 posX = disX = 0; 'status' is defined but never used. (W098) 不推荐:定义之而不用之 Use '!二二'to compare with .(W041) 不推荐上或者二二做变量是否相等判断。只对发生更改的js文件进行语法检测 更现实的开发场景是,工程代码已存在很久,代码中有大量的不符合jshint 规范的代码。而根据当前的gulp配置,每次发生修改,都会全量检测一遍 所有的文件的语法问题,实际上已存在的问题我并不想在本次提交中修复(同 时也是其他同事写的,例如不加分号问题,改动量太大)。结果就是,一启动gulp,哗哗的语法错误提示,根本找不到自己想看的文件 检测结果。这时修改一个文件,又对所有文件做了一次全量检测,又是哗哗的 满屏错误提示。而我只关心当前修改的文件检测结果。gulp工程首页推荐了一个gulpcached插件,正好解决了这个问题。npm install gulp-cached 一一save-dev配置如下var gulp = require。gulp'),cache = require (J gulp-cached,),jshint = requiregulp-jshint,);gulp, task。jshint, function () gulp, src (J . /src/*/* js').pipe (cache (' jshint,).pipe (jshint ().pipe (jshint. reporter default,););gulp, task (J watch,, function () gulp, watch, /src/*/* js' , ' jshint,););gulp, task,default', ' jshint,, ' watch');这样就能清晰的看到刚才发生修改文件的语法检测结果了,欧耶。压缩-合并-重命名输出JS代码压缩:gulp-uglify梃好;Ps :有一款 gulp-minify(Desc: Minify JavaScriptwith UglifyJS2),默认压缩完毕之后会生成一个带-min的文件,略烦。合并:gulp-concat指定合并生成名字即可:, pipe(concat C all. js,)重命名:gulp-rename;可以仅仅为名字指定后缀(不改变文件后缀)Uke This: pipe(rename(suffix:'. min' )输出:gulp自带方法gulp. dest0/outPutPathName: String.pipe (gulp, dest(outPutPathName);压缩CSS代码(合并-重命名-输出同上)压缩:gulp-minify-css;嗯,这个直接将原文件压缩了,默认没有改其名字。如果直接输出到该目录下,会覆盖原文件;假设要输出同目录之下,可改改名字再输出,Like this :, pipe(minifycss () pipe(rename(suffix:'. min,), pipe(gulp, dest (outPut);PS:这个插件(默认)也会帮着干掉注释,过滤掉空类(没有内容的描述)等等。gulp-load-plugins 模块一般情况下,gulpfile.js中的模块需要一个个加载。var gulp = require ('gulp'),jshint = require C gulp-jshint,), uglify = requireC gulp-uglify,), concat = requiregulp-concat,);gulp, task, js', function () return gulp. src(,js/* js').pipe (jshint ().pipe (jshint. reporter (J default').pipe(uglify().pipe (concat C app. js').pipe (gulp, dest ('build'););上面代码中,除了 gulp模块以外,还加载另外三个模块。这种加载的写法,比拟麻烦。使用gulp-load-plugins模块,可以加载package.json文件中所有的gulp模块。上面的代码用gulp-load-plugins模 块改写,就是下面这样。var gulp = require ('gulp'),gulpLoadPlugins = require (J gulp-load-plugins,), plugins = gulpLoadPlugins ();gulp, task (J js,, function () return gulp. src(,js/* js,).pipe (plugins, jshint (), pipe (plugins, jshint. reporterdefault').pipe (plugins, uglify().pipe (plugins, concat (' app. js') pipe (gulp, dest (' build'););上面代码假设package.json文件包含以下内容。z,devDependenciesz,: “gulpconcat”: 2. 2. 0,gulp-uglify:,/zgulp-jshint/z: 1 5. 1,gulp :3. 5. 6gulp插件的快速安装谈及了基本应用之后,不得不谈下如何快速安装插件(毕竟,合作开发,彼此都 能便捷使用,才是王道)。对于所使用的插件可以一个个安装,同时也可以批量安装 Like This : npm install gulp-concat gulp-uglify gulp-jshint . . gulp-rename -save-dev-save :将保存配置信息至package.json ( package.json是nodejs工程配置文件);-dev :保存至 package.json 的 devDependencies 节点,不旨定-dev 4各保存至 dependencies 节点;为什么要保存至package.json ?因为node插件包相对来说非常庞大,所以不 加入版本管理,将配置信息写入package.json并将其加入版本管理,其他开 发者对应下载即可(命令提示符执行 npm install , 那么会根据package.json下 载所有需要的包)。对于这块细节可以参看gulp详细入门教程;大概来讲就是可以借助npm init 命令,按照其一步步提示,输入工程相关信息。完毕之后,加入需要依赖的插 件以及版本信息即可(注意:这是一个普通json文件,一定得符合json格式; 同时需要安装的插件版本也得是 <=线上最新版本)。PS :前文涉及到的插件 下载,即可如此配置予以完成:在生成的package.json中加入如下 json(2015-10-26 日情形):“devDependencies”: ,zgulp-concatz/: 2 6. 0, gulp-uglify:L4.2, “gulp-jshint: “gulp-rename”: 1 2. 2, “gulp-minify-css”: 1 2. z,gulp-cached,z: 1 1. 0, "gulp: 3. 9.0如此,其他开发者只需更新gulpfile.js以及这个package.json ,运行npm install 即可下载gulp所依赖插件于本地,(。)哇So Coologulp多工程管理(npm link)要谈下多工程管理了;比方这种场景:对于工程非常多而小,而且彼此间相互 独立;伊始,采用在工程根目录之下gulpfile, js和package.json (毕竟每个 单独小工程都来一发单独配置,岂不是要疯掉了),会将需要的插件down于 根目录下;而在gulpfile.js中控制所要操作的单个小工程路径。这样每次切换 工程,都要更改下gulpfile.js,即便将这个别离出来写一个config.js,也得手动去 更改,略略有点蛋疼。幸好,gulp有npm link,哇哦,体贴如你,夫复何求?对于npm link的介绍,可以参见阮一峰npm模块管理器一文;我们可以将 所需的插件,全局环境下载,在单独工程中link全局环境下插件。如此,不仅 可以不用每次都down ,而且,依赖的插件需要update ,只需一地更新,所 link之处都会受益。具体做法,首先将需要的插件全局环境下Down下来:npm install gulp gulp-concat gulp-rename gulp-uglify gulp-minify-css gulp-jshi nt gulp-cached -g接下来,(如果我们要使用gulp-concat这个模块)我们进入单独小工程(eg: gulpTest),使用 npm link gulp-concat 命令会去mac/linux】 /usr/local/lib/node_ modules/, windowD:UserProfilesusernameAppDataRoamingnpmnode_modules,目 录下查找