Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fail to resolve packages imported from another package in a monorepo #429

Closed
emilgpa opened this issue Jan 27, 2024 · 35 comments
Closed

fail to resolve packages imported from another package in a monorepo #429

emilgpa opened this issue Jan 27, 2024 · 35 comments
Labels
help wanted Extra attention is needed

Comments

@emilgpa
Copy link

emilgpa commented Jan 27, 2024

file located in monorepo/ui/components/Example/Example.tsx

import stylex from "@stylexjs/stylex"

const styles = stylex.create({
    base: {
        borderRadius: 40,
    },
})

export const Example = () => {
    return (
        <div {...stylex.props(styles.base)}>
            <h1>Example</h1>
        </div>
    )
}

file located in monorepo/web/src/root-layout.tsx

import { Example } from "@my-org/ui/components/Example/Example"
import stylex from "@stylexjs/stylex"

const styles = stylex.create({
    base: {
        padding: 10,
    },
})

export const RootLayout = async ({ children }: RootLayoutProps) => {
    return (
        <div id="__waku">
            <Header />
            <main>
                  <Example />
                  <div {...stylex.props(styles.base)}>
                      {children}
                  </div>
            </main>
            <Footer />
        </div>
    )
}

When load the page in browser I get the follow error:

Error: Error: Failed to load url ../../@stylexjs/stylex (resolved id: ../../@stylexjs/stylex) in ...

In this example I use stylex but It occurs with any external packages. The external package in the same package works but if it is loaded from another package in the same monorepo then it fails with that message error.

@dai-shi
Copy link
Owner

dai-shi commented Jan 27, 2024

So, is this an issue that happens only with monorepo?
@himself65 do you have any insight?

@dai-shi dai-shi added the help wanted Extra attention is needed label Jan 27, 2024
@himself65
Copy link
Contributor

What package manager are you using? and what's your vite config

@emilgpa
Copy link
Author

emilgpa commented Jan 28, 2024

@himself65 I'm using pnpm and the vite.config.js is:

import path from "node:path"
import url from "node:url"
import { defineConfig } from "vite"
import { stylexPlugin } from "vite-plugin-stylex-dev"
import tsconfigPaths from "vite-tsconfig-paths"

const workspacesRoot = path.resolve(
    path.dirname(url.fileURLToPath(import.meta.url)),
    "..",
)

export default defineConfig(({ mode }) => {
    return {
        plugins: [
            tsconfigPaths({
                projects: [
                    "./tsconfig.json",
                    "../browser-api/tsconfig.json",
                    "../browser-lib/tsconfig.json",
                    "../browser-ui/tsconfig.json",
                ],
            }),
            stylexPlugin({
                unstable_moduleResolution: {
                    type: "commonJS",
                    rootDir: workspacesRoot,
                },
            }),
        ],
    }
})

@himself65
Copy link
Contributor

what is unstable_moduleResolution here?

@emilgpa
Copy link
Author

emilgpa commented Jan 28, 2024

it is for to configure for looking styles of stylex from the root of monorepo but I think that it is maybe unnecessary. Anyway, I did test removing that but unfortunately the error persists.

@himself65
Copy link
Contributor

Is there any code for reproduction? I'm guessing there is some issue with vite

@emilgpa
Copy link
Author

emilgpa commented Jan 28, 2024

While I was preparing a repo for you to try, I already know what causes it.
In the tsconfig.json of the the package consumed (in this example, ui) by the other package (in this example, web) is set the property baseUrl to ".". The tsconfig.json is:

{
    "extends": "../tsconfig.json",
    "compilerOptions": {
        "alwaysStrict": true,
        "preserveConstEnums": true,
        "strictNullChecks": true,
        "strict": true,
        "sourceMap": true,
        "paths": {
            "@/*": ["./*"]
        },
        "module": "esnext",
        "moduleResolution": "Bundler",
        "target": "esnext",
        "baseUrl": ".", // <--- problem here!!
        "jsx": "react-jsx",
        "lib": ["DOM", "DOM.Iterable", "ESNext"],
        "allowJs": false,
        "experimentalDecorators": true,
        "esModuleInterop": false,
        "resolveJsonModule": true,
        "isolatedModules": true,
        "skipLibCheck": false,
        "allowSyntheticDefaultImports": true,
        "forceConsistentCasingInFileNames": true,
        "noEmit": true
    },
    "include": ["**/*.ts", "**/*.tsx"]
}

If you want the repository anyway, tell me and I'll upload it.

@emilgpa
Copy link
Author

emilgpa commented Jan 28, 2024

Hi again @himself65. I have another problem related to monorepo, maybe is different to this issue so if you want I open another issue, tell me and I will do it. The problem is that if I import "react" from another package in a monorepo setup then throws the follow error:

Error: SyntaxError: [vite] Named export 'useEffect' not found. The requested module 'react' is a CommonJS module, which may not support all module.exports as named exports.
CommonJS modules can always be imported via the default export, for example using:

