No Coffeescript.org:
bawbag = (x, y) ->
z = (x * y)
bawbag(5, 10)
compilaria para:
var bawbag;
bawbag = function(x, y) {
var z;
return (z = (x * y));
};
bawbag(5, 10);
compilar via coffee-script em node.js envolve o seguinte:
(function() {
var bawbag;
bawbag = function(x, y) {
var z;
return (z = (x * y));
};
bawbag(5, 10);
}).call(this);
Os documentos dizem:
Se você deseja criar variáveis de nível superior para uso de outros scripts, anexe-as como propriedades na janela ou no objeto de exportação no CommonJS. O operador existencial (abordado abaixo) fornece uma maneira confiável de descobrir onde adicioná-los, se você estiver direcionando o CommonJS e o navegador: root = export? isto
Como defino Variáveis Globais, em seguida, no CoffeeScript. O que significa 'anexá-los como propriedades na janela'?
javascript
coffeescript
Handloomweaver
fonte
fonte
window
objeto ou oexports
objeto. não há necessidade de criar variáveis globais.window
(ouglobal
objeto na nodejs)Respostas:
Como o script coffee não possui nenhuma
var
instrução, ele o insere automaticamente para todas as variáveis no script coffee-coffee, dessa forma evita que a versão JavaScript compilada vaze tudo para o diretório espaço de nomes global .Portanto, como não há como "vazar" algo no espaço para nome global a partir do lado do script de café, você precisa definir suas variáveis globais como propriedades do objeto global .
Isso significa que você precisa fazer algo como
window.foo = 'baz';
, que lida com o caso do navegador, já que existe o objeto global é owindow
.Node.js
No Node.js, não há
window
objeto, mas oexports
objeto que é passado para o wrapper que envolve o módulo Node.js. (Veja: https://github.com/ry/node/blob/master/src/node.js# L321 ), então no Node.js o que você precisa fazer éexports.foo = 'baz';
.Agora, vamos dar uma olhada no que ele diz em sua citação dos documentos:
Obviamente, isso é um script de café, então vamos dar uma olhada no que isso realmente compila:
Primeiro, ele verificará se
exports
está definido, pois tentar fazer referência a uma variável inexistente no JavaScript produziria um SyntaxError (exceto quando usado comtypeof
)Portanto, se
exports
existir, como é o caso do Node.js (ou em um site mal gravado ...), a raiz apontará para oexports
contráriothis
. Então o que éthis
?O uso
.call
de uma função vinculará athis
função interna ao primeiro parâmetro passado, no caso do navegadorthis
agora ser owindow
objeto; no caso do Node.js, seria o contexto global que também está disponível comoglobal
objeto.Mas como você tem a
require
função no Node.js., não há necessidade de atribuir algo aoglobal
objeto no Node.js. Em vez disso, você o atribui aoexports
objeto que é retornado pelarequire
função.Coffee-Script
Depois de toda essa explicação, aqui está o que você precisa fazer:
Isso declarará nossa função
foo
no espaço de nomes global (o que quer que seja).Isso é tudo :)
fonte
global
,GLOBAL
eroot
objetos em node.js?ReferenceError
?(exports ? this).foo = -> 'Hello World'
global = exports ? this
. A afirmação de que "no caso de Node.js seria o contexto global ..." está incorreta porque athis
variável, quando requerida ou executada por node.js, é avaliada como o escopo do módulo. Portanto, se você espera que definir adereços o torne acessível globalmente, ficará desapontado. Se você deseja definir as coisas globalmente no contexto node.js., você precisa usar aglobal
variável, em vez dethis
.Para mim, parece que @atomicules tem a resposta mais simples, mas acho que pode ser simplificada um pouco mais. Você precisa colocar um
@
antes de qualquer coisa que queira que seja global, para que seja compiladothis.anything
ethis
se refira ao objeto global.tão...
compila para ...
e funciona dentro e fora do wrapper fornecido pelo node.js
fonte
this
não se refere ao objeto globalwindow.myVariable
que funcionará em qualquer lugar.=>
em vez de->
que instrui Coffeescript para criar a função sob a esse namespace / globalO Ivo acertou em cheio, mas vou mencionar que há um truque sujo que você pode usar, embora eu não o recomende se você estiver procurando por pontos de estilo: você pode incorporar o código JavaScript diretamente no seu CoffeeScript, escapando-o com retalhos.
No entanto, eis o motivo pelo qual essa geralmente é uma má idéia: O compilador CoffeeScript não tem conhecimento dessas variáveis, o que significa que elas não obedecerão às regras normais de escopo do CoffeeScript. Assim,
compila para
e agora você tem dois
foo
segundos em escopos diferentes. Não há como modificar o globalfoo
do código CoffeeScript sem fazer referência ao objeto global, como Ivy descreveu.Obviamente, isso é apenas um problema se você fizer uma atribuição
foo
no CoffeeScript - se sefoo
tornar somente leitura depois de receber seu valor inicial (ou seja, é uma constante global), a abordagem da solução JavaScript incorporada poderá ser meio aceitável (embora ainda seja não recomendado).fonte
foo
variável, por causa davar
elevação (JS verifica frente para todas asvar
declarações e interpreta-os como se eles estavam no topo da função)expect = require('chai').expect;
torna aexpect
variável disponível em todos os meus arquivos de teste!Você pode passar a opção -b ao compilar o código via coffee-script em node.js. O código compilado será o mesmo que no coffeescript.org.
fonte
-b
/--bare
vai diretamente após ocoffee
comando.Para adicionar à resposta de Ivo Wetzel
Parece haver uma sintaxe abreviada para a
exports ? this
qual só consigo encontrar documentado / mencionado em uma postagem do grupo do Google .Ou seja, em uma página da web para disponibilizar uma função globalmente, você declara a função novamente com um
@
prefixo:fonte
Eu acho que o que você está tentando alcançar pode ser feito simplesmente assim:
Enquanto você estiver compilando o coffeescript, use o parâmetro "-b".
-b
/--bare
Compile o JavaScript sem o wrapper de segurança da função de nível superior.Então, algo como isto:
coffee -b --compile somefile.coffee whatever.js
Isso produzirá seu código exatamente como no site CoffeeScript.org.
fonte
Se você é uma pessoa má (eu sou uma pessoa má.), Você pode ser simples assim:
(->@)()
Como em,
Isso funciona porque, ao chamar a
Reference
paraFunction
'bare' (ou seja, emfunc()
vez denew func()
ouobj.func()
), algo geralmente chamado de 'padrão de chamada de função', sempre se ligathis
ao objeto global para esse contexto de execução .O CoffeeScript acima simplesmente compila para
(function(){ return this })()
; portanto, estamos exercitando esse comportamento para acessar de maneira confiável o objeto global.fonte
Como o coffeescript raramente é usado por si só, você pode usar a
global
variável fornecida pelo node.js ou pelo browserify (e quaisquer descendentes como coffeeify, scripts de construção do gulp, etc.).No node.js
global
está o espaço para nome global.No browserify
global
é igual awindow
.Então apenas:
fonte