1

Probably pretty straightforward question, but still I haven't found any feasible solution so far. Currently I am able to run the server purely from coffee files and even Mocha tests are able to work with coffee files. However RequireJS is still looking for *.js files :/ I am not feeling good about transpiling just to satisfy RequireJS.

Probably easier way would to be use NodeJS extensions, but since it's deprecated, it's not a good way. I am thinking about some solution like this:

requirejs.config({
    nodeRequire: require,
    compilers: [
        {
            extensions: ['.coffee','.litcoffee','.coffee.md']
            compiler: require('coffee-script').compile
        }
    ]
})

It would simply look for the file with these extensions and when found, compile it. Otherwise keep default behavior. Sure, it means some performance issues when looking for these files, but since it's meant for development only, I don't see a big problem.

Unfortunately it's hard for me to understand how RequireJS works under the hood. Otherwise I would have tried to work out some solution like this.

Is there some other solution that I am missing ?

SOLVED

After all of this I have decided for quite opposite approach. Use the require for the browser side too, so I don't need to change anything for server code.

FredyC
  • 3,999
  • 4
  • 30
  • 38

1 Answers1

0

Related (my question): how can I get connect-assets to recompile my coffee files when they change?

This is possible with connect-assets. This is a layer that sits between the request and the assets and compiles them on-demand. I tried going that route and found it to be a lot of work -- frequently ran into situations where connect wouldn't compile the coffee into js correctly. Or something, I was probably doing it wrong since I was new to node at the time. Also I wasn't really comfortable with relying on an asset layer like that in production.

In the end I settled on serving up js files and building them when they changed using grunt, grunt-contrib-watch and grunt-contrib-coffee. The advantage there is that if you run into an error on a particular line of js, you can just open up the file and look at the line that failed. If you're new to coffeescript you will occasionaly do it wrong and end up with some wacky javascript. It's helpful to be able to just pull up the js file and see it.

There are a lot of similar tasks that need to be automated in building a web app, so grunt is a useful tool in many situations. That would be my recommendation.

Here's a sample of my grunt setup:

  # Project configuration.
  grunt.initConfig
    watch:
      coffee:
        files: ['app/assets/src/coffee/**/*.coffee', 'app/assets/src/coffee/*.coffee', 'app/webserver.coffee']
        tasks: ['coffee:dev', 'replace', 'test']

With this setup (not all of which is here) I can transpile all my coffee files, run all my tests, perform a bit of text manipulation on some files and have a clean and ready to go web app inside of 2 seconds.

Require takes a bit to get your head around but in summary it just looks locally (client side) to see if it has a library and if it doesn't it gets it from the server. It won't do any transpiling and that seems a bit out of its 'mission parameters' if you will. Require is like the parts guy at an auto parts shop: it checks to see if a tool is available at the front counter; yes, it hands it to you; no, it goes and gets it.

If you just want to use coffee in node without transpiling it, try require-cs.

Community
  • 1
  • 1
jcollum
  • 43,623
  • 55
  • 191
  • 321
  • Sorry, but that's not what I asked. I know about grunt and have specifically said, that I don't want to transpile those files just to satisfy RequireJS. For checking errors I have SublimeText, don't see a point in checking transpiled JS file on the disk, that's cumbersome. Issue with require call is that it's getting files from filesystem, so no connect middleware can help with that. – FredyC Oct 10 '13 at 05:55
  • What you want is possible with connect-assets, which I put in the second line. I'm just telling you that that doesn't work as well as you'd like. – jcollum Oct 10 '13 at 15:20
  • I really don't understand how do you mean to use that. Please check out [simple example](https://github.com/FredyC/node-requirejs-coffeescript) I have made, fork it and show me please. – FredyC Oct 11 '13 at 18:23
  • Try this sample app: https://github.com/Hoverbear/Angular-Coffee-Express. I haven't used connect-assets for a while, I tried to fork your code and get it to work with C-A but couldn't :( Hoverbear has it all set up anyway. One important thing: you don't need js anywhere, including your 'boot' file. It's coffee all the way down. – jcollum Oct 11 '13 at 20:42
  • You are clearly missing my point ;) He is not using **RequireJS** anywhere there. That's the main deal for this question. I know that node can use coffee-script like this. And by the way, check his README, he is transpiling `server.coffee` to the js file before running. – FredyC Oct 12 '13 at 22:19
  • Dude *you* are missing the whole point: if you use connect assets you can pull js files in with require without having to worry about transpiling the files _anywhere_. Connect-assets handles that for you. The readme says "Lets test our installation by executing `coffee app.coffee`" -- there is no transpiling going on, except that which coffee does natively. Helping you with this question is turning into a lot of work! – jcollum Oct 14 '13 at 17:12
  • Ok, sorry that I had *bothered* you. But you are still talking about connect-assets without any example of real use. Even the project you referenced doesn't solve a thing in my problem. Have a nice day... – FredyC Oct 15 '13 at 17:33
  • I am completely aware that I can transpile coffee files in memory. But here *you* are missing the point. RequireJS is accessing JS files on the filesystem. You would need to somehow hook into filesystem to tell the program, it should be looking for coffee and transpile it to be served. – FredyC Oct 15 '13 at 17:40
  • But browsers don't read coffeescript! What do you mean no example of real use? I gave you a sample project that would be quite simple to hook require.js into and have zero manual transpilation of coffee files required by you. – jcollum Oct 15 '13 at 18:56
  • Sigh...What browsers ? I don't care about browsers. From the beginning I am talking about NodeJS and only that. That's why I don't understand why you are talking about Connect middleware when there are no HTTP requests going anywhere... – FredyC Oct 16 '13 at 19:52
  • Not sure why you'd use require.js instead of plain require in node but this may help: https://github.com/requirejs/require-cs. – jcollum Oct 16 '13 at 20:36
  • It's simple. Because I am writing client app too and using RequireJS there. It's nice to have the same syntax for both. Seems this is quite new for you, so [check this](http://requirejs.org/docs/node.html) out. Of course I know about this `require-cs`, but I don't like it, because it keeps weird "cs!" prefix all over the place... Oh well. I am glad, you finally got what this is about. Thanks for the effort. – FredyC Oct 18 '13 at 05:06
  • I use requirejs on the client side and require on the server side, I don't find the syntax to be all that rough. The big difference between the two is that requirejs always has a callback, while require doesn't. Your server code will be a lot cleaner with require. Re: cs prefix, well I think that's just the price you're gonna have to pay for what you want. This seems like _a lot_ of work to not have to compile your js with grunt. – jcollum Oct 18 '13 at 15:17
  • It didn't really helped, because you totally misunderstood the issue. However I am giving it to you for the effort you made here. I had eventually came up with rather opposite solution. Move `require` from nodejs to browser ... http://browserify.org/ – FredyC Nov 08 '13 at 15:27
  • Well that's the most backhanded "thanks for helping" I've heard in a long time. – jcollum Nov 08 '13 at 16:56