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

Implement 'exports' field in package.json for the core & basics setup packages #692

Merged
merged 1 commit into from
Oct 24, 2024

Conversation

fatton139
Copy link
Contributor

Added exports field to the core (@uiw/react-codemirror) and basic setup (@uiw/codemirror-extensions-basic-setup) package.json so Node-like environments such as the test runners can utilise the esm outputs.

Context:

Our unit tests are failing with:

Unrecognized extension value in extension set ([object Object]). This sometimes happens because multiple instances of @codemirror/state are loaded, breaking instanceof checks.

After some investigation, it looks like when this library is used in a Node environment all imports use the cjs output. main and module are already defined and work for bundlers. However, Node doesn't have support for module and opts to look in exports for entry points. Since exports is not defined it falls back to main meaning Node will use the cjs outputs of this library. Normally this is fine, but the @codemirror packages (i.e. @codemirror/language) in the peerDependencies do define exports so the esm outputs are used if we use any of those packages are used in our source code resulting in the error above.

We're using @codemirror/language to construct an extension that gets passed into useCodeMirror, where cjs is used but the extension uses the esm output. This results in the instanceof checfailingil as the esm instance is not the cjs class.

Likely related to #680 as they're using SSR which is potentially also in a Node-like environment.

We've manually modified the package.json locally to include the export field asserted our tests are passing and are using the correct esm output.

@jaywcjlove jaywcjlove merged commit 8f1ff2d into uiwjs:master Oct 24, 2024
1 check failed
jaywcjlove added a commit that referenced this pull request Oct 24, 2024
@jaywcjlove
Copy link
Member

"exports": {
".": {
"require": "./cjs/index.js",
"import": "./esm/index.js"
},
"./*": "./*"
},

@fatton139 modified exports field to fix README.md loading issue in documentation, unsure if other problems persist

github-actions bot pushed a commit that referenced this pull request Oct 24, 2024
@fatton139
Copy link
Contributor Author

"exports": {
".": {
"require": "./cjs/index.js",
"import": "./esm/index.js"
},
"./*": "./*"
},

@fatton139 modified exports field to fix README.md loading issue in documentation, unsure if other problems persist

Thanks for fixing that, no problems on our side.

Cheers!

jaywcjlove added a commit that referenced this pull request Oct 25, 2024
github-actions bot pushed a commit that referenced this pull request Oct 25, 2024
@sotasan
Copy link

sotasan commented Nov 1, 2024

This change now breaks my build and I always get this error:

#17 8.759 website:build: (node:66) Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension.
#17 8.759 website:build: (Use `node --trace-warnings ...` to show where the warning was created)
#17 8.760 website:build: /build/node_modules/.pnpm/@[email protected]_@[email protected]_@codemirror+lan_t2q76exsezmrgemrtohcxodgnq/node_modules/@uiw/codemirror-extensions-basic-setup/esm/index.js:1
#17 8.760 website:build: import { lineNumbers, highlightActiveLineGutter, highlightSpecialChars, drawSelection, dropCursor, rectangularSelection, crosshairCursor, highlightActiveLine, keymap } from '@codemirror/view';
#17 8.760 website:build: ^^^^^^
#17 8.760 website:build: 
#17 8.760 website:build: SyntaxError: Cannot use import statement outside a module
#17 8.760 website:build:     at wrapSafe (node:internal/modules/cjs/loader:1383:18)
#17 8.760 website:build:     at Module._compile (node:internal/modules/cjs/loader:1412:20)
#17 8.760 website:build:     at Object..js (node:internal/modules/cjs/loader:1551:10)
#17 8.760 website:build:     at Module.load (node:internal/modules/cjs/loader:1282:32)
#17 8.760 website:build:     at Function._load (node:internal/modules/cjs/loader:1098:12)
#17 8.760 website:build:     at TracingChannel.traceSync (node:diagnostics_channel:315:14)
#17 8.760 website:build:     at wrapModuleLoad (node:internal/modules/cjs/loader:215:24)
#17 8.760 website:build:     at cjsLoader (node:internal/modules/esm/translators:318:5)
#17 8.760 website:build:     at ModuleWrap.<anonymous> (node:internal/modules/esm/translators:258:7)
#17 8.760 website:build:     at ModuleJob.run (node:internal/modules/esm/module_job:262:25)

