Git Product home page Git Product logo

Comments (47)

michael-letcher avatar michael-letcher commented on May 10, 2024 37

@markgoho I understand there are community workarounds. But I'm after a response from the developers. As their last comment was an offical solution coming in January.

I'm already using a very close variation of your solution.

If they comeback saying what they were trying failed and to just use the workarounds here. Then so be it. But closing a ticket and not actually resolving it I think is a bad practise.

from nx.

gerardcastell avatar gerardcastell commented on May 10, 2024 28

Is there any solution from Nx team already? Thx

from nx.

sean-perkins avatar sean-perkins commented on May 10, 2024 25

I'm a little confused - as I had no issues implementing this across apps from a shared library.

I have all my shared assets (sass, i18n translations, images, etc.) inside libs/theme. My NX workspace scope is @maestro.

In my root package.json, I add a reference to my shared assets lib.

 "@maestro/theme": "file:libs/theme",

This will allow you to access SASS imports like so in your apps/ directory:

@import '~@maestro/theme/sass/global/tools/colors';

To get shared non-sass files to work, you need to update the .angular-cli.json to copy the glob pattern from libs/theme into your app.

"assets": [
        "assets",
        "favicon.ico",
        {
            "glob": "**/*",
            "input": "../../../libs/theme",
            "output": "./assets/"
        }
      ],

Now everything inside of libs/theme is available to your Angular projects from /assets.

from nx.

debuggerpk avatar debuggerpk commented on May 10, 2024 24

i have found a much easier solution to it with lerna.

  1. I do a lerna init in my project root folder to generate me a lerna.json.

  2. Then i edit my lerna.json to have

    {
      "packages": ["libs/*"],
      "version": "independent",
      "npmClient": "yarn",
      "stream": true,
      "useWorkspaces": true
    }
  3. Add a workspaces property to my package which looks like this

  "private": true,
  "workspaces": [
     "libs/*"
   ],
  1. And finally, lerna bootstrap.

This allows me to import from my theme doing

@import '~@workspace/theme/styles/abstracts/variables';

The trick is lerna bootstrap command, which creates a symlink in my root node_modules folder. However, I haven't gotten intensense to work with it.

from nx.

vsavkin avatar vsavkin commented on May 10, 2024 18

Folks. I'm going to close this.

We are reimplementing bazel support using the new capabilities provided by the bazel team. We are hoping to release an early beta in January.

from nx.

Toktik avatar Toktik commented on May 10, 2024 14

Any chance to implement ability for referencing library's scss from apps?

from nx.

paesku avatar paesku commented on May 10, 2024 12

@mkennedy3000's request is doable with @sean-perkins mentioned approach. Unfortunately the files are locked in your node_module and will not be updated on changes unless you remove the reference and do fresh install.

We completely extracted styles into a theme library which almost only contains mixins. They can be used in all other libs and apps. We would like to import them either with @import '~@theme-lib/src/sass/mixins/buttons'; or import '~theme-lib/src/sass/mixins/buttons'.
The reference in package.json feels wrong. Any other ideas?

apps
 |-app-1
   |- app-using-ui-lib-and-theme-styles
 |-app-2
libs
 |-ui-lib
    |-lib-using-theme-styles
 |-api-lib
 |-chart-lib
 |-another-lib
 |-theme-lib
    |- src
        |-sass

from nx.

skydever avatar skydever commented on May 10, 2024 12

Hi!

My setup looks like this, maybe this would help somehow:

  • I have a lib called my-styles with some scss files under libs/my-styles/src/lib/styles/:

    • _variables.scss
    • _core.scss
    • and some more ...
  • At angular.json I set the stylePreprocessorOptions like this (as already mentioned) for every app:

"stylePreprocessorOptions": {
  "includePaths": ["libs/hmi-styles/src/lib/styles/"]
}
  • At the styles.scss of an app I include the styles from the my-styles lib like this:
@import 'variables';
@import 'core';
  • When I need a scss variable from the lib at a scss file of a component, I do the following:
