vercel / turborepo

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

Modules not transpiled outside the NextJS app #665

Closed kettanaito closed 2 years ago

kettanaito commented 2 years ago

What version of Turborepo are you using?

1.1.1

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

npm

What operating system are you using?

Mac

Describe the Bug

I have a package under packages/server written in TypeScript. I'm trying to import that package in apps/web but getting the following error on runtime:

web:dev: Module parse failed: The keyword 'interface' is reserved (7:0)
web:dev: You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
web:dev: | import * as types from './types'
web:dev: | 
web:dev: > interface ResolvedSchema {
web:dev: |   typeDefs: DocumentNode[]
web:dev: |   resolvers: Record<string, any>

This implies that NextJS can't import a TS module outside of its directory (those are not transpiled per https://github.com/vercel/next.js/issues/5666).

Expected Behavior

I expect that TS modules can be freely imported across the monorepo, since that's the main point of introducing one.

To Reproduce

  1. npx create-turbo@latest.
  2. mkdir packages/server
  3. touch packages/server/index.ts
  4. Fill in the module contents:
    
    // packages/server/index.ts
    interface Foo {
    username: string 
    }

export const value: Foo = { username: 'john' }

5. `mkdir apps/web/api`
6. `touch appsp/web/api/foo.ts`
7. Fill in the module contents:
```ts
// appsp/web/api/foo.ts
import { username } from 'server'

export default (req, res) => {
  res.send(username)
  1. Run the monorepo via yarn dev (alias for turbo run dev --parallel).
  2. Navigate to http://localhost:3000/api/foo.
  3. See the exception I've mentioned.
kettanaito commented 2 years ago

Interesting that I can import TS modules from packages/ui without issues. This makes me thing I'm not setting up the TS correctly with a newly added repo server. This is what I have in packages/server/tsconfig.json:

{
  "extends": "tsconfig/base.json",
  "include": ["."],
  "exclude": ["node_modules"]
}

Should I add something else here?

Erwol commented 2 years ago

Does your new package contains a package.json? If so, did you add a main entrypoint or a files array (https://docs.npmjs.com/cli/v8/configuring-npm/package-json#main)?

Also, make sure to add your new package to both your app/web package.json and next.config.js (see the require('next-transpile-modules') array).

jaredpalmer commented 2 years ago

Hey! This is a Next.js / TypeScript problem and not directly related to turbo. See the documentation on https://www.npmjs.com/package/next-transpile-modules. You might also find it necessary to transpile your packages independently like in the design system example here https://github.com/vercel/turborepo/blob/main/examples/design-system/packages/acme-core/package.json

kettanaito commented 2 years ago

Thanks, @jaredpalmer.

SiTribal commented 2 years ago

@jaredpalmer I am not sure if this is related but having the error - Failed to load parser './parser.js' declared in '.eslintrc.json » eslint-config-next/core-web-vitals » /Users/simon.colman/Documents/GitHub/oroton-turbo-repo/node_modules/eslint-config-next/index.js': Cannot find module 'next/dist/compiled/babel/eslint-parser'

This is a linting error - the next node modules folder is not hoisting up to the root node modules directory

wlechowicz commented 2 years ago

@jaredpalmer I am not sure if this is related but having the error - Failed to load parser './parser.js' declared in '.eslintrc.json » eslint-config-next/core-web-vitals » /Users/simon.colman/Documents/GitHub/oroton-turbo-repo/node_modules/eslint-config-next/index.js': Cannot find module 'next/dist/compiled/babel/eslint-parser'

This is a linting error - the next node modules folder is not hoisting up to the root node modules directory

This happens when your nextjs and eslint-config-next dependencies are not in sync i.e. you updated next but forgot to update eslint-config-next.

jtlapp commented 1 year ago

@jaredpalmer:

You might also find it necessary to transpile your packages independently like in the design system example here https://github.com/vercel/turborepo/blob/main/examples/design-system/packages/acme-core/package.json

This solution has the drawback that you have to build a package after every change to the package before any other package will recognize the change. That's not the case with Next.js-transpiled packages.

If I have to live with this drawback, I would restructure my repo to have fewer packages. I'm presently being prolific with packages to flatten the source tree and make code easier to locate.

jtlapp commented 1 year ago

This solution has the drawback that you have to build a package after every change to the package before any other package will recognize the change. That's not the case with Next.js-transpiled packages.

I solved this problem by using the following package.json configuration:

"types": "src/index.ts"

instead of this, which appears in many of the example repos:

"types": "dist/index.d.ts"

I do wonder if I have to use the latter in publishable repos, though.

Easyvipin commented 10 months ago

Faced a similar problem , and solved it by adding transpilePackages: ["@repos/ui"] to next.config.js at workspace level :)