@jaywcjlove
Copy link
Member

@sotasan Could you provide an example to help us resolve this issue?

@rev-artian
Copy link

Similar to @sotasan I get the following error when running in dev mode (for HMR):

1:53:44 AM [vite] Error when evaluating SSR module virtual:react-router/server-build: failed to import "@uiw/react-codemirror/esm/index.js"
|- /Users/rev-artian/Documents/artian/frontend/node_modules/@uiw/react-codemirror/esm/index.js:1
import _extends from "@babel/runtime/helpers/extends";
^^^^^^

SyntaxError: Cannot use import statement outside a module
    at wrapSafe (node:internal/modules/cjs/loader:1281:20)
    at Module._compile (node:internal/modules/cjs/loader:1321:27)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1416:10)
    at Module.load (node:internal/modules/cjs/loader:1208:32)
    at Function.Module._load (node:internal/modules/cjs/loader:1024:12)
    at cjsLoader (node:internal/modules/esm/translators:348:17)
    at ModuleWrap.<anonymous> (node:internal/modules/esm/translators:297:7)
    at ModuleJob.run (node:internal/modules/esm/module_job:222:25)
    at ModuleLoader.import (node:internal/modules/esm/loader:316:24)
    at nodeImport (file:///Users/rev-artian/Documents/artian/frontend/node_modules/vite/dist/node/chunks/dep-CB_7IfJ-.js:53056:15)

1:53:44 AM [vite] Internal server error: Cannot use import statement outside a module
      at wrapSafe (node:internal/modules/cjs/loader:1281:20)
      at Module._compile (node:internal/modules/cjs/loader:1321:27)
      at Object.Module._extensions..js (node:internal/modules/cjs/loader:1416:10)
      at Module.load (node:internal/modules/cjs/loader:1208:32)
      at Function.Module._load (node:internal/modules/cjs/loader:1024:12)
      at cjsLoader (node:internal/modules/esm/translators:348:17)
      at ModuleWrap.<anonymous> (node:internal/modules/esm/translators:297:7)
      at ModuleJob.run (node:internal/modules/esm/module_job:222:25)
      at ModuleLoader.import (node:internal/modules/esm/loader:316:24)
      at nodeImport (file:///Users/rev-artian/Documents/artian/frontend/node_modules/vite/dist/node/chunks/dep-CB_7IfJ-.js:53056:15)

and this error when running in production mode:

> start
> react-router-serve ./build/server/index.js

(node:72467) Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension.
(Use `node --trace-warnings ...` to show where the warning was created)
/Users/rev-artian/Documents/artian/frontend/node_modules/@uiw/react-codemirror/esm/index.js:1
import _extends from "@babel/runtime/helpers/extends";
^^^^^^

SyntaxError: Cannot use import statement outside a module
    at wrapSafe (node:internal/modules/cjs/loader:1281:20)
    at Module._compile (node:internal/modules/cjs/loader:1321:27)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1416:10)
    at Module.load (node:internal/modules/cjs/loader:1208:32)
    at Function.Module._load (node:internal/modules/cjs/loader:1024:12)
    at cjsLoader (node:internal/modules/esm/translators:348:17)
    at ModuleWrap.<anonymous> (node:internal/modules/esm/translators:297:7)
    at ModuleJob.run (node:internal/modules/esm/module_job:222:25)
    at ModuleLoader.import (node:internal/modules/esm/loader:316:24)
    at run (/Users/rev-artian/Documents/artian/frontend/node_modules/@react-router/serve/dist/cli.js:80:15)

I'm using Typescript with Vite as my compiler. I get these errors as soon as I run npm run dev and npm run start respectively and try to access my app locally.

@fatton139
Copy link
Contributor Author

fatton139 commented Dec 4, 2024

The exports field directs node imports to the appropriate cjs or esm files depending on whether you're using cjs or esm. Based off of @sotasan and @rev-artian's error stacks it seems like an import from a cjs file has been incorrectly routed to the esm entrypoint when it should be going to the cjs entrypoint.

Would you be able to confirm your configurations for your build & package.json are setup to use cjs not esm (it could be the other way too, you may want to be using esm but it's not configured to do so)? Thanks.

@sotasan
Copy link

sotasan commented Dec 4, 2024

@fatton139 I am using a normal Vite project with ESM configured in the package.json and I am importing it with the normal ESM syntax.

@rev-artian
Copy link

rev-artian commented Dec 4, 2024

@fatton139 My intent is to use esm. When I import ReactCodeMirror using import ReactCodeMirror from '@uiw/react-codemirror' it points to "/Users/rev-artian/Documents/artian/frontend/node_modules/@uiw/react-codemirror/esm/index".

package.json:

{
  ...
  "sideEffects": false,
  "type": "module",
  "scripts": {
    "build": "react-router build",
    "dev": "react-router dev",
    "format": "prettier --config .prettierrc --write .",
    "lint": "eslint --ignore-path .gitignore --cache --cache-location ./node_modules/.cache/eslint .",
    "start": "react-router-serve ./build/server/index.js",
    "typecheck": "react-router typegen && tsc"
  },
  "dependencies": { ... },
  "devDependencies": { ... },
  "engines": {
    "node": ">=20.0.0"
  }
}

vite.config.ts:

import { reactRouter } from '@react-router/dev/vite';
import { defineConfig } from 'vite';
import tsconfigPaths from 'vite-tsconfig-paths';
import tailwindcss from 'tailwindcss';

export default defineConfig({
  plugins: [reactRouter(), tsconfigPaths()],
  css: {
    postcss: {
      plugins: [tailwindcss()],
    },
  },
});

@fatton139
Copy link
Contributor Author

@rev-artian I noticed you're using react-router as the build so I took a quick look and indeed your issue occurs. This seems to be an issue already raised remix-run/remix#9554 remix-run/remix#9070 and there are workarounds in the form of limiting your imports to *.client.tsx files or using the direct cjs import: import CodeMirror from '@uiw/react-codemirror/cjs/index.js'; which seems to remove the error for me. I believe a complete fix needs to come from the react-router side.

@sotasan I set up a "normal" vite app using npm create vite@latest my-vue-app -- --template react-ts and copied in the example from https://github.com/uiwjs/react-codemirror?tab=readme-ov-file#usage which also seems to have worked. Can you provide more information? Thanks.

@sotasan
Copy link

sotasan commented Dec 4, 2024

@fatton139 Sorry, I should have been more specific. This is not what you would call "normal". I am using SvelteKit (SPA) with the basic setup package, but everything should be bundled with normal Vite. Nevertheless I will try using the CJS file directly.

@sotasan
Copy link

sotasan commented Dec 4, 2024

I have now upgraded all my dependencies and with that, it seems to work.

@rev-artian
Copy link

@fatton139 I hadn't seen the *.client.tsx suggestion before, but that worked, thank you!

I had already tried import CodeMirror from '@uiw/react-codemirror/cjs/index.js'; which does get rid of the error on initial load but the component doesn't show up anymore, and instead I get the following error in the browser:

Screenshot 2024-12-04 at 2 18 32 PM

@aspiers
Copy link
Contributor

aspiers commented Dec 16, 2024

As mentioned in #613 (comment), this same approach needs applying to themes/theme/package.json.

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

Successfully merging this pull request may close these issues.

5 participants