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 < 3
top = target
target = target[item] or= {} for item in name.split '.'
block target, top
console.log "created namespace "+ name
root = exports ? window
root.namespace = namespace
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?
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 requireing namespace, not the one that will be returned from requireing 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.