Atualmente estou fazendo isso:
foo.js
const FOO = 5;
module.exports = {
FOO: FOO
};
E usá-lo em bar.js
:
var foo = require('foo');
foo.FOO; // 5
Existe uma maneira melhor de fazer isso? Parece estranho declarar a constante no objeto de exportação.
javascript
node.js
Torre
fonte
fonte
exports
. O que é estranho nisso?export const FOO = 5;
.module.exports={FOO:5};
?Respostas:
Você pode exportá-lo explicitamente para o escopo global com
global.FOO = 5
. Então você simplesmente precisa exigir o arquivo e nem mesmo salvar seu valor de retorno.Mas realmente, você não deveria fazer isso. Manter as coisas adequadamente encapsuladas é uma coisa boa. Você já tem a idéia certa, então continue fazendo o que está fazendo.
fonte
Na minha opinião, a utilização
Object.freeze
permite um estilo mais seco e declarativo. Meu padrão preferido é:./lib/constants.js
./lib/some-module.js
Aviso de desempenho desatualizado
O seguinte problema foi corrigido na v8 em janeiro de 2014 e não é mais relevante para a maioria dos desenvolvedores:
Lembre-se de que a configuração de gravável como false e o uso do Object.freeze têm uma penalidade de desempenho maciça na v8 - https://bugs.chromium.org/p/v8/issues/detail?id=1858 e http://jsperf.com / objeto congelado desempenho
fonte
Tecnicamente,
const
não faz parte da especificação ECMAScript. Além disso, usando o padrão "CommonJS Module" que você anotou, é possível alterar o valor dessa "constante", já que agora é apenas uma propriedade do objeto. (não tenho certeza se isso trará alterações em cascata a outros scripts que exigem o mesmo módulo, mas é possível)Para obter uma constante real que você também pode compartilhar, veja
Object.create
,Object.defineProperty
eObject.defineProperties
. Se você definirwritable: false
, o valor na sua "constante" não poderá ser modificado. :)É um pouco detalhado, (mas mesmo isso pode ser alterado com um pouco de JS), mas você só precisa fazer isso uma vez para o seu módulo de constantes. Usando esses métodos, qualquer atributo que você deixar de fora é o padrão
false
. (ao contrário de definir propriedades por meio de atribuição, cujo padrão é todos os atributostrue
)Então, hipoteticamente, você pode simplesmente definir
value
eenumerable
, deixando de forawritable
e,configurable
como eles serão o padrãofalse
, eu os incluí para maior clareza.Atualização - Criei um novo módulo ( constantes de nó ) com funções auxiliares para esse mesmo caso de uso.
constants.js - Bom
constants.js - Melhor
script.js
fonte
Object.defineProperty()
. Todas as propriedades não especificadas são assumidasfalse
neste contexto.ES6.
exportar em foo.js
importar em bar.js
fonte
const
inbar.js
que impõe a imutabilidade da variável destruída, não oconst
infoo.js
. Ou seja, pode-se usarlet {FOO} =
embar.js
e transformar a variável "constante". AFAIK, para reforçar a imutabilidade das exportações, ainda é necessário um módulo ES ouObject.freeze
.FOO
dentrofoo.js
.Eu achei a solução que Dominic sugeriu ser a melhor, mas ainda falta um recurso da declaração "const". Quando você declara uma constante em JS com a palavra-chave "const", a existência da constante é verificada no tempo de análise, não no tempo de execução. Portanto, se você digitou incorretamente o nome da constante em algum lugar posteriormente no seu código, receberá um erro ao tentar iniciar o programa node.js. Qual é uma verificação ortográfica muito mais melhor.
Se você definir a constante com a função define () como sugerido por Dominic, você não receberá um erro se tiver digitado incorretamente a constante, e o valor da constante incorreta será indefinido (o que pode levar a dores de cabeça na depuração).
Mas acho que é o melhor que podemos conseguir.
Além disso, aqui está um tipo de melhoria da função de Dominic, em constans.js:
Dessa forma, você pode usar a função define () em outros módulos, e permite definir constantes dentro do módulo constants.js e constantes dentro do módulo a partir do qual você chamou a função. A declaração de constantes do módulo pode ser feita de duas maneiras (em script.js).
Primeiro:
Segundo:
Além disso, se você deseja que a função define () seja chamada apenas a partir do módulo constantes (para não inchar o objeto global), defina-a assim em constants.js:
e use-o assim em script.js:
fonte
Da experiência anterior do projeto, esta é uma boa maneira:
No constants.js:
No main.js (ou app.js, etc.), use-o como abaixo:
fonte
Eu acho que
const
resolve o problema para a maioria das pessoas que procura esse anwwer. Se você realmente precisa de uma constante imutável, procure as outras respostas. Para manter tudo organizado, salve todas as constantes em uma pasta e exijo a pasta inteira.arquivo src / main.js
src / consts_folder / index.js
Ps. aqui o
deal
enote
será o primeiro nível no main.jssrc / consts_folder / note.js
Ps.
obj
será o segundo nível no main.jssrc / consts_folder / deal.js
Ps.
str
será o segundo nível no main.jsResultado final no arquivo main.js.
console.log(constants.deal);
Ouput:console.log(constants.note);
Ouput:fonte
import
eexport
(provavelmente precisará de algo como babel a partir de 2018 para usar a importação)types.js
myApp.js
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import
fonte
Como alternativa, você pode agrupar seus valores "constantes" em um objeto local e exportar uma função que retorna um clone superficial desse objeto.
Então, não importa se alguém reatribuir o FOO, porque isso afetará apenas sua cópia local.
fonte
Como o Node.js está usando os padrões CommonJS, você só pode compartilhar variáveis entre os módulos com
module.exports
ou definindo uma var global como faria no navegador, mas em vez de usar a janela usadaglobal.your_var = value;
.fonte
Acabei fazendo isso exportando um objeto congelado com funções getter anônimas, em vez das próprias constantes. Isso reduz o risco de erros desagradáveis introduzidos devido a um simples erro de digitação do nome const, pois um erro de tempo de execução será gerado no caso de um erro de digitação. Aqui está um exemplo completo que também usa os símbolos ES6 para as constantes, garantindo a exclusividade e as funções de seta ES6. Gostaria de receber feedback se algo nessa abordagem parecer problemático.
fonte
Eu recomendo fazê-lo com o webpack (pressupõe que você esteja usando o webpack).
Definir constantes é tão simples quanto definir o arquivo de configuração do webpack:
Dessa forma, você os define fora da sua fonte e eles estarão disponíveis em todos os seus arquivos.
fonte
Não acho que seja uma boa prática invadir o espaço GLOBAL a partir de módulos, mas em cenários onde poderia ser estritamente necessário implementá-lo:
Deve ser considerado o impacto desse recurso. Sem a nomeação adequada dessas constantes, o risco de SOBRESCREVER variáveis globais já definidas é algo real.
fonte