What's best practice to quickly try out a React component? - javascript

I created a React component with the following folder structure:
mycomponent git repo
+ dist
+ node_modules
- src
mycomponent.js
.env
.gitignore
README.md
index.js
package.json
yarn.lock
My component can be used by other applications by simply importing it and then using it in JSX. Let's call the following my "demo application" which is hosted on a different git repo:
demo app git repo
import React from 'react';
import mycomponent from 'mycomponent';
function() {
return (
This is my component
<mycomponent />
);
}
During development of my component I need to continuously edit code and then test the result. Obviously, it is very cumbersome to push every change to Git and NPM, then pull it down in my demo app just to see the result. So I created a new folder called "example" within my component repository and added a new app (built with create-react-app) there, so the whole repo now looks like this:
mycomponent git repo with example dir
+ dist
- example
+ node_modules
- src
App.js
index.js
index.scss
.env
README.md
package.json
updateAndRun.sh
yarn.lock
+ node_modules
- src
mycomponent.js
.env
.gitignore
README.md
index.js
package.json
yarn.lock
This application within the example folder imports mycomponent and uses it in the same way as described above:
example/src/App.js
import React from 'react';
import mycomponent from 'mycomponent';
function() {
return (
This is my component
<mycomponent />
);
}
Now, during development I let this application from the example directory run by doing $ cd example && yarn start. When I change my component, e.g. /src/mycomponent.js then I go to my example folder and run the updateAndRun.sh script. This script looks like this:
example/updateAndRun.sh
#!/bin/bash
cd .. && yarn run dist && cd example
rm -Rf ./node_modules/mycomponent/dist
cp -r ../dist ./node_modules/mycomponent
cp ../index.js ./node_modules/mycomponent
yarn start
As you can see it creates a new build of my component, then copies it into the node_modules folder within the example directory. Then I restart the app using $ yarn start. This allows me to quickly try out if my component would work as expected within a real application. There are some downsides to this though:
Everytime I do a change to my component code I have to stop the running example app and then run the updateAndRun.sh script manually.
Manually copying files into node_modules just feels wrong.
Question
What is the best practice here to quickly try out a component written in React without having to push/pull to a different application?
Note – Storybooks
I am aware of Storybooks. Problem here is that I cannot control the surrounding area of where my component is embedded into. For example, Storybooks would create a navigation bar on the left, has an overall light theme (I need dark) and a lot of other stuff which I don't want. I want to be able to create a custom application and see how my component looks and behaves in there.

You can use yarn add to install a package from a folder on your disk.
From the yarn docs:
yarn add link:/path/to/local/folder installs a symlink to a package
that is on your local file system. This is useful to develop related
packages in monorepo environments.
This means you can keep the repos separate from each other, without copying files, and still use your component.

Related

Export shareable eslint config from a React library's dist folder for other projects

I have a published React library with a dist folder where I export numerous default React components for other projects and I would like to export my eslint config from there.
I've seen people do it in basic npm packages in the main index.js file, but I would like to export everything from one package and not rely on a second package for the eslint config.
I added all my rules to /src/components/eslint/index.js - this then gets translated into /dist/eslint/index.js
Is there any way to import this specific index.js with my eslint rules as eslint config in another project?
In another project I already tried linking it in package.json
and also in the .eslintrc.json file
without luck.
Any ideas?

Dynamically import React component from external URL and use parent React environment

I have a Main UI into which I want to load a Sub UI in the form of a React Component, which is then integrated through a React.Suspense JSX Tag. The Main and the Sub UI will both be separately bundled with Webpack. The Sub UI is bundled as a Webpack 5 Module Library.
Now, the dynamic loading of the component from an URL seems to be no problem. I can use
var path = "<< some URL to a JS-File in a CDN >>";
var SubUiComponent = React.lazy(() => import(/* webpackIgnore: true */ path));
But because the component that I want to import is bundled with Webpack, another React instance is being used. I have already tried to use Webpack Externals, but there seems to be no way that it can be used in combination with dynamic imports.
When I'm not defining externals, I get the following error:
Uncaught Error: Invalid hook call. Hooks can only be called inside of
the body of a function component. This could happen for one of the
following reasons:
You might have mismatching versions of React and the renderer (such as React DOM)
You might be breaking the Rules of Hooks
You might have more than one copy of React in the same app See https://reactjs.org/warnings/invalid-hook-call-warning.html for tips
about how to debug and fix this problem.
With externals defined in webpack.config.js, I get the expected error:
Uncaught ReferenceError: React is not defined
So, is there a way of bundling a React component "kind of" as a library and then import it into another React Environment and use it there?
With two of your different local react projects, you want to link/refer/import one from another? If this is what you're trying to do then yes, it is possible.
First Approach:
You need to research on npm link
Note that package-name is taken from package.json, not from the directory name.
npm link in a package folder will create a symlink in the global folder {prefix}/lib/node_modules/<package> that links to the package where the npm link command was executed.
It will also link any bins in the package to {prefix}/bin/{name}. Note that npm link uses the global prefix (see npm prefix -g for its value).
In some other location, npm link package-name will create a symbolic link from globally-installed package-name to node_modules/ of the current folder
cd ~/projects/some-dep
npm link # Step 1.
cd ~/projects/my-app
npm link some-dep # Step 2.
now, from your my-app folder, you can install some-dep
~/projects/my-app
npm install some-dep#
Second Approach:
Bundle and publish your project to npm registry then install, import it into your other project. Refer this one that I'd published to try out
Third Approach:
Webpack ModuleFederation, when you import the project/module, it will look for it in node_modules, if not found then in the federated modules.
Ref: https://webpack.js.org/concepts/module-federation/

