Implementar Angular en Heroku en modo PRODUCCIÓN

8

Lo siento si esto ha sido respondido en alguna parte.

Puedo implementar una aplicación Angular en heroku, pero a pesar de seguir los pasos de este artículo, no se ejecutará en el modo PRODUCCIÓN.

https://medium.com/@hellotunmbi/how-to-deploy-angular-application-to-heroku-1d56e09c5147

Tenemos dos archivos en la carpeta de entornos:

  • environment.prod.ts
  • environment.ts

Esencialmente, parece que Heroku usa el segundo archivo env llamado environment.ts en lugar de usar environment.prod.ts

En environment.ts, hay una variable env:

// This file can be replaced during build by using the `fileReplacements` array.
// `ng build --prod` replaces `environment.ts` with `environment.prod.ts`.
// The list of file replacements can be found in `angular.json`.

export const environment = {

  production: false,

};

fileReplacements también está configurado correctamente.

El archivo environment.prod.ts también contiene la variable producción y el valor es verdadero .

Sabemos que no es el modo de producción usando el siguiente código simple:

export class SettingsComponent implements OnInit {

  environmentIsProduction: boolean = false;

  constructor() {

  }

  ngOnInit() {
    this.environmentIsProduction = environment.production;
    console.warn('Environment is PRODUCTION: ' + environment.production);
  }

}

¿Alguien puede hacer una sugerencia sobre un paso que quizás hayamos olvidado?

Aquí está el archivo package.json completo

{
  "name": "angular-frontend",
  "version": "0.0.0",
  "engines": {
    "node": "8.11.2",
    "npm": "6.2.0"
  },
  "scripts": {
    "ng": "ng",
    "start": "node server.js",
    "build": "ng build",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e",
    "postinstall": "ng build --aot --prod"
  },
  "private": true,
  "dependencies": {
    "@angular/animations": "^6.1.0",
    "@angular/cdk": "^7.2.1",
    "@angular/cli": "~6.2.3",
    "@angular/common": "^6.1.0",
    "@angular/compiler": "^6.1.0",
    "@angular/compiler-cli": "^6.1.0",
    "@angular/core": "^6.1.0",
    "@angular/forms": "^6.1.0",
    "@angular/http": "^6.1.0",
    "@angular/platform-browser": "^6.1.0",
    "@angular/platform-browser-dynamic": "^6.1.0",
    "@angular/router": "^6.1.0",
    "@ng-bootstrap/ng-bootstrap": "^3.2.2",
    "@swimlane/ngx-datatable": "^14.0.0",
    "angular-notifier": "^4.1.1",
    "angular-svg-icon": "^7.0.1",
    "angularx-social-login": "^1.2.6",
    "bootstrap": "^4.1.3",
    "core-js": "^2.5.4",
    "express": "^4.16.4",
    "flag-icon-css": "^3.3.0",
    "jquery": "^1.9.1",
    "jw-bootstrap-switch-ng2": "^2.0.2",
    "ng-connection-service": "^1.0.4",
    "ng-pick-datetime": "^6.0.16",
    "ng2-currency-mask": "^5.3.1",
    "ng2-nouislider": "^1.7.12",
    "ngx-bootstrap": "^3.0.1",
    "ngx-flag-icon-css": "^1.0.1",
    "ngx-webstorage-service": "^3.1.1",
    "nouislider": "^11.0.0",
    "path": "^0.12.7",
    "popper.js": "^1.14.4",
    "rellax": "^1.7.0",
    "rxjs": "~6.2.0",
    "typescript": "~2.9.2",
    "zone.js": "~0.8.26"
  },
  "devDependencies": {
    "@angular-devkit/build-angular": "~0.8.0",
    "@angular/cli": "~6.2.3",
    "@angular/compiler-cli": "^6.1.0",
    "@angular/language-service": "^6.1.0",
    "@types/jasmine": "~2.8.8",
    "@types/jasminewd2": "~2.0.3",
    "@types/node": "~8.9.4",
    "codelyzer": "~4.3.0",
    "jasmine-core": "~2.99.1",
    "jasmine-spec-reporter": "~4.2.1",
    "karma": "~3.0.0",
    "karma-chrome-launcher": "~2.2.0",
    "karma-coverage-istanbul-reporter": "~2.0.1",
    "karma-jasmine": "~1.1.2",
    "karma-jasmine-html-reporter": "^0.2.2",
    "protractor": "~5.4.0",
    "ts-node": "~7.0.0",
    "tslint": "~5.11.0",
    "typescript": "~2.9.2"
  }
}
1
  • ¿Qué se supone que le diga al software si debe usar environment.tso no environment.prod.ts? Esperaría que sea impulsado por una variable de entorno (por ejemplo NODE_ENV), por lo que no tiene mucho sentido establecer una variable para definir el entorno dentro del archivo. En términos generales, Heroku espera que configure cosas como esta usando heroku:config, no a través de archivos. Los archivos de entorno son solo una forma indirecta de establecer variables de entorno.
    Chris
    15/03/19 a las 14:39
