Skip to content
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

Angular: Add styles and stylePreprocessorOptions to angular builder #16675

Merged
merged 11 commits into from Nov 26, 2021

Conversation

ThibaudAV
Copy link
Contributor

@ThibaudAV ThibaudAV commented Nov 12, 2021

Issue: #16763 #14612 #15246 #15855

Not solve but provide a solution / or related for

What I did

Add styles and stylePreprocessorOptions options storybook angular builder

Allow the angular 12.2.x and >=13 project to set styles config without using browserTarget in order to rely on another builder's config.

Very useful in the case of a library where you don't have an application but you want to configure styles in storybook like an app

How to test

  • Is this testable with Jest or Chromatic screenshots?
  • Does this need a new example in the kitchen sink apps?
  • Does this need an update to the documentation?

If your answer is yes to any of these, please make sure to include it in your PR.

…icated styles config

Allow the angular project to set styles config without using `browserTarget` in order to rely on another builder's config.

Very useful in the case of a library where you don't have an application but you want to configure styles in storybook like an app
@nx-cloud
Copy link

nx-cloud bot commented Nov 12, 2021

Nx Cloud Report

CI ran the following commands for commit 3beb736. Click to see the status, the terminal output, and the build insights.

📂 See all runs for this branch

Status Command
#000000 nx run-many --target=prepare --all --parallel --max-parallel=15

Sent with 💌 from NxCloud.

@ThibaudAV ThibaudAV changed the title Angular/add builder styles Angular: add styles and stylePreprocessorOptions options storybook angular builder Nov 12, 2021
@ThibaudAV ThibaudAV requested a review from a team November 12, 2021 20:25
Copy link
Member

@shilman shilman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ThibaudAV there are some failing unit tests -- can you please take a look?

…icated styles config

Allow the angular project to set styles config without using `browserTarget` in order to rely on another builder's config.

Very useful in the case of a library where you don't have an application but you want to configure styles in storybook like an app
@ThibaudAV
Copy link
Contributor Author

Oups, thanks
I miss some files. @shilman is fixed right ?

@Marklb
Copy link
Member

Marklb commented Nov 18, 2021

This didn't work in my library, but I will try to debug and see if I am just not using it correctly or if there is an error.

1. What I tried

I added the following "storybook" and "build-storybook" targets to my library config, with the "styles" array from the "application" config that I currently use. It didn't error, but also didn't include the styles.

"my-lib": {
  "projectType": "library",
  "root": "projects/my-lib",
  "sourceRoot": "projects/my-lib",
  "prefix": "lib",
  "architect": {
    "build": {
      // Library build config
      ...
    },
    "storybook": {
      "builder": "@storybook/angular:start-storybook",
      "options": {
        "browserTarget": "my-lib:build",
        "port": 6006,
        "compodoc": false,
        "styles": [
          "projects/my-lib/styles/theme.scss",
          "node_modules/@marklb/ngx-datatable/assets/icons.css"
        ]
      }
    },
    "build-storybook": {
      "builder": "@storybook/angular:build-storybook",
      "options": {
        "browserTarget": "my-lib:build",
        "compodoc": false,
        "styles": [
          "projects/my-lib/styles/theme.scss",
          "node_modules/@marklb/ngx-datatable/assets/icons.css"
        ]
      }
    }
  }
}

2. Questions

  1. I normally think of "assets" and "styles" together, since the global "styles" defined for Storybook in my library are "assets" in my published library. Would "assets" need to be another PR or would it make sense to be part of this one?

  2. I tried setting "browserTarget" to a "build" target in an "application" config and the styles worked, but the "assets" didn't. Is that would should have happened? This may not be a question for this PR and can be ignored for now, if so.

  3. In a typical "application" config there would be a "build" target using "@angular-devkit/build-angular:browser" builder and "serve" target using "@angular-devkit/build-angular:dev-server" builder, where "serve" is dependent on "build" for most of it's config. If Storybook adds "build-storybook" using "@storybook/angular:build-storybook" builder and "storybook" using "@storybook/angular:start-storybook" builder, their relation is similar to "build" and "serve", right? So, would it make sense for the "storybook" target to set the "build-storybook" target as it's "browserTarget". I assume the config will normally just be duplicated in both the way it is now.

