Compilando executáveis ​​do CoffeeScript

Você deve saber que pode preparar executáveis ​​de linha de comando para que outros instalem com o NPM. É fácil. Basta adicionar o bincampo ao seu package.jsonarquivo:

{ "bin" : { "myapp" : "./cli.js" } }

Aqui está mais sobre isso: https://docs.npmjs.com/files/package.json#bin

Agora, para que isso funcione, você precisa fornecer um chamadoshebang no início do cli.jsarquivo, para que seu shell saiba como lidar com isso. Você não pode esperar que ele entenda JavaScriptsozinho.

Esta é a aparência do cli.jsarquivo:

#!/usr/bin/env node

console
.log("Hello, I'm bin :)");

Agora, a partir do diretório de projetos, você pode instalá-lo assim:

npm install --global .

ou se você publicá-lo no repositório npm , qualquer pessoa pode instalá-lo assim:

npm install --global coffee-bin

Vai instalar o myappcomando no sistema, que pode ser executado na linha de comando, assim:

myapp

Com CoffeeScript

Você pode querer escrever seu programa em CoffeeScript. Recentemente, eu queria ter uma ferramenta de linha de comando em um dos meus projetos do Coffee e imediatamente tive alguns problemas com o shebang . Deixe-me dissecar para você:

Se você apenas adicionar o shebangao seu cli.coffeearquivo:

#!/usr/bin/env node

console
.log "Hello, I'm a coffee bin :)"

e depois compilar como de costume:

coffee --compile cli.coffee

então você obterá isto:

// Generated by CoffeeScript 1.10.0
(function() {
console
.log("Hello, I'm a coffee bin :)");

}).call(this);

Se você tentar executar myapp, obterá os seguintes erros:

myapp: line 1: //: Is a directory
myapp
: line 2: syntax error near unexpected token `('
myapp: line 2: `
(function() {'

Observe que não há vestígios de shebang no JavaScript compilado. Isso porque no CoffeeScript tudo que começa com um #caractere é um comentário e não vai chegar ao JS compilado. Isso não vai funcionar.

No entanto, você pode adicionar o chamado JavaScript incorporado, usando crases . O que quer que esteja dentro será passado literalmente para o código compilado. Vamos usar isso para adicionar um shebangque sobrevive à compilação!

`#!/usr/bin/env node`

console
.log "Hello, I'm a coffee bin :)"

Em seguida, compile e falhe novamente:

// Generated by CoffeeScript 1.10.0
(function() {
#!/usr/bin/env node;
console
.log("Hello, I'm a coffee bin :)");

}).call(this);

Desta vez, há um shebang, mas não está na primeira linha. Isso porque, por padrão, o compilador CoffeeScript envolve todos os arquivos na chamada Expressão de Função Imediatamente Invocada . Normalmente é uma coisa boa, mas em uma CLI não precisamos disso e ele engole nosso hashbang. Fácil de resolver, basta chamar o compilador com opção.--bare

A segunda coisa é o comentário na primeira linha. Isso tem que ir também. Adicione e você ficará quase bom com JS assim:Generated by CoffeeScript--no-header

#!/usr/bin/env node;
console
.log("Hello, I'm a coffee bin :)");

Quase. Executar seu script agora lhe dará:

/usr/bin/env: node;: No such file or directory

Há um ponto e vírgula no final da nossa shebanglinha e os shells não o suportam. O compilador CoffeeScript o adicionou e tinha seus motivos para isso. A solução é um pouco hacky, mas muito fácil. Basta adicionar uma nova linha antes da crase de terminação. A nova linha será preservada e o ponto-e-vírgula irá para sua própria linha. Lá não fará mal a ninguém, porque em JavaScript você pode ter quantos pontos-e-vírgulas quiser.

TL / DR

É assim que sua fonte deve ser:

`#!/usr/bin/env node
`


console
.log "Hello, I'm a coffee bin :)"

Você o compila assim:

coffee --compile --bare --no-header cli.coffee

E é isso que você obtém:

#!/usr/bin/env node
;
console
.log("Hello, I'm a coffee bin :)");

Funciona 🙂

Você pode ver tudo isso embrulhado no GitHub e também em um projeto real que usa este truque: lzrski / npm-git-install .