vercel / turborepo

Build system optimized for JavaScript and TypeScript, written in Rust
https://turbo.build/repo/docs
MIT License
26.39k stars 1.84k forks source link

[turborepo] DevDependencies not installed using yarn on vercel #4864

Closed fxmb closed 1 year ago

fxmb commented 1 year ago

What version of Turborepo are you using?

latest

What package manager are you using / does the bug impact?

Yarn v2/v3 (node_modules linker only)

What operating system are you using?

Mac

Describe the Bug

I have an issue since more than a week about deploying my nextjs app on vercel using yarn.

I am using a standard turborepo setup forked from this repository: https://github.com/aaron5670/webshop-starter/tree/main

  1. I add my nextjs repo under apps/store and install my deps via yarn install
  2. I then build my app using turbo run build locally. So far so good.
  3. When I deploy my app to vercel weird stuff is going on though:

a) I have left the install on vercel to the default using yarn install. It works fine. b) The build command is cd ../.. && turbo run build --filter={apps/store}.... This is where things start to get funky:

I consistently get build errors around certain packages and basic dependencies not found:

info  - Linting and checking validity of types...
It looks like you're trying to use TypeScript but do not have the required package(s) installed.
Please install typescript by running:
    yarn add --dev typescript
If you are not trying to use TypeScript, please remove the tsconfig.json file from your package root (and any TypeScript files in your pages directory).

Obviously typescript should be installed.

This is my package.json at the root:

{
  "name": "webshop-starter",
  "version": "0.0.0",
  "private": true,
  "workspaces": [
    "apps/*",
    "packages/*"
  ],
  "scripts": {
    "build": "turbo run build",
    "dev": "turbo run dev",
    "lint": "turbo run lint",
    "format": "prettier --write \"**/*.{ts,tsx,md}\""
  },
  "devDependencies": {
    "eslint-config-custom": "*",
    "prettier": "latest",
    "turbo": "latest",
  },
  "engines": {
    "node": ">=14.0.0"
  },
  "dependencies": {},
  "packageManager": "yarn@1.22.17"
}

and then my package.json on the apps/store level:

{
  "name": "medusa-next",
  "version": "1.0.3",
  "private": true,
  "description": "Next.js starter to be used with Medusa server",
  "keywords": [
    "medusa-storefront"
  ],
  "scripts": {
    "dev": "next dev -p 8000",
    "build": "next build",
    "start": "next start -p 8000",
    "lint": "next lint",
    "cypress": "cypress open",
    "analyze": "ANALYZE=true next build",
    "test": "jest --watch",
    "postbuild": "next-sitemap"
  },
  "resolutions": {
    "webpack": "^5"
  },
  "dependencies": {
    "@calcom/embed-react": "^1.0.10",
    "@headlessui/react": "^1.7.5",
    "@heroicons/react": "^2.0.13",
    "@hookform/error-message": "^2.0.0",
    "@medusajs/medusa": "1.7.8",
    "@medusajs/medusa-js": "^1.3.3",
    "@meilisearch/instant-meilisearch": "^0.7.1",
    "@next/font": "^13.1.5",
    "@paypal/paypal-js": "^5.0.6",
    "@paypal/react-paypal-js": "^7.8.1",
    "@react-pdf/font": "^2.3.1",
    "@react-pdf/renderer": "^3.0.3",
    "@stripe/react-stripe-js": "^1.7.2",
    "@stripe/stripe-js": "^1.29.0",
    "@supabase/supabase-js": "^2.2.1",
    "@twind/preset-tailwind-forms": "^1.0.3",
    "@vercel/og": "^0.0.27",
    "algoliasearch": "^4.14.2",
    "clsx": "^1.1.1",
    "editorjs-blocks-react-renderer": "^1.3.0",
    "flowbite": "^1.6.2",
    "flowbite-react": "^0.3.7",
    "fontkit": "^2.0.2",
    "heroicons-react": "^1.4.1",
    "i18n-iso-countries": "^7.5.0",
    "js-cookie": "^3.0.1",
    "lodash": "^4.17.21",
    "medusa-react": "^3.0.1",
    "meilisearch": "^0.30.0",
    "next": "^13.0.6",
    "next-seo": "^5.15.0",
    "next-sitemap": "^4.0.5",
    "react": "^18.2.0",
    "react-copy-to-clipboard": "^5.1.0",
    "react-country-flag": "^3.0.2",
    "react-dom": "^18.2.0",
    "react-hook-form": "^7.30.0",
    "react-instantsearch-hooks-web": "^6.29.0",
    "react-intersection-observer": "^9.3.4",
    "react-pdf-tailwind": "^1.0.1",
    "react-query": "^3.34.16",
    "sharp": "^0.30.7",
    "swr": "^2.0.0",
    "tailwind-scrollbar-hide": "^1.1.7",
    "uuid": "^9.0.0",
    "webfontloader": "^1.6.28"
  },
  "devDependencies": {
    "@babel/core": "^7.17.5",
    "@tailwindcss/aspect-ratio": "^0.4.2",
    "@tailwindcss/forms": "^0.5.3",
    "@tailwindcss/line-clamp": "^0.4.2",
    "@tailwindcss/typography": "^0.5.8",
    "@testing-library/jest-dom": "^5.16.5",
    "@testing-library/react": "^14.0.0",
    "@types/fontkit": "^2.0.1",
    "@types/js-cookie": "^3.0.3",
    "@types/node": "17.0.21",
    "@types/react-copy-to-clipboard": "^5.0.4",
    "@types/react-instantsearch-dom": "^6.12.3",
    "@types/uuid": "^9.0.1",
    "autoprefixer": "^10.4.13",
    "babel-loader": "^8.2.3",
    "cypress": "^9.5.2",
    "eslint": "8.10.0",
    "eslint-config-next": "^13.0.6",
    "jest": "^29.4.3",
    "jest-environment-jsdom": "^29.4.3",
    "lato-font": "^3.0.0",
    "msw": "^1.1.0",
    "postcss": "^8.4.19",
    "sitemap": "^7.1.1",
    "tailwind-scrollbar": "^3.0.0",
    "tailwindcss": "^3.2.4",
    "typescript": "4.6.2"
  }
}

