Cannot set fileReplacements to replace folder content with Angular 11
Asked Answered
P

3

8

I'm using the angular cli config fileReplacements in angular.json file to replace a folder content, like this:

{
  "projects": {
    "myProject": {
      "architect": {
        "build": {
          "configurations": {
            "prod": {
              "fileReplacements": [
                {
                  "replace": "src/environments/environment.ts",
                  "with": "src/environments/environment.prod.ts"
                },
                {
                  "replace": "node_modules/moment/locale/",
                  "with": "src/moment-js-locale/"
                }
              ]
            }
          }
        }
      }
    }
  }
}

Notice that in replace value I'm using a path to a folder instead of a path to a file. This is working code for Angular 10.

I upgraded to Angular 11 and now I'm getting an error when trying to build a prod version using this command: ng build --prod

The error I'm getting is:

Schema validation failed with the following errors:
  Data path ".fileReplacements[1]" should NOT have additional properties(replace).
  Data path ".fileReplacements[1].replace" should match pattern "\.(([cm]?j|t)sx?|json)$".
  Data path ".fileReplacements[1]" should match exactly one schema in oneOf.

ESLint is showing me this warning:

String does not match the pattern of "\.(([cm]?j|t)sx?|json)$".

What can I do with this? Is this an Angular 11 bug? should I use a different approach?

Any help will be appreciated.

Photoelectric answered 13/12, 2020 at 20:4 Comment(0)
P
7

So it turns out that this feature was in fact a Bug πŸ™‚ The fact that one could make a folder replacement till Angular 10 wasn't supposed to work from the beginning.

I asked this question in angular-cli repo and this was the answer that I got:

I am sorry that you are experiencing this issue after updating. However, replacing directories was never a supported use-case of the file replacements feature.

I guess that this will need to be handled by the developer. In my case I just added a script to do that with shell command and I'm running this script as a pre build script using npm run script.

Photoelectric answered 6/1, 2021 at 18:59 Comment(4)
This is a disappointing outcome, not your fault obviously! I had been using this to replace web.config files based on the target client, but now get an exception because "web.config" does not match the file pattern they're enforcing. Thanks for coming back with your findings. – Frodin
I agree with the disappointment. I was using this so that we could point to different API's when serving, reducing the need to run multiple api projects while only needing changes to your front end. – Communal
now what is the solution, upgraded to 14 from 10 – Folder
Wow, I just discovered this problem after trying to replace robots.prod.txt to robots.txt and I have to say that I find this restriction to only allow specific files is completely idiotic. – Komarek
T
2

I was successful with following configuration for web.config and images dedicated for production (I put files for production into src/deployment/prod and they are copied to dist directory into directory from "output" variable):

"fileReplacements": [
    {
        "replace": "src/environments/environment.ts",
        "with": "src/environments/environment.prod.ts"
    }
],
"assets": [
    "src/assets",
    "src/favicon.ico",
    {
        "input": "src/deployment/prod",
        "output": "/",
        "glob": "web.config"
    },
    {
        "input": "src/deployment/prod",
        "output": "assets/img",
        "glob": "*.png"
    }
]

so in your case you probably could use:

{
    "input": "node_modules/moment/locale/", -- source folder in ClientApp/
    "output": "moment-js-locale", -- destination folder in dist/
    "glob": "*.js" -- all js files will be copied
}
Topology answered 25/2, 2021 at 9:15 Comment(3)
Note: This works well for assets, files that have to be copied AFTER build in the dist folder. But if you want to move files that are required during build, that won't work. – Edme
i want to replace favicon.ico file – Folder
In case of favicon.ico, just put ico file into a src/deployment/prod folder and add in angula.json: {"input": "src/deployment/prod", "output": "/", "glob": "favicon.ico"} - I didn't test it, but should work fine. NOTE that browser cache favicon.ico and you may have to delete history local files to see new ico. – Topology
A
0

To do this the right way, simply change the tsconfig file in your angular.json file.

For example:

"configurations": {
  "staging": {
    "customWebpackConfig": {
      "path": "./webpack.config.ts"
    },
    "fileReplacements": [
      {
        "replace": "src/environments/environment.ts",
        "with": "src/environments/environment.prod.ts"
      }
    ],
    "outputHashing": "all",
    "tsConfig": "tsconfig.app.staging.json"

And create a separate tsconfig.app.staging.json like so:

{
  "extends": "./tsconfig.app.json",
  "compilerOptions": {
    "paths": {
      "@nav/*": [
        "src/app/nav/*"
      ]
    }
  }
}

You can put whatever relative paths you want, but keep in mind the "paths" variable will get replaced completely with whatever other values you have, since you're essentially redefining it.

J

Atwell answered 9/9, 2022 at 0:37 Comment(0)

© 2022 - 2024 β€” McMap. All rights reserved.