how do I use coffeescript's namespace code in Node?
Problem
related: Classes within Coffeescript 'Namespace'
OK so after reading that post I grabbed the namespace function and put it in its own file.
namespace.coffee
namespace = (target, name, block) ->
[target, name, block] = [(if typeof exports isnt 'undefined' then exports else window), arguments...] if arguments.length
and then in Repl:
> namespace = require('./assets/js/namespace.js').namespace
[Function]
If I toString() it it's correct.
OK, so now I want to use it: ns.coffee
(from Sandro's answer)
namespace = require('./namespace.js').namespace
class MyFirstClass
myFunc: () ->
console.log 'works'
class MySecondClass
constructor: (@options = {}) ->
myFunc: () ->
console.log 'works too'
console.log @options
namespace "Project.Something", (exports) ->
exports.MyFirstClass = MyFirstClass
exports.MySecondClass = MySecondClass
console.log 'done with exports'
Then I run it in Repl:
ns = require('./assets/js/ns.js') # compiled ns.coffee
done with exports
created namespace Project.Something
{}
It doesn't appear to be working:
> ns.MyFirstClass
undefined
> ns.MySecondClass
undefined
> ns.Project.Something.MySecondClass
TypeError: Cannot read property 'Something' of undefined
Am I doing something wrong here?
Solution
The exports
variable is the module.exports
for the file you reference it from. So when you call namespace
, it changes exports
that was returned from require
ing namespace
, not the one that will be returned from require
ing ns
.
Notice how namespace
takes 3 arguments, but the first line in it essentially makes target
optional. If you pass in the target
(you probably want exports
, or maybe exports ? window
if this needs to run in both server and client), then it should do what you want.
Discussion
View additional discussion.