ilearnio / module-alias

Register aliases of directories and custom module paths in Node
MIT License
1.74k stars 69 forks source link

Path alias import fails on production #111

Closed guilhermebkel closed 3 years ago

guilhermebkel commented 3 years ago

Hello! Recently I've started being in touch with a strange bug. It seems that the module-alias does not work on my production environment (does not matter if I run the same commands to build and start the app, it only works on development environment but not on production) šŸ¤”

I'm currently using lerna to run all project commands because it is a project inside a monorepository. So, in practice I build the app using the following Dockerfile:

FROM node:current-stretch

RUN mkdir -p /uno

WORKDIR /uno

COPY . /uno

RUN npm run ci:unapy

ENV PORT 80

ENV NODE_ENV production

EXPOSE 80 3667

CMD [ "npm", "run", "dev:unapy" ]

So, after building this app, I try to run it with the following command:

# 'npm run dev:unapy' is the command below
node -r module-alias/register dist/index.js

Then, I receive the following logs depending on the environment I'm currently in:

lerna notice cli v3.22.1 lerna notice filter including "@uno-game/unapy" lerna info filter [ '@uno-game/unapy' ] lerna info Executing command in 1 package: "npm run start"

@uno-game/unapy@0.0.0 start node -r module-alias/register dist/index.js node:internal/modules/cjs/loader:928 throw err; ^ Error: Cannot find module '@/Core' Require stack:

  • /uno/packages/unapy/dist/index.js at Function.Module._resolveFilename (node:internal/modules/cjs/loader:925:15) at Function.Module._resolveFilename (/uno/node_modules/module-alias/index.js:49:29) at Function.Module._load (node:internal/modules/cjs/loader:769:27) at Module.require (node:internal/modules/cjs/loader:997:19) at require (node:internal/modules/cjs/helpers:92:18) at Object. (/uno/packages/unapy/dist/index.js:7:32) at Module._compile (node:internal/modules/cjs/loader:1108:14) at Object.Module._extensions..js (node:internal/modules/cjs/loader:1137:10) at Module.load (node:internal/modules/cjs/loader:973:32) at Function.Module._load (node:internal/modules/cjs/loader:813:14) { code: 'MODULE_NOT_FOUND', requireStack: [ '/uno/packages/unapy/dist/index.js' ] } npm ERR! code 1 npm ERR! path /uno/packages/unapy npm ERR! command failed npm ERR! command sh -c node -r module-alias/register dist/index.js npm ERR! A complete log of this run can be found in: npm ERR! /root/.npm/_logs/2021-01-19T17_05_14_611Z-debug.log at Function.Module._resolveFilename (/uno/node_modules/module-alias/index.js:49:29) at Function.Module._load (node:internal/modules/cjs/loader:769:27) at Module.require (node:internal/modules/cjs/loader:997:19) at require (node:internal/modules/cjs/helpers:92:18) at Object. (/uno/packages/unapy/dist/index.js:7:32) at Module._compile (node:internal/modules/cjs/loader:1108:14) at Object.Module._extensions..js (node:internal/modules/cjs/loader:1137:10) at Module.load (node:internal/modules/cjs/loader:973:32) at Function.Module._load (node:internal/modules/cjs/loader:813:14) { code: 'MODULE_NOT_FOUND', requireStack: [ '/uno/packages/unapy/dist/index.js' ] } npm ERR! code 1 npm ERR! path /uno/packages/unapy npm ERR! command failed npm ERR! command sh -c node -r module-alias/register dist/index.js npm ERR! A complete log of this run can be found in: npm ERR! /root/.npm/_logs/2021-01-19T17_05_29_914Z-debug.log lerna ERR! npm run start exited 1 in '@uno-game/unapy'

lerna notice cli v3.22.1 lerna notice filter including "@uno-game/unapy" lerna info filter [ '@uno-game/unapy' ] lerna info Executing command in 1 package: "npm run start" @uno-game/unapy: > @uno-game/unapy@0.0.0 start /ssd/Github/uno-game/packages/unapy @uno-game/unapy: > node -r module-alias/register dist/index.js @uno-game/unapy: Server is running... [PORT 5000]


---

You can see some project configs below:

