├── .editorconfig ├── .gitignore ├── .jshintrc ├── .npmignore ├── .travis.yml ├── README.md ├── index.js ├── package.json └── test ├── fixtures ├── bar.html └── foo.html └── test.js /.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | root = true 3 | 4 | # Unix-style newlines with a newline ending every file 5 | [*] 6 | end_of_line = lf 7 | insert_final_newline = true 8 | charset = utf-8 9 | 10 | [*.php] 11 | indent_style = space 12 | indent_size = 4 13 | trim_trailing_whitespace = true 14 | 15 | [*.{js,twig,css,scss,html}] 16 | indent_style = space 17 | indent_size = 2 18 | 19 | [{Gruntfile.js,bower.json,composer.json,package.json}] 20 | indent_style = space 21 | indent_size = 2 22 | 23 | [*.md] 24 | trim_trailing_whitespace = false 25 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dest 3 | npm-debug.log 4 | .idea 5 | .tmp 6 | .temp 7 | -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "node": true, 3 | "esnext": true, 4 | "bitwise": true, 5 | "camelcase": true, 6 | "curly": true, 7 | "immed": true, 8 | "newcap": true, 9 | "noarg": true, 10 | "undef": true, 11 | "unused": "vars", 12 | "strict": true, 13 | "eqeqeq": true, 14 | "indent": 4, 15 | "evil": false, 16 | "maxdepth": 3, 17 | "mocha": true 18 | } 19 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | dest 2 | test 3 | .gitignore 4 | .jshintrc 5 | .travis.yml -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - 'iojs' 4 | - '0.12' 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # gulp-tmod [![NPM version][npm-image]][npm-url] [![Build Status][travis-image]][travis-url] [![Dependency Status][david-dm-image]][david-dm-url] 2 | 3 | [npm-url]: https://badge.fury.io/js/gulp-tmod 4 | [npm-image]: https://badge.fury.io/js/gulp-tmod.png 5 | [travis-url]: https://travis-ci.org/lichunqiang/gulp-tmod 6 | [travis-image]: https://travis-ci.org/lichunqiang/gulp-tmod.png?branch=master 7 | [david-dm-url]: https://david-dm.org/lichunqiang/gulp-tmod 8 | [david-dm-image]: https://david-dm.org/lichunqiang/gulp-tmod.png?theme=shields.io 9 | 10 | __Notice: Please read this [issue](https://github.com/lichunqiang/gulp-tmod/issues/7)__ 11 | 12 | 13 | > [tmodjs](https://github.com/aui/tmodjs)'s gulp version. 14 | 15 | ## Install 16 | 17 | ```sh 18 | $ npm install gulp-tmod --save-dev 19 | ``` 20 | 21 | ## Options 22 | 23 | Similar to [tmodjs options](https://github.com/aui/tmodjs#配置) with a bit of difference. 24 | 25 | #### output 26 | Default: `false` 27 | 28 | We use gulp steam other than tmodjs output, so set it to false prevent tmodjs create files. 29 | 30 | #### runtime 31 | Type: `String` 32 | 33 | Default: `template.js` 34 | 35 | This will be use as a path pass to [gulp-util File](https://github.com/gulpjs/gulp-util#new-fileobj) 36 | 37 | #### templateBase 38 | Default: `__dirname` 39 | 40 | Your template basepath. 41 | 42 | #### minify 43 | Minify is deprecated, we should use [gulp-uglify](https://www.npmjs.com/package/gulp-uglify) 44 | 45 | #### watch 46 | Watch is deprecated, we should use [gulp.watch](https://github.com/gulpjs/gulp/blob/master/docs/API.md#gulpwatchglob-opts-tasks) 47 | 48 | ## Usage 49 | 50 | ```javascript 51 | var tmodjs = require('gulp-tmod'); 52 | 53 | gulp.task('default', function(){ 54 | var stream = gulp.src('template/**/*.html') 55 | .pipe(tmodjs({ 56 | templateBase: 'template' 57 | })) 58 | .pipe(gulp.dest('dist')); 59 | return stream; 60 | }); 61 | ``` 62 | 63 | 64 | ## Test 65 | 66 | ```sh 67 | $ npm test 68 | ``` 69 | 70 | 71 | ## Changelog 72 | 73 | #### 2.0.0 74 | - Tt's a breaking change since 1.0.0. 75 | 76 | ## More 77 | 78 | See [__tmodjs__](https://github.com/aui/tmodjs) 79 | 80 | [grunt-tmod](https://github.com/Jsonzhang/grunt-tmod) 81 | 82 | _Issues should be reported on the tmodjs [issue tracker](https://github.com/aui/tmodjs/issues)_ 83 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var fs = require('fs'); 4 | var path = require('path'); 5 | var gutil = require('gulp-util'); 6 | var through = require('through2'); 7 | var TmodJS = require('tmodjs'); 8 | var extend = require("xtend"); 9 | var PluginError = gutil.PluginError; 10 | var File = gutil.File; 11 | 12 | var PLUGIN_NAME = 'gulp-tmod'; 13 | 14 | module.exports = function(opt) { 15 | var templatePaths = []; 16 | 17 | var defaults = { 18 | type: 'default', 19 | combo: true, 20 | watch: false, 21 | minify: false, 22 | output: false, 23 | verbose: false, 24 | runtime: 'template.js', 25 | templateBase: process.cwd() 26 | }; 27 | 28 | var config = extend({}, defaults, opt); 29 | config.runtime = path.basename(config.runtime); 30 | 31 | if(config.type !== 'default') config.combo = false; 32 | if(config.output !== false) config.output = path.join(process.cwd(), config.output); 33 | 34 | 35 | var tmodjs = new TmodJS(config.templateBase, config); 36 | var transformFiles = []; 37 | var hasOnCompile = false; 38 | var compileCount = 0; 39 | 40 | function transform(file, enc, cb) { 41 | if (file.isNull()) { 42 | cb(); 43 | return; 44 | } 45 | 46 | var templatePath = path.normalize(path.relative(config.templateBase, file.path)); 47 | 48 | if(!config.combo) { 49 | if (!hasOnCompile) { 50 | hasOnCompile = true; 51 | tmodjs.on('compile', function(error, data) { 52 | if (error) { 53 | cb(new gutil.PluginError(PLUGIN_NAME, error)); 54 | return; 55 | } 56 | 57 | var cfile = transformFiles[compileCount]; 58 | cfile.contents = new Buffer(data.output); 59 | cfile.path = gutil.replaceExtension(transformFiles[compileCount++].path, '.js'); 60 | 61 | this.push(cfile); 62 | cb(); 63 | }.bind(this)); 64 | } 65 | transformFiles.push(file); 66 | tmodjs.compile(templatePath); 67 | } else { 68 | templatePaths.push(templatePath); 69 | cb(); 70 | } 71 | } 72 | 73 | function flush(cb) { 74 | if (config.combo && templatePaths.length) { 75 | tmodjs.on('combo', function (error, data) { 76 | if (error) { 77 | cb(new gutil.PluginError(PLUGIN_NAME, error)); 78 | return; 79 | } 80 | 81 | var file = new File({ 82 | path: config.runtime, 83 | contents: new Buffer(data.output) 84 | }); 85 | 86 | this.push(file); 87 | cb(); 88 | }.bind(this)); 89 | tmodjs.compile(templatePaths); 90 | return; 91 | } 92 | 93 | if (!config.combo && compileCount) { 94 | tmodjs._buildRuntime(null, null, function(error, data) { 95 | if (error) { 96 | cb(new gutil.PluginError(PLUGIN_NAME, error)); 97 | return; 98 | } 99 | 100 | var file = new File({ 101 | path: config.runtime, 102 | contents: new Buffer(data) 103 | }); 104 | 105 | this.push(file); 106 | cb(); 107 | return; 108 | }.bind(this)) 109 | } 110 | 111 | cb(); 112 | } 113 | 114 | return through.obj(transform, flush); 115 | } 116 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "gulp-tmod", 3 | "version": "2.0.3", 4 | "description": "the gulp plugin for tmodjs", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "mocha" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git://github.com/lichunqiang/gulp-tmod" 12 | }, 13 | "keywords": [ 14 | "gulpplugin", 15 | "tmodjs", 16 | "seajs", 17 | "requirejs" 18 | ], 19 | "author": "light", 20 | "license": "MIT", 21 | "bugs": { 22 | "url": "https://github.com/lichunqiang/gulp-tmod/issues" 23 | }, 24 | "homepage": "https://github.com/lichunqiang/gulp-tmod", 25 | "devDependencies": { 26 | "del": "^2.2.0", 27 | "gulp": "^3.9.0", 28 | "mocha": "*", 29 | "should": "^5.0.0", 30 | "stream-array": "^1.0.1", 31 | "stream-assert": "^2.0.1" 32 | }, 33 | "dependencies": { 34 | "gulp-util": "^3.0.0", 35 | "through2": "^2.0.0", 36 | "xtend": "^4.0.1", 37 | "tmodjs": "git+https://github.com/calledT/tmodjs.git" 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /test/fixtures/bar.html: -------------------------------------------------------------------------------- 1 | {{include './foo'}} 2 |
{{bar}}
3 | -------------------------------------------------------------------------------- /test/fixtures/foo.html: -------------------------------------------------------------------------------- 1 |
{{foo}}
2 | -------------------------------------------------------------------------------- /test/test.js: -------------------------------------------------------------------------------- 1 | require('mocha'); 2 | 3 | var fs = require('fs'); 4 | var del = require('del'); 5 | var path = require('path'); 6 | var gulp = require('gulp'); 7 | var File = require('gulp-util').File; 8 | var tmod = require('../'); 9 | var should = require('should'); 10 | var assert = require('stream-assert'); 11 | 12 | function fixtures (glob) { return path.join(__dirname, 'fixtures', glob); } 13 | 14 | function compareOutput (filepath, data) { 15 | filepath = path.join(__dirname, filepath); 16 | if (fs.statSync(filepath)) { 17 | var file = fs.readFileSync(filepath); 18 | var expected = file.toString(); 19 | var actual = data.contents.toString(); 20 | return actual.should.be.equal(expected); 21 | } else { 22 | throw new Error('filepath not exist'); 23 | } 24 | } 25 | 26 | describe('gulp-tmod', function() { 27 | 28 | describe('tmod()', function() { 29 | 30 | after(function(done){ 31 | del.sync(path.join(__dirname, '../.tmp/**')); 32 | done(); 33 | }); 34 | 35 | it('should ignore null files when combo is false', function(done) { 36 | var stream = tmod({combo: false}); 37 | stream 38 | .pipe(assert.length(0)) 39 | .pipe(assert.end(done)); 40 | stream.write(new File()); 41 | stream.end(); 42 | }) 43 | 44 | it('should ignore null files when combo is true', function(done) { 45 | var stream = tmod({combo: true}); 46 | stream 47 | .pipe(assert.length(0)) 48 | .pipe(assert.end(done)); 49 | stream.write(new File()); 50 | stream.end(); 51 | }) 52 | 53 | it('should not combo file', function(done) { 54 | gulp.src(fixtures('*')) 55 | .pipe(tmod({combo: false, output: '.tmp'})) 56 | .pipe(assert.length(3)) 57 | .pipe(assert.first(function (d) { 58 | compareOutput('../.tmp/test/fixtures/bar.js', d); 59 | })) 60 | .pipe(assert.second(function (d) { 61 | compareOutput('../.tmp/test/fixtures/foo.js', d); 62 | })) 63 | .pipe(assert.last(function (d) { 64 | compareOutput('../.tmp/template.js', d); 65 | })) 66 | .pipe(assert.end(done)); 67 | }) 68 | 69 | it('should combo file', function(done) { 70 | gulp.src(fixtures('*')) 71 | .pipe(tmod({combo: true, output: '.tmp'})) 72 | .pipe(assert.length(1)) 73 | .pipe(assert.first(function (d) { 74 | compareOutput('../.tmp/template.js', d); 75 | })) 76 | .pipe(assert.end(done)); 77 | }) 78 | 79 | it('should escape', function(done) { 80 | gulp.src(fixtures('*')) 81 | .pipe(tmod({escape: true, output: '.tmp'})) 82 | .pipe(assert.first(function (d) { 83 | compareOutput('../.tmp/template.js', d); 84 | })) 85 | .pipe(assert.end(done)) 86 | }) 87 | 88 | it('should not escape', function(done) { 89 | gulp.src(fixtures('*')) 90 | .pipe(tmod({escape: false, output: '.tmp'})) 91 | .pipe(assert.first(function (d) { 92 | compareOutput('../.tmp/template.js', d); 93 | })) 94 | .pipe(assert.end(done)) 95 | }) 96 | 97 | it('should use runtime option', function(done) { 98 | gulp.src(fixtures('*')) 99 | .pipe(tmod({combo: true, runtime: 'combo.js'})) 100 | .pipe(assert.length(1)) 101 | .pipe(assert.first(function (d) { 102 | path.basename(d.path).should.eql('combo.js'); 103 | })) 104 | .pipe(assert.end(done)); 105 | }) 106 | 107 | it('should use templateBase option', function(done) { 108 | gulp.src(fixtures('*')) 109 | .pipe(tmod({combo: false, templateBase: 'test/', output: '.tmp'})) 110 | .pipe(assert.first(function (d) { 111 | compareOutput('../.tmp/fixtures/bar.js', d); 112 | })) 113 | .pipe(assert.second(function (d) { 114 | compareOutput('../.tmp/fixtures/foo.js', d); 115 | })) 116 | .pipe(assert.end(done)); 117 | }) 118 | }); 119 | 120 | }); 121 | --------------------------------------------------------------------------------