Skip to content

Prefixable style imports similar to tsconfig.json's compilerOptions.paths #12573

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
damienwebdev opened this issue Oct 12, 2018 · 2 comments
Closed
Labels
area: @angular-devkit/build-angular feature Issue that requests a new feature
Milestone

Comments

@damienwebdev
Copy link

damienwebdev commented Oct 12, 2018

Bug Report or Feature Request (mark with an x)

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

Command (mark with an x)

- [ ] new
- [] build
- [] serve
- [] test
- [ ] e2e
- [ ] generate
- [ ] add
- [ ] update
- [ ] lint
- [ ] xi18n
- [ ] run
- [x] config
- [ ] help
- [ ] version
- [ ] doc

Versions

damien$ node --version
v8.9.4
-----
damien$ ng --version

     _                      _                 ____ _     ___
    / \   _ __   __ _ _   _| | __ _ _ __     / ___| |   |_ _|
   / △ \ | '_ \ / _` | | | | |/ _` | '__|   | |   | |    | |
  / ___ \| | | | (_| | |_| | | (_| | |      | |___| |___ | |
 /_/   \_\_| |_|\__, |\__,_|_|\__,_|_|       \____|_____|___|
                |___/
    

Angular CLI: 6.2.3
Node: 8.9.4
OS: darwin x64
Angular: 
... 

Package                      Version
------------------------------------------------------
@angular-devkit/architect    0.8.3
@angular-devkit/core         0.8.3
@angular-devkit/schematics   0.8.3
@schematics/angular          0.8.3
@schematics/update           0.8.3
rxjs                         6.2.2
typescript                   2.9.2

Repro steps

  1. Add two libraries with the same scss file name: e.g sample.scss
  2. Add both libraries scss paths to your projects.project.architect.build.stylePreprocessorOptions.includePaths
 "build": {
          "builder": "@angular-devkit/build-angular:browser",
          "options": {
            "outputPath": "dist/apps/demo",
            "index": "apps/demo/src/index.html",
            "main": "apps/demo/src/main.ts",
            "polyfills": "apps/demo/src/polyfills.ts",
            "tsConfig": "apps/demo/tsconfig.json",
            "assets": [
              "apps/demo/src/assets",
              "apps/demo/src/favicon.ico"
            ],
            "styles": [
              "apps/demo/src/scss/styles.scss"
            ],
            "stylePreprocessorOptions": {
              "includePaths": [
                "apps/demo/src/scss",
                "libs/design/scss"
              ]
            },
            "scripts": []
          }
        },
  1. In your src/styles.scss reference the sample.scss file.
@import "sample.scss"
  1. Be unsure which file is chosen by sass-loader

Desired functionality

  1. Add two libraries that happen to have the same scss file name: e.g sample.scss
  2. Add both libraries scss paths to your projects.project.architect.build.stylePreprocessorOptions.includePaths but INCLUDE a prefix if desired.
"build": {
          "builder": "@angular-devkit/build-angular:browser",
          "options": {
            "outputPath": "dist/apps/demo",
            "index": "apps/demo/src/index.html",
            "main": "apps/demo/src/main.ts",
            "polyfills": "apps/demo/src/polyfills.ts",
            "tsConfig": "apps/demo/tsconfig.json",
            "assets": [
              "apps/demo/src/assets",
              "apps/demo/src/favicon.ico"
            ],
            "styles": [
              "apps/demo/src/scss/styles.scss"
            ],
            "stylePreprocessorOptions": {
              "includePaths": [
                { path: "apps/demo/src/scss", prefix: "@demo"},
                { path: "libs/design/scss", prefix: "@design"},
                "potentially/some/other/non-prefixed/path"
              ]
            },
            "scripts": []
          }
        },
  1. In your src/styles.scss reference the sample.scss file.
@import "@demo/sample.scss"
@import "@design/sample.scss"
  1. Be sure which sample was imported.

Mention any other details that might be useful

Issues & PRs

Revisits #1791
Revisits #4003
Revisits #5287
Potential Solution for #9018

Discussion

I came about this as a part of considering how to build a component library for an angular project. It struck me like a thunderbolt after reading @clydin 's commenting saying that the ideas put out by @angular/material2 with imports via ~ are unsupported

I've also spent a fair bit of time reviewing how webpack's sass-loader works compared to how the AngularCompiler plugin handles loading paths via tsconfig.json. Hats off to @clydin for the new reliance on webpack.resolve for handling tsconfig.json compilerOptions.paths implementation in v7.0.0. Reviewing all of the PRs and issues on styles up to this point has led me to the following:

I think the current includePaths functionality is severely limiting and can lead to significant confusion. It's really nice to KNOW where your styles are coming from rather than guessing which path it happens to come from. To this idea, I'd really like to point out the developer experience from component library perspective (think @angular/material2). Specifically, I'd like to clarify via a simple example of how it feels to develop components that use dependent styles (variables, mixins, functions, etc).

Comparative Example

Let's imagine we treated typescript classes & files (critical application code) like how includePaths forces us to treat .scss/.css/.less files (I'd also argue these are critical application code).

import { Input };

//as opposed to:
//import { Input } from '@angular/core';

As an application maintainer, I'd feel terrified of having any clue as to what was going on with that reference. Who knows where Input is coming from, which dependency you're referring to and as such, what the class even does. I can't even imagine maintaining that for a week let alone long term.

Currently, this is the experience of an Angular dev working with any kind of styles.

//my.component.ts
import 'util';

.component {
  @include some-mixin-from-util;
}

Looking at this, I have no idea where util comes from, no appreciation for whether or not it's imported from my project or a dependency and no way of knowing how to find the file. If I go check includePaths I'm then stuck sifting through how ever many paths are listed there. I feel that it is less than stellar and thus needs to be re-considered.

It would be much more sane to do something like:

//my.component.ts
import '@namespace/util';

.component {
  @include some-mixin-from-util;
}

Potential Solution

I could be very wrong here as this is a naive solution, but after reviewing how webpack's resolve.alias works, taking advantage of it seems like a decent approach. At build time, we could copy the elements from projects.PROJECTNAME.architect.build.stylePreprocessorOptions.includePaths that have prefixes into resolve.alias and be good to go. You'd have to reference your style file in your component's stylesheet via an import '@namespace/util.scss' but having to include the filetype doesn't seem to be the end of the world. If it won't break anything, we could even include .scss,.css,.less in the resolve.extensions.

@damienwebdev damienwebdev changed the title Prefixable scss imports similar to tsconfig.json compilerOptions.paths Prefixable scss imports similar to tsconfig.json's compilerOptions.paths Oct 12, 2018
@damienwebdev damienwebdev changed the title Prefixable scss imports similar to tsconfig.json's compilerOptions.paths Prefixable style imports similar to tsconfig.json's compilerOptions.paths Oct 14, 2018
@alan-agius4 alan-agius4 added feature Issue that requests a new feature area: @angular-devkit/build-angular labels Oct 15, 2018
@ngbot ngbot bot added this to the Backlog milestone Oct 15, 2018
@alan-agius4 alan-agius4 added the needs: discussion On the agenda for team meeting to determine next steps label Oct 15, 2018
@alexeagle
Copy link
Contributor

CLI is the wrong layer to fix this. We want to call out to the existing toolchain using their supported semantics, not layer additional semantics into CLI.

@hansl hansl removed needs: discussion On the agenda for team meeting to determine next steps labels Jan 24, 2019
@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Sep 9, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area: @angular-devkit/build-angular feature Issue that requests a new feature
Projects
None yet
Development

No branches or pull requests

4 participants