Example:

"my-lib": {
  "projectType": "library",
  "root": "projects/my-lib",
  "sourceRoot": "projects/my-lib",
  "prefix": "lib",
  "architect": {
    "build": {
      // Library build config
      ...
    },
    "storybook": {
      "builder": "@storybook/angular:start-storybook",
      "options": {
        "browserTarget": "my-lib:build-storybook",
        "port": 6006
      }
    },
    "build-storybook": {
      "builder": "@storybook/angular:build-storybook",
      "options": {
        "browserTarget": "my-lib:build",
        "compodoc": false,
        "styles": [
          "projects/my-lib/styles/theme.scss",
          "node_modules/@marklb/ngx-datatable/assets/icons.css"
        ]
      }
    }
  }
}

That would make the config reading more complicated, because "build-storybook" would need to read "build" then "storybook" would need to read "build-storybook" with the config it read from "build", but I am wondering if that would be worth it. It would save around ~110 lines in my angular.json. In my library, I use a builder that wraps the ng-packagr and adds support for an "assets" property. Before switching my library to a builder for Storybook I will need "assets" support, but if I need to define "assets" in all three targets then I will be duplicating 55 lines in 3 places. (I use object syntax for the assets, so each assets object is 5 lines.) For styles, they should only be duplicated twice, but the implementation would probably be the same. *This may not be necessary for this initial implementation though.

@shilman shilman added the linear label Nov 18, 2021
@shilman shilman changed the title Angular: add styles and stylePreprocessorOptions options storybook angular builder Angular: Add styles and stylePreprocessorOptions to angular builder Nov 18, 2021
@shilman shilman added linear and removed linear labels Nov 18, 2021
@ThibaudAV
Copy link
Contributor Author

ThibaudAV commented Nov 18, 2021

  1. What I tried
    I wonder if the file root is good 🤔
    "projects/my-lib/styles/theme.scss" -> "styles/theme.scss"

On my lib it works you can test with the PR: gravitee-io/gravitee-ui-particles#13
you can test to debug yours or help me to find the problem

  1. Questions
  1. I normally think of "assets" and "styles" together, since the global "styles" defined for Storybook in my library are "assets" in my published library. Would "assets" need to be another PR or would it make sense to be part of this one?

The styles are analyzed stuff. I don't think they should be confused with assets
I think this can be the subject of a specific PR because for me the assets for storybook are defined by staticDir and now we need to use : https://github.com/storybookjs/storybook/blob/e5939c2f8c3c7484418cc19f85263067bd674ec0/MIGRATION.md#deprecated---static-dir-cli-flag

  1. I tried setting "browserTarget" to a "build" target in an "application" config and the styles worked, but the "assets" didn't. Is that would should have happened? This may not be a question for this PR and can be ignored for now, if so.

related to what I said above ?

  1. In a typical "application" config there would be a "build" target using

I see what you mean but I find that it does not help to understand. That would be really twisted 😁

I will say more that start-storybook and build-storybook are like all the others (test, extract-i18n, serve) and can only have one browserTarget ( browser for this "builder": "@angular-devkit/build-angular:browser" only)

but if the configuration of storybook becomes as complex as that of browser builder. Then we can make a buildStorybookTarget
but I don't think it's necessary for the moment 🤷‍♂️

@ThibaudAV
Copy link
Contributor Author

📝 This feature is for future versions of angular. And allows to complete a lack for the angular 13 support of storybook

Allow the angular 12.2.x and >=13 project to set styles config without using browserTarget in order to rely on another builder's config.

@Marklb
Copy link
Member

Marklb commented Nov 19, 2021

That makes sense why my library wasn't working with ng12.0.5. I was thinking the description meant that it added additional logic for 12.2.x and >= 13, but assumed the existing versions supported by Storybook would still work.