@import 'variables';

// you have access to all variables defined at _variables.scss of the lib

So basically you have to import the scss file where you defined the variables to have access to them.

from nx.

CanKattwinkel avatar CanKattwinkel commented on May 10, 2024 9

I also ran into this challenge - would be great if nx had a solution for this. Maybe we can already collect requirements?

  • No solutions that require any additional npm install to update styles
  • Some sort of scss build in order to publish a .css bundle (it is quite common in my projects that we develop libraries in nx workspaces but publish them to external teams)
  • consumption via scope (@import "~@scope/lib-name";)

from nx.

achimschrepfer avatar achimschrepfer commented on May 10, 2024 8

Ok guys, this is what works for my so far: I added the folder where I place my global SCSS files to the stylePreprocessorOptions section of angular.json (see also https://github.com/angular/angular-cli/wiki/stories-global-styles). This way, everything works as expected (I can use the styles, variables and mixins in SCSS scripts throughout the workspace plus reload on change works).

The only drawback is that VSCode does not recognize this and therefore does not offer any Intellisense-support on global styles. To achieve this, I also added a search pattern to the styles section in angular.json - see screenshot for complete config.

screenshot 2019-02-13 at 09 46 48

I'm not quite sure if this has any side effects, especially for the build process (we try to go towards incremental builds for the whole workspace), but for now it works.

After all: I'd highly appreciate if NRWL came up with a solution/best practice for this use case since many users of NX face it for years.

from nx.

helgetan avatar helgetan commented on May 10, 2024 8

Any Updates here?

from nx.

michael-letcher avatar michael-letcher commented on May 10, 2024 8

@vsavkin I really dislike closing a ticket for the sake of closing the ticket and saying "something will happen".

As you can already see, two comments months later than your "early January" of wanting updates to this issue.

Is there a solution and why hasn't it been linked to the what I'd consider an open ticket.

from nx.

HMubaireek avatar HMubaireek commented on May 10, 2024 7

The solution I followed is this.

  • I have a theme library in libs. In libs/theme/package.json, change the name to:
    @fs/theme

  • in global package.json I added:
    "@fs/theme": "file:libs/theme",

  • npm install

  • from app's styles.scss file I import the library as this:
    @import '~@fs/theme/src/styles/all';

from nx.

markgoho avatar markgoho commented on May 10, 2024 7

Hi @achimschrepfer

So I have the theme lib:
image

And in the styles.scss I have:

@charset "UTF-8";

@import './scss/normalize';
@import './scss/typography';
@import './scss/color';
@import './scss/spacing';
@import './scss/forms';

:root {
  --header-height: 48px;
  --nav-width: 256px;
  --border-radius: 6px;
  --box-shadow: 0 4px 6px 0 hsla(0, 0%, 0%, 0.2);
  --border: 1px solid var(--color-neutral-600);
}

... more styles

In my angular.json for the apps that I want to use my theme lib styles:

projects: {
  "dashboard": { <---- my app name
    "architect": {
      "build": {
        "options": {
          "styles": [
            "libs/theme/src/lib/styles.scss",
          ],

I'm only using CSS Custom Properties (CSS Variables) declared at the root level and thus are accessible anywhere in any component without importing any special files.

So, for example in my _color.scss file:

:root {
  --color-primary-1000: hsl(234, 62%, 26%);
  --color-primary-900: hsl(232, 51%, 36%);
  --color-primary-800: hsl(230, 49%, 41%);
  --color-primary-700: hsl(228, 45%, 45%);
  --color-primary-600: hsl(227, 42%, 51%);
  --color-primary-500: hsl(227, 50%, 59%);
  --color-primary-400: hsl(225, 57%, 67%);
  --color-primary-300: hsl(224, 67%, 76%);
  --color-primary-200: hsl(221, 78%, 86%);
  --color-primary-100: hsl(221, 68%, 93%);
}

and in a component in another lib:

.header-text {
  color: var(--color-primary-500);
}

from nx.

Eladigo avatar Eladigo commented on May 10, 2024 7

So... January (of 2021..) is here..
I got a little lost from all the possibilities, what is the recommended way according to NX itself?

from nx.

lupeportias avatar lupeportias commented on May 10, 2024 5

I created a theme folder in my libs...
and inside the styles.scss of my app I imported the global scss...

@import '../../../libs/common-components/src/lib/theme/global.scss';

from nx.

markgoho avatar markgoho commented on May 10, 2024 5

@Eladigo I use this method on all new projects. Please let me know if you need assistance understanding this strategy or help getting it set up for your repo.

from nx.

paesku avatar paesku commented on May 10, 2024 3

@amrstha it's pity that there is no proper solution for this issue.
I'm still referencing styles within apps or *libs like this @import 'scss-library/src/sass/scss-file';
altough my IDE (webstorm) comlaints about unresolved path, it all works fine.

├── apps
    ├── app-1
    └── app-2
└── libs
    ├── library-1
    ├── library-2
    └── scss-library

whereas the scss-library is a normal library setup with nx.

from nx.

brianpkelley avatar brianpkelley commented on May 10, 2024 3

Key component to getting this to work:

Run npm install after adding your libraries to the package.json

from nx.

markgoho avatar markgoho commented on May 10, 2024 3

So I've tried this but I'm wondering if anyone can find a problem with:

angular.json:

"projects": {
  "dashboard": {
    "architect": {
      "build": {
        "options": {
          "styles": [
            "libs/theme/src/lib/styles.scss",
          ],

I'm including the "theme" scss file from the theme lib.

You do get the application to rebuild when these files are edited and saved.

With the package.json method above, you have to break the build, npm install, and recompile each time you make changes to the theme scss files when included this way.

🎄

from nx.

drakenfly avatar drakenfly commented on May 10, 2024 1

@paesku's request is exactly what I need.

I tried @sean-perkins approach and it seems to work for me (without reinstall), but of course it would be great if there is any way nx could provide a native way for this in future.

Is there any ongoing work or anything I can help with?

from nx.

dgroh avatar dgroh commented on May 10, 2024 1

I created a styles.scss in the root of my lib. Where can I reference it?

image

from nx.

brianpkelley avatar brianpkelley commented on May 10, 2024 1

@MrCroft The way I have mine set up is that each component has its included styles in scss file and then its "changeable" values in another wrapped in a mixin/function as above. Much like

libs/
    - ui/
        - dropdown/
            - dropdown.component.scss
            - _dropdown.theme.scss

Then you just @import '~@lib/ui/dropdown/dropdown.theme' file in your app.scss file and @include dropdown-theme($theme);

from nx.

tcoz avatar tcoz commented on May 10, 2024 1

from nx.

tomwanzek avatar tomwanzek commented on May 10, 2024

First of, I love the effort you are putting forward with nx!

Not having support for shared styles (i.e. similar to Angular Material theming support) at the library level is a major roadblock to adopting the current monorepo approach, however.

So far (using other library builders), I always had to opt for building and linking the libraries to ensure style import paths can be resolved, e.g. import "~mylib/styles/theming" during the development process. Addressing this use case would be most welcome.

from nx.

tomwanzek avatar tomwanzek commented on May 10, 2024

@sean-perkins I'll double check my setup, conceivably it was an issue with a particular version of the underlying Angular cli/Angular version. I ran into resolution errors w.r.t. the SASS file imports for the theme.

from nx.

killbox-code avatar killbox-code commented on May 10, 2024

@paesku is spot on - the suggestion from @sean-perkins has me up and running, but it's been much more pain than usual for me to put my 'guess-and-check' styles hat on lately. I'd be happy to spearhead the work and submit a PR, I just don't know where to start other than some ugly pre-start script that copies everything to my app's src/assets and syncs changes back to the lib. Thinking there has to be a better way...

from nx.

milocosmopolitan avatar milocosmopolitan commented on May 10, 2024

I've been using webpack to compile LESS into css, separately from Angular libraries

libs
|_ styles
    |_ css
    |_ less
    |_ package.json
    |_ webpack.conf.js

In my webpack config

var webpack = require('webpack');
var path = require('path');
var MODULE_BUILD_DIR = path.resolve(__dirname, 'css');

const ExtractTextPlugin = require("extract-text-webpack-plugin");

const extractLess = new ExtractTextPlugin({
  filename: "output_name.css",
  disable: process.env.NODE_ENV === "development"
});

module.exports = {
  entry: './libs/styles/less/style.less',
  output: {
    path: MODULE_BUILD_DIR,
    filename: 'output_name.css'
  },
  module: {
    rules: [
      {
        test: /\.less$/,
        use: extractLess.extract({
          use: [
            {
              loader: "css-loader"
            },
            {
              loader: "less-loader",
              options:{
                sourceMap: true,
              }
            },
          ],
          fallback: "style-loader"
        })
      },
      {
        test: /\.(png|jpg|gif)$/,
        use: [
          {
            loader: 'file-loader',
            options: {
              name: '../[path][name].[ext]'
            }
          }
        ]
      }
    ]
  },
  plugins: [
    extractLess
  ]
};

When I'm bundling libs using ng-packagr it copied styles library as well.

Then able to use @import "~@scope/lib-name"; in LESS file when npm package is installed from file directly "@scope/lib-name": "file:libs/lib-name",

from nx.

HMubaireek avatar HMubaireek commented on May 10, 2024

I'd love a solution for this. @sean-perkins your solution didn't work for me. When I type npm install, it doesn't install my local lib. However, if I type npm i @fs/theme it will install a link for the package in node modules, and add new entry in package.json with the name theme only without @fs/ part.

from nx.

woppa684 avatar woppa684 commented on May 10, 2024

Not a solution obivously, but for now I just have a symbolic link in place ...

mklink /D .\node_modules\@myscope\theme ..\..\libs\theme

At least this gets my project going for now ... And it DOES refresh the dev server when I change something in the theme.

from nx.

dgroh avatar dgroh commented on May 10, 2024

I just realised i opened an issue related to that one. So any updates on this?

#718

from nx.

crestamr avatar crestamr commented on May 10, 2024

Is this issue resolved?
Can anyone suggest a better way for referencing library's scss from apps?

@paesku, How did you accomplish this, can you help me?

from nx.

achimschrepfer avatar achimschrepfer commented on May 10, 2024

@markgoho how do you use the styles of styles.scss then in your application? I tried your approach, VSCode is able to resolve the styles (see screenshot) but when I run ng serve, I get an error (just like the mixin or the variable does not exist).

screenshot 2019-02-13 at 09 19 36

screenshot 2019-02-13 at 09 21 19

from nx.

achimschrepfer avatar achimschrepfer commented on May 10, 2024

@markgoho seems that I've found the reason: the SCSS style gets completely preprocessed and compiled by the build process when you include it your way. So we do not have a chance to use mixins or variables this way.

from nx.

achimschrepfer avatar achimschrepfer commented on May 10, 2024

@skydever thanks for sharing - the same works for me. What IDE/Editor are you using? Does it support this approach with Intellisense/Autocompletion?

from nx.

skydever avatar skydever commented on May 10, 2024

hi @achimschrepfer! I am using vscode but the intellisense/autocompletion seems not work. Should it work out of the box or is there an extension required for this?

from nx.

achimschrepfer avatar achimschrepfer commented on May 10, 2024

I'm using the SCSS Intellisense extension for VScode. But if I set up as you suggested, Intellisense does not work at all.

As you can see in my last comment above yours, I've managed to get Intellisense support by adding the styles not only to stylePreprocessorOptions but also to the styles option in the architect settings.

from nx.

skydever avatar skydever commented on May 10, 2024

I see, thx 👍

from nx.

intellix avatar intellix commented on May 10, 2024

Wanting to do: https://material.angular.io/guide/theming-your-components

ng g lib layout
ng g c header --project=layout
ng g c footer --project=layout

Creates a tree like:

libs
  /layout
    /src
      /lib
        /header
          header.component.html
          header.component.scss
          header.component.spec.ts
          header.component.ts
          header.theme.scss
        /footer
          footer.component.html
          footer.component.scss
          footer.component.spec.ts
          footer.component.ts
          footer.theme.scss
      

Now, you can create a file next to index.ts for that lib /libs/layout/src/theming.scss:

@import './lib/header/header.theme.scss';
@import './lib/footer/footer.theme.scss';

and inside your app's styles.scss:

@import 'libs/layout/src/theming';

@include header-theme($theme) { ... }
@include footer-theme($theme) { ... }

It seems to work well IMO. You're whitelisting/exporting only theme files so you don't start duplicating SCSS as you import.

You don't need to update stylePreprocessorOptions.includePaths.

For sure this would be cool, but it only looks prettier:

@import '~@angular/material/theming';
@import '~@myapp/layout/theming';

from nx.

MrCroft avatar MrCroft commented on May 10, 2024

How about another use case with monorepos, when you have multiple apps and a common ui components library? And those ui components need to have different colors (and possibly other style properties that differ), depending on which app consumes them.

For example:

apps/
    - app1
    - app2
libs/
    - ui/
        - dropdown/

Depending on which app consumes the dropdown, the dropdown needs to have different colors for borders, active items, hovered items, shadow etc.
That's the issue I'm facing right now.
How can we achieve that? (ie without taking all styles from the ui components library and making them global) since it's impossible to know at the ui component's css level what app consumes the component...

from nx.

inglkruiz avatar inglkruiz commented on May 10, 2024

I found a way to share mixins, variables, and functions between apps and libs. I created a folder in the root styles and then I imported what I need in any scss files just by adding @import 'styles/variables', for example. If you want to share a base style for your components then from there is quite easy. Let me know what do you think.

from nx.

markgoho avatar markgoho commented on May 10, 2024

@michael-letcher there are a number of workable solutions presented in this thread

  1. create a theme lib
  2. import styles and assets from that lib in angular.json file for any apps that need it
  3. use css custom properties to share variables between libs

There is a ponyfill for css custom properties if you need to support IE.

from nx.

evanjmg avatar evanjmg commented on May 10, 2024

There should be lib support also for React apps with lerna etc without using css modules. Is this possible? Right now I am just copying the scss file?

from nx.

B1Z1 avatar B1Z1 commented on May 10, 2024

Yo, I find out great solution, to provide lib/styles into app. You can look here in the example of nextjs https://github.com/erkobridee/nx-nextjs

from nx.

Splaktar avatar Splaktar commented on May 10, 2024

@markgoho's approach seems to work pretty well. However, I think that I've run into an edge case.

Here's what we're seeing.

  1. We have libs/theme/task/_comment.scss and libs/theme/task/_task.scss that imports comment.
  2. In our app's build config in angular.json's styles array, we have libs/theme/task/_task.scss.
  3. Using ng serve client-app, we make a change to libs/theme/task/_comment.scss and the app reloads.
  4. Push to CI and have a production build done and stored in the cache.
  5. Push a Sass change to libs/theme/task/_comment.scss to CI and the production build hits the cache and quickly replays the cache result.
  6. Test the output of this build, the Sass changes from (5) are missing.

So most everything works fine, but the Nx build cache doesn't detect this change.

It looks like I'll need to add

  "implicitDependencies": {
    "libs/theme/**/*.scss": ["client-app"]
  },

from nx.

raberana avatar raberana commented on May 10, 2024

Hello. Is there already a more elegant solution for this requirement?
We would like to create a pure css library that can be imported by an angular, react and vuejs libraries/applications.

from nx.

github-actions avatar github-actions commented on May 10, 2024

This issue has been closed for more than 30 days. If this issue is still occuring, please open a new issue with more recent context.

from nx.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.