I struggle deploying my node.js(TS)/angular app with heroku.
When I try to deploy it on git with git push heroku master
, every step go fine until the heroku-postbuild
one.
Hence, it returns the following :
Generating browser application bundles (phase: setup)...
remote: An unhandled exception occurred: ENOENT: no such file or directory, lstat '/tmp/build_24879b07/front/node_modules'
remote: See "/tmp/ng-REYivA/angular-errors.log" for further details.
My project architecture is...
Project
|
|-- api/...
|-- front/...
|-- package.json
|-- ...
...which might cause some problems.
In addition, here are the most probably concerned files :
./package.json
{
"name": "mymusicads",
"scripts": {
"heroku-postbuild": "cd front && ng build --configuration production",
"start": "cd api && npm run start"
},
"engines": {
"node": "16.x",
"npm": "7.x"
},
"dependencies": {
"@angular-devkit/build-angular": "^12.2.12",
"@angular/cli": "^11.2.13",
"@angular/common": "^11.2.13",
"@angular/compiler": "^12.2.12",
"@angular/compiler-cli": "^11.2.13",
"@angular/core": "^11.2.13",
"@angular/platform-browser": "^11.2.13",
"rxjs": "^6.6.7",
"typescript": "^4.3.5"
}
}
./api/index.ts
import express, { Request, Response } from 'express';
import * as dotenv from 'dotenv';
import path from 'path';
import { adDataRoutes } from './app/routes/ad-data.route';
import { errorHandler } from './middleware/error.middleware';
import { notFoundHandler } from './middleware/not-found.middleware';
dotenv.config();
const app = express();
app.use(express.json());
app.use('/api/addata', adDataRoutes);
app.use(express.static(path.join(__dirname, 'mymusicads', 'dist', 'front')));
app.use(errorHandler);
app.use(notFoundHandler);
app.get('/', (req: Request, res: Response) => {
res.sendFile(path.join(__dirname, 'mymusicads', 'dist', 'front', 'index.html'));
});
app.listen(process.env.PORT || 3000, () => {
console.log(`Listening on port ${process.env.PORT || 3000}`);
});
./front/angular.json
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"version": 1,
"newProjectRoot": "projects",
"projects": {
"front": {
"projectType": "application",
"schematics": {
"@schematics/angular:component": {
"style": "scss"
},
"@schematics/angular:application": {
"strict": true
}
},
"root": "",
"sourceRoot": "src",
"prefix": "app",
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"outputPath": "dist/front",
"index": "src/index.html",
"main": "src/main.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "tsconfig.app.json",
"aot": true,
"assets": [
"src/favicon.ico",
"src/assets"
],
"styles": [
"./node_modules/@angular/material/prebuilt-themes/indigo-pink.css",
"src/styles.scss"
],
"scripts": []
},
"configurations": {
"production": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
}
],
"optimization": true,
"outputHashing": "all",
"sourceMap": false,
"namedChunks": false,
"extractLicenses": true,
"vendorChunk": false,
"buildOptimizer": true,
"budgets": [
{
"type": "initial",
"maximumWarning": "3mb",
"maximumError": "6mb"
},
{
"type": "anyComponentStyle",
"maximumWarning": "10kb",
"maximumError": "20kb"
}
]
}
}
},
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"options": {
"browserTarget": "front:build",
"proxyConfig": "proxy.conf.json"
},
"configurations": {
"production": {
"browserTarget": "front:build:production"
}
}
},
"extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n",
"options": {
"browserTarget": "front:build"
}
},
"test": { [...] },
"lint": { [...] }
}
}
}
},
"defaultProject": "front"
}
From what I understood, the problem come from my api/index.ts
file, I may not be targeting the right path with res.sendFile(path.join(__dirname, 'mymusicads', 'dist', 'front', 'index.html'))
.
Thanks !
CodePudding user response:
Can't recall if I ran into the same issue exactly, but had a different setup. In front
folder I had a package.json specifically for Angular app - basically the default Angular CLI setup
Top level package.json
had very few dependencies (if any), mainly scripts (client folder where you use front). For prebuild, run npm install
in client folder, and npm run --prefix client build -- -- prod
For the server:
// Static files
app.use(
express.static(path.join(__dirname, '../client/dist/my-app'), {
maxAge: '1y',
})
);
// Angular app
app.get('*', (req, res) => {
res.sendFile(
path.join(__dirname, '../client/dist/my-app/index.html')
);
});