- **Lerna package.json:**
```json
{
  "name": "uno-game",
  "version": "0.0.0",
  "private": true,
  "author": "Guilherme Mota <guilhermebromonschenkel@gmail.com>",
  "license": "MIT",
  "scripts": {
    "setup": "npm run setup:app && npm run setup:env",
    "setup:app": "npm install && npm run install:unapy && npm run install:unoenty && npm run bootstrap",
    "setup:env": "npm run env:unapy && npm run env:unoenty",
    "bootstrap": "lerna bootstrap --use-workspaces --hoist && lerna link",
    "list": "lerna ls",
    "deploy": "lerna version",
    "install:unapy": "lerna exec --stream --scope @uno-game/unapy -- npm install",
    "build:unapy": "lerna run build --scope @uno-game/unapy --stream",
    "start:unapy": "lerna run start --scope @uno-game/unapy --stream",
    "dev:unapy": "lerna run dev --scope @uno-game/unapy --stream",
    "env:unapy": "cp packages/unapy/.env.example packages/unapy/.env",
    "install:unoenty": "lerna exec --stream --scope @uno-game/unoenty -- npm install",
    "build:unoenty": "lerna run build --scope @uno-game/unoenty --stream",
    "env:unoenty": "cp packages/unoenty/.env.example packages/unoenty/.env",
    "ci:unapy": "npm install && npm run install:unapy && npm run bootstrap && npm run build:unapy",
    "ci:unoenty": "npm install && npm run install:unoenty && npm run bootstrap && npm run build:unoenty"
  },
  "devDependencies": {
    "@typescript-eslint/eslint-plugin": "^3.7.0",
    "@typescript-eslint/parser": "^3.7.0",
    "cross-env": "^7.0.2",
    "eslint": "^6.6.0",
    "eslint-config-standard": "^14.1.1",
    "eslint-import-resolver-typescript": "^2.0.0",
    "eslint-plugin-flowtype": "^5.2.0",
    "eslint-plugin-import": "^2.22.0",
    "eslint-plugin-jsx-a11y": "^6.3.1",
    "eslint-plugin-node": "^11.1.0",
    "eslint-plugin-promise": "^4.2.1",
    "eslint-plugin-react": "^7.20.3",
    "eslint-plugin-react-hooks": "^4.0.8",
    "eslint-plugin-standard": "^4.0.1",
    "git-commit-msg-linter": "^2.4.3",
    "husky": "^4.2.5",
    "lerna": "^3.20.2",
    "lint-staged": "^10.2.10",
    "typescript": "^3.9.2"
  },
  "workspaces": [
    "packages/*",
    "packages/shared/*"
  ]
}
randal923 commented 3 years ago

I have the same issue. My build scripts:

"scripts": {
    "dev": "nodemon src/server.ts",
    "start": "NODE_ENV=production pm2 start dist/server.js --name='api'",
    "build": "rimraf dist && tsc -p tsconfig-build.json",
  }

It works fine in development but it fails in production. Anyone know what might be going on?

randal923 commented 3 years ago

I fixed it. I had this in my package.json:

"_moduleAliases": {
    "@": "src"
  }

I changed it to this:

"_moduleAliases": {
    "@": "dist"
  }
guilhermebkel commented 3 years ago

@randal923 Thanks for giving your approach for solving that! Unfortunately I already use that production config on my project and it does not work :/

randal923 commented 3 years ago

@guilhermebkel I see. I will share all my configs with you. If you still can't get it to work, message me on Discord at shui#8603 and we can figure it out.

So, I am import in my the module-alias/register in my server.ts:

import 'module-alias/register'
import * as dotenv from 'dotenv'
import App from '@/app'
dotenv.config()

const app = new App(Number(process.env.PORT))
app.listen()

If you are using TypeScript, I have this in my TS config:

{
  "compilerOptions": {
    "outDir": "dist",
    "module": "commonjs",
    "target": "es2019",
    "esModuleInterop": true,
    "sourceMap": true,
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true,
    "baseUrl": "./src",
    "paths": {
      "@/*": [
        "*"
      ]
    }
  },
  "include": [
    "src"
  ],
  "exclude": []
}

Lastly, I have the module alias in my package.json like I have shown above:

"_moduleAliases": {
    "@": "dist"
  }

I believe this is it. It was super straight forward. If I had to guess what is wrong with yours is you are not importing the module-alias/register before running build. You have to import it the main file of your app, before any other code.

danielrhodes commented 3 years ago

@guilhermebkel I think may be an issue in how this module interacts with yarn workspaces. For example, if you put your _moduleAliases in your root package.json (adjusting the relative paths), it works.

guilhermebkel commented 3 years ago

Hello guys! Thanks for giving a feedback about my error!

At first, @randal923 I had already used these configurations and it didn't work šŸ˜”, I would like to give you a huge thanks for offering a help on discord to me, but before I tried to get in touch with you, I've tried the tip that @danielrhodes has given in the last comment and it worked like a charm! It really looks like an issue of this module behavior when dealing with workspaces (so adding the module alias config in the root package.json really works).

A huge thanks for all the help!

diegoulloao commented 2 years ago

any solution for this? I'm using module-alias for a npm package I created but when I'm trying it after install it I get this error:

Error: Cannot find module '@root/inspector'

Seems to not recognize custom paths.