What does <package-name>: "workspace:^" mean in package.json in yarn workspaces - package

Often, in the IDE when people are developing a package, I see that they have a package.json file.
In the package.json file, it will look something like this. (fyi, using yarn workspaces)
name: <name-of-package>
version: <version-of-package>
dependencies: {
"name-of-package": "workspace:^"
}
What exactly does "workspace:^" mean? Is it to reference the latest version of a a package that is within your repository?
For example, if you have a folder structure like this.
packageA/
...
package.json
packageB/
...
package.json
In packageA, you want to use packageB, but you want packageA to always pull the latest version of packageB without manually bumping the package.json in PackageA. To achieve this, you use "packageA": "workspace:^"
Thank you all!

Related

How to share react component across multiple projects?

I have few react components in a project that I would like to use in another few react projects. What would be the best way to share the components across the projects ? I know that we could use something like bitly to do it but is there any other open source way like git submodules to share the components across multiple projects.
One way that worked for me is to define a component in a React app (using create-react-app), bring that whole React app to Github, and npm install it as a dependency. I highly encourage you to check out this resource which explains in detail how to prepare a React component for this process. Follow the steps in the linked tutorial up to #3, then bring everything (including the /dist folder) to Github. Then, do npm install org_name/repo_nameand install it as a dependency in your second React app. Then, to import a specific component, you can do something like import { Button } from 'repo_name/dist/index' or reference whatever file you used to export your components.
In case the link doesn't work, here are the steps in the article:
Create a folder called lib that stores all the components you want to bring to the other react app. Also define a file called index.js in this folder that exports these components.
Create a repo for the components on Github
Install Babel and build the dist folder.(npm install --save-dev #babel/core #babel/cli #babel/preset-env and npm install -save #babel/polyfill)
Add the following config file to the top-level folder of your project:
{
"presets": [
[
"#babel/env",
{
"targets": {
"edge": "17",
"firefox": "60",
"chrome": "67",
"safari": "11.1"
},
"useBuiltIns": "usage",
"corejs": "3.6.5"
}
],
"#babel/preset-react"
]
}
In package.json, replace the build script with the following: "build": "rm -rf dist && NODE_ENV=production babel src/lib --out-dir dist --copy-files";
Run the command npm run build
There are multiple ways depending on your setup. As #Alex Wayne suggested the easiest way is to use a monorepo. If you setup does not allow it, you can publish a package to npm. If you can't or don't want to package a public package, you can publish private packages (with a payed account) or use a private package registry, such as GitHub packages (also payed for private packages). There are also self managed solutions for package registries if you want to safe some bucks in exchange for some work.
So going monorepo is an option, and so is creating and managing (and configs) many npm packages, but another option is to use an open-source tool like bit that decouples component development from a specific repo and handles stuff like packaging, configs, and dependencies for you.
Here are a couple of tutorials on how to share React components across multiple projects and repos in practically any architecture:
Video tutorial
Walkthrough with code
(I'm on the team building Bit, here are some of my own examples).
If you are using the webpack version 5 or above, you can use the concept of module federation. Or you could publish npm package for those shared components (But here you will have to manually upgrade the package any time you change the components).
Below links could help, have a look:
https://webpack.js.org/concepts/module-federation/
https://www.youtube.com/watch?v=d1SS7KAsbdY&ab_channel=KevinGhadyani-JavaScript

How to use Turborepo for an existing react app created with Create React App in order to make it a monorepo?

I have a fun project made with create react app. I want to convert the same application to a browser extension. This idea forces me to make the project a mono repo. Because in both applications, I will use the same components, hooks, providers, etc.
I don't want use Lerna or Yarn workspaces. And, this will be my first monorepo. I want to get start with Turborepo. However, I couldn't imagine how to make it work in a good way.
My targeted folder structure exists below
apps/
app1/
app2/
packages/
components/
hooks/
providers/
styles/
package.json
package-lock.json
I will import monorepo dependencies from packages folder into apps exists in apps folder.
For instance;
import { useExampleHook } from '#projectname/hooks'
import { ExampleComponent } from '#projectname/components'
If you have another solution besides Turborepo, don't hesitate to let me know. NPM workspaces is an acceptable solution as well. But, turborepo has the priority due to better performance.
Thanks in advance for your time and answer
TL;DR:
You can do this by using yarn workspaces to make the project a monorepo and then add turborepo to it as a dev dependency.
Steps:
Create a yarn workspace.
Configure your repositories root package.json file from step 1 as:
{
"private": true,
"workspaces": [
"packages/*",
"apps/*"
],
}
Now assuming from your example, you want to import files from packages/hooks into apps/app1, do the following:
//packages/hooks/package.json
{
"name": "hooks", // This can also be "#projectname/hooks" if you prefer
"version": "1.2.3",
...
}
//apps/app1/package.json
{
"name": "app1",
"version": "2.3.4",
"dependencies": {
"hooks": "1.2.3" //This version here must be same as the one in hooks package.json
}
}
// Some js file in apps/app1/...
import { useExampleHook } from "hooks";
...
Now if you want you should be able to install Terborepo to manage your monorepo. (Haven't personally tried this step but theoretically should work)
Tips:
Go through the yarn workspace docs and tutorials.
If you want to convert an existing react project into a monorepo, first transfer all your files to a folder such as root-dir/apps/app1 and then follow from step 1 inside root-dir.
Turborepo has great explanation on how to do it, right in their docs.
In short:
Turborepo is considered to be a taskrunner. So, it is added as a development dependency to your existing project.
npm install turbo -D
The only thing you should watch out tho is the turbo tasks itself.
So, you will have to tweak your start scripts and pipelines.

dependency tree error using create-react-app and storybook

TLDR:
how can I instruct storybook to use babel-loader v8.1.0 OR force react-scripts to use babel-loader v^8.2.2 ?
Details
I Develop a lib with ./example folder which is itself project created with create-react-app. I wanted to add storybook in addition to the normal example pages, so I installed storybook.
after installing storybook I can no longer start the example project with yarn start or the story book with yarn storybook.
There might be a problem with the project dependency tree.
It is likely not a bug in Create React App, but something you need to fix locally.
The react-scripts package provided by Create React App requires a dependency:
"babel-loader": "8.1.0"
Don't try to install it manually: your package manager does it automatically.
However, a different version of babel-loader was detected higher up in the tree:
D:\Eliav\projects\git projects\react-xarrows\examples\node_modules\babel-loader (version: 8.2.2)
Manually installing incompatible versions is known to cause hard-to-debug issues.
If you would prefer to ignore this check, add SKIP_PREFLIGHT_CHECK=true to an .env file in your project.
That will permanently disable this message but you might encounter other issues.
To fix the dependency tree, try following the steps below in the exact order:
1. Delete package-lock.json (not package.json!) and/or yarn.lock in your project folder.
2. Delete node_modules in your project folder.
3. Remove "babel-loader" from dependencies and/or devDependencies in the package.json file in your project folder.
4. Run npm install or yarn, depending on the package manager you use.
well I know what the issue but I don't know how to fix it:
I'm using react-scripts v4.0.3 which for unknown reason requiring exactly babel-loader v8.1.0. i can see this it in yarn.lock:
react-scripts#^4.0.1:
version "4.0.3"
...
dependencies:
...
babel-loader "8.1.0"
and storybook requiring babel-loader v8.2.2 or above:
"#storybook/builder-webpack4#6.2.9":
version "6.2.9"
...
dependencies:
...
babel-loader "^8.2.2"
already tried
what is written in the error above.
hoped that yarn upgrade would upgrade babel-loader from v8.1.0 to v8.2.2 but it does not work because react-scripts require exactly v8.1.0
a workaround that worked
Create a .env file in your project directory and include SKIP_PREFLIGHT_CHECK=true in the file.
but I want to avoid it. is it possible?
So for anyone to whom this is still unclear.
I used create-react-app to create a new app
I added storybook using npx sb init
then they clashed.
SOLUTION:
yarn add babel-loader#8.1.0
UPDATE:
The error you often see is that CRA (create-react-app) relies on specific dependencies (e.g. for webpack or babel).
What can also be done is you specify which versions those dependencies must resolve to, based on the error messages
This can be done using the resolutions field in package.json, e.g.:
"resolutions": {
"babel-loader": "8.1.0",
"webpack": "4.x.x",
}
After this all will work Fine.
2 Links to consider https://github.com/facebook/create-react-app/issues/10123
and https://github.com/storybookjs/storybook/issues/4764#issuecomment-740785850
Seems that most people are installing the package to get it to work even thou it says not to install in manually.
So try:
yarn add babel-loader#8.1.0

What is the purpose of each file in the React Native file architecture?

I started to use React Native recently and, following the oficial docs, I initialized a project using npx react-native init ProjectName.
I'm not sure if the tools versions matters (probably yes), but i'm using npm version 6.13.7, react-native-cli version 2.0.1 and react-native 0.62.2. With that config, the file architecture i that get is the following:
I seached about it, but i not found an answer. So, can someone please explain to me what is the purpose of each file in this file architecture and which of these files can i remove?
Thank you in advance :D
Package.json
This file holds all of the dependencies of modules that your app is using and needed to install for running your app.
yarn.lock files yarn and package-lock.json
These two files hold the version of your dependencies yarn.lock package-lock.json is automatically generated for any operations where npm or yarn modifies either the node_modules tree or package.json. It describes the exact tree that was generated, such that subsequent installs are able to generate identical trees, regardless of intermediate dependency updates.
app.json
This file holds your application name etc.
babel.config.js
This file holds configs related to babel, Babels is a transpiler that transpile ES6 to ES5.
index.js
This is the entry point of your application form where your react-native code start executing.
EsLint and Prettier
These file related to maintaining the code indentation, Unused imports, extra, spacing, these files holds configs related to these things(EsLint and prettier are used to avoid above-mentioned things).
.watchMan
watchman watches the code changes when the packager is running, so this file have configs about this.
.Flow
Flow is been used for type checking so it holds the configs related to this.
node_modules
This folder holds all of the modules that your app is been using also lited down in your package.json.
And then there is Android(which holds native android code), IOS(which holds native ios code), and other JS files which holds code react-native js code.

Package dependencies in NPM and Bower

First time user of npm and bower. I am able to install packages correctly but I am not sure how the dependencies work? As an example, I did "npm install angularjs" in my application root which created a folder "node_modules/angularjs/" with some files in it. I can also see that there is a package.json file within the angularjs folder, and it looks like it has not been processed as there is numerous packages listed in it and not installed.
Long story short, should I install all these packages manually or is there a built in feature that npm/bower can also process these sets of dependencies?
UPDATE:
I greatly lack the ability to ask precise questions, I apologise to those who have answered and did not give the correct sypnosis.
What I expect to happen:
Using npm or bower, I want to clarify that if I do an install of one of their packages, will it automatically also install the new package's dependancies or would I need to do a npm/bower install for each of the packages.json or bower.json files manually?
What I did to try make it work:
Created folder D:\Websites\TestSite
Within the folder through CMD, I did a "npm init" and ran through the guide
I followed that up with a "npm install angularjs"
A new folder was created D:\Websites\TestSite\node_modules\angularjs and within this folder there was a "index.js" and package.json file
Opening index.js I get a "require("angular");" and module.exports = window.angular.
The package.json file contains a number of dependancies which has not been installed.
My Result:
As per my expectations, npm install in point 3 above did not install the dependancies of the package.json file after it installed angularjs.
I am not sure but I assume that the index.js file needs to be included in my html and that it required the requirejs library initiated? If this is the case, then requirejs (which I do not have installed on my site) should be a dependancy for angularjs to work, and should be installed prior to giving me the ability to try and initiate it?
Am I missing a step or misunderstanding the functionality of NPM/Bower? Thank you for your patience!
Npm and Bower are great tools for managing your dependencies, i'll try to make it clear in a few words.
In general npm is used for managing your back-end dependencies and Bower is responsible for your front end dependencies.
There are 2 config files:
package.json, here are listed your dependencies that are not used in browser(e.g. bower, grunt). To install all dependencies in package.json run npm install.
Bower.json, here will be listed your "in browser" dependencies(e.g angular, jQuery). Run bower install to install all dependencies listed here in bower_components
You can find a extended guide i wrote here.

Resources