Solucionado (ver solução)
Solucionado
(ver solução)
3
respostas

Dúvida - como carregar módulos do express para que fiquem disponíveis?

Galera, estou seguindo o curso de node.js numa boa. Mas fiquei com uma dúvida geral aqui na questão do carregamento de módulos. Eu estava fazendo uns testes e queria fazer o hash de uma senha. Acabei achando o módulo bcrypt. Na hora de dar o "require" é que veio o problema. Como fazer isso no config/express? O bcrypt não é um middleware. Se fosse eu colocaria no app.use... mas não é - se eu só colocar o require no config/express ele não vai ficar dentro do app e não estará disponível no meu controller... Minha solução foi colocar o require no próprio controller. Mas isso não é o ideal, né? E aí, como colocar no config/express um módulo que não é middleware??

3 respostas

Oi Alexandre, não vejo problema algum em fazer um require específico como esse. Você vai precisar muito pouco dele. No entanto, caso queira fazer mesmo isso, você pode tentar colocar ele nas configurações do express-load ou consign.

Oi Wanderson, obrigado por tua resposta. Imagino que um require tão específico não seja um problema. Mas poderia não ser né? Poderia ser algo usado em vários lugares... e aí? Como faz o carregamento? No caso do bcrypt, tentei várias coisas e não funcionou. Pesquisei o consign na internet e tem vários exemplos de como carregar seus models, controllers/routers, middlewares, mas não achei nenhum exemplo de como ele pode ser usado para carregar um módulo do node. Coloco abaixo vários testes e resultados insatisfatórios... mas honestamente não sei se o "consign" é o indicado para resolver isso...

Ainda não consegui entender, em linhas gerais - como é que fazemos o carregamento dos módulos do node quando estamos usando o express, sem ter que repetir todos os módulos em todas as rotas...

Tentativa 1: incluir o bcrypt no consign (como se estivesse fazendo um "require")

    consign({cwd: 'app'})
        .include('drivers')
        .then('../node_modules/bcrypt')
        .then('models')
        .then('controllers')
        .into(app);

o consign tenta carregar todos os arquivos, um por um, da pasta do bcrypt e dá erro no carregamento. A aplicação não sobe:

/var/www/html/chaos/node_modules/bcrypt/CHANGELOG.md:1
(function (exports, require, module, __filename, __dirname) { # 3.0.0 (2018-07-06)
                                                              ^

SyntaxError: Invalid or unexpected token
    at new Script (vm.js:74:7)
    at createScript (vm.js:246:10)
    at Object.runInThisContext (vm.js:298:10)
    at Module._compile (internal/modules/cjs/loader.js:657:28)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:700:10)
    at Module.load (internal/modules/cjs/loader.js:599:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:538:12)
    at Function.Module._load (internal/modules/cjs/loader.js:530:3)
    at Module.require (internal/modules/cjs/loader.js:637:17)
    at require (internal/modules/cjs/helpers.js:20:18)
[nodemon] app crashed - waiting for file changes before starting...

Tentativa 2: incluir o caminho completo até o bcrypt.js

    consign({cwd: 'app'})
        .include('drivers')
        .then('../node_modules/bcrypt/bcrypt.js')
        .then('models')
        .then('controllers')
        .into(app);

aí o consign consegue carregar...

consign v0.1.6 Initialized in app
+ ./drivers/connectionFactory.js
+ ./var/www/html/chaos/node_modules/bcrypt/bcrypt.js
+ ./models/SysAppsDAO.js
+ ./models/SysTenantsDAO.js
+ ./models/SysUsersDAO.js
+ ./controllers/home.js
+ ./controllers/sysApps.js
+ ./controllers/sysTenants.js
+ ./controllers/sysUsers.js
Chaos Platform is up and listening for requests. Mon Aug 06 2018 19:25:31 GMT-0300 (Brasilia Standard Time)

mas dá "pau" na chamada da função... Tentei várias sintaxes... Esta primeira referenciando bcrypt direto...

 if (bcrypt.compareSync(sysuser.password, results[0].password)) { ... }

resulta em

ReferenceError: bcrypt is not defined

Depois essa aqui, referenciando app.bcrypt (que para mim é a que faria mais sentido)

 if (app.bcrypt.compareSync(sysuser.password, results[0].password)) { ... }

resulta em

TypeError: Cannot read property 'compareSync' of undefined

ou seja, mesmo tendo carregado, app.bcrypt é undefined...

Esta aqui, chamando "compareSync" direto (puro desespero)

if (compareSync(sysuser.password, results[0].password)) {

resulta em

ReferenceError: compareSync is not defined
solução!

Consegui encontrar a resposta em uma das aulas do curso (Aula 8).

A resposta é:

no config/express.js:

var bcrypt = require('bcrypt');
...
app.set('bcrypt',bcrypt);

e na hora de usar a função do módulo:

app.get('bcrypt').compareSync(.....)

ou ainda

var bcrypt = app.get('bcrypt');
bcrypt.compareSync(......)