How does dependencies get picked in react native? - reactjs

To elaborate:
Lets say I have a react native project running on a specific version, and there are different npm packages installed, We know that each npm package will have its own node_modules and build.gradle file, In what scenario those dependencies local to that package will be used in my project and in what scenarios my project's dependencies will be used?
In the react native new architecture turbo modules are supported whereas I am using a library that does not has turbo modules enable is working, just wanted to know on what grounds the local versions of that package is being used and not the ones present in my project

Let's say for example that you are using react-native-reanimated 2. This package has react-native-gesture-handler as its dependency. In most cases you'll have react-native-gesture-handler added as a local dependency as well.
Now, wherever you are importing reanimated 2 and using its functions, the react-native-gesture-handler of reanimated will be used, not your local one. In some cases, a conflict arises where different versions of dependencies make conflict. In that case you can use resolutions or override in package.json
In your specific case, if a library you are using does not support turbo modules then it will not work with new architecture because new architecture only supports turbo modules as native module.

Related

Should we bundle shared component library separately in lerna monorepo?

I have three packages inside standard lerna monorepo.
client
react library
core
Core - is a shared component library with some utils (may or may not publish on npm).
React library is component library which will be shared on npm.
client is a bundled js library which will be consumed in browser with static html files.
core is a dependency in react-lib as well as client
Question 1 - How to setup core, should I transpile with tsc and bundle with tools such as rollup or vite (i personally prefer vite/rollup over webpack). or just leave it as is and import it in client and react-lib with absolute paths like 'core/src/*"?
Question 2 - can i build core in 'es' format and build client just like normal react app with either cra or vite. I tried this but i think i am missing something as final bundle doesn't seem to work in browser.
Any help would be really appreciated.
You have a few questions and I might not be able to answer them all but hopefully enough to guide you for the solution you're looking for.
Core - is a shared component library with some utils (may or may not publish on npm).
If you want to use Lerna then I guess you'll have to eventually publish the package on npm or a private repository. As an alternative, you could also use pnpm workspaces and their workspace: protocol which will allow you to link the packages in your workspace (monorepo) without ever downloading them from npm, for example if you use workspace:* then it will always use and link to the latest code from your local workspace. You could also use workspace: protocol with Lerna (or Lerna-Lite) since they both support it.
For your next Questions, I'll answer the last part of your Question 1 first because that affects the other portion of the question.
Question 1: ...or just leave it as is and import it in client and react-lib with absolute paths like 'core/src/*'?
Use absolute paths outside of the package is not a good thing to do since it will only work on your local project and you cannot publish that to npm since it will be broken for the other users. It's better to stick with the workspace and let the package use the main or exports entries defined in your package.json. In other words, it's preferable to always build/transpile and let your other package use the transpiled code and if you need to debug then make sure to also include sourcemap
Question 1: How to setup core, should I transpile with tsc and bundle with tools such as rollup or vite (i personally prefer vite/rollup over webpack)
It probably doesn't matter which one you use TypeScript, Rollup or WebPack, In one of my project I use TypeScript in watch mode, it will auto-transpile whenever you change your code, the downside is that the more packages you have then the more TypeScript threads are opened in watch mode (1x per package) but in your case if you only have 3 then it's fine, there's also this TypeScript issue that I'm following which will hopefully bring multi-threaded compilation in the future. You could also use Rollup and the concept would be the same, use it in watch mode for each package (I've done it with Vite/Rollup using vite build --watch
as explained in the next paragraph).
You can take a look at a project I've done Vue 3 and pnpm workspace using pnpm workspace with the workspace: protocol, it uses Rollup for transpiling and also uses Vite library mode which allows to bundle your library for distribution (on npm or others...), this allows you to bundle each package as a lib that is easily reusable by other projects. It's a Vue 3 project, so it's not a React project but it should give you enough ideas on how to do in React and it should help to answer your Question 2. Also that project is not using Lerna/Lerna-Lite but since it uses the workspace: protocol then it would be super easy to add Lerna on top of it in the future (basically just adding the lerna.json config should be enough)

How to make changes to third party package in React Native 0.60+

