Integrating React / Preact based widget library into a legacy web app - reactjs

A client has request me to build a set of reusable components / widget to be integrated on legacy web development (JQuery, ES5 based).
My idea is to create:
A library that will make use of React / Preact to build the widgets.
Use ES6/TS + webpack + babel, to end up transpiling to ES5 and packing it into a library.
My main concern comes with the third party libraries dependencies(e.g. react, react-dom or preact…), I’m thinking about taking one of this two approaches:
A. Treat third party libraries as just external dependencies, the legacy application that needs to consume my widget library have to reference that library.
Pros: no extra weight added to my bundle, this library could be used in legacy apps and modern apps.
Cons: possible versioning hell in the future, e.g. we release the library for React 16, and in the future, they mix other widgets from another library that depend on React 18 (maybe a possible workaround is to fix versions and perform an all or nothing migration from time to time).
B. Embed preact into the library bundle:
Pros: only adding 3 to 4 Kb to the library bundle, the bundle is self contained.
Cons: probably we could not use these components on modern development (e.g. compose it with other components from other react based libraries).
What could be the best approach? Is there another option available? Does approach B make sense? (haven’t tried that one before).

I would lean to the B answer.
if you need to combine them with other libraries, you still have the sources in ES6+ which allows you to import them easily inside a new project.
I actually only work with the B approach because it removes the dependency nightmare. You know that you ship code with the compatible react version, and you have total control of the final ES5 code with babel.
If you worry that much over 10kb, there's plenty of ways to reduce size (enabling compression, making sure you use production bundle, etc).

Related

Should the complex components of react be moved to library?

I'm new to react development. I'm currently using Typescript for react with webpack and npm.
i'm working on a large scale project where components are complex. As of now they are kept in certain hierachy in project folder.
i recently learn about making components library. I'm thinking of taking complex components out of project and put them in a separate component library. However, other team members say it would cauae headache to maintain library separately. since there is less to no chance of using this in any other project (thats the current situation) they should not take the components out and maintain separately.
i want to know if that is the only reason the react developers create component and creating component to test it better and simplifing thw project complexity are not the valid reasons?

Common React Components across multiple apps

We have 3 react apps. Some of the components being used in these apps are common for the 3 apps. We want to have a separate common git repo, where we can put the code for the common components and use those components in the 3 apps. Currently, we do have a repo for common components which is linked from the 3 apps like this in package.json:
package-name username/repo#commit-id
This arrangement poses some difficulties:
For some reason, hooks don't work in the common repo even if we upgrade the react version.
While developing locally, we change package.json to package-name ../path. Everytime we make a change locally in the common repo, the common repo has to be built again manually.
Overall, the process is not good. Many times it throws strange errors which are hard to solve.
Can you suggest an alternative way to accomplish the same?
For some reason, hooks don't work in the common repo even if we upgrade the react version.
Treat the component package as its own project. It should have its own package.json that declares its dependencies.
It sounds like you are trying to develop the component package at the same time you develop the other projects that use them. Instead, you should develop the component package in its own environment. If you find problems or think of new features to add to the component package while you work on a project that uses it, create new issues for the component package project and work on them there.
The projects that use this component package should declare a specific version (either by a tag or a commit) which they use. Upgrading to a new version of the component package should follow the same process as upgrading versions of a 3rd party package, such as React itself.

lerna monorepo package structure

