viewstools / yarn-workspaces-cra-crna Goto Github PK
View Code? Open in Web Editor NEWHow to use yarn workspaces with Create React App and Create React Native App (Expo) to share common code across
How to use yarn workspaces with Create React App and Create React Native App (Expo) to share common code across
This post is on medium too!
FYI this link in the README links to https://medium.com
For example, adding a tsconfig.json (as a Project Reference in Typescript 3) causes this Metro error:
Root has to be a valid directory
. Looks like glob
isn't correctly excluding files (despite the trailing slash).
I am trying to use yarn workspaces together with React Native. Previously, I was using [email protected]
, [email protected]
, and [email protected]
, and everything was working fine out-of-the-box. I didn't need a custom rn-cli.config.js
.
After upgrading to [email protected]
and [email protected]
, things are no longer working cleanly. The list of watched directories that Metro prints when it starts up no longer includes the root folder of the monorepo, and as such attempts to resolve "secondary" dependencies (ie. dependencies of dependencies, which yarn workspaces store in the root folder) fail.
I'm trying to use the metro-bundler-config-yarn-workspaces
package to rectify the situation. However, I'm getting an ambiguous resolution error when I try to use it:
error: bundling failed: ambiguous resolution: module `/Users/ashoat/Dropbox/src/Sites/squadcal/native/app.react.js` tries to require `react-native`, but there are several files providing this module. You can delete or fix them:
* `/Users/ashoat/Dropbox/src/Sites/squadcal/native/node_modules/react-native/package.json`
* `/Users/ashoat/Dropbox/src/Sites/squadcal/node_modules/react-native/package.json`
Perhaps the blacklist is misconfigured? Would appreciate any help I could get. If you'd like more details, the issue I posted on the metro repo has them.
Hi,
I've just tried or am trying to upgrade to Expo 31.0.0 and RN 0.57.
The metro config has changed as of this https://facebook.github.io/metro/docs/en/configuration.
I've tried to adapt to the new format like this in my rn-cli.js :
const getConfig = require("metro-bundler-config-yarn-workspaces");
const config = getConfig(__dirname);
module.exports = {
watchFolders: config.getProjectRoots(),
resolver: {
blacklistRE: blacklist
}
};
Doesn't seem to work ...
I'll fiddle a bit more but if anyone else has experienced the same please share.
/Stephen.
You can still install the 'metro-bundler' node module separately, but the bundle that gets created as part of CRNA currently puts the blacklist file under 'metro'
The blacklist import needs to be updated
const blacklist = require('metro-bundler/src/blacklist')
becomes =>
const blacklist = require('metro/src/blacklist')
does this only work with cra and crna or a pure react native project should work as well?
can we add docs for this config?
The paths returned from getWorkspaces are not platform agnostic, and break when running on windows builds. path.join will return correct platform agnostic paths, but these get corrupted by glob.sync.
So where path.join returns 'D:\\Users\\nickm\\Documents\\Code\\my-app\\core'
after being passed through globs it becomes:
'D:/Users/nickm/Documents/Code/my-app/core'
Which will not work on windows.
So I've been using this as the basis for a project using cra and crna.
Using the workspace_example provided running yarn test on the native project doesn't work (pretty obvious as it sitl points to ./node_modules/jest/.bin/jest.js which is now in the parent directory.
pointing to the jest file in the parent directory doesn't fix the issue as jest-expo preset is still using the native directory as it's root to find other modules.
Next level of fixing is to change the rootDir in jest. in the end I had to add the following lines to the package.json jest config.
"jest": {
"preset": "jest-expo",
"rootDir": "..",
"roots": [
"<rootDir>/native",
"<rootDir>/node_modules"
]
},
the roots are needed such that it doesn't try and run tests in all folders from the workspace but can still find node modules, however it then can't interpret es6 things anymore. This is where I'm stuck.
Good morning my friends
I'm having trouble using create-react-native-app on lerna using workspaces
Below I do the step by step, but we see that this way the node_modules folder in the package is not stored
It is necessary to have the node_modules folder in the folder in packages, because you have an android folder with requests to that folder
$ lerna info
System:
OS: Linux 5.4 Ubuntu 20.04 LTS (Focal Fossa)
CPU: (4) x64 Intel(R) Core(TM) i7-5500U CPU @ 2.40GHz
Binaries:
lerna: v3.22.1
Node: 12.18.1 - ~/.nvm/versions/node/v12.18.1/bin/node
Yarn: 1.22.4 - /usr/bin/yarn
npm: 6.14.5 - ~/.nvm/versions/node/v12.18.1/bin/npm
Utilities:
Git: 2.25.1 - /usr/bin/git
$ react-native info
info Fetching system and libraries information...
System:
OS: Linux 5.4 Ubuntu 20.04 LTS (Focal Fossa)
CPU: (4) x64 Intel(R) Core(TM) i7-5500U CPU @ 2.40GHz
Memory: 1.07 GB / 15.56 GB
Shell: 5.0.16 - /bin/bash
Binaries:
Node: 12.18.1 - ~/.nvm/versions/node/v12.18.1/bin/node
Yarn: 1.22.4 - /usr/bin/yarn
npm: 6.14.5 - ~/.nvm/versions/node/v12.18.1/bin/npm
Watchman: 4.9.0 - /home/linuxbrew/.linuxbrew/bin/watchman
SDKs:
Android SDK:
API Levels: 28, 30
Build Tools: 28.0.3, 30.0.0
System Images: android-30 | Google APIs Intel x86 Atom, android-30 | Google Play Intel x86 Atom
Android NDK: Not Found
IDEs:
Android Studio: Not Found
Languages:
Java: 11.0.7 - /usr/bin/javac
Python: 2.7.18 - /usr/bin/python
npmPackages:
@react-native-community/cli: Not Found
react: ~16.11.0 => 16.11.0
react-native: ~0.62.2 => 0.62.2
npmGlobalPackages:
*react-native*: Not Found
$ python --version
Python 2.7.18rc1
$ python3 --version
Python 3.8.2
$ npm list -g --depth 0
/home/marcio/.nvm/versions/node/v12.18.1/lib
├── @prettier/[email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
└── [email protected]
#
cd ~/Downloads
rm -fr ~/Downloads/monorepo-3
mkdir -p ~/Downloads/monorepo-3
cd ~/Downloads/monorepo-3
pwd && ls
echo '{
"version": "independent",
"npmClient": "yarn",
"useWorkspaces": true,
"packages": [
"packages/*"
]
}' >lerna.json
cat lerna.json
echo '{
"name": "root",
"private": true,
"workspaces": [
"packages/*"
],
"devDependencies": {
"lerna": "^3.22.1"
}
}' >package.json
cat package.json
lerna init
#
cd packages
npx create-react-native-app default-create-react-native-app --yes
# OR
# react-native init defaultreactnative
# clean
cd ..
yarn check --integrity --verify-tree || true
lerna list --all --long || true
lerna clean --yes || true
pwd && ls
rm -fr node_modules
find . -name "node_modules" -type d
find \
. \
-name "node_modules" \
-o -name ".yarncache" \
-type d -prune | while read ITEM; do
(du -sh "$ITEM")
(rm -fr "$ITEM")
done
find \
. \
-name "*.touch" \
-o -name "*error.log" \
-o -name "*debug.log" \
-o -name "*lock.json" \
-o -name "*lock.yaml" \
-o -name "audit-resolve.json" \
-o -name ".yarnclean" \
-o -name "yarn.lock" \
-type f | while read ITEM; do
(du -sh "$ITEM")
(rm -fr "$ITEM")
done
#
lerna init
lerna info
lerna list --all --long
lerna bootstrap
#
ls && ls ./packages/*
du -sh ./packages/default-create-react-native-app/node_modules/react-native-unimodules/gradle.groovy
du -sh ./packages/default-create-react-native-app/node_modules/react-native/react.gradle
du -sh ./packages/default-create-react-native-app/node_modules/expo-updates/scripts/create-manifest-android.gradle
du -sh ./packages/default-create-react-native-app/node_modules/@react-native-community/cli-platform-android/native_modules.gradle
#
I may be missing something but it doesn't seem to be working when there's multiple levels of dependencies between workspace modules. I.e. moduleA -> moduleB -> moduleC. ModuleA finds moduleB but moduleB can't find moduleC (where all modules are internal and located in packages
folder). Is this a use case that is supported? The issue seems to be that moduleB will look for the package relative to moduleA rather than from the packages folder. Here's some output to illustrate better:
Unable to resolve ../../native/src/shared/domain/schema/widgets" from ".//.../packages/components/widgets/text.tsx`: The module `../../native/src/shared/domain/schema/widgets` could not be found"
native
is the package where the crna app is located and where the app is started. The shared
folder is setup with a package.json and named 'shared'. Here's the import statement:
import { TEXT } from "shared/domain/schema/widgets";
Any chance some steps could be put together to get this working after ejecting?
I get a unable to resolve module error. npm start -- --reset-cache
does not fix nor the steps the error recommends.
Let me know thanks!
If you keep your individual packages in anything that's not top level, this approach doesn't seem to work.
// package.json
{
"workspaces": {
"packages": ["packages/*"]
}
}
// directories
package.json
|_ packages/
|_ native/
|_ web/
running yarn start
in the native
directory results in:
ENOENT: no such file or directory, stat '...PROJECT/packages/node_modules'
Metro Bundler process exited with code 1
moving native
and web
outside of packages solves this problem.
yarn start
yarn run v1.3.2
$ node link-workspaces.js
$ react-native-scripts start
20:00:09: Starting packager...
***ERROR STARTING PACKAGER***
Starting React Native packager...
ENOENT: no such file or directory, stat '/Users/hassankhan/Projects/workspace-project/packages/node_modules'
am I correct in thinking that the get-yarn-workspaces
package in this repo assumes forward slashes? I was unable to use get-yarn-workspaces
on windows as a result.
not sure if related to #28 it has a code snippet with executing yarn as a child process is a nice workaround but the pure js of get-yarn-workspaces
is kind of nice
In order to get my React-Native project running, I had to do two extra things that aren't written in the readme:
yarn add --dev metro-bundler
rn-cli.config.js
const getConfig = require('metro-bundler-config-yarn-workspaces')
module.exports = getConfig(__dirname, {})
Otherwise, I would get Cannot read property 'nodeModules' of undefined
.
I can sent a PR if these are legitimate issues and if they weren't specific to my use case.
Hi! 👋
Firstly, thanks for your work on this project! 🙂
Today I used patch-package to patch [email protected]
for the project I'm working on.
I use this pattern in my root package file:
{
...
"workspaces": [
"apps/*",
"packages/*"
]
}
I have some files in my packages
directory and get-yarn-workspaces
is picking those up as workspaces which breaks some downstream code.
Since workspaces are inherently directories, it makes sense to filter out non-directories.
Here is the diff that solved my problem:
diff --git a/node_modules/get-yarn-workspaces/index.js b/node_modules/get-yarn-workspaces/index.js
index bbacbcb..2803a6e 100644
--- a/node_modules/get-yarn-workspaces/index.js
+++ b/node_modules/get-yarn-workspaces/index.js
@@ -24,5 +24,5 @@ module.exports = function getWorkspaces(from) {
});
const packages = getPackages(require(path.join(root, 'package.json')));
- return flatten(packages.map(name => glob.sync(path.join(root, name))));
+ return flatten(packages.map(name => glob.sync(path.join(root, name)))).filter(w => fs.statSync(w).isDirectory());
};
This issue body was partially generated by patch-package.
Hello @dariocravero,
Thank you very much for this library!
I found something interesting:
when installing get-yarn-workspaces
, I get the following index.js
file:
const findRoot = require('find-root');
const flatten = require('flatten');
const fs = require('fs');
const path = require('path');
const glob = require('glob');
// as per https://yarnpkg.com/blog/2018/02/15/nohoist/ -
// "workspaces" can be an array or an object that contains "packages"
function getPackages(packageJson) {
if (!('workspaces' in packageJson)) {
return null;
}
const {workspaces} = packageJson;
if (Array.isArray(workspaces)) {
return workspaces;
}
return workspaces.packages || null;
}
module.exports = function getWorkspaces(from) {
const root = findRoot(from, dir => {
const pkg = path.join(dir, 'package.json');
return fs.existsSync(pkg) && getPackages(require(pkg)) !== null;
});
const packages = getPackages(require(path.join(root, 'package.json')));
return flatten(packages.map(name => glob.sync(path.join(root, name))));
};
You can see that the penultimate line
return flatten(packages.map(name => glob.sync(path.join(root, name))));
does not filter out files, unlike the version of this file on this repository:
return flatten(packages.map(name => glob.sync(path.join(root, `${name}/`))));
The package.json
files downloaded in my node_modules has the correct version, namely 1.0.2.
This caused some nasty bug which was very difficult to pinpoint: a README.md file in the workspace folder seems so innocent! 😄
Could you please inquire? It could be worth bumping the patch version and then publish it to npm.
If I can be of any assistance, please let me know. Thank you very much.
My application makes uses of server-side rendering and a express server.js file. Normally I would edit my package.js: "start": "node server.js"
But since "start": "react-app-rewired start"
is already used, how do I get this to run node server.js
instead of the normal react-scripts start
which I guess it runs after overriding the configuration?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.