I will take another look at my library and see if I can get it working tonight.

From what I tried in a new project, the "@storybook/angular:start-storybook" builder seems to be working. I was unable to try the "@storybook/angular:build-storybook" builder, because it was throwing an error that I didn't have time to debug at the moment. The error also happens when running the build-storybook executable, so I don't think it is specific to this builder.

The only thing I saw that seems like a problem is the tsConfig file used. I would expect the .storybook/tsconfig.json to be used, if it exists, and use the tsConfig from the builder options as the fallback. I noticed that and described it below in my application/2-app-tsconfig-fix branch notes.

The following is notes I took while building and configuring an ng12.2.0 project with just a root application then adding a library. The repo containing the following branches is: https://github.com/Marklb/sb-repro-16675-ng12.2.0

Branch: application/1-app-tsconfig-issue

This is a new repo with, what I assume, should be the minimum required setup to work.

If you run npm run storybook, it works fine and loads both "styles" and "assets".

If you run npx ng run example-current:storybook, it errors. The typescript error is from the builder using the tsconfig defined in the "build" target, which normally would not include ".stories.ts" files for the same reason it wouldn't include ".spec.ts" files.

Branch: application/2-app-tsconfig-fix

This fixes the compile error, from npx ng run example-current:storybook, by using the tsconfig in the .storybook/ folder, which I think the builder should do. It should probably use the tsconfig defined in angular.json when there isn't one in .storybook/, which is what start-storybook does I think.

If you run npm run storybook, it works fine and loads both "styles" and "assets".

If you run npx ng run example-current:storybook, it works without the "styles". The "styles" should be read from the "browserTarget" option, if not in the storybook target, right?

Branch: application/3-app-styles-working

This branch has "styles" and "assets" working.

Branch: library/1-lib-and-app-together

This includes the app and library stories, when running npx ng run example-current:storybook or npx ng run foo:storybook.

Branch: library/2-lib-and-app-config

This adds a .storybook/ folder to the library folder.

If you run npx ng run foo:storybook, it works as I expected.

@ThibaudAV
Copy link
Contributor Author

ThibaudAV commented Nov 22, 2021

Thanks for the feedback @Marklb. So if I understand correctly it's ok for the subject of this PR.
For the tsConfig indeed it seems to me not a good behavior.

I propose to fix it in this PR too with this one. With this resolve :

  1. user defined (currently by the builder)
  2. tsConfig in the configDir (.storybook/)
  3. use find-up so will trace back from configDir (.storybook/)
  4. use the one from browserTarget (normally will not happen 🤷‍♂️ )

@ThibaudAV ThibaudAV force-pushed the angular/add-builder-styles branch 2 times, most recently from 4397e21 to fcb5a01 Compare November 24, 2021 09:56
@Marklb
Copy link
Member

Marklb commented Nov 24, 2021

I just tried again with newly generated Angular12.2 and Angular13 projects, with the following results. The following results are not for a project containing a library. I will try a library project next, but I expect similar results.

Setup

Angular 12.2 setup

$ npx -p @angular/cli@12.2.0 ng new example --style=scss --routing=false
$ npx sb@6.4.0-rc.4 init // This installed "^6.4.0-rc.7"
// Then I manually set all storybook packages to "6.4.0-rc.5" in `package.json`.
$ npm i
// Then I started a local verdaccio server, with packages built from this PR's branch.
// Then I manually set all storybook packages to "6.4.0-rc.7" in `package.json`.
$ npm i

Angular 13 setup

$ npx -p @angular/cli@13.0.0 ng new example --style=scss --routing=false
$ npx sb@6.4.0-rc.4 init // This installed "^6.4.0-rc.7"
// Then I manually set all storybook packages to "6.4.0-rc.5" in `package.json`.
$ npm i
// Then I started a local verdaccio server, with packages built from this PR's branch.
// Then I manually set all storybook packages to "6.4.0-rc.7" in `package.json`.
$ npm i

Testing

Both worked fine, with npm run storybook and npm run build-storybook, without changing anything after the setup.