import pkg from 'react';
const {useEffect} = pkg;

The configuration is the same but futhermore of import "stylex" now this component import "react" too.

@himself65
Copy link
Contributor

Hi again @himself65. I have another problem related to monorepo, maybe is different to this issue so if you want I open another issue, tell me and I will do it. The problem is that if I import "react" from another package in a monorepo setup then throws the follow error:

Error: SyntaxError: [vite] Named export 'useEffect' not found. The requested module 'react' is a CommonJS module, which may not support all module.exports as named exports.
CommonJS modules can always be imported via the default export, for example using:

import pkg from 'react';
const {useEffect} = pkg;

The configuration is the same but futhermore of import "stylex" now this component import "react" too.

vite specific issue, toeverything/blocksuite#304

@himself65
Copy link
Contributor

My suggestion to fix this to use resolve.alias

@Aslemammad
Copy link
Contributor

@emilgpa I think the last version of waku might resolve this. Let us know.

@emilgpa
Copy link
Author

emilgpa commented Mar 28, 2024

@Aslemammad I get the same error in console. In the browser is: SyntaxError: Unexpected token ':', ":after {" is not valid JSON (from react-server-dom-webpack_client.js)

@Aslemammad
Copy link
Contributor

Ok, I'll check this today! Can you prepare a reproduction meanwhile (preferably Stackblitz)?

@emilgpa
Copy link
Author

emilgpa commented Mar 28, 2024

@Aslemammad
Copy link
Contributor

Aslemammad commented Mar 28, 2024

The issue is (which I don't know if it's your configuration that causes it, or waku or even vite) but:

"use client"

import stylex from "@stylexjs/stylex"
import React from "react"
console.log('React', React)

const styles = stylex.create({
    base: {
        color: "red"
    }
})

And it logs React, but the rsc one:

React {
  Children: {
    map: [Function: mapChildren],
    forEach: [Function: forEachChildren],
    count: [Function: countChildren],
    toArray: [Function: toArray],
    only: [Function: onlyChild]
  },
  Fragment: Symbol(react.fragment),
  Profiler: Symbol(react.profiler),
  StrictMode: Symbol(react.strict_mode),
  Suspense: Symbol(react.suspense),
  __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: {
    ReactCurrentDispatcher: { current: null },
    ReactCurrentOwner: { current: null },
    ReactDebugCurrentFrame: {
      setExtraStackFrame: [Function (anonymous)],
      getCurrentStack: null,
      getStackAddendum: [Function (anonymous)]
    }
  },
  __SECRET_SERVER_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: { ReactCurrentCache: { current: null } },
  cache: [Function: cache],
  cloneElement: [Function: cloneElement],
  createElement: [Function: createElement],
  createRef: [Function: createRef],
  forwardRef: [Function: forwardRef],
  isValidElement: [Function: isValidElement],
  lazy: [Function: lazy],
  memo: [Function: memo],
  startTransition: [Function: startTransition],
  use: [Function: use],
  useCallback: [Function: useCallback],
  useDebugValue: [Function: useDebugValue],
  useId: [Function: useId],
  useMemo: [Function: useMemo],
  version: '18.3.0-canary-670811593-20240322'
}

So there's no useEffect for the Heading.tsx component.

Maybe Waku has a problem identifying Client components outside of the root.

I have to not that this issue consists of two sub-issues.
1- React is not being optimized (solution: using default export, which is not a good solution, but a temporary one)
2- After using the temporary solution, waku has hard time identifying Heading.tsx as a client component.

@dai-shi
Copy link
Owner

dai-shi commented Mar 28, 2024

