Bit: Cannot include a shared Sass partial in more than one component

Created on 12 Mar 2019  路  10Comments  路  Source: teambit/bit

Expected Behavior

Bit should allow the tracking of single Sass files in multiple components

Actual Behavior

When adding a component and a base Sass file that has already been tracked by another one, Bit throws an error saying it can't track that component. I would expect that Bit should be able to track shared files (or S/CSS at least).

I have a project structure that implements a pretty strict hierarchy regarding styles... consider the structure below:

  |- _variables.scss
src
  |- components
     |- buttons
       |- _base.scss (@imports src/variable.scss)
       |- Button
         |- index.module.scss (@imports ../base.scss)
         |- index.js
       |- ButtonText
         |- index.module.scss (@imports ../base.scss)
         |- index.js

For tracking the Button component, I would need to track the variables and the base sass files. But if I want export but the ButtonText component, I would need to also track the variables and base sass files, and then Bit throws me an error.

In order to actually get around this, I created a node script that compiled my SCSS down to CSS into another director and then used Bit to track the components in that directory. I have a lot of hands touching our components and I still like the idea of keeping them in a mono repo and forgoing the ability to edit the components in different projects. That decision would make what we have above a sustainable methodology, but the inability to track a sass file in more than one component is kind of grinding us to a halt on really implementing Bit.

Steps to Reproduce the Problem

  1. Import a sass file into one component
  2. Track that component
  3. Import the same sass file into another component
  4. Track that component
  5. Use bit status to try to export it
  6. See the error

Specifications

  • Bit version: 14.0.1
  • Node version: 10.15.0
  • npm / yarn version: 6.5.0
  • Platform: MacOS
  • Bit compiler (include version): bit.envs/compilers/[email protected]
  • Bit tester (include version): N/A

Most helpful comment

@drewdecarme We just found out (thanks to your example) that we have issues with dependencies resolution when you have a comment in your file.
We are working on a fix to this issue right now.
It will probably be merged into master in a few days.
Thanks again and let me know if you need any more help.

All 10 comments

@drewdecarme Thanks for reporting this.
Why don't you make _variables.scss and base.scss different components instead?
You can see a real example with instructions in this repo:
https://github.com/teambit/movie-app
(see bit add src/global.css --id style/global)
You can also see the final collection here:
https://bitsrc.io/bit/movie-app

haha no way, that's a great idea. I think I was more trying to cut down on the number of components that needed to be maintained, but I guess in a way, its actually going to work a little better seeing as that if we want to update a base mixin, we only have to update that "mixin" component and not the entire component.

I'm not sure how that's going to play with how sass handles it's own, but I'll get back to this thread with what I find. I think this is an interesting problem and if we can solve it the way that you indicated, it could be pretty interesting.

@GiladShoham I like the way you think mate

@GiladShoham the strategy you layed out was definitely sound... and now that I think about it, I kind of like it more now that we're using semantic versioning for our styles.

However, when I went to include the base "sass" component that I created that has a lot of our style definitions inside of the "base" buttons sass partial, Bit didn't recognize that it was trying to install a dependency and skipped over it.

Here's a quick rundown:

// Import base styles
@import "@bit/ORG_NAME.styles.sass";

// primary
$button-color__primary: $color-neutral-4;
$button-color__primary-border: $color-neutral-4;
$button-color__primary-text: $color-neutral-0;

When I created this file as a Bit component and then exported it to a collection, the dependencies were listed as 0. The reason why we would need it in this file is for Sass to correctly grab the variables that are being passed from the "sass" component and then utilize them in the above file at build time.

Is Bit supposed to recognize the node_modules that are imported into Sass files using the below syntax?

@import "@bit/..."

I think it's also worth mentioning, that when I go to check the status of a React component that includes the above statement in a localized Sass file, I'm getting a linking problem. I'll run thebit link command, don't get any errors, but when I go to check the status one more time, I get the same error below:

new components
(use "bit tag --all [version]" to lock a version with all your changes)

     > typography/caption ...  issues found       
       missing links (use "bit link" to build missing component links): 
          src/app/typography/Caption/index.style.scss -> ORG_NAME.styles/typography

see troubleshooting at https://docs.bitsrc.io/docs/troubleshooting-isolating.html

