angular-cli: fileReplacements doesn't work with css files

Bug Report or Feature Request (mark with an x)

- [x] bug report -> please search issues before submitting
- [ ] feature request

Area

- [x] devkit
- [ ] schematics

Versions

node --version: v9.4.0 npm --version: 5.6.0 macOS high sierra 10.13.5

Repro steps

1- In angular.json add a new configuration and try to replace a css file. 2- add a simple background style to header.local.css 3- import the header.css file into styles.scss

E.g.

"configurations": {
            "local": {              
              "optimization": false,
              "outputHashing": "all",
              "sourceMap": false,
              "extractCss": true,
              "namedChunks": false,
              "aot": true,
              "extractLicenses": false,
              "vendorChunk": false,
              "buildOptimizer": false,
              "fileReplacements": [
                {
                  "replace": "src/environments/environment.ts",
                  "with": "src/environments/enviroment.local.ts"
                },
                {
                  "replace": "src/css/header.css",
                  "with": "src/css/header.local.css"
                }
              ]
            },

The log given by the failure

none

Desired functionality

get the header.css replaced by header.local.css

Mention any other details that might be useful

Tested with angular cli version 6.0.1 and angular cli version 6.1.0-beta.0

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 52
  • Comments: 45 (3 by maintainers)

Commits related to this issue

Most upvoted comments

I am writing an app that is built for several clients. Each clients have a variable.scss file with its Material Design variables I wanted to use fileReplacements to switch this variable file at build time but it does not work. I am pretty sure this is a common need, not sure how others do but fixing this issue would make the world a better place. thanks

@shprink

We also needed different variable configurations for different customers.

This is the workaround we used:

src/
    scss/
        product_configurations/
            classic/
                _product_configuration.scss
                _fonts.scss
                ...
            special-customer/
                _product_configuration.scss
                _fonts.scss
                ...
            ...
        _variables.scss
        style.scss

src/scss/_variables.scss

@import '_product_configuration';

/** Other variables, e.g. using colour functions, etc. */
/** [...] */

src/scss/style.scss

@import '_variables';
@import '_fonts';

/** Other imports, that use the variables, e.g. Bootstrap, Angular Material */
/** [...] */

/** Other styles */
/** [...] */

Excerpt from angular.json:

          "configurations": {
            "classic": {
              "stylePreprocessorOptions": {
                "includePaths": ["src/scss/product_configurations/classic"]
              },
              "fileReplacements": [
                {
                  "replace": "src/environments/environment.ts",
                  "with": "src/environments/environment.classic.ts"
                },
                {
                  "replace": "src/index.html",
                  "with": "src/index.classic.html"
                }
              ]
            },
            "special-customer": {
              "stylePreprocessorOptions": {
                "includePaths": ["src/scss/product_configurations/special-customer"]
              },
              "fileReplacements": [
                {
                  "replace": "src/environments/environment.ts",
                  "with": "src/environments/environment.special-customer.ts"
                },
                {
                  "replace": "src/index.html",
                  "with": "src/index.special-customer.html"
                }
              ]
            }
          }

Still doesn’t work in 2020 !

Using angular 7.2 I’m able to replace html files but not for scss files. Is there any updates?

The functionality of fileReplacements block is not very sophisticated because it just replaces files. The main problem is that it doesn’t affect the resolve process of imports, thus breaks for almost all files that have transitive relative imports.

For example if you have the following structure

  • app
    • components
      • test
        • test.component.scss
        • test.component.html
        • test.component.ts
  • replacements
    • test-new.component.ts (with templateUrl and styleUrl “…/app/components/test/test.component.xxx”)

and you want to replace the test.component.ts with test-new.component.ts, it won’t work because the file content just replaces the content of the original test.component.ts in the test folder. The build process then looks up the imports like templateUrl and styleUrls which cannot be resolved in that context.

There may be a way to have a working folder structure to deal with such problems, but it’s very cumbersome.

Because we need such functionality I’m using webpack with a custom webpack-resolve plugin instead of angular-cli. For the moment it works fine when using JIT and a bit limited when using AOT. But with angular 9 and ivy, new issues arrived. The hassle is real.

There really should be a more sophisticated “fileReplacement” option that deals with the correct resolvement and imports of replaced files.

Its a very important feature, please do give a fix on this ASAP.

On working with Internationalization it is very much essential thing. Also the component specific files should also be get replaced by this Angular config.

I am i18n for Internationalization, but the issue is with the SCSS file replacement for Arabic layout.

So I have updated angular/cli to version 6.1.2 but to no avail. @filipesilva so far we know that it works with html, and ts files. It doesn’t work (from what I have tested) with css, scss and json files. What are the next steps to this issue? Can we at least make sure that the basic files like css, html and ts get replaced so most use cases are covered?

Using angular 7.2 I’m able to replace html files but not for scss files. Is there any updates?

Actually html files don’t work for me with 7.3

As said in https://github.com/angular/angular-cli/issues/10881#issuecomment-389644466, ng-cli should be able to replace all type of files from 6.1.0, and not only .ts files. This feature seems to be active in the rc but not in beta, see https://github.com/angular/angular-cli/issues/10881#issuecomment-399063501.

Hi asphub, for the Internationalization you can use the i18n built in mechanism provided by Angular !

The assets don’t count as part of the JS bundles, and he’s been using that, see:

"assets": [
  "src/config"
  "..."
],

They are part of the bundle only if you import them directly using the --resolveJsonModule that you’ve linked above. Basically, if use use that flag with this kind of import, then you can use fileReplacemens:

import * as APP_CONFIG  from './app.config.json';

Otherwise, you’ll need something like this: https://github.com/angular/angular-cli/issues/7506#issuecomment-324981817

More related info: #3855, #7506, #7704


P.S. @manoyanx, your comment and the discussion that followed is not related to the original issue, if the above linked issues don’t help, you should create a new issue.

Thanks @richardtreier your solution worked perfectly!

Since I’m a bit new to Angular CLI I had a bit of trouble understanding what stylePreprocessorOptions does. For anyone needing a bit more information about stylePreprocessorOptions you can have a look at this article:

https://scotch.io/tutorials/angular-shortcut-to-importing-styles-files-in-components

I need this feature for the ability to build the app using a specific theme which I can pass using a parameter.

with @angular/cli: 6.2.1 I was able to switch the global style file, but not a variables file like this:

"fileReplacements": [
  {
    "replace": "projects/example/src/styles.scss",
    "with": "projects/example/src/styles-example.scss"
  }
]

However the latter would be a more lean solution.

We added the generic replacement functionality in https://github.com/angular/devkit/pull/887, but this is limited to webpack loader and plugins that actually use the webpack file system. This might not work for all files, and we should error out when we know that’s the case.