Yarn workspace, react, monorepo issue with conflict library version - reactjs

I'm experimenting with yarn workspace monorepo. It is consisting of a TestProject created with create-react-app, and a SharedLib1 which is created with create-react-library. TestProject imports code from SharedLib1. The problem being, TestProject uses react-scripts 3.3.0 which is dependent on babel-jest ^24.9.0, while SharedLib1 uses react-scripts-ts ^2.16.0 which is dependent on babel-jest 22.4.4. When running yarn start in TestProject, it complains:
The react-scripts package provided by Create React App requires a dependency:
"babel-jest": "^24.9.0"
Don't try to install it manually: your package manager does it automatically.
However, a different version of babel-jest was detected higher up in the tree:
/monoRepo/node_modules/babel-jest (version: 22.4.4)
I could disable the error by setting SKIP_PREFLIGHT_CHECK=true in TestProject or manually upgrade the react-scripts inside SharedLib1, but I'd like to know if there's a better way of handling this.
myMonorepo
-web
-SharedLib1
-package.json
-TestProject
-package.json
-package.json
Package.json of myMonoRepo:
{
"name": "my-mono-repo",
"version": "0.1.0",
"private": true,
"workspaces": [
"web/*"
],
"nohoist": [
"**/babel-jest",
"**/babel-jest/**"
]
}
Package.json of myMonoRepo:
{
"name": "test-proj",
"version": "0.1.0",
"private": true,
"dependencies": {
...
"shared-lib-1": "^1.0.0"
}
}
And the test code App.tsx:
import React from 'react';
import TestComp from 'shared-lib-1';
import './App.css';
const App: React.FC = () => {
return (
<div className="App">
<TestComp text={'aaa'}/>
Learn React
</div>
);
}
export default App;
There is a babel-jest 24.9.0 inside the node_modules of TestProj and another 22.4.4 inside the node_modules of myMonoRepo

This is very similar, if not the same, to an issue opened on the GH repo for create-react-app and you may find additional information there.
That said, you might try moving babel-jest to a devDependency instead of a package dependency. If that does not work, you might try Selective dependency resolutions, where you can force your project to a specific version of babel-jest -
"resolutions": {
"babel-jest": "^24.9.0",
"shared-lib-1": "^1.0.0"
}

Related

yarn workspaces monorepo with vite, react, tailwind - VS Code fails to resolve packages

I have created a monorepo using yarn#3 workspaces.
My root package.json:
{
"name": "hello-yarn-workspaces",
"packageManager": "yarn#3.1.1",
"workspaces": [
"apps/*",
"packages/*"
],
"devDependencies": {
"#commitlint/cli": "^16.0.1",
"#commitlint/config-conventional": "^16.0.0",
"husky": "^7.0.4"
},
"scripts": {
"postinstall": "husky install",
"prepublishOnly": "pinst --disable",
"postpublish": "pinst --enable"
}
}
The package.json in apps/ui:
{
"name": "ui",
"packageManager": "yarn#3.1.1",
"scripts": {
"dev": "vite"
},
"dependencies": {
"react": "^17.0.2",
"react-dom": "^17.0.2"
},
"devDependencies": {
"#tailwindcss/forms": "^0.4.0",
"#types/react": "^17.0.38",
"#types/react-dom": "^17.0.11",
"#vitejs/plugin-react": "^1.1.3",
"autoprefixer": "latest",
"postcss": "latest",
"tailwindcss": "latest",
"typescript": "^4.5.4",
"vite": "^2.7.10"
}
}
I have created a component inside my apps/ui/src folder and when I run yarn workspace ui run dev, the app can be started in the browser.
However, when opening my monorepo in VS Code, it fails to resolve npm packages in import statements:
// Cannot find module 'react' or its corresponding type declarations.ts(2307)
import React, { ReactElement, useState } from 'react'
The same happens for the vite.config.ts in apps/ui
// Cannot find module 'vite' or its corresponding type declarations.ts(2307)
import { defineConfig } from 'vite'
// Cannot find module '#vitejs/plugin-react' or its corresponding type declarations.ts(2307)
import react from '#vitejs/plugin-react'
When opening the monorepo in WebStorm, everything is ok.
The repro repository can be found here.
Update: It looks like it is related to the PnP mechanism. I came across this question and setting nodeLinker: node-modules in .yarnrc.yml followed by yarn install fixed it.
However, the ansers for this question didn't work for me.
I get this error in VS Code after running yarn dlx #yarnpkg/sdks vscode:
The path /Users/alexzeitler/src/hello-yarn-workspaces/.yarn/sdks/typescript/lib/tsserver.js doesn't point to a valid tsserver install. Falling back to bundled TypeScript version.
The files in .yarn/sdks/typescript/lib actually don't exist but I have a file integrations.yml in .yarn/sdks:
# This file is automatically generated by #yarnpkg/sdks.
# Manual changes might be lost!
integrations:
- vscode
Looks like the missing pieces have been due to the PnP configuration:
yarn add --dev typescript ts-node prettier
yarn dlx #yarnpkg/sdks vscode
Add a minimal tsconfig.json:
{
"compilerOptions": {
/* Basic Options */
"target": "es5",
"module": "commonjs",
"lib": ["ESNext"],
/* Strict Type-Checking Options */
"strict": true,
/* Module Resolution Options */
"moduleResolution": "node",
"esModuleInterop": true,
/* Advanced Options */
"forceConsistentCasingInFileNames": true,
"skipLibCheck": true
}
}
Then install this VS Code extension followed by these steps:
Press ctrl+shift+p in a TypeScript file
Choose "Select TypeScript Version"
Pick "Use Workspace Version"
More details can be found in the docs.

