1

I'm a newbie in angular trying to pass a parameter to my angular build process.

I want to build my app for a specific client so I'm using npm variables to copy the client settings:

npm run build --client=cocacola

However, I cannot figure out how to pass my client name (e.g: cocacola) to my angular.js

This is my scripts in package.json

"scripts": {
  "ng": "ng",
  "start": "ng serve",
  "prebuild": "cp src/app/clients/$npm_config_client.settings.ts src/app/app.settings.ts",
  "build": "ng build",
  "test": "ng test",
  "lint": "ng lint",
  "e2e": "ng e2e"
},

This is part of my angular.json

"build": {
  "builder": "@angular-devkit/build-angular:browser",
  "options": {
    "outputPath": "dist",
    "index": "src/index.html",
    "main": "src/main.ts",
    "polyfills": "src/polyfills.ts",
    "tsConfig": "src/tsconfig.app.json",
    "assets": [
      "src/favicon.ico",
      "src/assets",
      {"glob": "**/*", "input" : "src/$npm_config_client/assets", "output": "/assets/"}
    ],
    "styles": [
      "src/styles.scss"
    ],
    "scripts": [
      "node_modules/jquery/dist/jquery.min.js",
      "node_modules/popper.js/dist/umd/popper.min.js",
      "node_modules/bootstrap/dist/js/bootstrap.min.js"
    ]
  },

Where I'm trying to use my --client in options/assets to load specific client assets.

{"glob": "**/*", "input" : "src/$npm_config_client/assets", "output": "/assets/"}

Is it possible to do this in Angular?

I also created one angular.json per each client but there has to be a better way.

luiscla27
  • 4,956
  • 37
  • 49
Johnny Johnny
  • 319
  • 2
  • 11

2 Answers2

2

I'd suggest you want to actually build multiple projects, so:

angular.json:

{
  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
  "version": 1,
  "newProjectRoot": "projects",
  "projects": {
      "main":{
         "architect": {
            "build": {
               ... standard build configuration
            }
         }
      }
      "cocacola":{
         "architect": {
            "build": {
               ... add cocacola wherever you need here
            }
         }

      }
   }
   "defaultProject": "main"
}

you can then turn this option on or off using the project option of the angular command, so:

package.json:

"scripts": {
    "build": "ng build",
    "build:cocacola": "ng build cocacola"
}

npm run build:cocacola will now run the cocacola project and npm run build runs the none cocacola option.

Liam
  • 27,717
  • 28
  • 128
  • 190
  • That's awesome @Liam, thank you so much : ) but with your approach I'm repeating same code once and again because projects configurations (main, cocacola, pepsi, etc) are almost the same. The only thing that changes is their assets (logos). – Johnny Johnny Jul 19 '20 at 20:23
  • I don't think there is a better way to do this @JohnnyJohnny. You could have a look for a webpack plugin maybe but this is the only way I know that you can achieve what you want. Angular build has many, many moving parts so there possibly is another way but you'll have to do some experimentation to figure that out – Liam Jul 20 '20 at 07:38
  • @JohnnyJohnny, @Liam, any improvement for in this past 2 years?? I have the same requirement however, every `build` section is 110+ lines long... So I don't think the suggested approach is the best ([also neither this](https://stackoverflow.com/questions/53263011/possible-to-pass-variable-to-angular-json-and-avoid-code-duplication)). – luiscla27 Jun 22 '22 at 23:31
  • Maybe look at [MakeFile](https://www.gnu.org/software/make/manual/make.html)? @luiscla27The code smell here though is that your build needs 100 lines of code. In the 20 odd years of engineering, I've never heard of this – Liam Jun 23 '22 at 12:50
0

Have you tried to use "configuration"?

Like this:

"configurations": {
"cocacola": {
          "assets": [{"glob": "**/*", "input" : "src/cocacola/assets", "output": "/assets/"}],
        }}
frazzaglia
  • 39
  • 5