Does now work with yarn workspaces? If so, what's the correct setup?
@TooTallNate Do Yarn workspaces require some sort of change on the platform end?
I'm struggling with this right now, the biggest trouble is that when you're deploying a workspace the dependencies of the root package.json aren't included:
root/
package.json # Shared dependencies here
workspace1/
package.json # workspace1 specific deps here
workspace2/
package.json # workspace2 specific deps here
now deploy workspace1/
# Build error: Cannot find dependency "shared-dependency"
This also means that when deploying workspace1 I don't have a yarn.lock in that folder, (that's the way workspaces work) so Zeit uses npm instead of yarn which means I get errors because I use package aliases. Ref #938
It'd be great if yarn workspaces were detected and yarn used.
Okay, I think I know how I'd want/expect this to work.
Let's say I have a monorepo with multiple microservices that structured as a yarn workspace:
root/
package.json # Shared dependencies here
yarn.lock # Shared lock file
now.json # Shared now config
server1/
package.json # server1 specific deps here
server2/
package.json # server2 specific deps here
now.json # server2 specific now configuration
yarn.lock # Duplicate deps that don't match the root version are in this optional lock file
Now from the root folder I start deploying server2:
now deploy server2/
Here is what now-cli should do in this case:
server2/ is a workspace in a monorepo by checking if there's a "workspaces" field in the package.jsonserver2/ folder locally (maybe we can directly use the same merging algorithm yarn uses somehow?)now.json configuration files, letting the more specific server2/now.json override the root oneserver2/ folder with the merged filesAm I making sense?
Note: This should also work if you're deploying from inside the
server2folder, sonow-cliwould move up a level and check if the parent folder has theworkspaceskey in itspackage.jsonand that the current folder is a workspace.
This should probably also work if you're deploying from inside the server1 folder, so now-cli would move up a level and check if the parent folder has the workspaces key in its package.json and that the current folder is a workspace.
It would potentially need to move up more than one level (until it reaches the root or a package.json with a workspaces key).
Anyway, I would love to know if now-cli plans to support workspaces. It would make managing microservices so much easier if we could use a monorepo format!
@Qix- @TooTallNate any hints as to whether this will be tackled sometime? It's fine if not, I'd just love to know :blush:
I'm going to have a go here as I need this for some mono-repo work we're doing.
Maybe some of the work at #3319 might help as well.
One of the yarn maintainers wrote on Twitter:
Yarn exposes some of its algorithms as packages, so everything is possible if you send a PR. You should definitely be able to reuse the root yarn.lock in a workspace in isolation, the extra resolutions will be ignored
Sounds good?
@mxstbr I really like your proposal of how this should be implemented
Hi guys I have the same problem while deploying apps with shared dependencies.
I am getting: Error! The build step of your project failed. To retry, runnow --force`.
I thought a following workaround could help:
But for some reasons, it always tries to either install or build the project even I leave the build step empty.
I've prepared a test repo for it: https://github.com/tomaswitek/next-workspaces.
I discussed it yesterday with @sergiodxa on a slack.
I tried everything @sergiodxa suggested without a success.
Can somebody help me pls?
Here is our whole conversation:
Tom Witek [11:57 PM]
Hi guys, is there a way how to build next app locally and just upload it to now?
sergiodxa [11:59 PM]
yes, just upload the ,next file and don't ignore it in your .gitignore or .npmignore (edited)
Tom Witek [12:01 AM]
@sergiodxa `now .next` ?
https://next-ssqxhaqfku.now.sh/
sergiodxa [12:01 AM]
no, upload your app code with the .next directory
you need the package.json
and any custom server code
Tom Witek [12:02 AM]
aaaaah ok
thx @sergiodxa
I guess also now.json should be included :wink:
sergiodxa [12:04 AM]
yes
Tom Witek [12:04 AM]
The original problem was that I have linked npm dependencies which can鈥檛 be buit on the server directlly, so I thought I鈥檒l build it locally and then just deplo it
sergiodxa [12:04 AM]
you need to upload everything + the .next folder
and don't have a build script or define an empty now-build directory
Tom Witek [12:12 AM]
@sergiodxa it stopped on ` Initializing鈥
sergiodxa [12:12 AM]
if you access the deployment URL with `/_logs` do you see logs?
did you got a deployment URL?
Tom Witek [12:14 AM]
no I didn't
I guess it gets stuck on installing npm modules
sergiodxa [12:16 AM]
:thinking_face: change the dependencies you can only install locally to devDependencies
and deploy with `NODE_ENV` as `production` on now.json or with `-e NODE_ENV=production`
Tom Witek [12:18 AM]
good idea let me try
OK man I give up, it鈥檚 still throwing errors on me and it鈥檚 too late. Anyway thank you for your help!!! (edited)
good night
Is there someone working on this?
If not, I can try...
@chabou yes please! I don't think anybody's working on this :pray:
@mxstbr I have a few questions to:
聽Merge the package.json and yarn.lock from the root folder with the ones in the server2/ folder locally (maybe we can directly use the same merging algorithm yarn uses somehow?)
1) There should be just one yarn.lock file. So there is no merging needed for this file right? We just need it for deployment.
2) Do you specify some dependencies in root package.json? Or what is the exact reason for merging package.json files?
@chabou is there already some branch open? Can I help?
I'd like to help if you need, so we can ship this :) @chabou
I use something like this until better support for workspaces is added:
"scripts": {
"deploy": "yes | cp ../../yarn.lock . && now -e NODE_ENV=production && now alias"
}
And add this copied yarn.lock to .gitignore.
you can use nohoist https://yarnpkg.com/blog/2018/02/15/nohoist/
@rauchg should this work with now v2? I tried but now tries to upload the whole monorepo instead of what I specified in the now.json:
{
"name": "myapp",
"alias": ["myapp.com", "www.myapp.com"],
"builds": [
{ "src": "packages/web/build/index.html", "use": "@now/static" },
{ "src": "packages/server/index.js", "use": "@now/node" }
],
"public": false,
"scale": {
"gru1": {
"min": 1,
"max": "auto"
}
},
"version": 2
}
scale is no longer necessary. Just regionspublic: false is always the default now@now/static-build@now/node-server. But most importantly, you probably want to break it down into smaller entrypoints instead, which is the recommended way (@now/node)@rauchg Thanks.
Sorry I was not clear at my issue description, but I just managed to make it work :)
Details below for reference.
It's a yarn workspace project. I have the following files:
- now.json
- packages
- server
- index.js
now.json
{
"name": "myapp",
"builds": [{ "src": "packages/server/index.js", "use": "@now/node" }],
"routes": [
{ "src": "/(.*)", "dest": "/packages/server/$1" }
],
"regions": ["gru1"],
"version": 2
}
packages/server/index.js
module.exports = (req, res) => {
res.end('It works!')
}
This worked great. It uploaded around 500b of files and showed It works! in the browser.
But my real project actually had more packages inside the monorepo, like the mobile one:
- now.json
- packages
- server
- index.js
+ - mobile
+ - android (huge folder)
+ - ios (huge folder)
+ - ...
When I ran the same now command with the same now.json:
Expected: Keep working as before. Upload 500b of files.
Behavior: it tried to upload hundreds of files and broke with File size limit exceeded (5 MB). It probably included the mobile folder, but that was not intended.
Adding packages/mobile to .nowignore solved it.
I also have a web project that uses create-react-app:
- now.json
- packages
- server
- index.js
- mobile
- android (huge folder)
- ios (huge folder)
- ...
+ - web
+ - dist
+ - src
Here's my final now.json that is working:
{
"name": "myapp",
"alias": "myapp.com",
"builds": [
{ "src": "packages/web/dist/**", "use": "@now/static" },
{ "src": "packages/server/index.js", "use": "@now/node" }
],
"routes": [
{ "src": "/api", "dest": "/packages/server/" },
{ "src": "/(.*)", "dest": "/packages/web/dist/$1" }
],
"regions": ["gru1"],
"version": 2
}
PS: /api is just for test purposes, I'll use small entry points later.
The only pending issue is that it only worked with @now/static. When trying @now/static-build I got build errors like Couldn't find the binary git, which may be related to this issue here (because of hoisted node modules due to yarn workspaces).
As you can see above, this works as of Now 2.0!
02/04 07:24 AM (1m) info No lockfile found.
@leo it's clearly not working?
@igl it's working for me, I have one yarn.lock file in the root of my project and no lock files in any of the workspaces.
@tim-phillips can you share a snippet of your now.json?
@igl Sorry, I鈥檝e only done this in a private project and I can鈥檛 share anything from that. You might want to make a simplified repo that reproduces this issue and post it to https://spectrum.chat/zeit/now
Here's a public repo, a barebones project for the moment: https://github.com/fillipvt/portfolio
It has yarn workspaces with 2 NextJS apps and 1 GraphQL implementation. The most recent push to production did work.
alright i will have to investigate the "No lockfile found" happening in my project.
How is this suppose to work with a multi app - monorepo? You'll get 1 project in Now, with 1 config at the root? We have a setup kinda like this:
root/
apps/
app-1/
next.config.js
app-2/
next.config.js
packages/
internal-package/
@fillipvt question for you... why do you need to treat shared-components as an actual BUILT npm package?
doesn't transpileModules: ['@fillipvt/components'], take care of doing all the "building" of that shared package when you run next?
Also have the same issue with @maraisr. Our set-up is like this
root/
apps/
api/ <-- not deployed to now
client/ <-- serverless app deployed to now
next.config.js
libs/
shared_stuff/
The issue is that the libs/ is not included in the files sync to now so they are missing during the build process.
now.json to the root but not enough{
"version": 2,
"routes": [
{
"src": "^/service-worker.js$",
"dest": "/_next/static/service-worker.js",
"headers": {
"cache-control": "public, max-age=43200, immutable",
"Service-Worker-Allowed": "/"
}
}
],
"builds": [
{
"src": "apps/client/next.config.js",
"use": "@now/next"
}
]
}
Running now results to a success but the deployed app is a directory listing and navigating to apps/client/ will open a site but the CSS paths are not working.
"now-build": "next build apps/client" with a root/now.jsonStill no
"now-build": "next build" insteadStill no
next.config.js to root folder.Doesn't work too
Ended up moving the shared folders to the client folder so they can by synced to now.
Most helpful comment
Okay, I think I know how I'd want/expect this to work.
Let's say I have a monorepo with multiple microservices that structured as a yarn workspace:
Now from the root folder I start deploying
server2:Here is what
now-clishould do in this case:server2/is a workspace in a monorepo by checking if there's a "workspaces" field in the package.jsonserver2/folder locally (maybe we can directly use the same merging algorithm yarn uses somehow?)now.jsonconfiguration files, letting the more specificserver2/now.jsonoverride the root oneserver2/folder with the merged filesAm I making sense?