简体   繁体   中英

NodeJS + CoffeeScript, render coffeescript compiled js on request

What I would like to do is add the following to me already running coffeescript written server

app.get '/test.js', (req, res) ->
    render coffee somecoffeefile.coffee

Is something like this possible with NodeJS, Express, and Coffeescript?

Thanks!

Jose

Good news: This is already comes with Connect (and therefore Express, which extends Connect) as a plugin! It's not well-documented; in fact, I wrote something similar myself ( connect-coffee ) before I was informed that such a thing already existed.

Here's how you'd go about setting it up with Express:

# Notice the following code is coffescript
# You must add the parens for the app.use method to use in js
coffeeDir = __dirname + '/coffee'
publicDir = __dirname + '/public'
app.use express.compiler(src: coffeeDir, dest: publicDir, enable: ['coffeescript'])
app.use express.static(publicDir)

Now when, say, http://yourapp/foo.js gets requested, if no such file exists in your public directory, foo.coffee will automatically be compiled, and the resulting foo.js will be served. Note that it's important for static to be set up after compiler .

Update: As of Connect 1.7, the compiler middleware has been removed. Partly because of that, and partly to provide a more Rails 3.1-like experience, I've created a new middleware called connect-assets . Install it with npm, then set it up like so:

app.use require('connect-assets')(directory)

where directory is the folder your CoffeeScript files are in (the default is assets ). Simple, right? Try it out and let me know what you think.

CoffeeScript = require 'coffee-script'

app.get '/test.js', (req, res) ->
  render CoffeeScript.compile coffeeSourceCode

For some reason, the compiler isn't working anymore, so I did this:

fs = require 'fs'
coffee = require 'coffee-script'

app.use express.static "#{__dirname}/static"

app.get '/:script.js', (req, res) ->
  res.header 'Content-Type', 'application/x-javascript'
  cs = fs.readFileSync "#{__dirname}/coffee/#{req.params.script}.coffee", "ascii"
  js = coffee.compile cs 
  res.send js

Now you can code up coffee/animal.coffee and in your html, do a standard script src='/animal.js'. This hides the implementation detail. The coffeescript is not accessible because "/coffee" dir is not exposed as a static path.

Notes:

  1. This is, of course, a CoffeeScript Node app. I assume if you're using CS for client scripts, you're using it for your server too!
  2. The "static" line is optional. My point is you can happily keep "js" files in the static dir, eg library files like jquery.min.js.
  3. Like most Node/Express examples, this is good for development; but for production, you should send cache headers, compress it, and ideally some form of reverse-proxying to avoid reading the file and compiling it each time.

For those of us using the latest version of Connect and Express, I've just published a new module, npm install connect-coffee-script , which compile coffee script files on the fly. Documentation and a sample are provided as well as an introduction article .

Here's an exemple from the readme:

    var coffeescript = require('connect-coffee-script');
    var connect = require('connect');

    var app = connect();

    app.use(coffeescript({
        src: __dirname,
        dest: __dirname + '/public',
        bare: true
    }));

    app.use(connect.static(__dirname + '/public'));

    app.listen(3000)

If you would like to use a great existing plugin I would recommend Trevor Burnham's Connect-Assets . It helps compiling, minifying and concatenating .js and .coffee-files and optimizes how the files are being served (a far-future expires header with invalidation using the file's md5-hash). Well written plugin.

coffee-middleware did exactly what I wanted to - minimal setup, no generated files, and not sloppy. When it gets a request for somescript.js it will check if there is a somescript.coffee . If there is, it will compile it and send it over.

Install it:

npm install coffee-middleware

To use, just add

app.use require('coffee-middleware') src: "#{__dirname}/your/web/root"

before whatever you use to serve static files.

Simple example that serves files in a "public" directory, complies coffeescript before sending it over, and does colored logging:

app = require('express')()

app.use require('morgan') 'dev'
app.use require('coffee-middleware') src: "#{__dirname}/views"
app.use require('serve-static') "#{__dirname}/views"
app.listen 80

To use above code:

mkdir coffeeServer
cd coffeeServer
npm install morgan coffee-middleware serve-static
npm install coffee-script -g

echo 'app = require("express")()
app.use require("morgan") "dev"
app.use require("coffee-middleware") src: "#{__dirname}/views"
app.use require("serve-static") "#{__dirname}/views"
app.listen 80' > server.coffee

coffee -c server.coffee
mkdir views
cd views
echo 'console.log "Hello world!"' > script.coffee
cd ..
node server.js

You can copy the whole bunch into the terminal and it will setup and run the server.

To test:

curl XXX.XXX.XXX.XXX/script.js

That last bit should spit out

(function() {
  console.log("Hello world!");

}).call(this);

//@ sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2NyaXB0LmpzIiwic291cmNlcyI6WyJzY3JpcHQuY29mZmVlIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FBQUEsRUFBQSxPQUFPLENBQUMsR0FBUixDQUFZLGNBQVosQ0FBQSxDQUFBO0FBQUEifQ==NHS0076

Good luck!

I think you should compile COFFEE files only once , especially with production mode

If you want use coffee with Express 3 , or with any web framework look to this repo ExpressOnSteroids You can use this solution, or create your own with Cakefile from this project

You can use Coffee4Clients to render coffee assets to javascript on the fly with your express server.

Update: Coffee4Clients has been killed in favour of DocPad which pre-compiles your assets.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM