Docs says gt Every li…
Docs says:
> Every library has an index.ts
file, which defines its public API. Other applications and libraries should only access what the index.ts
exports. Everything else in the library is private.
but maybe there is a workaround?
Responses:
Technically it’s just resolved in the tsconfig paths, I think. You could try removing the /index.ts
from this portion of the root tsconfig
"paths": {
"@ossur/package-a": ["libs/package-a/src/index.ts"],
"@ossur/package-b": ["libs/package-b/src/index.ts"],
Although one could argue that you could also just have more smaller libs and export all of them
I setup it like this:
"paths": {
"@project/auth/*": ["libs/auth/src/lib/*"],
}
And added a libs/auth/src/lib/component/index.ts
which just reexports the component created by the nx
cli tool.
Now I can import it like this:
import LegalTerms from '@project/auth/legal-terms';
Is this ok? Maybe I will hit some problems in the future?
regarding the dependency graph - there shouldn’t be any problems I’d assume - as long as typescript compilation passes, commands like nx affected
should continue to work even if you have some custom setup in your paths.
if you change the Nx defaults for libs, you might have some problems with the move
command, but I’m not sure what problems :smile:
btw - one of the biggest advantages of libs is they allow you to package your code and expose only a few items from them in your index.ts
(a very shallow API surface). That gives you more freedom later to change implementation details, because you’ve not allowed anyone to depend on them. If you export everything from a lib, like in your case, you lose this advantage - that tight control of what others can import from your lib.
Yep, but it is a limitation from React.lazy, it only supports default
exports.
I already tried to abstract this away so you can do const Comp = importLazy(() => import("dependency"), 'NamedExport')
, but my TS knowledge is limited and couldn’t make it work for multiple components.
I thought it would work, but doesn’t, it doen’st compile, although everything is fine when serving it
can you share an example repo please? :thinking_face:
I can try to have a look
sure
https://github.com/montogeek/nx-demo/ I created it private, but can’t remember my password to make it public
can you give me permission? my github is rarmatei
added :slightly_smiling_face:
You can serve it with:
npm run nx -- serve @scope/patient
It works just fine, but when building it:
npm run nx build @scope/patient
It throws an error that can’t find the custom import.
I had a look. Made a https://github.com/montogeek/nx-demo/pull/1/files|PR here:
-
you can have normal named exports from libs, just export your components in index.ts
. Then in your app, when you user Reactlazy()
, just pick whatever component you need from the library, and wrap it in the required shape: see <https://github.com/montogeek/nx-demo/pull/1/files#diff-5af0ad0287973bd527e89c2a78065219R6HERE> - Compilation is failling because you use the
@
sign in your folder names - not sure why. Removing that makes it pass. I wouldn’t recommend prefixing your folders with@
anyway - you can add if you want in yourtsconfig
paths -
Based on the above, you can now use normal lib mappings in your tsconfig.json
(see <https://github.com/montogeek/nx-demo/pull/1/files#diff-e5e546dd2eb0351f813d63d1b39dbc48R19here>). This should allow you to use normal Nx defaults.
Thanks a lot for taking the time, there is no way to avoid the named export?
I really want to use them directly
Our arquitecture will be: • Base React App • Sub components by domain • UI Library And subcomponents have inner component that you can use, for example “scope/auth” could export Login, Logout, ChangePassword, AcceptToS, etc.
It is also confusing how it works in serve mode, but no when building it, what could be it?
for me it didn’t work in serve mode either - the command was succesful, but when I launched the app it couldn’t load the component
I understand - your architecture makes sense, and it’s something supported by Nx. You can scope libs with the --directory
option. I don’t completely understand though why you want to import them as defaults. In my mind, the only difference is
lazy(() => import("@my-org/shared/ui").then(res => ({default: res.MyComponent})));
vs.
lazy(() => import("."@my-org/shared/ui/MyComponent"));
Second option is a bit cleaner, yes, but it’d involved creating a lib just for that component.
Some options I can think of: • create one component per lib (might be a bit overkill, but at least you can export them as defaults, if that’s something you want) • create some intermediate files in your app that import the named component from the lib, and re-exports it as default