I'm struggling with making changes and possible a pull request for a third party react native package with cocoapods and auto linking.
In this case I want to add some minor functionality to React Native Camera. And I've forked the repo.
While developing I'd like to use my local code, but I can't get it to work.
I'ven tried using npm link, but this doesn't work since React Native can't find the linked package with the TypeScript import statement.
I've also tried just to edit Objective C code directly in node_modules, running pod install again and rerunning react-native run-ios, but it doesn't seem to include my changes.
I've never really made pull requests to other packages before, so I think I need some help. I thought this would be the easiest thing to google, but it turns out it's not.
You may be doing this already, but make sure that you clean and rebuild the project from xcode if you're modifying objective C code in the node modules folder, before re running react-native run-ios.
If you've already installed the library you also shouldn't need to rerun pod install.
Similarly on android, be sure to rebuild the project in android studio.

Deploy React components to many personal projects

I hope this is a reasonable forum for this question.
I have a library of React components that I've developed that I'd like to use in multiple personal projects. When I update/improve that library I'd like it to allow me to update in all projects where it is used.
I'm using Meteor as a build tool, which will prompt me when there is an update available for a dependency it's using, so I assume it'd be an NPM module or something. It is checked in to GitHub and I don't mind if it's public.
What would be the best way to achieve this?
I know two ways:
Publish your module on NPM
Link using npm link
For the first one, your module will be public unless you pay NPM for a private module.
The second one, make your module available locally only (It is used for a development purpose, but it fits your needs).
https://docs.npmjs.com/cli/link
If you have your package published on GitHub, you can simply create dependency by linking to tarball/master. If your path is https://github.com/my-nick/my-package, just add to your dependencies in your project's package.json:
"my-package": "https://github.com/my-nick/my-package/tarball/master"
If you have your package well described (package.json file with name, main and version attributes) it should works after meteor npm install.
Of course it works for Meteor 1.3 and higher only, lower versions don't support npm.
I did not use is personally yet, but an frequently mentioned tool for this purpose is https://lernajs.io/, which is e.g. used by create-react-app.

Reusing react components across projects

I want to split my web project into three: front-end, back-end and super-admin.
What is the best way to re-use the components across code bases? Npm packages? That seems hard to maintain:
Open component dev package
Make changes
Push changes
Tag version
Update all projects
Seems complex and prone to errors. Is there a better way?
Depends on if you need to use different versions of the shared components from different projects. If so, you probably need to make a versioned npm package. However, if you just want to share the packages and use the same version everywhere, you have other options. For one, you don't have to actually build and publish an npm packge, you can just use npm link. This will basically create a symlink to your shared code in node_modules of the other projects.
Alternatively, you can do it without any npm package at all, just have the shared components in a separate project (directory) and import them in javascript through an alias, using a bundling system (webpack alias / browserify aliasify).

How to create new app projects without downloading and installing npm modules again and again? [duplicate]

This question already has answers here:
How can I make multiple projects share node_modules directory?
(7 answers)
Closed 4 years ago.
I've installed most of the NPM modules globally with -g
However, I see that whenever I create a new app project (example: angular project) using Yeoman, I see that the npm modules get downloaded again and get installed in the local node_modules folder.
I consider that this is extremely wasteful that the same modules gets downloaded and copied for each new project. The size of each new project is then around 160MB.
Is there a way to download only the modules locally in the new project that are not already available in the global npm node_modules folder? Say, anyway to automatically create symbolic links from the local node_modules folder to the globally installed npm modules?
Is this possible? How to set it up?
This is actually by design. From the Node.js blog:
In general, the rule of thumb is:
1.If you’re installing something that you want to use in your program, using require('whatever'), then install it locally, at the root of your project.
2.If you’re installing something that you want to use in your shell, on the command line or something, install it globally, so that its binaries end up in your PATH environment variable.
it is important for you to install project dependencies locally, as you have no guarantee that what is installed globally on your machine may be available on the deployment machine. True, you may manage both machines, or they may in fact be the same machine, but that case is never guaranteed.
Also, it's not unusual for you to have projects which rely upon a specific version of an npm which you may have installed an update for globally, breaking the project that needed the older version. Isolation is a key to keeping projects functional.
if you REALLY need to only maintain one copy, you can use symlinks. npm link globalnpm
Install it globally, and then npm link coffee-script or npm link express (if you’re on a platform that supports symbolic links.) Then you only need to update the global copy to update all the symlinks as well.
Note that the symlink option is really only relevant for hand initialized projects; generators such as Yeoman will always use local, as they follow the grain.
There are workarounds, but this is intentional to avoid equivalent to DLL hell or specifically library versioning mismatch meltdown. Besides 160 MB is a tiny price to pay for this luxury. Discrete functioning bundles are much nicer to ship as a unit of goodness - trust me

Resources