I’m learning about React and plan to use Firebase and Firebase Functions in an app. When I create a React project I am given a package.json file.
If I add Firebase Functions to the project I am given a second package.json file in the functions folder.
Is this advisable or does it create a specific issue?
If two files is ok, where would you add future scripts?
it's completely fine to have multiple package.jsons in a project so long as they aren't at the same level in the directory
your use case sounds like it's correct to use both but just remember to install future packages in the correct one. You should keep the firebase functions one inside /firebase-functions package and then only install firebase function related stuff
in your other directory use this for installing node_modules you will use for your project. and remember you will need to install firebase in this package.json as you'll be using it in this project
again for future scripts, just add them to the relevant directory
Related
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)
I created a React component and uploaded it to a private git repo. It's a fairly simple component that renders a data table that can be sorted etc. I used nwb to for the setup / build process (https://github.com/insin/nwb).
It's not published on npm, so when I want to use it on a project I install via something like npm install --save git+ssh://git#github.com/Me/myRepo.git. This all works fine in normal React projects.
Unfortunately on a NextJS site I'm working on, NextJS won't compile, and is giving the error CSS Modules cannot be imported from within node_modules and linking me to https://nextjs.org/docs/messages/css-modules-npm
That page suggests that I might be accidentally using the package's source files - but I'm not. When I look in my /node_modules/myComponent/ folder, there's a /lib/ folder that has the compiled source. However, the styles are still in separate files and are included into the compiled source just like you might normally do (var _defaultModule = _interopRequireDefault(require("./styles/default.module.scss"));).
I did some searching online and it seems like the "quick and easy" solution is to use https://github.com/martpie/next-transpile-modules.
I'd prefer to solve this by fixing my repo though, so that when I install it on a project (whether NextJS or whatever) I get whatever it is that NextJS wants.
So my various questions are:
Is there a way to set up my repo so NextJS is happy with it?
Is nwb not the preferred way to make a React component? Should I have used some other process? I'm not having this problem with any other component, so it seems like this is something I did wrong with my repo.
How do I set up a Create React App to make a single myApp.js and myApp.css file that can be moved where ever I need?
Background:
At my work we have two older websites in need of updating and both have a React app inside the multi page site. The React apps use Create React App. Not my choice of configuration, this is just what I have to work with and I can not change everything.
Currently, when small changes are made to the site we build the bundled a take the final myApp.js and myApp.css files the CRA produce and moved these to the folder where the website expects them to be.
It might be easier to understand it this way. The app builds the .js|.css bundle files here:
../appA/someFolder/build/static/main.js and ../appA/someFolder/build/static/main.css.
These files are then moved to here:
../appA/hostThisSite/someFolder/js/main.js and ../appA/hostThisSite/someFolder/css/main.css
And for the second website it does the same yet moves the file to a whole other website structure
../../appB/hostThisSite/someFolder/js/main.js and ../../appB/hostThisSite/someFolder/css/main.css
Currently we need to update the React app. And to do so I need to address that the new Create React App creates a bunch of files in the /build/static/ folder (and they include hashes in the name and not myApp.js and myApp.css.)
I have done research and the only thing I have come up with is this:
https://www.labnol.org/code/bundle-react-app-single-file-200514
And the boss doesn't want me to use gulp.
This is a known issue in create-react-app, several proposed solutions in https://github.com/facebook/create-react-app/issues/5306 that involve using npm packages such as react-app-rewired or craco.
Another answer to this question with two possible solutions, one with eject another with react-app-rewired https://stackoverflow.com/a/58570278/388038
I have been trying to come up with an elegant solution to share code between two projects that are closely related to each other.
I have a React web app which simply includes all of the client code and I have an Express app which serves the React web app, but it also acts as an API. Because I use Typescript for both projects, I want to reuse some types. To accomplish that, I created a shared project.
My current folder structures is as follows:
web-app
shared
server
Now I want to link the web-app and server projects with my shared project, but there are some restrictions:
This shared folder should not be uploaded to npm.
I have to be able to still deploy everything with Heroku (which rules out npm link I believe).
I would prefer not to eject my React project.
I am not sure whether my current structure of projects allows the functionality I need, so feel free to also suggest other folder structures.
You can use yarn workspaces for that kind of purpose,
There's a minimal working boilerplate I have created exactly for that kind of configuration:
https://github.com/rok-tel/ts-express-react
take a look at ./packages/shared folder which is consumed both by server (express) and client (react)
Consider use Nx - https://nx.dev/
This is an awesome framework to manage monorepos.
Use their React application boilerplate for the client side project
Use their express project boilerplate to create the API
Use their shared code package boilerplate to create shared code package
Docs for creating the shared code package:
https://nx.dev/l/r/tutorial/07-share-code
If you are using create-react-app to create the web-app then you can easily use NODE_PATH environment variable to do absolute imports without creating node modules.
Create a .env file at the root level (same level as package.json of web-app directory)
Set an environment variable, NODE_PATH to shared/ (NODE_PATH=shared/)
Now instead of doing something like
import { editUser } from ‘../../../shared/actions’;
you can use
import { editUser } from ‘shared/actions’;
Fixing ESLint
Install eslint-plugin-import to prevent eslint from throwing import errors. And update your .eslintrc file as
{
"settings": {
"import/resolver": {
"node": {
"moduleDirectory": ["node_modules", "shared/"]
}
}
}
}
Fixing Flow
Add the following content to your .flowconfig file
[options]
module.system.node.resolve_dirname=node_modules
module.system.node.resolve_dirname=shared
How do I add these JS packages to a meteor project? Do I simply place the JS files in the public folder so the client and server can access them? Or is there some specific steps that I need to follow?
These kind of standalone libraries can be directly placed in the /lib directory under your project.
For use on both the client and the server, place them into project/lib folder.
Or if you want to use them only at client-side, place them as usual in project/client/lib
In short, It depends.
I would recommend you check out http://atmosphere.meteor.com for a list of packages. If what you're looking for is there, install meteorite with npm install -g meteorite (https://github.com/oortcloud/meteorite)
Once you have metorite installed you can install these community packages quite easily using mrt add packagename
Most packages are on http://atmosphere.meteor.com.
But if for some reason the JS package you want isn't on atmosphere, depending on the package, if its a UI package (e.g datepicker, etc) put it in the /client/lib folder to avoid meteor crashing (only accessible by client).
If its a type of module abstractor (e.g backbone - backbone is included in meteor already btw: add using meteor add backbone) you could put it in the /lib directory of your package, it will be referenced automatically by both the server and client.
You have to add the packages via console.
Type "meteor add accounts-password" for example.
See here
Perhaps you should watch some of these videos here
to get an idea how meteor packages are added.