Пространство имен в coffeescript

#coffeescript

#coffeescript

Вопрос:

Существует ли какая-либо встроенная поддержка пространства имен в coffeescript?

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

Комментарии:

1. У вас есть автоматически закрываемые файлы, разве этого недостаточно?

2. Вы должны уточнить, что вы подразумеваете под «пространством имен». Это неоднозначный термин.

Ответ №1:

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

Где-то при запуске приложения вы определяете пространства имен глобально (замените 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
  

Комментарии:

1. Обратите внимание, что вам не обязательно использовать window.App.Models здесь. Просто App.Models ?= {} подойдет.

2. Правильно. Мне нравятся ссылки window. в моих назначениях, чтобы было ясно, что я имею в виду глобальное назначение. Для меня это просто стиль кодирования.

Ответ №2:

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

 # 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 . Если вы хотите использовать его только в тестовом пространстве имен, вы можете упростить его еще больше:

 window.Test or= {}

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

Комментарии:

1. Ключевым моментом здесь является window. Мои ошибки компилятора без этого.

Ответ №3:

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

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
    #[...]
  

Комментарии:

1. Мне нравится этот вариант, он приятный и понятный и хорошо вписывается в синтаксис coffee script. 1’d

2. Мне тоже очень нравится это решение, но IntelliJ IDEA делает разрыв строки после каждого «:» при автоматическом форматировании кода CoffeeScript, который затем прерывает файл : (

3. Это нарушает работу большинства библиотек сжатия (например, ваша уменьшенная версия не будет работать). Классы под именами пространств имен искажаются.

Ответ №4:

Из раздела о пространстве имен в вики: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!'
  

Комментарии:

1. Я бы не сказал, что это популярный шаблон в CoffeeScript. Обычно люди просто пишут exports.foo = bar напрямую.

Ответ №5:

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

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

 #<< 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'
  

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

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

Ответ №6:

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

 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);
  

Ответ №7:

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

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

Ответ №8:

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

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