I cleared the cache a few times using bit cc. It appears there might be some issues with how Bit resolves node_module imports in Sass files.

@drewdecarme
I'm glad you loved it:)
Ok, so css files doesn't support importing from node_modules out of the box.
There are different ways to require css from node_modules. Usally with webpack plugin for example.
What most tools does (like webpack, see more here) is to ask you to add ~ in the import.
so you should change

// Import base styles
@import "@bit/ORG_NAME.styles.sass";

to

// Import base styles
@import "~@bit/ORG_NAME.styles.sass";

When requireing sass from another sass file.
When you require in your react component I think you don't need the ~.
Another bug I just noticed is that after export you will have in the base style in the node_modules dir an index.sass (this is an auto generated file by bit) but when installing it via npm you won't have it.
This is a bug in bit and i'll fix it.
Mean time you should import it like this:

// Import base styles
@import "~@bit/ORG_NAME.COMPONENT_NAME/EXACT_PATH_TO_FILE.sass";

Another usfull refrence is this issue - https://github.com/teambit/bit/issues/1103 - see what @davidfirst wrote there.
(I saw your last comment there about the http issue, and I'm fixing it)

Awesome!

So it worked for the most part, but I'm still having trouble in creating a "Sass" component that imports another Sass component. The dependency still doesn't seem to be resolbing when using the Tilda and explicitly indicating the location of the file needed.

Referencing my original diagram...

  |- _variables.scss (ORG_NAME.styles.sass)
src
  |- components
     |- buttons
       |- _index.scss (@import "~@bit/ORG_NAME.styles.sass/_index.scss") (Fail)
       |- Button
         |- index.module.scss (@import "~@bit/ORG_NAME.styles.buttons/_index.scss") (Success)
         |- index.js
       |- ButtonText
         |- index.module.scss (@import "~@bit/ORG_NAME.styles.buttons/_index.scss") (Success)
         |- index.js

I created the buttons/_index.scss as a component @bit/ORG_NAME.styles.buttons, checked the Bit dashboard and it doesn't list any dependencies.

However when I Created the buttons/button component and checked the Bit dashboard, the dependencies correctly list the @bit/ORG_NAME.styles.buttons as a proper dependency.

It would seem to me from this, as that since the React component is in taking its local Sass file which includes the @bit/ORG_NAME.styles.buttons, it's resolving fine... but when its just a Sass component, something seems to be lost in translation.

I tried to do my due diligence and removed the ORG_NAME.styles.sass Sass component completely as well as the ORG_NAM.styles.buttons Sass component as well, re-exporting them and still the same result.

I had a hunch when I was going back and debugging this.

I had a comment at the top of my Sass file before using the @import Sass directive. That comment actually stopped Bit from recognizing the Sass component dependency. I removed the comment, re-tagged the component and exported it and that fixed the dependency issue. Bit now shows that there is a "Sass" component dependency.

So, I went from this...

// Import base styles
@import "~@bit/ORG_NAME.styles.sass/_index.scss";

to this...

@import "~@bit/ORG_NAME.styles.sass/_index.scss";

@drewdecarme We just found out (thanks to your example) that we have issues with dependencies resolution when you have a comment in your file.
We are working on a fix to this issue right now.
It will probably be merged into master in a few days.
Thanks again and let me know if you need any more help.

@GiladShoham Nice! Great to hear I can help uncover some hard to find bugs. I'll be diving back into my use case tomorrow and I'll let you know if I run into any more trouble or find anything that looks weird or is off.

Regarding the bug @GiladShoham mentioned of index.js generated on export but not on npm install, it has been fixed and merged in this PR: https://github.com/teambit/bit/pull/1488.
The fix generates package.json file on export with 'main' property points to the main file, instead of generating an index.js file.

Everything looks great. This definitely solves my issues. The styles are working great as being their own components and a nice side effect that any change to a cascading file is also going to patch version the component that imports it. This automatic resolution is awesome.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

rap0so picture rap0so  路  13Comments

ranm8 picture ranm8  路  16Comments

poriaz picture poriaz  路  15Comments

jimmi-joensson picture jimmi-joensson  路  14Comments

JoshK2 picture JoshK2  路  12Comments