diff --git a/index.js b/index.js index 73b2806..a3e2568 100644 --- a/index.js +++ b/index.js @@ -6,56 +6,74 @@ var applySourceMap = require('vinyl-sourcemaps-apply'); var objectAssign = require('object-assign'); var replaceExt = require('replace-ext'); var babel = require('babel-core'); +var lru = require('lru-cache'); +var crypto = require('crypto'); function replaceExtension(fp) { return path.extname(fp) ? replaceExt(fp, '.js') : fp; } -module.exports = function (opts) { - opts = opts || {}; - - return through.obj(function (file, enc, cb) { - if (file.isNull()) { - cb(null, file); - return; - } - - if (file.isStream()) { - cb(new gutil.PluginError('gulp-babel', 'Streaming not supported')); - return; - } - - try { - var fileOpts = objectAssign({}, opts, { - filename: file.path, - filenameRelative: file.relative, - sourceMap: Boolean(file.sourceMap), - sourceFileName: file.relative, - sourceMapTarget: file.relative - }); - - var res = babel.transform(file.contents.toString(), fileOpts); - - if (file.sourceMap && res.map) { - res.map.file = replaceExtension(res.map.file); - applySourceMap(file, res.map); +module.exports = function (lruOptions) { + lruOptions = lruOptions || 500; + + var cache = lru(lruOptions); + + return function (opts) { + opts = opts || {}; + + return through.obj(function (file, enc, cb) { + if (file.isNull()) { + cb(null, file); + return; } - if (!res.ignored) { - file.contents = new Buffer(res.code); - file.path = replaceExtension(file.path); + if (file.isStream()) { + cb(new gutil.PluginError('gulp-babel', 'Streaming not supported')); + return; } - file.babel = res.metadata; + try { + var fileOpts = objectAssign({}, opts, { + filename: file.path, + filenameRelative: file.relative, + sourceMap: Boolean(file.sourceMap), + sourceFileName: file.relative, + sourceMapTarget: file.relative + }); + + var resultHash = crypto.createHash('sha1').update(file.contents.toString()).digest('hex'); + + var res; + + res = cache.get(resultHash); - this.push(file); - } catch (err) { - this.emit('error', new gutil.PluginError('gulp-babel', err, { - fileName: file.path, - showProperties: false - })); - } + if (!res) { + res = babel.transform(file.contents.toString(), fileOpts); + + cache.set(resultHash, res); + } + + if (file.sourceMap && res.map) { + res.map.file = replaceExtension(res.map.file); + applySourceMap(file, res.map); + } + + if (!res.ignored) { + file.contents = new Buffer(res.code); + file.path = replaceExtension(file.path); + } + + file.babel = res.metadata; + + this.push(file); + } catch (err) { + this.emit('error', new gutil.PluginError('gulp-babel', err, { + fileName: file.path, + showProperties: false + })); + } - cb(); - }); + cb(); + }); + }; }; diff --git a/package.json b/package.json index d7b3faf..1ae6bdf 100644 --- a/package.json +++ b/package.json @@ -36,6 +36,7 @@ "dependencies": { "babel-core": "^6.0.2", "gulp-util": "^3.0.0", + "lru-cache": "^4.0.0", "object-assign": "^4.0.1", "replace-ext": "0.0.1", "through2": "^2.0.0", diff --git a/readme.md b/readme.md index ee8f8fd..af2a864 100644 --- a/readme.md +++ b/readme.md @@ -30,12 +30,28 @@ gulp.task('default', () => ## API -### babel([options]) - -#### options - -See the Babel [options](https://babeljs.io/docs/usage/options/), except for `sourceMap` and `filename` which is handled for you. - +```js +import createBabel from 'gulp-babel2'; + +/** + * @see https://github.com/isaacs/node-lru-cache#options + */ +type lruOptions = { + max: ?number, + length: ?Function, + dispose: ?Function, + maxAge: ?number +}; + +/** + * @see See the Babel options (https://babeljs.io/docs/usage/options/), except for `sourceMap` and `filename` which is handled for you. + */ +type babelOptions = {}; + +const babel = createBabel({max: 500}: lruOptions); + +babel({}: babelOptions); +``` ## Source Maps @@ -44,9 +60,11 @@ Use [gulp-sourcemaps](https://github.com/floridoo/gulp-sourcemaps) like this: ```js const gulp = require('gulp'); const sourcemaps = require('gulp-sourcemaps'); -const babel = require('gulp-babel'); +const createBabel = require('gulp-babel2'); const concat = require('gulp-concat'); +const babel = createBabel(); + gulp.task('default', () => gulp.src('src/**/*.js') .pipe(sourcemaps.init()) @@ -59,7 +77,6 @@ gulp.task('default', () => ); ``` - ## Babel Metadata Files in the stream are annotated with a `babel` property, which contains the metadata from [`babel.transform()`](https://babeljs.io/docs/usage/api/). @@ -68,9 +85,11 @@ Files in the stream are annotated with a `babel` property, which contains the me ```js const gulp = require('gulp'); -const babel = require('gulp-babel'); +const createBabel = require('gulp-babel2'); const through = require('through2'); +const babel = createBabel(); + function logFileHelpers() { return through.obj((file, enc, cb) => { console.log(file.babel.usedHelpers); @@ -102,7 +121,9 @@ Use it as plugin: ```js const gulp = require('gulp'); -const babel = require('gulp-babel'); +const createBabel = require('gulp-babel2'); + +const babel = createBabel(); gulp.task('default', () => gulp.src('src/app.js')