Building an NPM package that serves both React and React Native - javascript

We are building an NPM package called Chat for a company project. It is based on a Redux reducer and Firebase.
For both web and RN the use is:
<Chat
userName={user.userName}
password={user.password}
avatarUrl={user.avatarUrl}
defaultAvatar={defaultAvatar}
defaultGroupAvatar={defaultGroupAvatar}
name={user.name}
/>
However there are differences between web and mobile:
Dependencies: RN requires react-native and other RN packages, while web requires react-textarea-autosize and other web packages. Needless to say, installing React Native's packages for web is quite an overhead.
Compilation: RN can work with ES6 but web requires babel to transpile to JS.
We thought of two different ways to go about it:
Creating a base package with the common code: reducers and utils, and then create two additional packages for web and mobile components.
Placing the dependencies from package.json in peerDependencies.
Both ways have their downsides. The first one creates a clutter of packages and the second one means the package.json is not descriptive. Any better way to go with it? What is the proper way to build cross-platform React NPM packages?

Related

When Do I Need To Use Compile or Webpack To Create React Ui Libraries?

I would like to develop a UI library using React (without CRA) with Webpack 5, Ts, Storybook, and Third Party Libraries and publish to NPM, and parts of the library components should know how to render SVG as props from the consumer app or in the design of the component.
I saw a couple examples, and they made me very confused. The different guides that I follow build a simple component called a button, and publish it to NPM.
In the first guide, the components were created, then compiled with TS, exported to NPM, and used in a React app created with CRA.
In the second guide, Webpack was used to create the dist folder, then it was published to NPM. And he imported the Button components and used them without any issues.
If you could share with me any knowledge from your experience, what kind of problems can come up, thanks.

Export multiple NPM packages from single directory

Suppose a Node app which is a "micro-UI". So it has its own UI components, maybe some Redux stuff, some classes to make API calls, etc.
I have need to export some part of this repo for consumption in other micro-UIs:
API classes should be exported as my-project-api NPM package.
UI things (React router, Redux stuff, UI components, API classes, etc.) should be exported as my-project-ui NPM package.
In other micro-UIs where I need the API classes from this repo (but not the UI components), I'll install my-project-api via NPM.
In the "main UI" project which gathers all micro-UIs and build a single SPA from them, I'll install my-project-ui via NPM.
So, my package.json needs to support publishing multiple package (e.g. the name field needs to be flexible). How can this be accomplished without splitting the API source from the non-API source?
I think the answer is likely to split out the API components / UI components into their own packages in the same repo. But I'm wondering if there's another way.

Publish Aurelia component on NPM?

We have built a small-ish application using Aurelia, and would like to be able to integrate the app into a larger codebase. For example, it may be desirable to publish the Aurelia app on NPM, so other projects could integrate our code.
How can we build/publish the Aurelia app, so that it can be instantiated in a larger JavaScript application?
Typically, you wouldn't publish an entire Aurelia application to NPM, rather you would push plugins to NPM.
The simplest way to learn how to do this is to follow the example of the various Aurelia repos. We build the code in to multiple formats, but the most important are AMD and CommonJS (which is more important for your company is dependent on what tooling your company is using). Once you've built the code, the next step is to make sure your package.json file is set up correctly. It's best to copy the example of what we're doing in our own repos.
I would start by looking at either the dialog plugin or the templating-resources plugin. Both of these show good examples of how to publish your Aurelia plugin to NPM, whether it is a public or private npm feed.
https://github.com/aurelia/dialog/blob/master/package.json
https://github.com/aurelia/templating-resources/blob/master/package.json
Both of these plugins are set up to support Webpack, JSPM/SystemJS, and the Aurelia CLI out of the box.
I totally agree with #Ashley in not publishing larger applications to the global NPM registry. The big advantage of it is the simplicity of all that small packages which can be used to build large applications.
If you feel you got some reusable code, put in an own package and publish it.
Anyway, to give you an answer which does not require you to publish your complete app: you can include a complete repository (which is probobly what you are lookig for) in a different application via NPM.
npm install git://github.com/somegit/hubrepo.git
Or directly via the package.json:
"dependencies": {
"private-repo": "git+ssh://git#github.com:somegit/hubrepo.git#v1.0.0",
}
You can also do something similiar e.g. using JSPM. This would be simply:
jspm install your-app=github:OrgOrUser/your-app#your-branch
If you are facing long relative paths in your imports now, depending on your tooling, you may be interested in something like e.g. Resolving require paths with webpack which shows how to alias relative paths.
Sources/Links:
How to install a private NPM module without my own registry?
npm install private github repositories by dependency in package.json

