Using pnpm workspaces in 2023?

Hello Netlify Support,

When deploying a site from my pnpm monorepo, the build fails to find the workspace package (5:59:28 PM: + vuetify-extra 0.1.8 <- ../../packages/vuetify-extra) from the same monorepo (full build log below)

I happen to have a pnpm monorepo, containing multiple sites, and a multiple shared libraries.
The full monorepo is located on GitLab, and linked to Netlify.

So, my approach is this one. Even though at this point, only one site is now being build.

The article continues to not mention pnpm workspaces, but I understand that pnpm workspaces are now supported (right?).

The site that’s being build is: apps/vuetify-starter, and these are the settings:

  • Netlify site name: charming-basbousa-02e955.netlify.app
  • Base directory: apps/vuetify-starter
  • Build command: pnpm run build
  • Publish directory: apps/vuetify-starter/dist

Furthermore:

  • I have no netlify.toml files (should I?).
  • There is a pnpm-lock.yaml at the root of the monorepo (only).
  • The site and package in question are git subtrees, but I doubt that is the issue.
  • I also notice that the build scope is much more than the site I’m deploying, it seems to be building packages not related to this site. (5:59:08 PM: Scope: all 6 workspace projects)

If feel that I may need to configure some additional settings?
Here is the full build log:

5:59:01 PM: build-image version: 0bc34a4ade77d89b410ec23c508464028dd4b785 (focal)
5:59:01 PM: buildbot version: 0bc34a4ade77d89b410ec23c508464028dd4b785
5:59:01 PM: Fetching cached dependencies
5:59:01 PM: Failed to fetch cache, continuing with build
5:59:01 PM: Starting to prepare the repo for build
5:59:01 PM: No cached dependencies found. Cloning fresh repo
5:59:01 PM: git clone --filter=blob:none git@gitlab.com:questr/vexna
5:59:02 PM: Preparing Git Reference refs/heads/main
5:59:04 PM: Parsing package.json dependencies
5:59:05 PM: Different publish path detected, going to use the one specified in the Netlify configuration file: 'apps/vuetify-starter/dist' versus 'dist' in the Netlify UI
5:59:05 PM: Starting build script
5:59:05 PM: Installing dependencies
5:59:05 PM: Python version set to 2.7
5:59:06 PM: v16.19.0 is already installed.
5:59:06 PM: Now using node v16.19.0 (npm v8.19.3)
5:59:06 PM: Enabling Node.js Corepack
5:59:06 PM: Started restoring cached build plugins
5:59:06 PM: Finished restoring cached build plugins
5:59:06 PM: Attempting Ruby version 2.7.2, read from environment
5:59:07 PM: Using Ruby version 2.7.2
5:59:07 PM: Using PHP version 8.0
5:59:07 PM: Started restoring cached corepack dependencies
5:59:07 PM: Finished restoring cached corepack dependencies
5:59:07 PM: pnpm workspaces detected
5:59:07 PM: Installing npm packages using pnpm version 7.13.4
5:59:08 PM: Scope: all 6 workspace projects
5:59:08 PM: ../..                                    | Progress: resolved 1, reused 0, downloaded 0, added 0
5:59:08 PM: ../..                                    |    +1169 ++++++++++++++++++++++++++++
5:59:08 PM: Packages are hard linked from the content-addressable store to the virtual store.
5:59:08 PM:   Content-addressable store is at: /opt/build/.pnpm-store/v3
5:59:08 PM:   Virtual store is at:             ../../node_modules/.pnpm
5:59:09 PM: ../..                                    | Progress: resolved 1169, reused 0, downloaded 30, added 30
5:59:10 PM: ../..                                    | Progress: resolved 1169, reused 0, downloaded 84, added 87
5:59:11 PM: ../..                                    | Progress: resolved 1169, reused 0, downloaded 138, added 140
5:59:12 PM: ../..                                    | Progress: resolved 1169, reused 0, downloaded 244, added 246
5:59:13 PM: ../..                                    | Progress: resolved 1169, reused 0, downloaded 393, added 393
5:59:14 PM: ../..                                    | Progress: resolved 1169, reused 0, downloaded 518, added 523
5:59:15 PM: ../..                                    | Progress: resolved 1169, reused 0, downloaded 625, added 637
5:59:16 PM: ../..                                    | Progress: resolved 1169, reused 0, downloaded 768, added 785
5:59:17 PM: ../..                                    | Progress: resolved 1169, reused 0, downloaded 922, added 937
5:59:18 PM: ../..                                    | Progress: resolved 1169, reused 0, downloaded 996, added 1014
5:59:19 PM: ../..                                    | Progress: resolved 1169, reused 0, downloaded 1119, added 1137
5:59:20 PM:  WARN  Local dependency not found at /opt/build/repo/apps/open-easyrtc-server
5:59:20 PM: .../node_modules/browser-tabs-lock postinstall$ node scripts/postinstall.js
5:59:20 PM: .../core-js@3.27.1/node_modules/core-js postinstall$ node -e "try{require('./postinstall')}catch(e){}"
5:59:20 PM: ../..                                    | Progress: resolved 1169, reused 0, downloaded 1148, added 1169, done
5:59:20 PM: .../node_modules/highlight.js postinstall$ node deprecated.js
5:59:20 PM: .../node_modules/browser-tabs-lock postinstall: Thank you for using browser-tabs-lock ( https://github.com/supertokens/browser-tabs-lock ).
5:59:20 PM: .../node_modules/browser-tabs-lock postinstall: This library was created as a part of a larger project, SuperTokens( https://supertokens.io ) - an open source auth solution.
5:59:20 PM: .../node_modules/browser-tabs-lock postinstall: You can also check out our other projects on https://github.com/supertokens
5:59:20 PM: .../node_modules/browser-tabs-lock postinstall:
5:59:20 PM: .../node_modules/browser-tabs-lock postinstall: Done
5:59:20 PM: .../node_modules/leveldown install$ node-gyp-build
5:59:20 PM: .../core-js@3.27.1/node_modules/core-js postinstall: Done
5:59:20 PM: .../node_modules/highlight.js postinstall: -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
5:59:20 PM: .../node_modules/highlight.js postinstall:
5:59:20 PM: .../node_modules/highlight.js postinstall:   Verion 9 of Highlight.js has reached EOL.  It will no longer
5:59:20 PM: .../node_modules/highlight.js postinstall:   be supported or receive security updates in the future.
5:59:20 PM: .../node_modules/highlight.js postinstall:   Please upgrade to version 10 or encourage your indirect
5:59:20 PM: .../node_modules/highlight.js postinstall:   dependencies to do so.
5:59:20 PM: .../node_modules/highlight.js postinstall:   For more info:
5:59:20 PM: .../node_modules/highlight.js postinstall:
5:59:20 PM: .../node_modules/highlight.js postinstall:   https://github.com/highlightjs/highlight.js/issues/2877
5:59:20 PM: .../node_modules/highlight.js postinstall:   https://github.com/highlightjs/highlight.js/blob/master/VERSION_10_UPGRADE.md
5:59:20 PM: .../node_modules/highlight.js postinstall:
5:59:20 PM: .../node_modules/highlight.js postinstall: -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
5:59:20 PM: .../node_modules/highlight.js postinstall: Done
5:59:20 PM: .../node_modules/leveldown install: Done
5:59:20 PM: .../node_modules/vue-demi postinstall$ node ./scripts/postinstall.js
5:59:20 PM: .../node_modules/vue-demi postinstall: Done
5:59:20 PM: .../esbuild@0.15.18/node_modules/esbuild postinstall$ node install.js
5:59:20 PM: .../esbuild@0.16.17/node_modules/esbuild postinstall$ node install.js
5:59:20 PM: .../esbuild@0.15.18/node_modules/esbuild postinstall: Done
5:59:20 PM: .../esbuild@0.16.17/node_modules/esbuild postinstall: Done
5:59:20 PM: .../cypress@12.4.0/node_modules/cypress postinstall$ node index.js --exec install
5:59:21 PM: .../cypress@12.4.0/node_modules/cypress postinstall: Note: Overriding Cypress cache directory to: ./node_modules/.cache/CypressBinary
5:59:21 PM: .../cypress@12.4.0/node_modules/cypress postinstall:       Previous installs of Cypress may not be found.
5:59:21 PM: .../cypress@12.4.0/node_modules/cypress postinstall: Installing Cypress (version: 12.4.0)
5:59:21 PM: .../cypress@12.4.0/node_modules/cypress postinstall: [STARTED] Task without title.
5:59:22 PM: .../cypress@12.4.0/node_modules/cypress postinstall: [SUCCESS] Task without title.
5:59:22 PM: .../cypress@12.4.0/node_modules/cypress postinstall: [STARTED] Task without title.
5:59:27 PM: .../cypress@12.4.0/node_modules/cypress postinstall: [SUCCESS] Task without title.
5:59:27 PM: .../cypress@12.4.0/node_modules/cypress postinstall: [STARTED] Task without title.
5:59:27 PM: .../cypress@12.4.0/node_modules/cypress postinstall: [SUCCESS] Task without title.
5:59:28 PM: .../cypress@12.4.0/node_modules/cypress postinstall: You can now open Cypress by running: node_modules/.bin/cypress open
5:59:28 PM: .../cypress@12.4.0/node_modules/cypress postinstall: https://on.cypress.io/installing-cypress
5:59:28 PM: .../cypress@12.4.0/node_modules/cypress postinstall: Done
5:59:28 PM: dependencies:
5:59:28 PM: + @auth0/auth0-vue 1.0.3
5:59:28 PM: + @cloudinary/vue 1.8.1
5:59:28 PM: + @mdi/font 7.0.96
5:59:28 PM: + @syncedstore/core 0.4.2
5:59:28 PM: + @vexna/ttrpg 1.0.0 <- ../../packages/ttrpg
5:59:28 PM: + @vexna/util 1.0.0 <- ../../packages/util
5:59:28 PM: + @vueuse/head 1.0.23
5:59:28 PM: + downloadjs 1.4.7
5:59:28 PM: + flagpack-core 2.0.0
5:59:28 PM: + lodash 4.17.21
5:59:28 PM: + pdf-lib 1.17.1
5:59:28 PM: + peerjs 1.4.7
5:59:28 PM: + pinia 2.0.29
5:59:28 PM: + pouchdb-browser 8.0.0
5:59:28 PM: + qr-code-styling 1.6.0-rc.1
5:59:28 PM: + qrcode-generator 1.4.4
5:59:28 PM: + roboto-fontface 0.10.0
5:59:28 PM: + socket.io-client 2.5.0
5:59:28 PM: + vue 3.2.45
5:59:28 PM: + vue-country-flag-next 2.3.2
5:59:28 PM: + vue-i18n 9.2.2
5:59:28 PM: + vue-router 4.1.6
5:59:28 PM: + vuetify 3.1.2
5:59:28 PM: + vuetify-extra 0.1.8 <- ../../packages/vuetify-extra
5:59:28 PM: + webfontloader 1.6.28
5:59:28 PM: + workbox-build 6.5.4
5:59:28 PM: + workbox-window 6.5.4
5:59:28 PM: + y-indexeddb 9.0.9
5:59:28 PM: + y-webrtc 10.2.4
5:59:28 PM: + y-websocket 1.4.5
5:59:28 PM: + yjs 13.5.44
5:59:28 PM: devDependencies:
5:59:28 PM: + @intlify/unplugin-vue-i18n 0.8.1
5:59:28 PM: + @types/downloadjs 1.4.3
5:59:28 PM: + @types/lodash 4.14.191
5:59:28 PM: + @types/node 18.11.18
5:59:28 PM: + @types/pouchdb-browser 6.1.3
5:59:28 PM: + @types/socket.io-client 3.0.0
5:59:28 PM: + @types/webfontloader 1.6.35
5:59:28 PM: + @vitejs/plugin-vue 4.0.0
5:59:28 PM: + @vue/eslint-config-typescript 11.0.2
5:59:28 PM: + eslint 8.32.0
5:59:28 PM: + eslint-plugin-vue 9.9.0
5:59:28 PM: + open-easyrtc 0.0.0 <- ../open-easyrtc-server
5:59:28 PM: + typescript 4.9.4
5:59:28 PM: + vite 4.0.4
5:59:28 PM: + vite-plugin-mkcert 1.11.0
5:59:28 PM: + vite-plugin-pages 0.28.0
5:59:28 PM: + vite-plugin-pwa 0.14.1
5:59:28 PM: + vite-plugin-vuetify 1.0.1
5:59:28 PM: + vitest 0.28.4
5:59:28 PM: + vue-tsc 1.0.24
5:59:28 PM: Done in 20.5s
5:59:28 PM: npm packages installed using pnpm
5:59:28 PM: Started restoring cached go cache
5:59:28 PM: Finished restoring cached go cache
5:59:28 PM: go version go1.19.5 linux/amd64
5:59:29 PM: Detected 1 framework(s)
5:59:29 PM: "vite" at version "4.0.4"
5:59:29 PM: Installing missing commands
5:59:29 PM: Verify run directory
5:59:29 PM: Section completed: initializing
5:59:30 PM: ​
5:59:30 PM:   Netlify Build                                                 
5:59:30 PM: ────────────────────────────────────────────────────────────────
5:59:30 PM: ​
5:59:30 PM: ❯ Version
5:59:30 PM:   @netlify/build 29.5.4
5:59:30 PM: ​
5:59:30 PM: ❯ Flags
5:59:30 PM:   baseRelDir: true
5:59:30 PM:   buildId: 63e131cff9bd2700088198e1
5:59:30 PM:   deployId: 63e131cff9bd2700088198e3
5:59:30 PM: ​
5:59:30 PM: ❯ Current directory
5:59:30 PM:   /opt/build/repo/apps/vuetify-starter
5:59:30 PM: ​
5:59:30 PM: ❯ Config file
5:59:30 PM:   /opt/build/repo/netlify.toml
5:59:30 PM: ​
5:59:30 PM: ❯ Context
5:59:30 PM:   production
5:59:30 PM: ​
5:59:30 PM:   1. Build command from Netlify app                             
5:59:30 PM: ────────────────────────────────────────────────────────────────
5:59:30 PM: ​
5:59:30 PM: $ pnpm build
5:59:31 PM: > vuetify-starter@1.0.0 build /opt/build/repo/apps/vuetify-starter
5:59:31 PM: > vue-tsc --noEmit && vite build
5:59:35 PM: src/App.vue(40,34): error TS2307: Cannot find module 'vuetify-extra' or its corresponding type declarations.
5:59:35 PM: src/components/example/ExampleI18n.vue(97,33): error TS2307: Cannot find module 'vuetify-extra' or its corresponding type declarations.
5:59:35 PM:  ELIFECYCLE  Command failed with exit code 2. (https://ntl.fyi/exit-code-2)
5:59:35 PM: ​
5:59:35 PM:   "build.command" failed                                        
5:59:35 PM: ────────────────────────────────────────────────────────────────
5:59:35 PM: ​
5:59:35 PM:   Error message
5:59:35 PM:   Command failed with exit code 1: pnpm build (https://ntl.fyi/exit-code-1)
5:59:35 PM: ​
5:59:35 PM:   Error location
5:59:35 PM:   In Build command from Netlify app:
5:59:35 PM:   pnpm build
5:59:35 PM: ​
5:59:35 PM:   Resolved config
5:59:35 PM:   build:
5:59:35 PM:     base: /opt/build/repo/apps/vuetify-starter
5:59:35 PM:     command: pnpm build
5:59:35 PM:     commandOrigin: ui
5:59:35 PM:     environment:
5:59:35 PM:       - VITE_AUTH0_CLIENT_ID
5:59:35 PM:       - VITE_AUTH0_DOMAIN
5:59:35 PM:       - VITE_CLOUDINARY_API_KEY
5:59:35 PM:       - VITE_CLOUDINARY_API_SECRET
5:59:35 PM:       - VITE_CLOUDINARY_CLOUD_NAME
5:59:35 PM:       - VITE_CLOUDINARY_UPLOAD_PRESET
5:59:35 PM:     publish: /opt/build/repo/apps/vuetify-starter/dist
5:59:35 PM:     publishOrigin: ui
5:59:36 PM: Caching artifacts
5:59:36 PM: Started saving workspace packages/ttrpg node modules
5:59:36 PM: Finished saving workspace packages/ttrpg node modules
5:59:36 PM: Started saving workspace packages/util node modules
5:59:36 PM: Finished saving workspace packages/util node modules
5:59:36 PM: Started saving workspace packages/vuetify-extra node modules
5:59:36 PM: Finished saving workspace packages/vuetify-extra node modules
5:59:36 PM: Started saving workspace apps/dread-vitesse node modules
5:59:37 PM: Failed during stage 'building site': Build script returned non-zero exit code: 2 (https://ntl.fyi/exit-code-2)
5:59:36 PM: Finished saving workspace apps/dread-vitesse node modules
5:59:36 PM: Started saving workspace apps/vuetify-starter node modules
5:59:36 PM: Finished saving workspace apps/vuetify-starter node modules
5:59:36 PM: Started saving workspace root node modules
5:59:36 PM: Finished saving workspace root node modules
5:59:36 PM: Started saving build plugins
5:59:36 PM: Finished saving build plugins
5:59:36 PM: Started saving corepack cache
5:59:36 PM: Finished saving corepack cache
5:59:36 PM: Started saving pip cache
5:59:36 PM: Finished saving pip cache
5:59:36 PM: Started saving emacs cask dependencies
5:59:36 PM: Finished saving emacs cask dependencies
5:59:36 PM: Started saving maven dependencies
5:59:36 PM: Finished saving maven dependencies
5:59:36 PM: Started saving boot dependencies
5:59:36 PM: Finished saving boot dependencies
5:59:36 PM: Started saving rust rustup cache
5:59:36 PM: Finished saving rust rustup cache
5:59:36 PM: Started saving go dependencies
5:59:36 PM: Finished saving go dependencies
5:59:37 PM: Build failed due to a user error: Build script returned non-zero exit code: 2
5:59:37 PM: Failing build: Failed to build site
5:59:37 PM: Finished processing build request in 36.429s

Related:

Maybe related (something changed in January?):

Finally, I feel that I have to say that Netlify is doing a stellar job providing this amazing service!!

Hi did you give this a read Monorepos | Netlify Docs?

That article is how I got started actually :smile:… But since that post was written things have changed (for the better). For one, that PNPM is now supported, which wasn’t the case yet when this article was written.

Now, I’m not entirely sure that PNPM is actually the issue here, it just looks like it. It could just as well be some sort of misconfiguration on my side.

So, I haven’t been able to tackle this yet. Has anyone got pnpm monorepo with internal package references working in Netlify? Tips/hints/solutions/examples are very much appreciated!

Hey @StuStu.

Have you tried using the --shamefully-hoist flag: Manage build dependencies | Netlify Docs?

Hey @hrishikesh,

I have tried it but didn’t work unfortunately. Do you have any suggestion on how to fix this issue?

8:50:47 PM: dependencies:
8:50:47 PM: + @types/react 18.2.8
8:50:47 PM: + @types/react-dom 18.2.4
8:50:47 PM: + autoprefixer 10.4.14
8:50:47 PM: + frontend-client 1.0.5 <- ../../packages/frontend-client
8:50:47 PM: + next 13.4.4
8:50:47 PM: + postcss 8.4.24
8:50:47 PM: + react 18.2.0
8:50:47 PM: + react-dom 18.2.0
8:50:47 PM: + tailwindcss 3.3.2
8:50:47 PM: Done in 7.2s

I have the same issue with a package named frontend-client. It lives in the pnpm workspace and netlify has a hard time to find the page in the code:

8:51:06 PM: ./src/app/page.tsx
8:51:06 PM: Module not found: Can't resolve 'frontend-client'

EDIT 09 Jun:

Also tried to add public-hoist-pattern[]=* in .npmrc file but couldn’t run it.

EDIT 10 Jun:

@StuStu I found a problem. The reason why it can’t resolve the package is most likely because you haven’t build the workspace package. I slightly change the build command in netlify.toml to:

[build]
command = "pnpm -C ../../ build:packages && pnpm run build"

The first command pnpm -C ../../ build:packages executes pnpm --filter "./packages/*" build from the root dir. This generates build folder which then can be used in your apps.

Alternatively what you can do is, you can build them locally and remove build folder from .gitignore (in my case it was dist, could be also out, build or whatever).

Hope I could help you with my post.