I'm trying to deploy my app on Heroku, having 2 package.json files.
First is for the frontend:
{
"name": "quiz",
"version": "0.0.0",
"scripts": {
"ng": "ng",
"start": "npm start --prefix server",
"build": "ng build",
"watch": "ng build --watch --configuration development",
"test": "ng test",
"heroku-postbuild": "npm run build --prefix server && ng build --prod"
},
"private": true,
"dependencies": {
"@angular/animations": "~12.0.2",
"@angular/common": "~12.0.2",
"@angular/compiler": "~12.0.2",
"@angular/core": "~12.0.2",
"@angular/forms": "~12.0.2",
"@angular/platform-browser": "~12.0.2",
"@angular/platform-browser-dynamic": "~12.0.2",
"@angular/router": "~12.0.2",
"rxjs": "~6.6.0",
"tslib": "^2.1.0",
"zone.js": "~0.11.4"
},
"devDependencies": {
"@types/express": "^4.17.13",
"@angular-devkit/build-angular": "~12.0.2",
"@angular/cli": "~12.0.2",
"@angular/compiler-cli": "~12.0.2",
"@types/jasmine": "~3.6.0",
"@types/node": "^12.11.1",
"jasmine-core": "~3.8.0",
"karma": "~6.3.0",
"karma-chrome-launcher": "~3.1.0",
"karma-coverage": "~2.0.3",
"karma-jasmine": "~4.0.0",
"karma-jasmine-html-reporter": "^1.7.0",
"typescript": "~4.2.3"
},
"engines": {
"node": "16.x",
"npm": "7.x"
}
}
Second is for the backend:
{
"name": "server",
"version": "1.0.0",
"description": "",
"main": "dist/index",
"scripts": {
"start": "node ./dist/server/index.js",
"dev": "nodemon index.ts",
"build": "tsc -p ."
},
"author": "",
"license": "ISC",
"devDependencies": {
"@types/express": "^4.17.13",
"@types/node": "^16.6.1",
"nodemon": "^2.0.12",
"ts-node": "^10.2.1",
"typescript": "^4.3.5"
},
"dependencies": {
"express": "^4.17.1",
"zone.js": "^0.11.4"
},
"engines": {
"node": "16.x",
"npm": "7.x"
}
}
As my package.json starts first and triggers /server/package.json - first I try to build backend, using "heroku-postbuild" command in main package.json file and after that this command builds Angular app.
But after Heroku runs "start" command it shows such mistake:
Error: Cannot find module 'express'
2021-09-18T17:16:28.140193 00:00 app[web.1]: Require stack:
2021-09-18T17:16:28.140194 00:00 app[web.1]: - /app/server/dist/server/config/express.js
2021-09-18T17:16:28.140194 00:00 app[web.1]: - /app/server/dist/server/index.js
2021-09-18T17:16:28.140199 00:00 app[web.1]: at Function.Module._resolveFilename (node:internal/modules/cjs/loader:933:15)
2021-09-18T17:16:28.140200 00:00 app[web.1]: at Function.Module._load (node:internal/modules/cjs/loader:778:27)
2021-09-18T17:16:28.140200 00:00 app[web.1]: at Module.require (node:internal/modules/cjs/loader:1005:19)
2021-09-18T17:16:28.140200 00:00 app[web.1]: at require (node:internal/modules/cjs/helpers:94:18)
2021-09-18T17:16:28.140201 00:00 app[web.1]: at Object.<anonymous> (/app/server/dist/server/config/express.js:6:33)
2021-09-18T17:16:28.140201 00:00 app[web.1]: at Module._compile (node:internal/modules/cjs/loader:1101:14)
2021-09-18T17:16:28.140202 00:00 app[web.1]: at Object.Module._extensions..js (node:internal/modules/cjs/loader:1153:10)
2021-09-18T17:16:28.140202 00:00 app[web.1]: at Module.load (node:internal/modules/cjs/loader:981:32)
2021-09-18T17:16:28.140202 00:00 app[web.1]: at Function.Module._load (node:internal/modules/cjs/loader:822:12)
2021-09-18T17:16:28.140202 00:00 app[web.1]: at Module.require (node:internal/modules/cjs/loader:1005:19) {
2021-09-18T17:16:28.140203 00:00 app[web.1]: code: 'MODULE_NOT_FOUND',
2021-09-18T17:16:28.140204 00:00 app[web.1]: requireStack: [
2021-09-18T17:16:28.140204 00:00 app[web.1]: '/app/server/dist/server/config/express.js',
2021-09-18T17:16:28.140204 00:00 app[web.1]: '/app/server/dist/server/index.js'
2021-09-18T17:16:28.140205 00:00 app[web.1]: ]
2021-09-18T17:16:28.140205 00:00 app[web.1]: }
When I run all those commands locally - it works.
I solved that problem by moving "express" into my main package.json file, but that's not what I'm trying to achieve. I want to have 2 separate json files so I can handle my installed modules for each backend and frontend easily.
What am I doing wrong?
CodePudding user response:
So the problem was actually that I needed to do npm install
both in server and frontend folders.
Heroku has a special command 'heroku-prebuild' which helps to prepary every folder to be built after.
I created such commands:
"heroku-prebuild": "npm install --prefix server && npm install",
"heroku-postbuild": "npm run build --prefix server && ng build --prod"
Firstly, Heroku runs "heroku-prebuild", which installs all npm modules for both frontend and backend and, after that, it runs "heroku-postbuild", which again builds front and back using different package.json files.
After that it runs "start": "npm start --prefix server"
and everything works.