"@storybook/angular:start-storybook" builder

  • "styles" are not inherited from "browserTarget" config.
  • "stylePreprocessorOptions" are not in inherited from "browserTarget" config.
  • In the Angular12.2 project, I had to add "allowSyntheticDefaultImports": true to the tsconfig "compilerOptions".
    • The problem was with the React export in "node_modules/@types/react/index.d.ts".

"@storybook/angular:build-storybook" builder

  • "styles" are not inherited from "browserTarget" config.
  • "stylePreprocessorOptions" are not in inherited from "browserTarget" config.
  • In the Angular12.2 project, I had to add "allowSyntheticDefaultImports": true to the tsconfig "compilerOptions".
    • The problem was with the React export in "node_modules/@types/react/index.d.ts".

@Marklb
Copy link
Member

Marklb commented Nov 24, 2021

I just added a library to the projects I previously tested and got similar results.

So, at the moment, I think fixing the "styles" and "stylePreprocessorOptions" not inheriting from the "browserTarget" config and the "allowSyntheticDefaultImports" compilerOption being required when using the builders are the only two things the probably need to be fixed for this PR.

@ThibaudAV
Copy link
Contributor Author

@Marklb Thanks again actually builder with json validation do things I hadn't planned in this way 😱

It should be better

@Marklb
Copy link
Member

Marklb commented Nov 25, 2021

@ThibaudAV Do you mean that not getting styles from the "browserTarget" is or isn't intended? The schema description implies that it does get styles from there. If not getting the styles from "browserTarget" is intended then it seems that it would add additional required configuration to manage that most projects have no reason to change from what "build" uses. I do get that "test" builder separately defines them, so I am still not fully convinced which way it should work, yet.

To me it seems confusing how less than ng12.2 doesn't support styles the same way. Is that intended to be added by another PR?

Do you intend "assets" and "scripts" will be changed to work the same way? I know that my projects can't use the builder unless "assets" work, which should for mine at the moment, because I use a builder that wraps the ng-packagr builder and adds "assets" to the configuration for library projects.

@ThibaudAV
Copy link
Contributor Author

ThibaudAV commented Nov 25, 2021

@ThibaudAV Do you mean that not getting styles from the "browserTarget" is or isn't intended? The schema description implies that it does get styles from there. If not getting the styles from "browserTarget" is intended then it seems that it would add additional required configuration to manage that most projects have no reason to change from what "build" uses. I do get that "test" builder separately defines them, so I am still not fully convinced which way it should work, yet.

I didn't expect the angular builder to add an empty value if styles and stylePreprocessorOptions are not filled in, which caused the problem you mentioned before.

  • If browserTarget is given then use the styles of browserTarget one
  • If browserTarget is given and there are also styles in the storybook builder then these are the storybook styles that override the browser target styles (those of the browserTarget are ignored) (no merge that would not be consistent)

Same for stylePreprocessorOptions

To me it seems confusing how less than ng12.2 doesn't support styles the same way. Is that intended to be added by another PR?

Not planned by myself. (or only for ng14 ^^) not the subject here. but go ahead if you want

Do you intend "assets" and "scripts" will be changed to work the same way? I know that my projects can't use the builder unless "assets" work, which should for mine at the moment, because I use a builder that wraps the ng-packagr builder and adds "assets" to the configuration for library projects.

not the subject here.
But, for the moment I have the impression that it is different the angular assets are represented by the static-dir in storybook, right ?
but if not, yes in an other PR if it is relevant. but I have not met the use case

and for scripts I don't know, do the test. Currently you have other ways to add them in storybook.
I need to have a use case to do something

@shilman
Copy link
Member

shilman commented Nov 26, 2021

@ThibaudAV @Marklb thanks so much for hustling on this. in the interest of getting it available for the community to test, i'm going to merge and release this now. if there's still more work to be done here, let's do it in a follow-up PR! 🙏

@mandarini
Copy link
Contributor

mandarini commented Feb 21, 2022

Added this to Nx too

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants