Where should I store my React reusable components? - javascript

I have several ReactJS projects and I am starting to have a lot of reusable components. I do not want to publish them to npm or have them mixed with the imported node_modules directory at the root of my project. Where should they go?
My projects look like this:
project1/
node_modules/
src/
index.js
A.jsx
project2/
node_modules/
src/
index.js
A.jsx
A.jsx defines a reusable component and I'm just copying the file everywhere... I would like to have it in one place only and my projects use it with import A from 'A'.
I have tried to make symlinks to A.jsx in src/ or in node_modules/ but that won't compile, like react-scripts can't handle them. How have you worked around this? Thanks for your help!

I do not want them mixed with the imported node_modules
Why not? Extracting your reusable components into their own library it's the best way to make them reusable. Once they are extracted, you can compose your projects by importing only what you need. You can also write their own tests without running the tests of an entire project. And finally you can handle different versions of the components independently of the projects.
I have tried to make symlinks to A.jsx in src/ or in node_modules/ but…
Symlinking files from one project to another one could be a good idea, but you are creating dependencies between your projects instead of creating dependencies between your projects and your components library. If you want to deploy project B that uses a component from project A, you will need to deploy both projects and recreate the symlink on the server. Also, project A is probably a bigger dependency (with its own dependencies) than a simple components library.
I do not want to publish them to npm
If you don't want to publish your components on NPM (I don't do neither), I'd still suggest you to extract your components into their own repository (GitLab has free private repositories).
Then you can install the library directly from the repository like this:
npm install git+ssh://git#git.mydomain.com:Username/Repository-name
It will create an entry in your package.json:
"Repository-name": "git+ssh://git#git.mydomain.com:Username/Repository-name"
Then you can import your reusable components:
import { ComponentA, ComponentB } from 'Repository-name'

Related

Imported component from local vite+vue library not updating