Hooks and multiple instances of React in Gatsby app

I'm trying to use useState in a simple function component in GatsbyJS but I'm getting a seemingly common error in React.
My stripped-down component:
import React, { useState } from 'react';
export default function Header () {
const [isOpen, toggleOpen] = useState(false);
return (
<header>
<button onClick={() => toggleOpen( !isOpen )}>Click Me</button>
</header>
)
}
I get the following error:
Invalid hook call. Hooks can only be called inside of the body of a
function component. This could happen for one of the following
reasons:
You might have mismatching versions of React and the renderer (such as React DOM)
You might be breaking the Rules of Hooks
You might have more than one copy of React in the same app See redacted to quell SO error for tips about how to debug and
fix this problem.
So I read up about the error on this Facebook/React docs page and have determined that my react-dom version is >16.8.0 (I'm using ^16.13.1). My react version is the same.
I'm pretty sure there's nothing wrong with my component function (I basically copied the example from the docs).
The third thing, which I suspect is the issue, is multiple versions of react running simultaneously. When I run npm ls react I get:
+-- gatsby#2.24.73
| `-- gatsby-cli#2.12.107
| `-- react#16.13.1 deduped
`-- react#16.13.1
I tried moving react and react-dom to peerDependencies, as per this response from this Github issues thread, in my `package.json' but that didn't fix the problem, e.g:
"peerDependencies": {
"react": "^16.13.1",
"react-dom": "^16.13.1"
}
I also tried adding a GATSBY_HOT_LOADER = “fast-refresh” var in a .env.development file according to this Gatsby thread but the issue persisted.
require("dotenv").config({
path: `.env.${process.env.NODE_ENV}`,
})
Here's my package.json
{
"name": "gatsby-starter-hello-world",
"private": true,
"description": "A simplified bare-bones starter for Gatsby",
"version": "0.1.0",
"license": "0BSD",
"scripts": {
"build": "gatsby build",
"develop": "gatsby develop",
"format": "prettier --write \"**/*.{js,jsx,ts,tsx,json,md}\"",
"start": "npm run develop",
"serve": "gatsby serve",
"clean": "gatsby clean",
"test": "echo \"Write tests! -> https://gatsby.dev/unit-testing\" && exit 1"
},
"dependencies": {
"gatsby": "^2.24.73",
"gatsby-image": "^2.4.21",
"gatsby-plugin-sass": "^2.3.16",
"gatsby-plugin-sharp": "^2.6.40",
"gatsby-source-filesystem": "^2.3.34",
"gatsby-transformer-sharp": "^2.5.17",
"hamburgers": "^1.1.3",
"node-sass": "^4.14.1",
"react": "^16.13.1",
"react-dom": "^16.13.1"
},
"devDependencies": {
"eslint-plugin-react-hooks": "^4.1.2",
"prettier": "2.1.2"
},
"repository": {
"type": "git",
"url": "https://github.com/gatsbyjs/gatsby-starter-hello-world"
},
"bugs": {
"url": "https://github.com/gatsbyjs/gatsby/issues"
}
}
And environment info:
System:
OS: Windows 10 10.0.18362
CPU: (8) x64 Intel(R) Core(TM) i5-8300H CPU # 2.30GHz
Binaries:
Node: 12.16.1 - C:\Program Files\nodejs\node.EXE
npm: 6.13.4 - C:\Program Files\nodejs\npm.CMD
Browsers:
Edge: 44.18362.449.0
npmPackages:
gatsby: ^2.24.73 => 2.24.73
gatsby-image: ^2.4.21 => 2.4.21
gatsby-plugin-sass: ^2.3.16 => 2.3.16
gatsby-source-filesystem: ^2.3.34 => 2.3.34
I've been using Gatsby without issues for some time now so I'm surprised by this error. I suspect it has to do with Gatsby running a version of React, although "deduped", and another version of React also running as seen when I run npm ls react.
Where can I go from here?
Thanks,
I'm also using React#16.13.1. Notably, the gatsby-starter currently only uses React#16.12.1. I ultimately came across an answer from Jeremy Albright on the Gatsby Spectrum that pointed out this could be related to react-hot-loader being deprecated.
Gatsby already has support instead for fast-refresh, you just have to enable the flag.
The fix that worked for me was to add GATSBY_HOT_LOADER=fast-refresh to my .env file.
Source
So I ended up starting over and downloading a fresh copy of the gatsby-starter I was using and that's resolved the issue.
I think I inadvertently installed react and react-dom while I was trying to install a plugin at some point and having multiple versions of react running (one within gatsby) and one installed somewhere else in my project caused the issue.

Module is not installed in Monorepo

For a new project i am using Lerna and React Storybook. I want to create a monorepo with multiple packages.
My folder structure looks like this:
.babelrc
.storybook
package.json
node_modules
packages/
button/
.babelrc
node_modules/
package.json
index.js
theme/
node_modules/
package.json
index.js
I want to import the theme from the theme package inside my button package, which i install through npm in my button package.
In my button package i am importing the theme
import theme from '#company/company-theme';
and i get the following error:
Module not found: Error: Can't resolve '#company/company-theme' in buttonpath
At first i thought it was a babel problem and in the package.json i installed the following babel packages
"babel-cli": "^6.26.0",
"babel-jest": "^23.4.2",
"babel-plugin-transform-es2015-modules-commonjs": "^6.26.2",
"babel-preset-env": "^1.7.0",
"babel-preset-react": "^6.24.1"
And in the projectroot and the button root i created a .babelrc and added the following code:
{
"presets": ["env", "react"],
"env": {
"dev": {
"plugins": [
"transform-es2015-modules-commonjs"
]
}
}
}
The problem however still exists. Anyone here knows what to do?

React Storybook Fails on Demo

I'm attempting to use React Storybook in a project that already has an extensive Webpack 2 config. I started the Storybook following the basic steps:
npm i -g #storybook/cli
getstorybook
When I run yarn storybook, it breaks on the JSX of the demo component:
ERROR in ./stories/index.jsx
Module parse failed: /Users/alexanderhadik/project/web/node_modules/#storybook/react/node_modules/babel-loader/lib/index.js??ref--0!/Users/alexanderhadik/project/web/stories/index.jsx Unexpected token (9:55)
You may need an appropriate loader to handle this file type.
| import { Button, Welcome } from '#storybook/react/demo';
|
| storiesOf('Welcome', module).add('to Storybook', () => <Welcome showApp={linkTo('Button')} />);
|
| storiesOf('Button', module)
# ./.storybook/config.js 4:2-23
# multi ./node_modules/#storybook/react/dist/server/config/polyfills.js ./node_modules/#storybook/react/dist/server/config/globals.js ./node_modules/webpack-hot-middleware/client.js?reload=true ./.storybook/config.js
Since I didn't start this project originally using create-react-app - do I need to modify the Storybook webpack config to enable JSX?
This might to be a problem with Storybook not replicating webpack babelrc behaviour exactly.
In my case, I had an empty (just {}) .babelrc file with all the important react/jsx plugins defined in webpack.config.js. Storybook read the .babelrc instead of using the babel settings in webpack.config.js.
Deleting the .babelrc solved that issue.
in my case, i didnt have a .babelrc at all -- i used the entry "babel" in the package.json. when running the storybook in this project, the babel entry wasnt there. i added it and things magically started working.
{
"name": "root",
"private": true,
"devDependencies": {
"#storybook/addon-actions": "^4.1.11",
"#storybook/addon-links": "^4.1.11",
"#storybook/addons": "^4.1.11",
"#storybook/react": "^4.1.11",
...
},
"dependencies": {},
"scripts": {
"storybook": "start-storybook -p 6006",
"build-storybook": "build-storybook"
},
"babel": {
"presets": [
"#babel/preset-env",
"#babel/preset-react"
]
}
}
i hope this helps someone.

NPM + React + TypeScript with AMD modules

I'm trying to setup dev environment for app written in typescript using react.
I alreally have existing typescript code that compiles to ES5 and AMD modules.
I would like to avoid any js transpilation in the browser. Please notice, that I don't need to use babel to transpile jsx, since typescript compiles tags into React.createElement in tsx files.
I've done the usual:
npm install react -save
npm install react-dom -save
npm install typescript -save-dev
npm install typings -save-dev
typings install react --ambient --save
typings install react-dom --ambient --save
now, I have two questions:
how to correctly import/require the react and react-dom in my tsx files which compiles to ES5/AMD?
currently I'm just doing this:
/// <reference path="../../typings/browser/ambient/react-dom/index.d.ts" />
/// <reference path="../../typings/browser/ambient/react/index.d.ts" />
export class MyComponent extends __React.Component<any, {}> {
public render() {
return (
<h1>MyCompoentnt</h1>
);
}
}
however the compilations fails with error TS2304: Cannot find name 'React'.
how to include react.js and react-dom.js in my app? I quess some transpilation or browserification will be needed. Or should I just and them to index.html?
<script src="scripts/react.js"></script>
<script src="scripts/react-dom.js"></script>
<script src="scripts/require.min.js" data-main="scripts/app"></script>
here is my package.json:
{
"name": "myhtmlapp",
"version": "1.0.0",
"description": "react test app",
"main": "index.js",
"dependencies": {
"jquery": "^2.2.3",
"react": "^15.0.0",
"react-dom": "^15.0.0"
},
"devDependencies": {
"browser-sync": "^2.11.2",
"typescript": "^1.8.9",
"typings": "^0.7.12"
},
"scripts": {
"watch:typescript": "tsc --p ./appscripts -w",
"watch:css": "browser-sync start --server --files .wwwroot/css/*.css",
"compile": "tsc --p ./appscripts",
"test": "echo \"Error: no test specified\" "
},
"keywords": [],
"author": "",
"license": "ISC"
}
here is entire app: https://onedrive.live.com/redir?resid=51A46BBA4E9EF07E!263323&authkey=!AKQ6FqjE2W2YVBo&ithint=file%2czip
I am pretty sure there a several ways to do this. Below I am posting my way of getting things you have mentioned play together:
To import react I use standard import, like this:
import * as React from 'react';
import * as ReactDOM from 'react-dom';
export class MyComponent extends React.Component<any, any>
{
//...
}
To 'inculde' react into the application I use systemjs as module loader (due to some reasons that goes beyong the question I cant use browserify, but pretty sure it can be used to do the same). You will need to install systemjs via npm. Then instruct it to know where to look for react. To do this put the following script in your index.html:
<script src="systemjs/dist/system.src.js"></script>
<script>
System.config({
baseURL: './lib',
paths: {
"react*": 'react/dist/react-with-addons'
}
});
System.defaultJSExtensions = true;
</script>
Where react/dist/react-with-addons is a path (without '.js' extension) to the dist of react-with-addons.js. And systemjs/dist/system.src.js - path to systemjs dist.
Hope this helps.

Resources