My tsconfig on the apps/store:

{
  "compilerOptions": {
    "target": "es5",
    "lib": ["dom", "dom.iterable", "esnext"],
    "allowJs": true,
    "skipLibCheck": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "noEmit": true,
    "esModuleInterop": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "jsx": "preserve",
    "incremental": true,
    "types": ["cypress", "jest",  "@testing-library/jest-dom"],
    "baseUrl": "./src",
    "paths": {
      "@lib/*": ["lib/*"],
      "@modules/*": ["modules/*"],
      "@pages/*": ["pages/*"],
    }
  },
  "include": [
    "next-env.d.ts",
    "**/*.ts",
    "**/*.tsx",
    "cypress/support/index.js",
    "cypress/support/commands.js",
    "cypress/integration/product.spec.js",
    "cypress/plugins/index.js",
  ],
  "exclude": [
    "node_modules",
    ".next",
    ".nyc_output",
    "cypress-coverage",
    "coverage",
    "jest-coverage"
  ]
}

We would really appreciate any kind of help, this has been an issue for more than a week now and I really do not understand what is causing the issue here.

It seems that my dependencies are not properly installed or that my vercel build command is off not recognizsing the correct node_modules folder.

Expected Behavior

I would expect the build command to succeed on vercel

To Reproduce

Clone this repository and deploy to vercel: https://github.com/aaron5670/webshop-starter/tree/main

Reproduction Repo

https://github.com/aaron5670/webshop-starter/tree/main

fxmb commented 1 year ago

The issue seems to be related to devDependencies. Whenever I add the missing package (e.g. typescript) to the regular dependencies it works for that package. It then throws the next error:

medusa-next:build: Type error: Could not find a declaration file for module 'js-cookie'. '/vercel/path0/node_modules/js-cookie/index.js' implicitly has an 'any' type.

If I then go ahead and add @types/js-cookie to the actual dependencies, not the dev dependencies it gets installed and works, e.g. it complains about the next type declaration file it is missing. However, all type declartaions are there in devDependencies already. they should be recognized and working without being part of the actual dependency ...

I am sure I am just missing a tiny detail in my setup but I would really appreciate some help to fix this and the deployments running. Thanks

estubmo commented 1 year ago

Isn't the whole point of devDependencies that they get installed in a development environment, and not in production, such as on vercel?

tknickman commented 1 year ago

This is expected behavior of yarn when operating in a production context (docs). Do you have NODE_ENV set to production by chance? That's one thing that will alter this behavior of yarn.

If you do need dev deps installed at build time on vercel you can override this by passing an arg to yarn on install (--prod=false).