I have a ui library of components and I've added them all to bit.
My ui components repo is using Storybook.
Each component folder includes a ...story.js file, and some of the stories are using other components (from sibling folders), and this is used only for the purpose of the story.
Here's the component's directory structure:

import { Menu } from "./Menu";
import { Icon } from "../Icon"; // needed only for this story
import { Button } from "../Button"; // needed only for this story
As you can see, the path is relative, but.. this component is being imported in another App (different repo), and the story should run there also.
The other App also should use the imported stories, since it also uses Storybook.
The other App also has the Icon & Button bit components imported, luckily the same relative paths above should work.
After I run bit add src/components/Menu
Seem I must also run bit tag --all so I could export that component.
Not finally running bit export ... but the exported component does now show up as expected. It does not have any index.js, or any other js file in the path (unlike all the other components I've exported):

Other components structure is as expected:

The tree viewer adds folders and links if there are any relative file imports to other components. When you open the menu folder, does it show the files correctly? What is the content of the other dirs (icons, button).
You can see how Bit tracks each component before you tag or export by running bit show menu.
On a side note, I'd recommend tracking the storybook files with --tests. The main benefit of it is that it allows Bit to build a devDependencies graph for the component. Meaning that only when you import the component you get the dependencies that defined in the stories, and if you use npm i, you only get the dependencies.
So in your case - bit add src/components/menu --tests menu.story.js.
But why are the actual menu component files in a folder called "Menu" and are not on the root path of the component? I want them to be in the root. Being in the root causes no issues and I don't see any reason why not.
I need this for consistency when importing components by others, so each component would be imported the same way. why should menu be different when importing?
import {Layout} from '../@layout' // good, exported root path index.js
import {Icon} from '../@icon' // good, exported root path index.js
import {Menu} from '../@menu/Menu' // ← no need for nested path
I would like to suggest adding some project-scoped bit configuration where global add patterns could be defined, so for example every story file (regex) will be automatically added with --tests.
Also, I've added all of my components at once, as shown in most tutorials, so how could I have know about this devDependencies suggestion? I simply had no notion of this, so I guess now I would have to remove all my bit components and re-add them? (what would be the best way to fix this for all packages retro?)
And, could I have used the --tests option (for _story_ files) when adding all packages with
bit add src/components/*
?
I don't want to manually type a custom command for each component separately
There's no need to remove all components and track fresh ones.
bit add works by appending "layers" of files to track. So if you run bit add --tests src/components/menu/menu.story.js --id menu for example, Bit will track menu.story.js as a test file.
By the way, if you are having trouble with the CLI, you can use the programmatic API for adding components.
When you import a component Bit points to the correct entry point of the component by generating a package.json file for the component which you then require by import Comp from '@bit/owner.collection.comp'. I think that in terms of consistency and usability its a bit better.
There's an example here (by the way, once you export components, you can use the same absolute import statement in the project the component was exported from).
This is so import statements stay the same, no matter if you use bit import or npm install (for cases where the consumer uses npm i as first, but then wants to modify the component so they run bit import, and move back to use npm package by running bit export --eject).
As for the tutorials, sadly the one in the blog does not contain any tests at all. I've written a very detailed one and added it to the docs about 2 months ago. Perhaps it'll provide you with the missing information.
Thanks for the detailed answer, helpful information.
But what about my question regarding Menu being exported in a nested way, which does not reflect the real & desired component directory structure? (updated the screenshot at the top of this thread)
Or should I replace all of my bit relative imports to global ones?
// current:
import {Menu} from '../@menu/Menu'
// better:
import Menu from '@bit/owner.collection.menu'
_That would indeed solve any path issues since I wouldn't care about how bit structure is generated per component._
Are there any implications converting everything to this format?
For some reason importing directly from the bit collection doesn't work:
import Menu from '@bit/owner.collection.menu'
// Attempted import error: '@bit/✱✱✱✱.✱✱✱✱.menu' does not contain a default export (imported as 'Menu').
nor this
import {Menu} from '@bit/owner.collection.menu'
// "export 'default' (reexported as 'Menu') was not found in './Menu.js'
Even though the overview tab in the component (in bit.dev) shows the first use example.
I think bit is trying to fetch Menu.js from the root path as well and is not aware it isn't there.
Does the package.json of the imported component points to the correct entry point, and that entry point links to the correct file?
Can you give me read permissions so that I can try and reproduce it locally? my email is itayATbit.dev (you know where the @ should be :) )
appears so..
"main": "Menu/index.js"
I'll give you permissions now, thanks!
Added.
BTW - when adding user permissions from _bit.dev_, the email field is not trimmed thus does not pass validations.
I got an error when pasting your email with a trailing space (ticket should be opened separately)
I think that you forgot to add a compiler to your component, as the code is in es6 and needs to be transpilied.
Please run bit import bit.envs/compilers/react --compiler in your project. Afterward run bit status to see that all components are modified (as they will have a compiler defined for them).
Now tag and export, and update the version in the consuming project to see if that helps.
I did it locally and was able to properly import menu.
Why must I add a compiler? I thought it's an optional step.
I don't want the code to be transpiled.. Why would I want that?
I cannot understand why is that necessary, and why bit has created the folder "Menu".. It seems like a bug. if it hadn't have done that, and keeps the files structure as is, it would be better, no?
I feel there should more documentation regarding frequently asked questions, perhaps a page listing common issues and how to solve them
A compiler is needed for code transpilation. It is not mandatory for vanilla JS (and Angular, but this is for completely different reasons), other than that - it's pretty important.
If you are shipping uncompiled code, the consumer will have to make sure to compile the components. Meaning that consumers can install components with npm and use them as packages. So there's no need for bit import. And even if you import the code with Bit, it comes with the compiler, so a consumer that uses es5 can require a component that is written in es6, as Bit ensures the component is transpiled to es5.
Bit creates the directories it needs to support the relative require paths that you use in your code. This is so that Bit will not need to try and modify the import statements in the code.
Bit creates the dir structure that supports all the required paths. Then, if in these paths contains components, Bit creates "link files" that import and export the component that is expected to be there.
Thanks for the detailed answer (though I already have understanding of everything that was said)
But, I have some questions:
why would anyone prefer consume a bit component as an NPM/Yarn package rather then Bit, there is no benefit in limiting yourself, over adding a component using bit import..
I've imported components into my project using bit import..., and they show in the correct directory in my /src/components, but why are they also being created inside the node_modules/@bit directory? it's very odd.
Why the docs mention bit.json where in fact the bit configuration is written inside the main package.json file? it's very confusing where docs and articles mention bit.json but the file is non-existent
I've created a collection of components and had imported them to a project.
I want to copy all the components in a collection to a new collection in another bit.dev profile, what's the fastest way of doing that?
is import Menu from '@bit/owner.collection.menu' the suggested way and not
import {Menu} from '../@menu/Menu'? Because it's clearly taking the component code from node_modules directory (as mentioned in (2)), so how can _bit_ know if I modify an imported component in /src/components/menu. How can both exist?
I will probably have more questions soon, thanks!
nodem_modules contains a link to the imported component. This is so a consumer could use absolute import instead of relative one (@bit/component instead of ../../../component).bit.json to package.json). We've tried to update all the docs, perhaps we've missed a few places. You can still move the bit object to a file named bit.json.bit build (or use bit watch to automate the rebuild process). Bit then rebuild the dist from the modified source. You can also import components with the --ignore-dist flag and skip that feature completely.@yairEO
Some more info:
Thanks a lot @itaymendel and @GiladShoham.
The "puzzle" in my head is now more complete.
I have a huge problem. I am changing components which were imported, locally, and the changes aren't applied. This is because, as I said in (2), there is a duplication of code in node_modules/@bit/... so when I change the component which is in the /src/comp directory, then same file changes are not being applied in component's files in node_modules/@bit/..
I've tried running bit watch as suggested by you in this discussion, and indeed it detected a component change: ...index.js has been changed, calling build..
But still the code in node_modules/@bit/.. does not update to reflect changes in the "real" component's code in /src/comp
What should I do?
@yairEO We just found out about few bugs with the bit watch command. Sometimes it's not working as expected.
If you can open a new issue about it with steps to reproduce, it will be awesome.
I'm working to solve this.
@yairEO We just found out about few bugs with the
bit watchcommand. Sometimes it's not working as expected.
If you can open a new issue about it with steps to reproduce, it will be awesome.
I'm working to solve this.
Are there any updates? This seems like an important issue.
Most helpful comment
@yairEO We just found out about few bugs with the
bit watchcommand. Sometimes it's not working as expected.If you can open a new issue about it with steps to reproduce, it will be awesome.
I'm working to solve this.