19

Espero que esto ayude a alguien....

Por fin encontré la solución: https://devcenter.heroku.com/articles/nodejs-support#heroku-specific-build-steps

En package.json, era necesario cambiar la siguiente línea:

"postinstall": "ng build --aot --prod"

para

"heroku-postbuild": "ng build --configuration=production"

Aunque el comando original pasó por todos los pasos de la compilación de producción y la ocultación de los nombres de los archivos, etc., podando ... luego se estaba ejecutando una compilación ng normal.

Noté este comportamiento en los registros durante la implementación en Heroku.

Una vez que se usó heroku-postbuild, la compilación solo sucedió una vez ... para la producción.

2
  • 1
    ¡Esto me ayudó! ¡Gracias! 10 abr.20 a las 14:10
  • No es necesario eliminar / reemplazar la configuración "postinstall", lo suficiente como para agregar un nuevo "heroku-postbuild" 10 de enero a las 18:25
1

Para cualquiera que tenga este problema en 2021, una alternativa al uso de postinstall o heroku-postbuild en su package.json es ir a la configuración de su aplicación Heroku para agregar un NODE_BUILD_FLAGS a sus variables de configuración ( https://devcenter.heroku.com/articles / nodejs-support # build-flags ).

Una vez en la configuración de su aplicación Heroku, es tan simple como hacer clic en revelar variables de configuración, configurar una nueva clave de NODE_BUILD_FLAGS y su valor en --configuration = production, ¡y listo! Heroku agregará automáticamente --configuration = production a ng build. Una vez que haga clic en implementar, sabrá ejecutar ng build en función de su script de compilación,

"build": "ng build"

agregue el indicador recién configurado, y su aplicación debería estar en modo de producción sin ningún cambio real en su repositorio.

Es un pequeño truco ingenioso de Heroku que puede ayudar y debería funcionar de manera similar con muchas aplicaciones basadas en Node.js, ¡así que espero que esto ayude a cualquiera que se encuentre con este problema!

0

Para ampliar la respuesta de @Nick C para aquellos de ustedes que implementan Angular Universal. Al construir Angular Universal, el comando termina con el siguiente aspecto:
ng build --configuration=production && ng run my-app:server:production

Desafortunadamente, no pude hacer que esto funcione con NODE_BUILD_FLAGS de Heroku. Terminé creando un pequeño script de nodo en su lugar. Esta solución también me permite implementar en un servidor intermedio de Heroku y un servidor de producción. El script de nodo lee una variable de entorno de nodo y luego decide qué comando de compilación ejecutar.

En package.json: "build": "node build-app.js",

build-app.js:

const { exec } = require('child_process');

let buildScript = 'ng build --configuration=staging && ng run my-app:server:staging';
if (process.env.ANGULAR_ENVIRONMENT_CONFIGURATION === 'production') {
    buildScript = 'ng build --configuration=production';
}
const child = exec(buildScript, function (err, stdout, stderr) {
    if (err) throw err;
    else console.info(stdout);
});

child.stdout.on('data', function (data) {
    process.stdout.write(data);
});

child.stderr.on('data', function (data) {
    process.stdout.write(data);
});

child.on('exit', function (data) {
    process.stdout.write("I'm done!");
});

Entro en más detalles, incluida la actualización de angular.json, en la publicación de mi blog: https://dev.to/jfbloom22/a-better-way-to-deploy-angular-universal-to-multiple-environments-206j