26

I'd like to know if there is a way to include a file in a coffee script. Something like #include in C or require in PHP...

John Kugelman
  • 349,597
  • 67
  • 533
  • 578
Mathieu Mahé
  • 2,647
  • 3
  • 35
  • 50

6 Answers6

20

If you use coffeescript with node.js (e.g. when using the commandline tool coffee) then you can use node's require() function exactly as you would for a JS-file.

Say you want to include included-file.coffee in main.coffee:

In included-file.coffee: declare and export objects you want to export

someVar = ...
exports.someVar = someVar

In main.coffee you can then say:

someVar = require('included-file.coffee').someVar

This gives you clean modularization and avoids namespace conflicts when including external code.

jerico
  • 1,659
  • 15
  • 20
  • how do you over come required not being in the browser without using another plugin js file? – Lpc_dark Apr 10 '14 at 02:12
  • @Lpc_dark: This solution was about node.js on the server. It doesn't work in the browser where node.js is not available, unless you do something like this https://stackoverflow.com/questions/5081191/could-node-js-run-client-side-in-chrome-with-its-native-client-to-be-released-s (I haven't tried this out myself, though). – jerico Apr 10 '14 at 18:57
  • and I found this article is useful to this solution: [Where Does Node.js And Require() Look For Modules?](http://www.bennadel.com/blog/2169-where-does-node-js-and-require-look-for-modules.htm) – Zhiyong Oct 24 '15 at 03:02
19

How about coffeescript-concat?

coffeescript-concat is a utility that preprocesses and concatenates CoffeeScript source files.

It makes it easy to keep your CoffeeScript code in separate units and still run them easily. You can keep your source logically separated without the frustration of putting it all together to run or embed in a web page. Additionally, coffeescript-concat will give you a single sourcefile that will easily compile to a single Javascript file.

Nathan Arthur
  • 8,287
  • 7
  • 55
  • 80
Jason Reis
  • 312
  • 2
  • 7
4

Tl;DR: Browserify, possibly with a build tool like Grunt...

Solutions review

Build tool + import pre-processor

If what you want is a single JS file to be run in the browser, I recommend using a build tool like Grunt (or Gulp, or Cake, or Mimosa, or any other) to pre-process your Coffeescript, along with an include/require/import module that will concatenate included files into your compiled output, like one of these:

  • Browserify: probably the rising standard and my personal favourite, lets you to use Node's exports/require API in your code, then extracts and concatenates everything required into a browser includable file. Exists for Grunt, Gulp, Mimosa and probably most others . To this day I reckon it is probably the best solution if you're after compatibility both Node and the browser (and even otherwise)
  • Some Rails Sprocket-like solutions like grunt-sprockets-directives or gulp-include will also work in a consistent way with CSS pre-processors (though those generally have their own importing mechanisms)
  • Other solutions include grunt-includes or grunt-import

Standalone import pre-processor

If you'd rather avoid the extra-complexity of a build tool, you can use Browserify stand-alone, or alternatives not based on Node's require like coffeescript-concat or Coffee-Stir

[Not recommended] Asynchronous dynamic loading (AJAX + eval)

If you're writing exclusively for the browser and don't mind, or rather really want, your script being spread across several files fetched via AJAX, you can use a myriad of tools like:

  • yepnope.js or Modernizr's .load based on yepnope: Please note that yepnope is now deprecated by its maintainer, who recommend using build tools and concatenation instead of remote loading
  • RequireJS
  • HeadJS
  • jQuery's $.getScript
  • Vanilla AJAX + eval
  • your own implementation of AMD
ejoubaud
  • 5,013
  • 6
  • 37
  • 39
2

You can try this library I made to solve this same problem coffee-stir its very simple. Just type #include and the name of the file that you want to include

#include MyBaseClass.coffee

For details http://beastjavascript.github.io/Coffee-Stir/

Roman Podlinov
  • 23,806
  • 7
  • 41
  • 60
Lpc_dark
  • 2,834
  • 7
  • 32
  • 49
  • Coffee-stir has a several disadvantages: 1)It adds redundant text after processing, because of this you can use it in pipe (or you have to remove the last line someway) 2) It can't directly compile into .JS – Roman Podlinov Dec 12 '14 at 18:03
  • You are right. If I use "require" it includes both of files. – kapellan Jan 08 '16 at 21:49
1

I found that using "gulp-concat" to merge my coffee scripts before processing them did the trick. It can be easily installed to your project with npm.

npm install gulp-concat

Then edit your gulpfile.js:

var gulp = require('gulp')
,coffee = require('gulp-coffee')
,concat = require('gulp-concat');

gulp.task('coffee', function(){
  gulp.src('src/*.coffee')
    .pipe(concat('app.coffee')
    .pipe(coffee({bare: true}).on('error', gulp.log))
    .pipe(gulp.dest('build/')
})

This is the code I used to concatenate all my coffee scripts before gulp processed it into the final build Javascript. The only issue is the files are processed in alphabetical order. You can explicitly state which file to process to achieve your own file order, but you lose the flexibility of adding dynamic .coffee files.

gulp.src(['src/file3.coffee', 'src/file1.coffee', 'src/file2.coffee'])
  .pipe(concat('app.coffee'))
  .pipe(coffee({bare: true}).on('error', gulp.log))
  .pipe(gulp.dest('build/')

gulp-concat as of February 25th, 2015 is available at this url.

chrsc
  • 11
  • 5
  • While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. – Rodrigo Taboada Feb 25 '15 at 02:28
  • Cheers! I'm new to contributing here. I'll edit this. – chrsc Feb 25 '15 at 05:53
0

Rails uses sprockets to do this, and this syntax has been adapted to https://www.npmjs.org/package/grunt-sprockets-directives. Works well for me.

aceofspades
  • 7,568
  • 1
  • 35
  • 48