#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), который предоставляет «пространства имен» остальной части кода.