Existem algumas bibliotecas Javascript de terceiros que têm algumas funcionalidades que eu gostaria de usar em um servidor Node.js. (Especificamente, quero usar uma biblioteca javascript QuadTree que encontrei.) Mas essas bibliotecas são apenas .js
arquivos diretos e não "bibliotecas Node.js".
Como tal, essas bibliotecas não seguem a exports.var_name
sintaxe que o Node.js espera para seus módulos. Pelo que entendi, isso significa quando você o faz module = require('module_name');
ou module = require('./path/to/file.js');
acabará com um módulo sem funções acessíveis ao público, etc.
Minha pergunta é: "Como carrego um arquivo javascript arbitrário no Node.js de modo que possa utilizar sua funcionalidade sem ter que reescrevê-lo para que funcione exports
?"
Eu sou muito novo no Node.js, então, por favor, deixe-me saber se há alguma falha gritante no meu entendimento de como ele funciona.
EDIT : Pesquisando mais sobre as coisas, vejo agora que o padrão de carregamento do módulo que o Node.js usa é na verdade parte de um padrão desenvolvido recentemente para carregar bibliotecas Javascript chamado CommonJS . Diz isso diretamente na página de doc do módulo para Node.js , mas eu perdi isso até agora.
Pode acabar sendo que a resposta à minha pergunta é "espere até que os autores da sua biblioteca consigam escrever uma interface CommonJS ou faça você mesmo".
fonte
Respostas:
Existe um método muito melhor do que usar
eval
: ovm
módulo.Por exemplo, aqui está meu
execfile
módulo, que avalia o scriptpath
em umcontext
ou no contexto global:E pode ser usado assim:
Onde
example.js
contém:A grande vantagem desse método é que você tem controle total sobre as variáveis globais no script executado: você pode passar globais personalizados (via
context
) e todos os globais criados pelo script serão adicionadoscontext
. A depuração também é mais fácil porque os erros de sintaxe e similares serão relatados com o nome de arquivo correto.fonte
runInNewContext
o contexto global secontext
(também conhecido comosandbox
, nos documentos) for indefinido? (este ponto não foi esclarecido por nenhum documento que encontrei)vm
módulo pode oferecer neste caso?Aqui está o que eu acho que é a resposta 'mais certa' para esta situação.
Digamos que você tenha um arquivo de script chamado
quadtree.js
.Você deve construir um custom
node_module
que tenha este tipo de estrutura de diretório ...Tudo em seu
./node_modules/quadtree/quadtree-lib/
diretório são arquivos de sua biblioteca de terceiros.Em seguida, seu
./node_modules/quadtree/index.js
arquivo irá apenas carregar aquela biblioteca do sistema de arquivos e fazer o trabalho de exportar as coisas corretamente.Agora você pode usar seu
quadtree
módulo como qualquer outro módulo de nó ...Eu gosto desse método porque não há necessidade de alterar nenhum código-fonte de sua biblioteca de terceiros - por isso é mais fácil de manter. Tudo o que você precisa fazer na atualização é olhar o código-fonte e garantir que ainda está exportando os objetos apropriados.
fonte
npm link
-la em seu aplicativo. Em seguida, é tratado como se fosse um pacote Node.js nativo.A maneira mais simples é:
eval(require('fs').readFileSync('./path/to/file.js', 'utf8'));
Isso funciona muito bem para testar no shell interativo.fonte
AFAIK, é assim que os módulos devem ser carregados. No entanto, em vez de anexar todas as funções exportadas ao
exports
objeto, você também pode anexá-lasthis
(o que de outra forma seria o objeto global).Portanto, se você quiser manter as outras bibliotecas compatíveis, pode fazer o seguinte:
ou, quando a biblioteca externa já tem seu próprio namespace, por exemplo
jQuery
(não que você possa usar isso em um ambiente do lado do servidor):Em um ambiente não-Node,
this
resolveria para o objeto global, tornando-o uma variável global ... o que já era. Portanto, não deve quebrar nada.Edit : James Herdman tem um bom artigo sobre node.js para iniciantes, que também menciona isso.
fonte
Não tenho certeza se vou realmente acabar usando isso porque é uma solução bastante hacky, mas uma maneira de contornar isso é construir um pequeno importador de mini-módulo como este ...
No arquivo
./node_modules/vanilla.js
:Então, quando quiser usar a funcionalidade de sua biblioteca, você precisará escolher manualmente quais nomes exportar.
Então, para uma biblioteca como o arquivo
./lib/mylibrary.js
...Quando você deseja usar sua funcionalidade em seu código Node.js ...
Não sei se isso funcionaria bem na prática.
fonte
Consegui fazer funcionar atualizando o script deles, com muita facilidade, simplesmente adicionando
module.exports =
onde apropriado ...Por exemplo, peguei o arquivo deles e copiei para './libs/apprise.js'. Então, onde começa com
Atribuí a função para
module.exports =
:Assim, posso importar a biblioteca para o meu código desta forma:
E eu estava pronto para ir. YMMV, isso foi com webpack .
fonte
Uma
include(filename)
função simples com melhor mensagem de erro (pilha, nome do arquivo etc.) paraeval
, em caso de erros:Mas fica ainda mais sujo com nodejs: você precisa especificar isto:
Caso contrário, você não pode usar variáveis globais em arquivos incluídos com
include(...)
.fonte