From 5f371811b0c04aac089d16deefb992028d3d8374 Mon Sep 17 00:00:00 2001 From: OpenShift guest Date: Fri, 1 Feb 2013 11:27:40 -0500 Subject: [PATCH] Improve source-mapping support --- compilers/typescript/index.coffee | 3 ++ index.coffee | 78 ++++++++++++++++++++----------- middleware/cors.coffee | 2 +- package.json | 4 +- 4 files changed, 58 insertions(+), 29 deletions(-) diff --git a/compilers/typescript/index.coffee b/compilers/typescript/index.coffee index f8a8a83..91bad16 100644 --- a/compilers/typescript/index.coffee +++ b/compilers/typescript/index.coffee @@ -42,7 +42,10 @@ module.exports = compiler.typeCheck() compiler.emit (filename) -> + console.log "Compiling", filename if filename.match(/\.map$/) then mapOutput else jsOutput + console.log "Sourcemap", mapOutput.source + fn null, jsOutput.source, mapOutput.source diff --git a/index.coffee b/index.coffee index 3cf8161..c3aa58f 100644 --- a/index.coffee +++ b/index.coffee @@ -31,21 +31,31 @@ sourcemaps = LRU(512) apiUrl = nconf.get("url:api") -coffee = require("coffee-script") +coffee = require("coffee-script-redux") livescript = require("LiveScript") iced = require("iced-coffee-script") less = require("less") sass = require("sass") +scss = require("node-sass") jade = require("jade") markdown = require("marked") stylus = require("stylus") nib = require("nib") compilers = + scss: + match: /\.css$/ + ext: ['scss'] + compile: (path, filename, source, str, fn) -> + try + scss.render(str, fn) + catch err + fn(err) + sass: match: /\.css$/ ext: ['sass'] - compile: (filename, source, str, fn) -> + compile: (path, filename, source, str, fn) -> try fn(null, sass.render(str)) catch err @@ -54,7 +64,7 @@ compilers = less: match: /\.css$/ ext: ['less'] - compile: (filename, source, str, fn) -> + compile: (path, filename, source, str, fn) -> try less.render(str, fn) catch err @@ -63,7 +73,7 @@ compilers = stylus: match: /\.css/ ext: ['styl'] - compile: (filename, source, str, fn) -> + compile: (path, filename, source, str, fn) -> try stylus(str) .use(nib()) @@ -74,16 +84,23 @@ compilers = coffeescript: match: /\.js$/ ext: ['coffee'] - compile: (filename, source, str, fn) -> + compile: (path, filename, source, str, fn) -> try - fn(null, coffee.compile(str, bare: true)) + csAst = coffee.parse str, optimise: false, raw: true, inputSource: "#{path}#{source}" + jsAst = coffee.compile csAst, bare: true + + smap = coffee.sourceMap(jsAst, "#{path}#{source}") + js = coffee.js(jsAst) + "\n//@ sourceMappingURL=#{path}#{filename}.map" + + + fn(null, js, smap) catch err fn(err) livescript: match: /\.js$/ ext: ['ls'] - compile: (filename, source, str, fn) -> + compile: (path, filename, source, str, fn) -> try fn(null, livescript.compile(str)) catch err @@ -92,7 +109,7 @@ compilers = icedcoffee: match: /\.js$/ ext: ['iced'] - compile: (filename, source, str, fn) -> + compile: (path, filename, source, str, fn) -> try fn(null, iced.compile(str, runtime: "inline")) catch err @@ -101,7 +118,7 @@ compilers = jade: match: /\.html$/ ext: ['jade'] - compile: (filename, source, str, fn) -> + compile: (path, filename, source, str, fn) -> render = jade.compile(str, pretty: true) try fn(null, render({})) @@ -111,7 +128,7 @@ compilers = markdown: match: /\.html$/ ext: ['md',"markdown"] - compile: (filename, source, str, fn) -> + compile: (path, filename, source, str, fn) -> try fn(null, markdown(str)) catch err @@ -120,7 +137,6 @@ compilers = typescript: require("./compilers/typescript") renderPlunkFile = (req, res, next) -> - # TODO: Determine if a special plunk 'landing' page should be served and serve it plunk = req.plunk filename = req.params[0] or "index.html" file = plunk.files[filename] @@ -130,7 +146,14 @@ renderPlunkFile = (req, res, next) -> if file res.set("Content-Type": if req.accepts(file.mime) then file.mime else "text/plain") - res.send(200, file.content) + return res.send(200, file.content) + + else if sourcemap = sourcemaps.get("#{req.dir}#{filename}") + res.set "Content-Type", "application/json" + res.send 200, sourcemap + + console.log "[**] Served sourcemap", "#{req.dir}#{filename}" + else base = path.basename(filename, path.extname(filename)) type = mime.lookup(filename) or "text/plain" @@ -138,26 +161,23 @@ renderPlunkFile = (req, res, next) -> for name, compiler of compilers when filename.match(compiler.match) for ext in compiler.ext if found = plunk.files["#{base}.#{ext}"] - compiler.compile filename, "#{base}.#{ext}", found.content, (err, compiled, sourcemap) -> - if err then next(err) + return compiler.compile req.dir, filename, found.filename, found.content, (err, compiled, sourcemap) -> + if err + console.log "[ERR] Compilation error:", err.message + return res.send 500, err.message or "Compilation error" else if sourcemap - sourcemap_id = "#{genid(16)}/#{filename}" + sourcemap_id = "#{req.dir}#{filename}.map" sourcemaps.set sourcemap_id, sourcemap - res.header "X-SourceMap", "/sourcemaps/#{sourcemap_id}/#{filename}.map" + + res.set "SourceMap", sourcemap_id + res.set "Content-Type", if req.accepts(type) then type else "text/plain" res.send 200, compiled - break - res.send(404) unless found - - - -app.get "/sourcemaps/:id/:filename", (req, res, next) -> - if sourcemap = sourcemaps.get("#{req.params.id}/#{req.params.filename}") - res.set "Content-Type", "application/json" - res.send 200, sourcemap - else res.send(404) + # Control will reach here if no file was found + console.log "[ERR] No suitable source file for: ", filename + res.send(404) app.get "/plunks/:id/*", (req, res, next) -> req_url = url.parse(req.url) @@ -165,6 +185,8 @@ app.get "/plunks/:id/*", (req, res, next) -> req_url.pathname += "/" return res.redirect(301, url.format(req_url)) + req.dir = "/plunks/#{req.params.id}/" + request.get "#{apiUrl}/plunks/#{req.params.id}", (err, response, body) -> return res.send(500) if err return res.send(response.statusCode) if response.statusCode >= 400 @@ -192,7 +214,7 @@ app.post "/:id?", (req, res, next) -> property: "files" message: "A minimum of one file is required" - unless valid then next(new Error("Invalid json: #{errors}")) + unless valid then return next(new Error("Invalid json: #{errors}")) else id = req.params.id or genid() # Don't care about id clashes. They are disposable anyway json.id = id @@ -223,6 +245,8 @@ app.get "/:id/*", (req, res, next) -> req_url.pathname += "/" return res.redirect(301, url.format(req_url)) + req.dir = "/#{req.params.id}/" + renderPlunkFile(req, res, next) app.get "*", (req, res) -> diff --git a/middleware/cors.coffee b/middleware/cors.coffee index 507580a..277d034 100644 --- a/middleware/cors.coffee +++ b/middleware/cors.coffee @@ -6,7 +6,7 @@ module.exports.middleware = (config = {}) -> res.set("Access-Control-Allow-Origin", req.headers.origin or "*") res.set("Access-Control-Allow-Methods", "OPTIONS,GET,PUT,POST,DELETE") - res.set("Access-Control-Allow-Headers", "Authorization, User-Agent, Referer, X-Requested-With, Proxy-Authorization, Proxy-Connection, Accept-Language, Accept-Encoding, Accept-Charset, Connection, Content-Length, Host, Origin, Pragma, Accept-Charset, Cache-Control, Accept, Content-Type") + res.set("Access-Control-Allow-Headers", "Authorization, User-Agent, Referer, SourceMap, X-Requested-With, Proxy-Authorization, Proxy-Connection, Accept-Language, Accept-Encoding, Accept-Charset, Connection, Content-Length, Host, Origin, Pragma, Accept-Charset, Cache-Control, Accept, Content-Type") res.set("Access-Control-Expose-Headers", "Link") res.set("Access-Control-Max-Age", "60") diff --git a/package.json b/package.json index 53a608f..e3dabe2 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,7 @@ "engines": { "node": "0.8.x" }, - "version": "0.3.14-21", + "version": "0.3.14-53", "private": true, "dependencies": { "coffee-script": "1.x", @@ -22,12 +22,14 @@ "json-schema": "https://github.com/kriszyp/json-schema/tarball/master", "lru-cache": "1.1.x", "request": "2.x", + "node-sass": "https://github.com/filearts/node-sass/tarball/master", "sass": "*", "less": "*", "jade": "*", "marked": "*", "LiveScript": "*", "iced-coffee-script": "*", + "coffee-script-redux": "https://github.com/michaelficarra/CoffeeScriptRedux/tarball/master", "stylus": "*", "nib": "*", "typescript-wrapper": "*"