NPM: should I use one of my dependencies' dependencies, or should I explicitly install it into the project at the root level?

TL;DR Summary
(I'm using Lodash as an example here, but it could be any other package)
In addition to using Lodash for its own purposes, my application also needs to import JavaScript from an NPM package that I created. The JavaScript in this package relies on Lodash as well. It's possible that each codebase may have installed a different version of Lodash. If JavaScript in my application and JavaScript in the installed package both import the same Lodash functions, then I want to avoid having to bundle two different versions of the same function. I understand that NPM is able to resolve the dependencies and that nothing will break, but the size of my application's JavaScript bundle will continue to grow as each codebase uses functions from different versions of the same libraries. It sounds like the only way to keep the versions in sync is to continuously monitor them and upgrade manually when appropriate, or to use the version provided by the installed package directly, without ever installing it into my application's own package.json. Is doing the latter a bad idea and is there no better way?
Original Question
At my company, we've created a Git repository that houses most of our UI component code. This repository also contains a static site generator, which transforms our UI component code into a "living style guide" website. The purpose of this website is to document and showcase our UI components on the web (similar to how PatternLab works).
We also distribute this code via NPM, so that it can be shared across multiple projects. Each project installs the NPM module as a dependency, then imports the SASS and JavaScript files contained within. The JavaScript has been written in ES6 and has not been bundled or transpiled. We've intentionally chosen not to distribute browser-ready code. Instead, each project is responsible for compiling its own SASS and bundling/transpiling its own JavaScript.
Most of our UI component JavaScript is simple and does not depend on any third-party libraries, so it's easy to import into our projects. However, some of our newer, more complex components rely on NPM packages such as Lodash, which presents a problem.
Obviously, we need to install Lodash in order for the static site generator to showcase our Lodash-reliant components inside of a web browser. Similarly, projects that consume the NPM package will also need to install Lodash, in order to create instances of these same components. This forces us to install Lodash twice: once in the UI component project, then again in the project that consumes the NPM package. This is problematic because the two projects could potentially install different versions of Lodash, which could lead to compatibility issues and/or increase the size of our JavaScript bundle.
One solution that I've discovered is to include Lodash under dependencies instead of devDependencies, in the UI component project. This way, when external projects install the UI component NPM module, Lodash will be installed along with it. This gives the project "free" access to Lodash without needing to explicitly install it itself. This is possible because NPM installs packages in a single, flat directory hierarchy, so it doesn't seem to matter if your project installs a package directly or if one of its dependencies exposes it as a dependency in it's own package.json. This eliminates version conflicts, since you don't have to install the package twice.
My question is, does this violate NPM best practices or is this how NPM is intended to work? After reading the NPM documentation and Googling for answers, it doesn't seem like this should be a problem. However, if what I'm suggesting is a bad idea, how else can I accomplish what I'm trying to do?
Here's a quick visual aid:
main.js
node_modules/
lodash/
foo/
bar.js
node_modules/
lodash/
main.js imports and uses Lodash. It also imports foo/bar.js, which uses Lodash too, but a potentially different version. Both files are ES6. main.js gets bundled and transpiled before being sent to the browser.
if is something you are directly using you should specify it in your package.json. it will be installed anyways but this way it will ensure that if your dependency removes that package as a dependency your project won't break

Setup ReactJS environment

I am new on ReactJS and learning from scratch. I see some using babel and some are webpack to configure as well some use yarn package manager. So can you suggest me which is better to work with react.
I just curious about configuring reactJS environment thorugh which bundle or package manager?
babel is a transpiler, webpack is a bundler and yarn (or npm) is a package manager. These tools are for different purposes. And usually we use all of them together.
React has a very handy tool called Create React App. With this tool you don't need to configure babel and webpack by yourself so you can start to learn React easily.
You can start working with react using create react app(along with official react documentation) which will provide you app structure with no build configuration. So there is no need to worry about babel, webpack. you will get all configured with proper documentation. It's up to you to use yarn or npm as package manager.
This is best place to start up with ReactJS
In older versions you need to setup react with babel and webpack but now on current latest version you can directly start with Create React App
ReactJS Installation and startup guide
Just follows steps on this page, then run HelloWorld example which is best programs to start with any new programming language.

Categories

Resources