One react app imported into another react app?

Is it possible to import one React app(built using create-react-app) into another completely different React app. We all have imported components in our SPA, but is it possible to import a different app entirely? If so how?
Furthermore, both these react apps MIGHT share a few similar dependencies/files/libraries.. such as bootstrap/css/Redux stores/etc. Also, with a possibility of a few common reducers. These common reducers, might need to interact/listen to actions in-between these two react app.
Lets say we have:
ReactDOM.render(<Provider store={store}><MainApp /></Provider>, document.getElementById('root'));
Could i add another app like this(that was NOT built in this), and target another nod in the dom???
ReactDOM.render(<Provider store={store}><ExternalAPP /></Provider>, document.getElementById('root22'));
Has this ever been done before? React compresses all our components into "chunks" which are basically js files.
Thank you, for any tips/suggestions/hints
You can use npm pack command.
It creates a tarball (.tgz) file from your current app. Then move this file your other app folder then run:
npm install app1 (assuming app1 is your first app name).
After it is installed, you can see your app1 files inside the node_modules/App1/. Now your can import the files or components you want and use it in other apps.
Hope this helps.
Also Checkout this: https://docs.npmjs.com/cli-commands/pack.html
One way that worked for me is to bring the CRA to Github and npm install it as a dependency. I highly encourage you to check out this resource which explains in detail how to prepare a React component for this process. Follow the steps in the linked tutorial up to #3, then bring everything (including the /dist folder) to Github. Then, do npm install org_name/repo_nameand install it as a dependency in your second React app. Then, to import a specific component, you can do something like import { Button } from 'repo_name/dist/index' or reference whatever file you used to export your components.
In case the link doesn't work, here are the steps in the article:
Create a folder called lib that stores all the components you want to bring to the other react app. Also define a file called index.js in this folder that exports these components.
Create a repo for the components on Github
Install Babel and build the dist folder.(npm install --save-dev #babel/core #babel/cli #babel/preset-env and npm install -save #babel/polyfill)
Add the following config file to the top-level folder of your project:
{
"presets": [
[
"#babel/env",
{
"targets": {
"edge": "17",
"firefox": "60",
"chrome": "67",
"safari": "11.1"
},
"useBuiltIns": "usage",
"corejs": "3.6.5"
}
],
"#babel/preset-react"
]
}
In package.json, replace the build script with the following: "build": "rm -rf dist && NODE_ENV=production babel src/lib --out-dir dist --copy-files";
Run the command npm run build

Why doesn't the Pod dependency manager detect the necessary modules for installation?

So this question is a follow up to my previous question:
How can different apps import from a shared components folder? react / react-native
So I've created my own npm module which I store all my components in. These components can be used by as many apps as I like. Because I will be making those components highly reusable.
But I still have stumbled upon a problem.
I have created a loading component which uses this library: #react-native-community/masked-view. This library needs to install a dependency inside /ios/Podfile. First I created this component inside one of the react-native projects.
yarn add #react-native-community/masked-view
..
success Saved 1 new dependency.
cd ios/
pod install
..
Installing RNCMaskedView (0.1.6)
Pod installation complete! There are 33 dependencies from the Podfile and 31 total pods installed.
'
So then I ran my code, and the Loading component works. Now I want to add this to the NPM module (that, again, I created myself) which will contain all my components.
So I go into /my-awesome-99-components/ which has its own package.json since it is a module which I will import in each project I'm working on.
In /my-awesome-99-components/
yarn add react react-native #react-native-community/masked-view
..
success Saved 1 new dependency.
// Created Loading.js - this is the loading component
yarn publish
..
In /react-native-project-1/
yarn add my-awesome-99-components
..
Done in 3.17s.
cd ios/
Pod install
..
This is where the problem comes up. Now the Podfile won't install the RNCMaskedView because apparently my module doesn't let the project know that it should install some packages inside the ios/Podfile.
Does anyone know why this happens, and what would be the best solution for this?
I appreciate all the help!
Have you tried adding a podspec file to your repo?
You can modify the podspec file from the masked-view package like
require 'json'
package = JSON.parse(File.read(File.join(__dir__, 'package.json')))
Pod::Spec.new do |s|
s.name = "RNCMaskedView"
s.version = package['version']
s.summary = package['description']
s.authors = package['author']
s.platforms = { :ios => "9.0", :tvos => "9.0" }
s.source = { :git => "https://github.com/react-native-community/react-native-masked-view.git", :tag => "v#{s.version}" }
s.source_files = "node_modules/#react-native-community/masked-view/ios/**/*.{h,m}"
s.dependency 'React'
end
only change here would be the path of the source files
This is a typical issue with Podfile and overall React Native linking from dependencies with dependencies. react-navigation-stack had the same issue with #react-native-community/masked-view.
The only solution is to mark as #react-native-community/masked-view a peerDependency, so the user using your library knows that there might be another dependency needed, and install it separately. Your problem might be better answered by this answer.

Making files in sub-folder available directly under npm import root

I am making an npm module that has this folder structure:
lib/
one-icon.jsx
another-icon.jsx
/* about 100 more */
package.json
I want to be able to import them like so:
import OneIcon from 'icon-package/one-icon';
I don't want to move the files from /lib/* to /*, because that will mess up my repo, and it will make the entire project a maintenance nightmare.
Is there any way I can tell npm that icon-package/some-icon refers to icon-package/lib/some-icon?
I tried setting the files field in package.json, but that only made sure the lib/ folder was included in the node_modules package.
Any ideas?
Maybe you can import like this?
import {OneIcon} from 'icon-package';
And having index.js in the package like this :-
export OneIcon from ‘./lib/OneIcon.jsx’

Categories

Resources