I'm researching options for a new project at work. We're thinking of using nuxt (or just regular vue 3) and creating a library where we will be keeping our shared components.
I'm trying to do the initial setup, but am having problems. I followed this tutorial to create the library and added typescript to it. I created a sample component with a counter and exported it.
The problem is that when I import the component from my library in a consuming project (whether it's the nuxt project or a vanilla vite vue project), the component looks like it's not reactive. Its internal counter is supposed to increase when it's clicked, but it's not updating. There are no errors or warning in the console.
Another issue is that its CSS is not being applied. It has some basic styling defined in the component, but it's not visible. I've created a minimal reproduction repo with setup instructions here: https://github.com/drekembe/vite-reproduction-2342
I've tried searching for similar issues or debugging it myself, but I haven't gotten anywhere.
Any help is greatly appreciated.
I encounter this problem today with my package and finally, I found the real culprit is the node_module inside the package that we tested locally. If you install the local package by npm link or install directly with the folder path like "components": "../components", your node_module will look like:
node_modules
|
--components
|
--node_modules <-- the culprit here
Your package will be shipped with its own node_module and inside that module has a vue package that is independent of the vue package that you are using in your app. So your components would not work as expected.
To test it, just delete the node_modules/components/node_modules and the vite cache node_modules/.vite then run yarn dev again. You will see your component works fine now.
Solution:
In your package folder components run npm pack to pack your package. It will create a tarball for your package. The output is the components-0.0.0.tgz file inside the components folder. This is the most important part because npm pack will create a pack of your package that is similar to what you will publish to the npm registry.
Now in your test project my-vite-app add your package to the package.json: "components": "file:../components/components-0.0.0.tgz"
Run yarn to install the package and yarn dev to run the app and see if your components work.
Every time you make a change on your package, don't forget to pack the package again and re-install it. You might want to increase your package version to invalidate the yarn cache
In your components folder run :
yarn build
then run :
yarn link
in my-vite-app folder run :
yarn link "components"
in the maint.ts import the style :
import { createApp } from 'vue'
import App from './App.vue'
import 'components/dist/style.css'
createApp(App).mount('#app')

Organize multiple Webpack entry file dependencies

How to organize JS reusable components with their own dependencies in 3rd part bundles (e.g. vendor/ subdirectories) with webpack different entry files/configs?
Description:
I have following structure with entrypoints and components
app/
assets/
index.js
package.json
webpack.config.js
vendor/
my-utils-bundle/
assets/
components/
MyMath.js
package.json
webpack.config.js
In my includable within different entry files/webpack configs MyMath.js components there's node_modules/ dependency to package e.g. mathjs with following line:
import { pi, pow, round, sqrt } from 'mathjs'
....some code below...
P.S. mathjs dependency package provided in this bundle (vendor/my-utils-bundle/package.json)
Then when i run yarn dev to compile my assets in app/assets/index.js there's following error:
"./vendor/my-utils-bundle/assets/components/MyMath.js" contains a reference to the file "mathjs".
This file can not be found, please check it for typos or update it if the file got moved.
Question:
How can i use this MyMath.js components as includable class in app/assets/index.js and maybe also in other "bundles" (e.g. vendor/my-other-bundle)?
Looks that I could install this mathjs dependency also in app/package.json but then it seems that on application level i should think about bundles JS dependencies that sounds not as the best solution.
This is an open question that has been going on pretty much since the launch of Encore. Even earlier, given that according to the best practices for bundles, third party dependencies shouldn't be distributed, and left for the app to manage.
That being said, there is at least one bundle (foxy) that attempts to solve this, by hooking into the composer commands and merge dependencies when packages are installed/updated.
From its README (emphasis mine):
Foxy focuses solely on automation of the validation, addition,
updating and deleting of the dependencies in the definition file of
the asset package, while restoring the project state, as well as PHP
dependencies if NPM or Yarn terminates with an error.
Foxy retrieves the list of all Composer dependencies to inject the
asset dependencies in the file package.json
[...]
Given that Foxy does not manipulate any asset
dependencies, and let alone the version constraints, this allows NPM
or Yarn to solve the asset dependencies without any intermediary

Will electron-builder use dependencies that it doesn't need

I have been wondering this for a while and i haven't found a specific answer.
I am building a whole app using Electron and React to make the ui.
My question is if i should have a 2 complete different source code for each part of the app (electron and react) because i don't know very wekk how the package electron-builder works.
To be precise, since i have installed react (and react packages related) and some others that i just use for the ui part, when i build the app for distribution, will electron include the dependencies that doesn't require? Making the final bundle bigger!
While electron-builder has configuration options to specify which files are to be included, it is not a replacement for a tool like webpack.
electron-builder creates the installer/target artefact for your platform and packs the files you have specified.
It does not sift through your node_modules via tree shaking to create a minified script that only contains the code you need.
You can compare it a with the files array in the package.json that tells npm pack which files should be put into the tarball.
In the default configuration (and I don't know if you can overwrite that, but it is surely worth a try by setting specific node modules to ignore) it will include the entire production dependencies.
Another solution than manually ignoring the react dependencies would be to hold your react app in its own directory in your project and only include the build artefact.
gui/
|_build/
|_your built stuff
|_your react stuff
|_node_modules
|_package.json
main.js
node_modules
package.json
In this case you would configure electron-builder to include main.js and gui/build. With this electron-builder should only include the production dependencies of the outer project.

How to correctly build a package so that suggestions/autocomplete work in intellij when this private styleguidist packages is used in another project

I made my own style guide using react-styleguidist and typescript. Now after building the node package (private) and importing (npm install) it into my other project (where I want to use my style guide components) I am not able to get intellij suggestions to work.
My folder structure is (some files are omitted):
My-library/
package.json
README.md
lib/
components/
Alert/
Alert.d.ts
Alert.d.ts
index.d.ts
index.js
Other_Components/
css/
fonts/
icons/
index.d.ts
index.js
styled-components.d.ts
styled-components.js
I did already check if my node_modules folder of my project was marked as library root (which it is) and I also checked if my package was showing up as not excluded.
My own style guide library works fine, I can use my components and type checking works as well.
I have been looking online for a good guide of how to build/package your project so that these IDE(suggestions/autocomplete) functions work correctly.
When I used the ant design(https://ant.design/) library in intellij and typed <Bu intellij would suggest me <Button>
Same goes for when using Material-ui and the extra #types/material-ui npm package
This is what I would like to achieve with my own npm package as well.
I have no clue if the problem is in my import/exports (default)/index files or in one of my config files (package.json, .babelrc or tsconfig.json, webpack.config.js)
In Visual code this works, so it has to be a bug in Intellij.
It has to do with exporting my component with styled-components like this in my Button.tsx file:
export default styled(Button)`
This is the bug report I found on Jetbrains youtrack:
https://youtrack.jetbrains.com/issue/WEB-33709

Best workflow for developing npm packages that depend on each other

Currently we're developing two React-based applicaties, say app-a and app-b that has two dependencies we also manage. A shared-components package, which contains shared components, and a shared-utilities package which contains shared utilities between app-a and app-b. Both of these have their own full on package.json, and are included in the package.json of app-a and app-b.
Dependencies:
app-a
|- shared-components
|- shared-utilities
and
app-b
|- shared-components
|- shared-utilities
Each time we're developing something in for example shared-components that we want to use in for example app-a we have to perform too many steps:
Make <AwesomeComponent /> in shared-components
Build files in shared-components.
Commit/push to GitHub.
Point dependency in package.json from app-a to the specific branch.
Run npm install.
Use the <AwesomeComponent />.
If we made a mistake in developing the , we need to retart from step 1. Ofcourse we can skip the commit/push and npm install by copying the build files to the node_modules folder directly, but still, this is quite a hassle everytime we're building a component.
What workflow do you guys use or any tips/advice to speed up local development here?
Note; we're using webpack to bundle our files and babel to transpile.
What you want might be npm link.
Simply, in the shared-components set it up with sudo npm link. This creates symlinks in the global npm directories (hence the need for elevated privileges if you installed it as root).
Next all you need to do is to go into app-a and run npm link shared-components which will replace the folder in node_modules with a symlink.

Categories

Resources