In React Native apps, should you try to keep all libraries/modules on their latest versions? How do you approach this?
As per say, it's always better to upgrade the libraries frequently and use those libraries which are popular. Suppose you use an old library which uses componentWillMount and that's deprecated. So it may cause some sideissues in your app which you want be able to trace.
But as like ruain change, you should always look for the modules before updating, like react-navigation almost the complete flow is different in v5 and v4 , so you need to change your app flow and also test the whole app again. Similiarly in react-firebase v5 and v6 is totally differnt.
TL,DR: Yes , you should update , but after updating check all the changes in modules and test your whole app again.
Hope it helps. feel free for doubts
I try to migrate after a certain time, as the most recent ones always come with great instability.
An example of this is the new version of:
react-navigation
version 5
is not dealing very well with the react-native-cli version, but is getting along very well with the expo
Related
I started to interest in monorepo approach and Nx.js in particularly. Almost all articles talks that monorepo solve the problem of incompatibility of library versions and I don't quite understand the how. There I have few questions:
If i understood right, the idea of monorepo (in terms of shared code) that all shared code always the same version and all changes are happen in one atomic commit (as advertisement of monorepo states). So lets imagine monorepo with 100 of projects and all of them are depend on libA in the same repo. If I change smth in libA than I have to check changes in all dependent project. Moreover, I have to wait all codeowners to review my changes. So what is pros?
Lets imagine I have monorepo with following projects: appA, libC, libD and there are some third party library, let's call it third-party-lib. appA depends on libC and libD. At some time appA need third-party-lib-v3, BUT libC depends on third-party-lib-v1. https://monorepo.tools/#code-generation states that: "One version of everything
No need to worry about incompatibilities because of projects depending on conflicting versions of third party libraries.". But it is not. In world of Javascript it results in 2 different versions of third-party-lib in different node_modules. Angain what is pros?
I could be very naive in my questions because I never encountered problems with libraries, also I just started learning monorepo topic so I would be glad if someone help me to deal with it.
Having worked with shared code in a non-monorepo environment, I can say that managing internal packages without a monorepo like NX requires discipline and can be more time consuming.
In your example of 100 projects using 1 library, all 100 projects should be tested and deployed with the new version of the code. The difference is when.
In separate repos, you would publish the new version of your package, with all the code reviews and unit testing that go along with it. Next you would update the package version in all your 100 apps, probably one by one. You would test them, get code reviews, and then deploy them.
Now, what if you found an issue with your new changes in one of the apps? Would you roll back to the previous version? If it was in the app then you could fix it in that one app, but if it was in the library, would you roll back the version number in all your apps? What if another change was needed in your library?
You could find yourself in a situation where your apps are using different versions of your library, and you can't push out new versions because you can't get some of your apps working with the previous version. Multiply that across many shared libraries and you have an administrative nightmare.
In a mono-repo, the pain is the same, but it requires less administrative work. With NX, you know what apps your change is affecting and can test all those apps before you deploy your changes, and deploy them all at once. You don't block other changes going into your library because the changes aren't committed until they are tested everywhere they are used.
It is the same with third party libraries. When you update the version of a library, you test it in all applications that use it before your change is committed. If it doesn't work in one application, you have a choice.
Fix the issue preventing that application from working OR
Don't update the package to the new version
It means that you don't have applications that are 'left behind' and are forced to keep everything up to date. It does mean that sometimes updates can take so much time that they are difficult to prioritise, but that is the same for multi-repo development.
Finally, I would to add that when starting to work with NX you may find yourself creating large, frequently changing libraries that are used by all apps, or perhaps putting large amounts of code in the apps themselves. This leads to pain where changes frequently result in deployments of the whole monorepo. I have found that it is better to create app specific folders that contain libraries that are only used by that app, and only create shared libraries when it makes business sense to do so. Examples are:
Services that call APIs and return business domain objects that should not really be changed (changes to these APIs and responses generally result in a V2 of the API and a new NX library could be created to serve that V2 API, leaving the V1 unchanged).
Core, stable atomic UI libraries for each component (again, try not to change the component itself, but create a V2 if it needs to change)
More information on this can be found here NX applications and libraries
My team has a monorepo written with React, built with Webpack, and managed with Lerna.
Currently, our monorepo contains a package for each screen in the app, plus a "container" package that is basically a router that lazily serves each screen. The container package has all the screens' packages as dependencies.
The problem we keep running into is that, by Lerna's convention, that container package always contains the latest version of each screen. However, we aren't always ready to take the latest version of each screen to production.
I think we need more granular control over the versions of each screen/dependency.
What would be a better way to handle this? Module Federation? peerDependencies? Are there other alternatives?
I don't know if this is right for your use case as you may need to stick with a monorepo for some reason, but we have a similar situation where our frontend needs to pull in different screens from different custom packages. The way we handle this is by structuring each screen or set of screens as its own npm package in its own directory (this can be as simple as just creating a corresponding package.json), publishing it to its own private Git repository, and then installing it in the container package via npm as you would any other module (you will need to create a Git token or set up SSH access if you use a private repo).
The added benefit of this is that you can use Git release tags to mark commits with versions (we wrote our own utility that manages this process for us automatically using Git hooks to make this easier), and then you can use the same semver ranges that you would with a regular npm package to control which version you install.
For example, one of your dependencies in your container package.json could look something like this: "my-package": "git+ssh://git#github.<company>.com:<org or user>/<repo>#semver:^1.0.0 and on the GitHub side, you would mark your commit with the tag v1.0.0. Now just import your components and render as needed
However, we aren't always ready to take the latest version of each screen to production.
If this is a situation that occurs very often, then maybe a monorepo is not the best way to structure the project code? A monorepo is ideal to accommodate the opposite case, where you want to be sure that everything integrates together before merging.
This is often the fastest way to develop, as you don't end up pushing an indeterminate amount of integration work into the future. If you (or someone else) have to come back to it later you'll lose time context switching. Getting it out of the way is more efficient and a monorepo makes that as easy as it can be.
If you need to support older versions of code for some time because it's depended on by code you can't change (yet), you can sometimes just store multiple versions on your main branch. React is a great example, take a look at all the .new.js and .old.js files:
https://github.com/facebook/react/tree/e099e1dc0eeaef7ef1cb2b6430533b2e962f80a9/packages/react-reconciler/src Current last commit on main
Sure, it creates some "duplication", but if you need to have both versions working and maintained for the foreseeable future, it's much easier if they're both there all the time. Everybody gets to pull it, nobody can miss it because they didn't check out some tag/branch.
You shouldn't overdo this either, of course. Ideally it's a temporary measure you can remove once no code depends on the old version anymore.
As these are downloadable from npm with their names with different sizes. In which scenarios we must downloads tanstack react query and for which react-query.
As far as I can tell the author chose to publish the new v4 version on #tanstack/react-query whilst keeping the v3 version on react-query.
So most likely, you want the latest version, which is #tanstack/react-query.
This is detailed here: https://tanstack.com/query/v4/docs/guides/migrating-to-react-query-4#react-query-is-now-tanstackreact-query
Create react app is an awesome way to setup a new react project. However i can see it forces certain decisions onto you that come baked in, eg using Jest rather than other test runners such as karma/mocha. As I am setting up a new greenfield project with React, am trying to identify is the best practise to stay with it and accept certain constraints or do most teams end up ejecting and in the parlance of brexit "take back control" and what the reasoning is.
create-react-app actually has a lot of sensible defaults and make it an ideal starting point. But they also regularly update things to stay in sync with where the industry is going. So that's great. And it is maintained by some of the same people responsible for React.
The biggest drawback (and strength) is that it doesn't include many other libraries. You have to add those yourself.
But if you do that you occasionally find that you need to add or tweak a small thing in the Babel/Webpack config.
Luckily there is a middle group. Using libraries like react-app-rewired (https://github.com/timarney/react-app-rewired) allows you to make small changes to the Webpack config without ejecting just yet.
Once you do that you will want to be very careful with upgrading react-scripts. Because every time you do it might break your Webpack changes to their script.
But only once that pain is too much would I consider ejecting.
I have recently moved from a web context into a mobile context (building a React Native app). One of the most powerful processes in the web world was Continuous Delivery. I would like to recreate a continuous delivery pipeline, into production, for the React Native mobile context. My understanding is that this is possible so long as only the javascript bundle gets updates rather than the underlying native components.
I have been finding blogs such as:
https://hiddentao.com/archives/2017/02/17/continuous-integration-for-react-native-with-testfairy-testflight-deploy/ and it appears that fastlane is the most common solution for Continuous Integration in the mobile ecosystem, but posts about Continuous Delivery are a little thin on the ground.
Is this because it is impossible? Is the promised land of "just update the js bundle" a lie? And if it is not impossible, how would I configure fastlane to push directly to production? Or would I use some other tool? Is it generally considered an anti pattern in the space? If so why?
It IS possible to update the javascript portion of a React Native app.
Fastlane is a great tool for building and deploying mobile apps but it is not itself a continuous delivery tool. However, used in conjunction with some other CI tool (Jenkins etc) it can make it easy to configure app store or beta releases triggered at some set interval or based on a certain trigger.
Fastlane is primarily designed to solve the issues associated with building and deploying native applications and as such it is very useful for building/deploying the native RN app to the app store but is likely not the best tool for managing your JS pushes. There are a few tools that are popular for pushing the JS code:
https://deploy.apphub.io/
and
http://microsoft.github.io/code-push/
are two popular mechanisms specifically built for this purpose and provide command line tools for deploying updated javascript. These could be configured in Jenkins (or another CI server) without necessarily needing to use fastlane.
As #john_ryan specified you could use CodePush for application updates. Nevertheless, it is worth taking into account some features of this solution:
You can't use hot updates if you need to add some native modules.
It strictly not recommended to use hot updates if you updated React Native version. In most cases, the consequences will be sad.
New users will get outdated built-in version at first app launching. Actual version will be presented on second run only.
Given all of the above CodePush is best for:
To decrease app update time for critical bugs. Of course you must release native update as soon as possible in this case also.
Non major updates. For major updates in most cases you need to update screenshots, app description, release notes and draw the user's attention about update. Hot update for major changes does not fit because of "second run update" cycle.
Testing stability of new update on a small part of users.
A/B testing.
You should use fastlane in any case. It really cool for custom builds, updating stores meta info, screenshots etc. For beta builds delivery I recommend Crashlytics Beta.