martpie / next-transpile-modules

Next.js plugin to transpile code from node_modules. Please see: https://github.com/martpie/next-transpile-modules/issues/291
MIT License
1.13k stars 85 forks source link

"yarn workspace" commands don't work #101

Closed aswbot closed 1 year ago

aswbot commented 4 years ago

Hello.

Are you trying to transpile a local package or an npm package? Local package

Describe the bug

../components/src/Header.tsx 3:5
Module parse failed: Unexpected token (3:5)
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
| import React from 'react'
| 
> type Props = React.PropsWithChildren<{
|   className?: string
| }>

To Reproduce

$ git clone https://github.com/aswbot/ntm-transpile-error.git && cd ntm-transpile-error
$ yarn
$ yarn workspace @app/web dev

Expected behavior It should work out of the box afaik, no babel configuration as Next comes with TypeScript support. It is weird but removing the types does work. It only complains about type annotations/declarations. 🤔 Any ideas?

Setup

ical10 commented 3 years ago

https://github.com/martpie/next-transpile-modules/issues/101#issuecomment-741963175

Hi @martpie, I am trying to transpile several packages from @polkadot/api (as advised in this issue thread: https://github.com/polkadot-js/api/issues/3374) but run into the same issue as the comment above.

Here is my configuration:

"next": "9.5.4",
"next-transpile-modules": "^6.4.0",

node v15.13.0 yarn v1.22.10 OS: MacOS v10.14.6

My next.config.js:

const withTM = require('next-transpile-modules')([
  '@polkadot/api',
  '@polkadot/api-derive',
  '@polkadot/extension-dapp',
  '@polkadot/hw-ledger',
  '@polkadot/hw-ledger-transports',
  '@polkadot/keyring',
  '@polkadot/metadata',
  '@polkadot/networks',
  '@polkadot/rpc-core',
  '@polkadot/rpc-core',
  '@polkadot/rpc-provider',
  '@polkadot/ts',
  '@polkadot/types',
  '@polkadot/types-known',
  '@polkadot/ui-keyring',
  '@polkadot/ui-settings',
  '@polkadot/util',
  '@polkadot/util-crypto',
  '@polkadot/wasm-crypto',
  '@polkadot/x-fetch',
  '@polkadot/x-global',
  '@polkadot/x-rxjs',
  '@polkadot/x-ws'
]);
module.exports = withTM({
  webpack(config) {
    config.module.rules.push({
      test: /\.svg$/,
      issuer: {
        test: /\.(js|ts)x?$/
      },
      use: ['@svgr/webpack']
    });

    return config;
  }
});

I aliased yarn dev into ts-node -r dotenv/config --project tsconfig.server.json server/index.ts and ran it, producing Error.log as the following:

/Users/rizal/GDrive/blocksphere/myri/myriad/node_modules/next-transpile-modules/src/next-transpile-modules.js:136
        throw new Error(
              ^
Error: next-transpile-modules - an unexpected error happened when trying to resolve "@polkadot/hw-ledger-transports"
Error: Can't resolve '@polkadot/hw-ledger-transports' in '/Users/rizal/GDrive/blocksphere/myri/myriad'
    at getPackageRootDirectory (/Users/rizal/GDrive/blocksphere/myri/myriad/node_modules/next-transpile-modules/src/next-transpile-modules.js:136:15)
    at Array.map (<anonymous>)
    at withTM (/Users/rizal/GDrive/blocksphere/myri/myriad/node_modules/next-transpile-modules/src/next-transpile-modules.js:145:34)
    at Object.<anonymous> (/Users/rizal/GDrive/blocksphere/myri/myriad/next.config.js:26:18)
    at Module._compile (node:internal/modules/cjs/loader:1092:14)
    at Module.m._compile (/Users/rizal/GDrive/blocksphere/myri/myriad/node_modules/ts-node/src/index.ts:1056:23)
    at Module._extensions..js (node:internal/modules/cjs/loader:1121:10)
    at Object.require.extensions.<computed> [as .js] (/Users/rizal/GDrive/blocksphere/myri/myriad/node_modules/ts-node/src/index.ts:1059:12)
    at Module.load (node:internal/modules/cjs/loader:972:32)
    at Function.Module._load (node:internal/modules/cjs/loader:813:14)

package.json of @polkadot/hw-ledger-transports contains:

  "main": "node.js",
  ...
  "exports": {
    ".": {
      "require": "./index.cjs", // Had to add these two lines, otherwise path error occurs
      "default": "./index.js", // Had to add these two lines, otherwise path error occurs
      "browser": {
        "require": "./browser.cjs",
        "default": "./browser.js"
      },
      "node": {
        "require": "./node.cjs",
        "default": "./node.js"
      },
      "react-native": {
        "require": "./react-native.cjs",
        "default": "./react-native.js"
      }
    }

Any clue where I might be wrong?

martpie commented 3 years ago

https://github.com/martpie/next-transpile-modules/issues/101#issuecomment-778690321

I haven't had time to investigate this issue too much yet

darwin403 commented 3 years ago

yarn install next-transpile-modules@4.1.0 did the job for me. It seems to be a problem with the module resolution of scoped variables like @company/my-package in the later versions. Here is a working boilerplate with next-js. https://github.com/brunolemos/react-native-web-monorepo

Note however that they do not use scoped variables there.

belgattitude commented 3 years ago

@darwin403 I haven't had problem with scoped packages and yarn or even yarn-3.0.0-rc.2 (not yet pnp).

It seems to be a problem with the module resolution of scoped variables like @company/my-package in the later versions.

I think you should be able to upgrade to latest NTM by

See the latest NTM doc about it.

PS:

darwin403 commented 3 years ago

@belgattitude Thanks. Creating a index.ts and exporting all components from there did the job for me!

dweste01 commented 3 years ago

⚠️ For anyone interested in diving into the issue ⚠️

the problem is most probably coming from this line:

https://github.com/martpie/next-transpile-modules/blob/2d935beb70f8420ca42dd0d7bb2ca6755ff8d38c/src/next-transpile-modules.js#L21

I imagine in a yarn workspace command, process.cwd() resolves to the root of the workspaces, but we want it to be resolved to the root of the Next.js application.

If anyone knows a quick way to fix this, feel free to post here a hint or submit a PR.

@martpie not sure if this is exactly what is needed - but the yarn API provides relativeCwd and workspacesCwds

martpie commented 3 years ago

Thank you @dweste01, will look into it

owensco commented 3 years ago

Getting the same error as above: next-transpile-modules - an unexpected error happened when trying to resolve...

But only when I deploy my monorepo via Vercel. Everything works as expected running locally 🤔

martpie commented 3 years ago

@owensco probably unrelated. Make sure your transpiled dependencies are NOT devDependencies

owensco commented 3 years ago

@martpie thanks for the reply.

I was able to resolve the error by modifying the path of the shared package in next.config.js:

from: const withTM = require('next-transpile-modules')(['shared']); to: const withTM = require('next-transpile-modules')(['../shared']);

I don't think this is an actual solve as none of the examples require this. It's also lead to new module not found errors in the shared app when deploying to Vercel (anything that the shared app imports e.g. @chakra-ui/react throws an error on deployment, but works locally). Fun times 😔

martpie commented 3 years ago

cf. https://github.com/martpie/next-transpile-modules/issues/101#issuecomment-776941232 The problem is explained here, I just don't know how to solve it.

owensco commented 3 years ago

@martpie that did it! Thank you so much!

For anyone running into this issue when deploying to Vercel, make sure you update your build & deploy settings to use yarn and not npm 🤦‍♂️

image

kherock commented 2 years ago

I think it would sound perfectly reasonable to pass a directory as an option to next-transpile-modules to fix this. Next.js already advises you to pass it for setting up the Jest preset: https://nextjs.org/docs/testing#setting-up-jest-with-the-rust-compiler

This is what it could look like as an option:

/* next.config.js */
const withTM = require('next-transpile-modules')(['some-module'], {
  dir: __dirname
})
/* next.config.mjs */
import nextTranspileModules from 'next-transpile-modules'
import { pathToFileURL } = from 'url'

const withTM = nextTranspileModules(['some-module'], {
  dir: fileURLToPath(new URL('.', import.meta.url))
})