Exclude assets in production build

Viewed 7306

I have some assets (images, styles) which I only need during development (ng serve). These assets must not be included in the production build. In production these assets are provided by a CDN.

I need:

  • ng serve should serve files contained in the folder ./assets-non-build

but:

  • ng build should not inculde the folder ./assets-non-build in the final build

I have worked through 10 similar questions here on SO and 5 issues on github, they all deal with excluding files, but none solved my situation.

4 Answers

Inside your angular.json there is a configurations object projects.{project-name}.architect.build.configurations.

Set the assets inside the prod entry to []

"production": {
  //...
  "assets": []
}

This is untested though, but by judging from what I know from the configuration file, this should be possible.

This will make any build and serve with the production flag to exclude the assets. If you really want all the builds, no matter the environment, to build without assets, you move the assets array from projects.{project-name}.architect.build.options to the projects.{project-name}.architect.serve.options and set the one in build to an empty array.

PS: Code not tried yet but for comment its getting too long so posting as answer here.

"architect": {
                "build": {
                    "builder": "@angular-devkit/build-angular:browser",
                    "options": {
                        ....
                        "tsConfig": "src/tsconfig.app.json",
                        "assets": [
                            "src/favicon.ico",
                            "src/assets"
                        ],
                        "styles": [
                             ...
                        ],
                        "scripts": []
                    }
                    }
                },
                "serve": {
                        "assets": [
                            "src/assets"
                        ],
                }

It seems the answer from Poul Kruijt is correct for older versions of angular. On Angular 9 prod entry do not work for me. You have to use production instead. So that is what works for me in angular 9.

This answer describes how to handle large assets in dev + production (using angular 12+) using GCP, but you can easily adapt this answer for other clouds or environments.

1st - Setup Angular to serve local assets

Angular Documentation reference

This assume you have some large or localhost only assets under src/large-assets. We're using angular object syntax to make them available under assets/ (Also make sure src/large-assets is gitignored, or under git-lfs)

"projects": {
    "[your-project-name]": {
      "architect": {
        "build": {
          "configurations": {
            "production": {
              "assets": [
                "src/favicon.ico",
                "src/assets"
              ],
            "development": {
              "assets": [
                "src/favicon.ico",
                "src/assets",
                {
                  "glob": "**/*",
                  "input": "src/large-assets/",
                  "output": "/assets/"
                }

2nd - Make assets URL environment specific

# src/environments/environment.ts
export const environment = {
  ...
  assetsUrl: 'https://localhost:4200/assets/',
  ...
};
# src/environments/environment.prod.ts
const GCP_PROJECT_NAME = 'gcp-project-name';
export const environment = {
  ...
  assetsUrl: `https://storage.googleapis.com/${GCP_PROJECT_NAME}.appspot.com/assets/`,
  ...
};

3rd - Setup Angular to replace environment in prod

# angular.json
"projects": {
    "[your-project-name]": {
     "architect": {
        "build": {
          "configurations": {
            "production": {
             "fileReplacements": [
                {
                  "replace": "src/environments/environment.ts",
                  "with": "src/environments/environment.prod.ts"
                }
              ],

4th - Use in components

# src/components/mycomponent.ts
import { environment } from './environments/environment';
# src/components/mycomponent.html
<img [src]="environment.assetsUrl + 'images/myimage.jpeg'" alt="alt">

5th - Upload your local large assets to CDN for production use

This is an example using GCP

gsutil cp -r src/large-assets gs://${GCP_PROJECT_NAME}.appspot.com/
gsutil iam ch allUsers:objectViewer gs://${GCP_PROJECT_NAME}.appspot.com/
Related