Пространство имен в coffeescript - PullRequest
30 голосов
/ 11 ноября 2011

Есть ли встроенная поддержка пространства имен в coffeescript?

Адекватное пространство имен похоже на то, что coffeescript действительно может помочь, хотя я, похоже, не могу найти ничего, чтобы предположить, что есть поддержка для этого.

Ответы [ 8 ]

35 голосов
/ 11 ноября 2011

Я предпочитаю использовать этот шаблон для "пространства имен". На самом деле это не пространство имен, а дерево объектов, но оно выполняет свою работу:

Где-то при запуске приложения вы определяете пространства имен глобально (замените window на exports или global в зависимости от вашей среды.

window.App =
  Models: {}
  Collections: {}
  Views: {}

Затем, когда вы хотите объявить классы, вы можете сделать это:

class App.Models.MyModel
  # The class is namespaced in App.Models

А когда вы хотите сослаться на него:

myModel = new App.Models.MyModel()

Если вам не нравится глобальный способ определения пространств имен, вы можете сделать это перед вашим классом:

window.App.Models ?= {} # Create the "namespace" if Models does not already exist.
class App.Models.MyModel
29 голосов
/ 28 марта 2012

Чтобы упростить обращение к классу как в его собственном «пространстве имен» (закрытой функции), так и в глобальном пространстве имен, можно назначить его немедленно.Пример:

# Define namespace unless it already exists
window.Test or= {}

# Create a class in the namespace and locally
window.Test.MyClass = class MyClass
  constructor: (@a) ->

# Alerts 3
alert new Test.MyClass(1).a + new MyClass(2).a

Как видите, теперь вы можете ссылаться на него как MyClass в файле, но если вам это нужно снаружи, он доступен как Test.MyClass.Если вам нужно только это в пространстве имен Test, вы можете упростить его еще больше:

window.Test or= {}

# Create only in the namespace
class window.Test.MyClass
  constructor: (@a) ->
10 голосов
/ 27 августа 2012

Вот моя личная реализация:

https://github.com/MaksJS/Namespace-in-CoffeeScript

Как использовать в браузере:

namespace Foo:SubPackage1:SubPackage2:
  class Bar extends Baz
    #[...]

Как использовать в среде CommonJS:

require './path/to/this/file' # once

namespace Foo:SubPackage1:SubPackage2:
  class Bar extends Baz
    #[...]
5 голосов
/ 11 ноября 2011

Из раздела о пространстве имен в вики: https://github.com/jashkenas/coffee-script/wiki/FAQ

# Code:
#
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

# Usage:
#
namespace 'Hello.World', (exports) ->
  # `exports` is where you attach namespace members
  exports.hi = -> console.log 'Hi World!'

namespace 'Say.Hello', (exports, top) ->
  # `top` is a reference to the main namespace
  exports.fn = -> top.Hello.World.hi()

Say.Hello.fn()  # prints 'Hi World!'
3 голосов
/ 26 апреля 2012

Вы должны действительно проверить CoffeeToaster:
https://github.com/serpentem/coffee-toaster

Он поставляется с системой упаковки, которая при включении будет использовать иерархию вашей папки в качестве объявлений пространств имен для ваших классов, если вы захотите, тогда вы сможете расширять классы из нескольких файлов, выполнять импорт и сыновье, например:

#<< another/package/myclass
class SomeClass extends another.package.MyClass

Конфигурация сборки чрезвычайно минималистична и проста, чтобы быть очевидной:

# => SRC FOLDER
toast 'src_folder'
    # => VENDORS (optional)
    # vendors: ['vendors/x.js', 'vendors/y.js', ... ]

    # => OPTIONS (optional, default values listed)
    # bare: false
    # packaging: true
    # expose: ''
    # minify: false

    # => HTTPFOLDER (optional), RELEASE / DEBUG (required)
    httpfolder: 'js'
    release: 'www/js/app.js'
    debug: 'www/js/app-debug.js'

Существует также опция отладки, которая компилирует файлы по отдельности для упрощения процессов отладки и другие полезные функции.

Надеюсь, это поможет.

1 голос
/ 14 ноября 2012

Обратите внимание, что можно написать:

class MyObject.MyClass
    constructor: () ->
        initializeStuff()
    myfunction: () ->
        doStuff()

если вы объявили объект / ns MyObject.

И пока мы здесь, вот моя реализация функции jquery-ns:

(function($) {
    $.namespace = function(namespace, initVal) {
        var nsParts = namespace.split("."),
            nsPart = nsParts.shift(),
            parent = window[nsPart] = window[nsPart] || {},
            myGlobal = parent;
        while(nsPart = nsParts.shift()) {
            parent = parent[nsPart] = parent[nsPart] || {};
        }
        return myGlobal;
    }
})(jQuery);
0 голосов
/ 08 августа 2012

Я настоятельно рекомендую использовать requirejs.org или аналогичные проверенные в бою загрузчики модулей. Особенно, если вы хотите загружать вещи асинхронно.

Свернуть собственную схему имен / модулей очень сложно, если вы проигнорируете простые, легкие и наивные подходы

0 голосов
/ 29 июля 2012

Поскольку я также занят изучением лучшего способа структурирования файлов и использования coffeescript в сочетании с магистралью и тортом, я создал небольшой проект на github , чтобы сохранить его в качестве справки для себя, может быть, это поможет вам слишком вокруг торта и некоторые основные вещи. Все .js (с файлами, откомпилированными с помощью торта) находятся в папке www , так что вы можете открыть их в своем браузере, а все исходные файлы (кроме конфигурации торта) находятся в папке src . В этом примере все файлы .coffee компилируются и объединяются в один выходной файл .js, который затем включается в html.

На основе некоторых ответов здесь, в StackOverflow, я создал небольшой файл util.coffee (в папке src), который предоставляет «пространства имен» для остальной части кода.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...