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

Vite plugin upset dependencies barrel files #7865

Closed
1 task done
xHomu opened this issue Nov 1, 2023 · 8 comments
Closed
1 task done

Vite plugin upset dependencies barrel files #7865

xHomu opened this issue Nov 1, 2023 · 8 comments

Comments

@xHomu
Copy link
Contributor

xHomu commented Nov 1, 2023

What version of Remix are you using?

v2.2.0

Are all your remix dependencies & dev-dependencies using the same version?

  • Yes

Steps to Reproduce

The vite plugin gets upset with certain dependencies' barrel files, complicating migrate path. Thus far, I encountered this issue with remix-i18next and react-code-block.

  1. npm install; npm run dev

Expected Behavior

If I avoid the barrel file and import directly, then the library works as expected

- import { CodeBlock } from "react-code-block";
+ import { CodeBlock } from "node_modules/react-code-block/dist/code-block.js";
image

Actual Behavior

The errors would be either of:

12:24:39 PM [vite] Error when evaluating SSR module /app/routes/_index.tsx: failed to import "react-code-block"
|- Error: Cannot find module '/Users/gamepress/Documents/GitHub/remix-template-vite/node_modules/react-code-block/dist/code-block' imported from /Users/gamepress/Documents/GitHub/remix-template-vite/node_modules/react-code-block/dist/index.js
    at new NodeError (node:internal/errors:406:5)
    at finalizeResolution (node:internal/modules/esm/resolve:233:11)
    at moduleResolve (node:internal/modules/esm/resolve:845:10)
    at defaultResolve (node:internal/modules/esm/resolve:1043:11)
    at ModuleLoader.defaultResolve (node:internal/modules/esm/loader:383:12)
    at ModuleLoader.resolve (node:internal/modules/esm/loader:352:25)
    at ModuleLoader.getModuleJob (node:internal/modules/esm/loader:228:38)
    at ModuleWrap.<anonymous> (node:internal/modules/esm/module_job:85:39)
    at link (node:internal/modules/esm/module_job:84:36)
12:41:38 PM [vite] Error when evaluating SSR module /app/utils/i18n/i18next.server.tsx: failed to import "remix-i18next"
|- /Users/gamepress/Documents/GitHub/core/node_modules/remix-i18next/browser/index.js:1
export * from "./client";
^^^^^^

SyntaxError: Unexpected token 'export'
    at internalCompileFunction (node:internal/vm:73:18)
    at wrapSafe (node:internal/modules/cjs/loader:1153:20)
    at Module._compile (node:internal/modules/cjs/loader:1205:27)
    at Module._extensions..js (node:internal/modules/cjs/loader:1295:10)
    at Object.require.extensions.<computed> [as .js] (/Users/gamepress/Documents/GitHub/core/node_modules/ts-node/src/index.ts:1608:43)
    at Module.load (node:internal/modules/cjs/loader:1091:32)
    at Function.Module._load (node:internal/modules/cjs/loader:938:12)
    at cjsLoader (node:internal/modules/esm/translators:284:17)
    at ModuleWrap.<anonymous> (node:internal/modules/esm/translators:234:7)
    at ModuleJob.run (node:internal/modules/esm/module_job:217:25)
@xHomu
Copy link
Contributor Author

xHomu commented Nov 1, 2023

Also reported on sergiodxa/remix-i18next#161

@hi-ogawa
Copy link
Contributor

hi-ogawa commented Nov 2, 2023

The issue might be partly due to react-code-block not conforming to ESM strictly.
I think node esm resolution strictly requires file extension to be written out, so react-code-block is supposed to have this internally:

// in react-code-block/dist/index.js
export * from './code-block.js'; // instead of './code-block'

Not quite sure yet, but the reason why direct import node_modules/react-code-block/dist/code-block.js works might be because vite thinking this is a local source file and thus vite applying all the transpilation like normal application source, so it's not required to be as strict as ESM (like typesscript's moduleResolution = Bundler).

The effect of it is probably similar to not "externalizing" the dependency (cf. https://vitejs.dev/guide/ssr.html#ssr-externals).
I tested with this config and this also seems to work, so maybe this is another workaround:

import { defineConfig } from "vite";
import { unstable_vitePlugin as remix } from "@remix-run/dev";
import tsconfigPaths from "vite-tsconfig-paths";

export default defineConfig({
  plugins: [remix(), tsconfigPaths()],
  ssr: {
    noExternal: ["react-code-block"]
  }
});

@pcattori pcattori added the vite label Nov 2, 2023
@xHomu
Copy link
Contributor Author

xHomu commented Nov 2, 2023

The issue might be partly due to react-code-block not conforming to ESM strictly. I think node esm resolution strictly requires file extension to be written out, so react-code-block is supposed to have this internally:

// in react-code-block/dist/index.js
export * from './code-block.js'; // instead of './code-block'

Not quite sure yet, but the reason why direct import node_modules/react-code-block/dist/code-block.js works might be because vite thinking this is a local source file and thus vite applying all the transpilation like normal application source, so it's not required to be as strict as ESM (like typesscript's moduleResolution = Bundler).

The effect of it is probably similar to not "externalizing" the dependency (cf. https://vitejs.dev/guide/ssr.html#ssr-externals). I tested with this config and this also seems to work, so maybe this is another workaround:

import { defineConfig } from "vite";
import { unstable_vitePlugin as remix } from "@remix-run/dev";
import tsconfigPaths from "vite-tsconfig-paths";

export default defineConfig({
  plugins: [remix(), tsconfigPaths()],
  ssr: {
    noExternal: ["react-code-block"]
  }
});

Thanks, that did the trick! Should this be considered solved as a vite problem instead of remix problem?

The trick should be added to the migration doc, reminds me a lot of the serverdependenciestobundle prop we had in remix.config.

@seanmcquaid
Copy link

Seeing something similar with a few of my dependencies as well! I tried the suggested fix above but got compilation errors in dev.

@hi-ogawa
Copy link
Contributor

hi-ogawa commented Nov 3, 2023

I'm glad that it worked in some cases!
One more note, I think optimizeDeps.include is another common vite option, which might be required to workaround esm/cjs issues for client. Some explanations are documented here:

@pcattori
Copy link
Contributor

Looks like react-code-block is misconfigured and we now have Future > Vite (Unstable) > Troubleshooting > ESM/CJS that documents the noExternal approach.

@seanmcquaid (or anyone else facing this issue) if you have a reproduction that cannot be fixed via noExternal, could you share it here and we can reopen the issue?

@bpfullmetal
Copy link

How can jQuery be used with the vite compiling? We're migrating a store to use vite but there is a lot of jQuery that we would rather not convert to js

@pcattori
Copy link
Contributor

@bpfullmetal this sounds maybe like a general Vite issue and not Remix-specific, so you might get better guidance asking in the Vite discord or GitHub. Are you able to get jQuery interop working how you expect in Vite w/o Remix?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants