Gulp 结构化最佳实践 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
爱意满满的作品展示区。
Kayo5994
V2EX    分享创造

Gulp 结构化最佳实践

  •  1
     
  •   Kayo5994 2016-08-23 22:07:58 +08:00 3075 次点击
    这是一个创建于 3391 天前的主题,其中的信息可能已经有所发展或是发生改变。

    在 Gulp 的官方文档中, Gulp 的任务都是写在 gulpfile.js 这一个文件中的,如果任务数量不多,这并不会有什么问题,但当任务数量较多时,会造成代码可读性差,难以维护,多人协作时还会容易造成冲突。因此,更好的处理方式是把 Gulp 的代码结构化。

    开始结构化

    https://github.com/QMUI/qmui_web

    这是一个前端框架,主要由一个 SASS 方法合集与内置的工作流构成,其中工作流部分提供了一系列的任务用于处理前端流程,并且由于是可配置的框架,需要读取配置文件,因此虽然原有的 gulpfile.js 的代码并不庞大,但仍然需要进行结构化处理,本文将会详细说明如何进行结构化处理。

    主要的思路是把 gulpfile.js 中的任务分散到独立的文件中编写,然后在 gulpfile.js 中引入这些 task 。因此最简便的方法是把每个 task 单独写在独立的文件中,以 task 名命名文件名,在 gulpfile.js 中把这些文件读取进去,例如:

    workflow/task/clean.js

    var del = require('del'); gulp.task('clean', '清理多余文件(清理内容在 config.json 中配置)', function() { // force: true 即允许 del 控制本目录以外的文件 del(common.config.cleanFileType, {force: true}); console.log(common.plugins.util.colors.green('QMUI Clean: ') + '清理所有的 ' + common.config.cleanFileType + ' 文件'); }); 

    gulpfile.js

    var gulp = require('gulp'), requireDir = require('require-dir'); // 遍历目录,加载 task 代码 requireDir('./workflow/task', { recurse: true }); gulp.task('default', ['clean']); 

    这种方法操作起来比较简单,同时基本不需要改动原有的代码,只需对 gulpfile.js 稍作改动即可。但同时也引入了一些问题,例如,文章开头说过的,像 QMUI 这类需要读取公共配置文件的需求,这里就无法解决,各个任务中如果需要引入配置表,都需要单独引入,同时像工具方法这类内容也会重复引入,造成浪费。因此实际上,clean.js 中也不是像上面的例子那样编写的,而是采用 module 的方式拆分任务。

    Module 形式的结构化

    为了避免在子任务文件中重复引入全局的配置、插件依赖和工具方法,更好的方式就是把全局配置、工具方法以及子任务都拆分成模块,并利用 require 的方式引入模块。

    首先,可以先看一下结构化后的目录结构:

    . ├── gulpfile.js ├── package.json └── workflow ├── common.js ├── lib.js └── task ├── clean.js ├── compass.js ├── include.js ├── initProject.js ├── merge.js ├── readToolMethod.js ├── start.js ├── version.js └── watch.js 

    接下来以其中几个文件为示例:

    common.js

    // 声明插件以及配置文件的依赖 var plugins = require('gulp-load-plugins')({ rename: { 'gulp-file-include': 'include', 'gulp-merge-link': 'merge' } }), packageInfo = require('../package.json'), lib = require('./lib.js'), cOnfig= require('./config.js');; // 创建 common 对象 var common = {}; common.plugins = plugins; common.cOnfig= config; common.packageInfo = packageInfo; common.lib = lib; module.exports = common; 

    clean.js

    var del = require('del'); module.exports = function(gulp, common) { gulp.task('clean', '清理多余文件(清理内容在 config.json 中配置)', function() { // force: true 即允许 del 控制本目录以外的文件 del(common.config.cleanFileType, {force: true}); common.plugins.util.log(common.plugins.util.colors.green('QMUI Clean: ') + '清理所有的 ' + common.config.cleanFileType + ' 文件'); }); }; 

    gulpfile.js

    /** * gulpfile.js QMUI Web Gulp 工作流 */ var gulp = require('gulp-help')(require('gulp'), { description: '展示这个帮助菜单', hideDepsMessage: true }), fs = require('fs'), common = require('./workflow/common.js'); // 载入任务 var taskPath = 'workflow/task'; fs.readdirSync(taskPath).filter(function (file) { return file.match(/js$/); // 排除非 JS 文件,如 Vim 临时文件 }).forEach(function (_file) { require('./' + taskPath + '/' + _file)(gulp, common); }); 

    总结如下:

    • 公共的配置、插件依赖和工具方法使用一个 common 对象关联起来,并且封装成模块
    • 每个子任务封装成模块,并且可以传入 gulp 和 common 两个参数,这样公共的部分可以复用
    • gulpfile.js 中遍历任务目录,对所有子任务都执行 require ,所有子任务都在 gulpfile.js 中成功注册

    至此,一个完整的结构化 Gulp 就处理好了, Gulp 的目录结构变得清晰很多,这时候无论是增加工具方法,增删子任务,尤其是多人协作时都会方便很多了。

    注意事项

    除了以上的主要思路,在实践中一些事项需要注意:

    • 子任务是被 gulpfile.js require 进去的,因此 gulp.srcgulp.dest 的相对目录关系并不需要修改,依然是以 gulpfile.js 所在目录为基准。但子任务文件中 require 文件是以子任务文件所在目录为基准的,如上面的代码中 common.js 在引入 package.json 是需要在上层目录中进行操作 packageInfo = require('../package.json')
    • require 当前目录的模块不能省略 ./,否则无效。
    • 需要有项目中依赖了多个 gulp 的插件,推荐使用 (gulp-load-plugins)[https://www.npmjs.com/package/gulp-load-plugins] 插件管理多个插件。
    3 条回复    2016-08-24 22:51:18 +08:00
    Seita
        1
    Seita  
       2016-08-23 22:12:32 +08:00
    对简单的构建,多入口且入口文件类型不同我用 gulp

    其它的都用 webpack
    xpol
        2
    xpol  
       2016-08-24 10:26:34 +08:00
    居然不是软文。赞一个!
    jostinsu
        3
    jostinsu  
       2016-08-24 22:51:18 +08:00
    原来可以这样子,我之前都是写一个文件,看起来有点复杂。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2570 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 29ms UTC 04:22 PVG 12:22 LAX 20:22 JFK 23:22
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86