├── .gitignore ├── LICENSE ├── README.md ├── fixtures ├── fixture.js └── fixture.txt ├── index.js ├── package.json └── test.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | compiled 3 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014 Sebastian McKenzie 2 | 3 | MIT License 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | "Software"), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # babel-connect 2 | 3 | [Babel](https://github.com/babel/babel) [connect](https://github.com/senchalabs/connect) plugin 4 | 5 | ## Installation 6 | 7 | $ npm install babel-connect 8 | 9 | ## Usage 10 | 11 | ```javascript 12 | var babelMiddleware = require("babel-connect"); 13 | 14 | app.use(babelMiddleware({ 15 | options: { 16 | // options to use when transforming files 17 | }, 18 | src: "assets", 19 | dest: "cache", 20 | ignore: /node_modules/ 21 | })); 22 | 23 | app.use(connect.static("cache")); 24 | ``` 25 | -------------------------------------------------------------------------------- /fixtures/fixture.js: -------------------------------------------------------------------------------- 1 | const square = n => n * n; 2 | -------------------------------------------------------------------------------- /fixtures/fixture.txt: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var square = function square(n) { 4 | return n * n; 5 | }; 6 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | var babel = require("babel-core"); 2 | var mkdirp = require("mkdirp"); 3 | var path = require("path"); 4 | var url = require("url"); 5 | var fs = require("fs"); 6 | var _ = require("lodash"); 7 | 8 | module.exports = function (opts) { 9 | opts = _.defaults(opts || {}, { 10 | options: {}, 11 | dest: "cache", 12 | src: "assets", 13 | ignore: false 14 | }); 15 | 16 | opts.ignore = babel.util.regexify(opts.ignore); 17 | 18 | var cache = Object.create(null); 19 | 20 | return function (req, res, next) { 21 | if (opts.ignore.test(req.url)) return next(); 22 | if (!babel.util.canCompile(req.url)) return next(); 23 | 24 | var pathname = path.normalize(url.parse(req.url).pathname); 25 | var dest = path.join(opts.dest, pathname); 26 | var src = path.join(opts.src, pathname); 27 | var srcStat; 28 | 29 | var send = function (data) { 30 | res.setHeader("Content-Type", "application/javascript"); 31 | res.end(data); 32 | }; 33 | 34 | var write = function (transformed) { 35 | mkdirp(path.dirname(dest), function (err) { 36 | if (err) return next(err); 37 | fs.writeFile(dest, transformed, function (err) { 38 | if (err) { 39 | next(err); 40 | } else { 41 | cache[pathname] = +srcStat.mtime; 42 | send(transformed); 43 | } 44 | }); 45 | }) 46 | }; 47 | 48 | var compile = function () { 49 | var transformOpts = _.clone(opts.options); 50 | transformOpts.sourceFileName = "babel:///" + src.replace(opts.src, ""); 51 | babel.transformFile(src, transformOpts, function (err, result) { 52 | if (err) { 53 | next(err); 54 | } else { 55 | write(result.code); 56 | } 57 | }); 58 | }; 59 | 60 | var tryCache = function () { 61 | fs.readFile(dest, function (err, data) { 62 | if (err && err.code === "ENOENT") { 63 | compile(); 64 | } else if (err) { 65 | next(err); 66 | } else { 67 | send(data); 68 | } 69 | }); 70 | }; 71 | 72 | fs.stat(src, function (err, stat) { 73 | srcStat = stat; 74 | if (err && err.code === "ENOENT") { 75 | next(); 76 | } else if (err) { 77 | next(err); 78 | } else if (cache[pathname] === +stat.mtime) { 79 | tryCache(); 80 | } else { 81 | compile(); 82 | } 83 | }); 84 | }; 85 | }; 86 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "babel-connect", 3 | "description": "babel connect middleware plugin", 4 | "version": "6.0.2", 5 | "author": "Sebastian McKenzie ", 6 | "homepage": "https://github.com/babel/babel-connect", 7 | "repository": { 8 | "type": "git", 9 | "url": "https://github.com/babel/babel-connect.git" 10 | }, 11 | "bugs": { 12 | "url": "https://github.com/babel/babel-connect/issues" 13 | }, 14 | "scripts": { 15 | "test": "mocha test.js" 16 | }, 17 | "dependencies": { 18 | "babel-core": "^6.2.1", 19 | "lodash": "2.4.1", 20 | "mkdirp": "^0.5.0", 21 | "through": "2.3.4" 22 | }, 23 | "devDependencies": { 24 | "babel-preset-es2015": "^6.1.18", 25 | "mocha": "^2.3.4", 26 | "serve-static": "^1.10.0", 27 | "supertest": "^1.1.0" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /test.js: -------------------------------------------------------------------------------- 1 | var http = require("http"); 2 | var serveStatic = require("serve-static"); 3 | var request = require("supertest"); 4 | var assert = require("assert"); 5 | var babelMiddleware = require("./"); 6 | 7 | var serve = serveStatic("cache"); 8 | var babel = babelMiddleware({ 9 | options: { 10 | presets: ["es2015"] 11 | }, 12 | src: "fixtures", 13 | dest: "compiled", 14 | ignore: /node_modules/ 15 | }); 16 | 17 | var server = http.createServer(function(req, res) { 18 | function onError(err) { 19 | res.statusCode = err.status || 500; 20 | res.end(err.message); 21 | return; 22 | } 23 | babel(req, res, function(err) { 24 | if (err) return onError(err); 25 | serve(req, res, function(err) { 26 | if (err) return onError(err); 27 | res.setHeader("Content-Type", "text/javascript"); 28 | res.end(); 29 | }); 30 | }); 31 | }); 32 | 33 | describe("babelMiddleware()", function() { 34 | it("should compile", function(done) { 35 | request(server) 36 | .get("/fixture.js") 37 | .expect(function(res) { 38 | assert.ok( 39 | res.text.indexOf("function square(n) {") > -1, 40 | "`" + res.text + "` should contain `function square(n) {`" 41 | ); 42 | }) 43 | .expect(200, done); 44 | }); 45 | 46 | it("should not compile", function(done) { 47 | request(server) 48 | .get("/fixture.txt") 49 | .expect(function(res) { 50 | assert.equal(res.text, ""); 51 | }) 52 | .expect(200, done); 53 | }); 54 | }); 55 | --------------------------------------------------------------------------------