Thanks for the investigation. I would like to understand the condition better:

  • Is this monorepo only issue? -> YES
  • Is this DEV only issue?
  • Is this PRD only issue?
  • Is this an issue without SSR? (It's not easy to test.)

@Aslemammad
Copy link
Contributor

It happens on DEV and PRD too.

@dai-shi
Copy link
Owner

dai-shi commented Apr 1, 2024

1- React is not being optimized (solution: using default export, which is not a good solution, but a temporary one)

Not sure, but may or may not be related: #633 (comment)

(edit) it isn't related.

It happens on DEV and PRD too.

Confirmed.

@dai-shi
Copy link
Owner

dai-shi commented Apr 1, 2024

Is this an issue without SSR? (It's not easy to test.)

Yes, it's an issue with RSC.

@dai-shi
Copy link
Owner

dai-shi commented Apr 2, 2024

For waku build, there are two issues:

  • 2a- With stylex plugin, it fails to transform client components
  • 2b- Even if it's solved, react-server-dom-webpack can't be imported in ui because it's not installed.

I think it applies to DEV too, so it's basically "2- After using the temporary solution, waku has hard time identifying Heading.tsx as a client component." split into two issues.

@dai-shi
Copy link
Owner

dai-shi commented Apr 2, 2024

2a- With stylex plugin, it fails to transform client components

#646 should fix it.

@dai-shi
Copy link
Owner

dai-shi commented Apr 2, 2024

What's remaining:

1- React is not being optimized (solution: using default export, which is not a good solution, but a temporary one)

It's probably a dev only issue.

2b- Even if it's solved, react-server-dom-webpack can't be imported in ui because it's not installed.

It's probably a bundling issue.

@pmelab
Copy link
Contributor

pmelab commented Apr 28, 2024

Not sure if this is related (or if its even a bug): Our setup is a monorepo with a react ui library shared between multiple applications. When trying to import a component marked with 'use client' into the Waku app, it fails. I had to add react-server-dom-webpack as a dependency to the ui libary to resolve it.

When trying to reproduce the same scenario in the Waku monorepo, it failed with the very clear error message (#684):

[vite]: Rollup failed to resolve import "react-server-dom-webpack/server" from "/Users/runner/work/waku/waku/e2e/fixtures/ui-library/index.js".

I the project setup though, it failed much more cryptic message spotted in #676

TypeError: Cannot read properties of null (reading 'use')
    at react_production_min.use ([...]/waku-test/dist/ssr/assets/rsc0-b97afaf68.js:324:22)
    at Slot ([...]/waku-test/dist/ssr/assets/rsc0-b97afaf68.js:10168:40)

That makes me think this line ...

/^import {registerClientReference} from "react-server-dom-webpack\/server";/.test(
... can cause havoc in monorepos because it relies on react-server-dom-webpack being in a parent node_modules folder?

@dai-shi
Copy link
Owner

dai-shi commented Apr 28, 2024

because it relies on react-server-dom-webpack being in a parent node_modules folder?

I'm aware it's a brittle hack. You can confirm if it causes the error by looking at your code in dist.

@pmelab
Copy link
Contributor

pmelab commented Apr 29, 2024

I'm aware it's a brittle hack. You can confirm if it causes the error by looking at your code in dist.

In the first case, there is no dist because rollup immediately breaks.

And in the second, I don't have proof. All I know is that it went away with adding the dependency. And the error message from #676 ...

TypeError: Cannot read properties of null (reading 'use')
    at react_production_min.use ([...]/waku-test/dist/ssr/assets/rsc0-b97afaf68.js:324:22)
    at Slot ([...]/waku-test/dist/ssr/assets/rsc0-b97afaf68.js:10168:40)

... seems to be related to the ReactCurrentDispatcher not being initialized. Maybe a broken import that is silently ignored and returns undefined?

Maybe we can resolve to the absolute path of the package first and import from there?

@pmelab
Copy link
Contributor

pmelab commented Apr 29, 2024

... seems to be related to the ReactCurrentDispatcher not being initialized.

After writing this, I realized that this could be pnpm resolving to two different react packages on disk. Maybe no relation after all.

@dai-shi dai-shi mentioned this issue May 27, 2024
86 tasks
@himself65
Copy link
Contributor

Here is a fixed version (https://github.com/himself65/waku-monorepo-example)

I think the reason is vite threat them as two module and cause some bundle issues

@himself65
Copy link
Contributor

I think we can close this issue since https://github.com/himself65/waku-monorepo-example has fixed it

for #676, I think this is a separate issue

/cc @dai-shi

@dai-shi
Copy link
Owner

dai-shi commented Jun 9, 2024

I think we can close this issue since https://github.com/himself65/waku-monorepo-example has fixed it

@himself65 What's the tldr of the fix?

@himself65
Copy link
Contributor

making sure react, react-dom and react-dom-server-webpack is installed and keeping the same version

@himself65
Copy link
Contributor

himself65 commented Jun 12, 2024

making sure react, react-dom and react-dom-server-webpack is installed and keeping the same version

Otherwise package manager will link them in different directories and cause the bundler make them different

@emilgpa
Copy link
Author

emilgpa commented Jun 12, 2024

@himself65 It's strange because the link I posted at the time with the monorepo as an example has the same version in react, react-dom and react-dom-server-webpack.

The diff that I see is:

  • react 19
  • new version waku
  • not exports property in ui package
  • module as nodenext in tsconfig of web package

And maybe another thing. Maybe is something of this list?

@emilgpa
Copy link
Author

emilgpa commented Jun 12, 2024

Oh, and the dependencies in web package now has not @myorg/ui as dependencies ("@myorg/ui": "workspace:^"). Is it possible to dispense with this dependency in real cases out there?

@emilgpa
Copy link
Author

emilgpa commented Jun 12, 2024

I updated to react to 19. The error persists. Updated to waku 0.20.2 and the error was gone. Sorry for not trying it at the time, I was a little busy. It seems that the problem was solved a long time ago. I think this can be closed.

@dai-shi
Copy link
Owner

dai-shi commented Jun 13, 2024

👍

@dai-shi dai-shi closed this as completed Jun 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

5 participants