Corrigindo o erro “Cannot overwrite ‘Model’ model once compiled” no Mongoose

Durante o desenvolvimento de um protótipo aqui na empresa, eu me deparei com uma situação bem interessante no Mongoose. Por algum motivo, comecei a receber o seguinte erro: OverwriteModelError: Cannot overwrite User model once compiled. 

O que me intrigou muito foi que sempre utilizei o Mongoose praticamente da mesma forma. O exemplo que gerou este erro é este aqui:

O model User:

E os 2 controllers, que simulam a utilização deste model:

Bom, analisando o erro novamente, podemos notar que por algum motivo ao executar o código, o módulo onde está o model está sendo instanciado mais de uma vez. E isso acarreta em setar o schema duas vezes, gerando assim este erro. Se analisarmos como está sendo dado o require em cada controller, vamos notar que um deles está como user e no outro User. No Windows, se tentarmos abrir um arquivo User.js ou user.js, ambos irão apontar para o mesmo local (que foi o que aconteceu aqui). Porém, o nodejs gerencia os módulos em si de maneira case-sensitive. Então se fizermos: require(‘./User’) e require(‘./user’), o nodejs vai tentar registrar 2x. O que duplica o registro do schema User no mongoose.

No Linux/Mac isso não aconteceria, pois bem antes de esse erro “pipocar”, o node já iria gritar dizendo que o módulo User.js não existe. E ficaria bem mais simples de encontrar o erro.

Outros efeitos colaterais deste problema:

Se por algum motivo, tivéssemos um trecho de código que não possuísse a restrição do mongoose+schema (de não poder ser registrado mais de uma vez). Este código seria executado 2x no Windows (pois o node registraria 2x o módulo).

Isso poderia gerar um bug/efeito colateral que aconteceria somente no Windows. E o código quebraria quando fosse colocado em produção no Linux.

O ideal então é manter um padrão, e chamar no require da mesma forma que o arquivo foi salvo. Evitando assim, muita dor de cabeça.