I am building a monorepo for a suite of React apps, and common library code. One of the packages would be a component library.
packages
app1
app2
common-ui
alert
button
I'm pretty new to the whole React/node ecosystem.
I've looked at a lot of actual UI library examples - react-bootstrap, material-design-components-react, etc.
It seems I would want to have each component in the common-ui lib to be distributed as single files, so that they can be cherry-picked when imported into a consuming app.
react-bootsrap does this by using babel to build the "lib". They build into a browser distributable, a commonjs lib, and an ES lib.
material-design-components-react does this by having their component lib itself by a lerna monorepo, with each component having its own package.json, and I believe they use webpack to build each component individually.
So my first question is,
Is a structure like material-design-components-react in my common-ui folder - kind of a monorepo within a monorepo possible?
Or would I have to restructure:
packages
app1
app2
alert
button
My second question is,
Which design is recommended by the community for a component library within a major monorepo? This must be a common structure developers have to solve when they have many client apps with common libraries. A package per common-ui component seems like a lot of overhead, but of course they have scripts to help out.
Is a structure like material-design-components-react in my common-ui
folder - kind of a monorepo within a monorepo possible?
Yes it's possible. But keep in mind, you and those libraries have very different requirements. You can think of your monorepo as small projects developed in same company., which are depending on similar 3rd party libraries and they follow same linting, testing etc.
Which design is recommended by the community for a component library
within a major monorepo? This must be a common structure developers
have to solve when they have many client apps with common libraries. A
package per common-ui component seems like a lot of overhead, but of
course they have scripts to help out.
First structure with 3 packages is most common way to start your repository/project.
In your case, I wouldn't recommend to divide your ux-library into single files. Your apps will likely use most of your ux-library and probably you won't have as much components as material or bootstrap has. Moreover, if you'd ever reach that point in your library, you can separate them later. For reference you can also check how lodash is publishing each of their functions. It's not different than your case (assuming you won't publish any fonts/images etc.).

Can react js web code be used for building mobile apps using react native?

I am working on a pet project ( web application ) and I was wondering if I should use react because it would be easy to create native apps from this code (in future if I need to).
And if the answer is yes, what are the best practices to follow for
most resuse?
If the answer is no, can you recommend an alternative?
Some more information about my situation.
I am relatively new to react and my alternative will be good ol' html with bootstrap and jquery. I am considering using asp.net mvc and web api.
Sharing app logic between a React Web app and a React Native app, while keeping the individual component rendering unique to each platform is possible!
In my opinion, it is a great option we have available. I will give you an overview of the approach and a few advices.
In an ideal world, we would be able to share 100% of the code. As far as I know, that isn't possible, but still we can share a lot of the code. Although React Native is like React, it is very important to note that the rendering code is different. Instead web things like <div> or <span>, you use React Native components like <View>, <Text> and other built-in components.
However, the business logic in most cases is just JavaScript though and that's one of the important things which we can share!
The plan
Based on the Flux architecture you are using, it would mean that your store(s), reducers, actions would be shared code, as well as most of the business logic (inside services or whatever) and the constants and utilities too.
The UI layer would then be written specifically for each native platform using React Native and for web using React. Not only because it’s necessary to replace the HTML elements with React Native components, but also because the components will probably have a very different behavior on the mobile app.
Some General Guidelines / Advices
Consider a good architecture and code structure in order to share as much code (and application logic) as possible. Try to separate the UI presentation components (which will be different for each platform).
Take a look at the JavaScript Environment specifics in the React Native docs. When using React Native, you're going to be running your JavaScript code in two environments:
On iOS simulators and devices, Android emulators and devices. React Native uses JavaScriptCore which is the JavaScript engine that powers Safari. On iOS JSC doesn't use JIT due to the absence of writable executable memory in iOS apps.
When using Chrome debugging, it runs all the JavaScript code within Chrome itself and communicates with native code via WebSocket. So you are using V8.
While both environments are very similar, you may end up hitting some inconsistencies.
Consider the different strategies for sharing the code. In order to accesses shared code, the apps you're building doesn't have to all live in the same codebase or git repository.
More realistically, you would have two or more projects hosted separately, so an npm package is one of the easiest ways to share code between them.
This is easy as making a new package and setting it as a dependency inside each of your projects. For the path to the shared project, you can use a git repository rather than pointing to a public package on npm.
Even though you're building only the web app now, you could spend some time thinking about how you could generalize some of the shared code, so it is easier to re-use it in future.
It's possible and viable. You must have a view for each platform (web/android/ios), because each one have your components..
The business logic must be out of the view. Use flux can easy your project with native, because the it move the api interaction to a data layer, letting the view be just a view.

React Native cross-platform codebase

Facebook has said that React Native builds on the principle of learn once, write everywhere, and that its goal is not to write cross-platform code.
NativeScript, which is pretty similar to ReactNative in the sense they both use Node.js, do offer the ability to share the same code over several platforms by writing platform specific code in files that uses native components that cannot be shared. It does that by simple naming convention, e.g foo.ios.js.
Since Facebook has not yet released their code for React Native for other platforms than iOS. Is this something they will likely support in the future?
I think there are far too many differences between Android, iOS and Web that it makes little sense to build common codebase for the whole projects. Android version will have not only native components, but also the logic of application screens and navigation will be different (iOS/Android/Web have all pretty different navigation patterns). Also there are many native components as part of the iOS/Android projects and they impact how application is started/debugged etc. so probably it is much better to keep Android and IOS parts as separate projects.
How I understand (and sympathise with) Facebok model:
Whenever there is a common functionality (in javascript) that you can separate out without dependency to react-native views, they will do it as separate component that can be reused across web/iOS/Android. For example they have relay library built for web Facebook. It abstracts away access to open-graph data on Facebook servers - the exact same relay library can be used in either environment as it has no dependencies to views, application logic and react as such.
I very much concur with that approach - the best way to do cross-platform is to follow the same practice:
make something work in one of the environments
make it separate, single-purpose library without dependencies to react, views, navigation logic.
use the library elsewhere
So the Android and iOS and Web react-based application for the same "project" will always be three different codebases, but they might have quite a lot of shared javascript code in form of reused libraries.

Resources