Skip to content

CSS files in library modules are not autoprefixed #11480

@kayahr

Description

@kayahr

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
v10.6.0

$ npm --version
6.1.0

$ lsb_release -a
Distributor ID:	Debian
Description:	Debian GNU/Linux 9.4 (stretch)
Release:	9.4
Codename:	stretch

$ ng -v
Angular CLI: 6.0.8
Node: 10.6.0
OS: linux x64
Angular: 6.0.7
... animations, common, compiler, compiler-cli, core, forms
... http, language-service, platform-browser
... platform-browser-dynamic, router

Package                            Version
------------------------------------------------------------
@angular-devkit/architect          0.6.8
@angular-devkit/build-angular      0.6.8
@angular-devkit/build-ng-packagr   0.6.8
@angular-devkit/build-optimizer    0.6.8
@angular-devkit/core               0.6.8
@angular-devkit/schematics         0.6.8
@angular/cli                       6.0.8
@ngtools/json-schema               1.1.0
@ngtools/webpack                   6.0.8
@schematics/angular                0.6.8
@schematics/update                 0.6.8
ng-packagr                         3.0.3
rxjs                               6.2.1
typescript                         2.7.2
webpack                            4.8.3

Repro steps

  1. Create a new demo app and a library project:

    $ ng new demo
    $ cd demo
    $ ng generate library demolib --prefix dl
    
  2. Add some old browsers to src/browserslist:

    IE 9-11
    safari 7
    
  3. Add the following CSS to src/app/app.component.css:

    .css-for-app-component {
      display: flex;
    }
    
  4. Change projects/demolib/src/lib/demolib.component.ts to use an external CSS file:

    ...
    @Component({
        ...
        styleUrls: ['./demolib.component.css']
    })
    ...
    
  5. Create projects/demolib/src/lib/demolib.component.css with the following content:

    .css-for-demolib-component {
      display: flex;
    }
    
  6. Include the demolib module in the application by changing src/app/app.module.ts:

    ...
    import { DemolibModule } from 'demolib';
    ...
    @NgModule({
        ...
        imports: [
            ...
            DemolibModule
        ],
        ...
    })
    ...
    
  7. Compile the library project and the app:

    $ ng build demolib
    $ ng build
    

The log given by the failure

Open the created dist/demo/main.js file and notice that the app CSS is prefixed but the library project CSS is not:

module.exports = ".css-for-app-component {\n  display: -webkit-flex;\n  display: -ms-flexbox;\n  display: flex;\n}\n"
DemolibComponent.decorators = [
        { type: _angular_core__WEBPACK_IMPORTED_MODULE_0__["Component"], args: [{
            selector: 'dl-demolib',
            template: "\n    <p>\n      demolib works!\n    </p>\n  ",
            styles: [".css-for-demolib-component{display:flex}"]
        },] },
];

Desired functionality

I would expect that all CSS in the project is autoprefixed according to the browserslist configuration.

Mention any other details that might be useful

Looks like the external CSS in the library project is embedded into the component by the compiler and it looks like the autoprefixer does only work with external CSS. So maybe this can be fixed by keeping the CSS external in the library and let the application build handle it? Or maybe the autoprefixer can be changed to also process embedded CSS? Then it would be possible to use embedded CSS in the app project, too, which is currently not autoprefixed.

However this issue is fixed it would be nice if it could be fixed in the application build (by autoprefixing the external CSS) and not in the library build (by running the autoprefixer there as well). Because in my opinion the application is responsible for deciding which browsers to support, not the library. The library can't know in which browsers it is used later. As long as the library is in the same project as the app this doesn't really matter but imagine you create an independent Angular component library, publish it on NPM and some app uses it as an external dependency. Now the App wants to support old IE and needs to prefix the CSS provided by the component library. This could work if the library project still provides the external CSS files which the app build can autoprefix before embedding it into the app bundle. Or the library project can embed the CSS into JavaScript and add some info to the generated metadata.json so the app build knows where the CSS can be found to pass it through the autoprefixer before writing it into the app bundle.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions