primereact icon indicating copy to clipboard operation
primereact copied to clipboard

SSR: Wrongly published ESM code

Open brillout opened this issue 2 years ago • 21 comments

Describe the bug

I'm the author of vite-plugin-ssr and users are reporting the following problem with PrimeReact:

file:///home/fabio/Desktop/playground/vps-cjs-issue/dist/server/entries/pages_index-page.mjs:2
import { Badge } from "primereact/badge/badge.esm.js";
         ^^^^^
SyntaxError: Named export 'Badge' not found. The requested module 'primereact/badge/badge.esm.js' 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 'primereact/badge/badge.esm.js';
const { Badge } = pkg;

    at ModuleJob._instantiate (node:internal/modules/esm/module_job:128:21)
    at ModuleJob.run (node:internal/modules/esm/module_job:194:5)
    at async Promise.all (index 0)
    at ESMLoader.import (node:internal/modules/esm/loader:385:24)
    at Object.pageFile.loadFile (/home/fabio/Desktop/playground/vps-cjs-issue/node_modules/vite-plugin-ssr/dist/cjs/shared/getPageFiles/parseGlobResults.js:35:40)
    at async Promise.all (index 0)
    at loadPageFilesServerSide (/home/fabio/Desktop/playground/vps-cjs-issue/node_modules/vite-plugin-ssr/dist/cjs/shared/getPageFiles/analyzePageServerSide/loadPageFilesServerSide.js:10:5)
    at async Promise.all (index 0)
    at loadPageFilesServer (/home/fabio/Desktop/playground/vps-cjs-issue/node_modules/vite-plugin-ssr/dist/cjs/node/runtime/renderPage/loadPageFilesServer.js:15:110)
    at /home/fabio/Desktop/playground/vps-cjs-issue/node_modules/vite-plugin-ssr/dist/cjs/node/prerender/runPrerender.js:257:48

I believe the problem is that Node.js treats the module as CJS because node_modules/primereact/badge/package.json doens't contain type: "module". A fix would be to change the file extension of node_modules/primereact/badge/badge.esm.js to badge.esm.mjs, as the .mjs reliably tells Node.js that the file is an ESM module.

Reproducer

https://github.com/brillout/vps-cjs-issue

PrimeReact version

9.6.0

React version

18.x

Language

TypeScript

Build / Runtime

Vite

Browser(s)

No response

Steps to reproduce the behavior

See the reproduction's Readme.

Expected behavior

No response

brillout avatar Jul 20 '23 10:07 brillout

Excellent feedback @brillout let me check with the team and get back to you.

melloware avatar Jul 20 '23 12:07 melloware

I submitted a PR switching the ESM to .mjs.

melloware avatar Sep 25 '23 21:09 melloware

@mertsincan Can you please review this before tomorrow's launch?

cagataycivici avatar Sep 26 '23 18:09 cagataycivici

It is a little difficult to decide this right away. Many libraries like us add modular structures to their bundles, and none of them make such changes. It is necessary to evaluate the pros and cons of this. I'll read https://blog.isquaredsoftware.com/2023/08/esm-modernization-lessons/

mertsincan avatar Sep 27 '23 14:09 mertsincan

Describe the bug

I got the same error and it seems to have been resolved:

// core/prime-react/index.tsx
import * as BtnPrime from "primereact/button";
const { Button } = BtnPrime;
export { Button };

and where I import to use

// Component.tsx
import { Button } from "#/core/prime-react";

however, a new bug appeared:

.../node_modules/primereact/api/api.esm.js:3
import { ObjectUtils } from 'primereact/utils';
^^^^^^

SyntaxError: Cannot use import statement outside a module
    at internalCompileFunction (node:internal/vm:73:18)
    at wrapSafe (node:internal/modules/cjs/loader:1178:20)
    at Module._compile (node:internal/modules/cjs/loader:1220:27)
    at Module._extensions..js (node:internal/modules/cjs/loader:1310:10)
    at Module.load (node:internal/modules/cjs/loader:1119:32)
    at Module._load (node:internal/modules/cjs/loader:960:12)
    at ModuleWrap.<anonymous> (node:internal/modules/esm/translators:169:29)
    at ModuleJob.run (node:internal/modules/esm/module_job:194:25)

i don't know how to handle it, can anyone give me some advice?

PrimeReact version

10.0.0

React version

18.x

vandinhhoangvu avatar Sep 29 '23 02:09 vandinhhoangvu

It is a bug I reported to PrimeTek and they are aware

melloware avatar Sep 29 '23 05:09 melloware

OK try 10.0.2 please.

melloware avatar Sep 29 '23 15:09 melloware

I have upgraded the version to 10.0.2 but looks like it hasn't been completely fixed yet

/dist/server/entry-server.js:20
import { Button } from "primereact/button/button.esm.js";
         ^^^^^^
SyntaxError: Named export 'Button' not found. The requested module 'primereact/button/button.esm.js' 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 'primereact/button/button.esm.js';
const { Button } = pkg;

    at ModuleJob._instantiate (node:internal/modules/esm/module_job:124:21)
    at async ModuleJob.run (node:internal/modules/esm/module_job:190:5)

This bug also occurs in many other components.

vandinhhoangvu avatar Oct 02 '23 03:10 vandinhhoangvu

Yes the original issue here is still open as PrimeTek reverted my change. They wanted to investigate deeper the correct way to fix it.

melloware avatar Oct 02 '23 11:10 melloware

I got the same problem. I tried adding PrimeReact to an Astro project, dev mode works fine, but when trying to build for prod I get this:

`Named export 'PrimeReactProvider' not found. The requested module 'primereact/api/api.esm.js' 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 'primereact/api/api.esm.js'; const { PrimeReactProvider } = pkg;`

LE a workaround is to add primereact to vite.ssr.noExternal, but that probably breaks treeshaking.

zawasp avatar Oct 26 '23 19:10 zawasp

I got the same problem. I tried adding PrimeReact to an Astro project, dev mode works fine, but when trying to build for prod I get this:

`Named export 'PrimeReactProvider' not found. The requested module 'primereact/api/api.esm.js' 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 'primereact/api/api.esm.js'; const { PrimeReactProvider } = pkg;`

LE a workaround is to add primereact to vite.ssr.noExternal, but that probably breaks treeshaking.

Thank you for mentioning your workaround. Just to be clear for anyone else who stumbles on this, you need to add the vite.ssr.noExternal into your astro config file. Cheers!

xflysaround avatar Nov 01 '23 00:11 xflysaround

Although a workaround, not ideal at all, as this includes the entire primereact library in the production build (~230kb). Huge if I just include one or two controls.

zawasp avatar Nov 01 '23 07:11 zawasp

OK PR submitted I am pretty sure solves the problems for most bundlers: https://github.com/primefaces/primereact/pull/5237

According to this guide: https://github.com/frehner/modern-guide-to-packaging-js-library

melloware avatar Nov 04 '23 11:11 melloware

My PR does not solve the problem and I think makes things worse...

melloware avatar Nov 21 '23 14:11 melloware

I have the same problem that was exposed in previous posts:

$ npm run build

[email protected] build astro build

22:54:45 [build] output: "static" 22:54:45 [build] directory: C:\dev\Demos\javascript\demo-astro-react-vite\dist
22:54:45 [build] Collecting build info... 22:54:45 [build] ✓ Completed in 281ms. 22:54:45 [build] Building static entrypoints... 22:54:46 [vite] ✓ built in 913ms 22:54:46 [build] ✓ Completed in 952ms.

building client (vite) 22:54:47 [vite] ✓ 74 modules transformed. 22:54:47 [vite] dist/_astro/primeicons.C6QP2o4f.woff2 35.15 kB 22:54:47 [vite] dist/_astro/primeicons.MpK4pl85.ttf 84.98 kB 22:54:47 [vite] dist/_astro/primeicons.WjwUDZjB.woff 85.06 kB 22:54:47 [vite] dist/_astro/primeicons.DMOk5skT.eot 85.16 kB 22:54:47 [vite] dist/_astro/primeicons.Dr5RGzOO.svg 342.53 kB │ gzip: 105.26 kB 22:54:47 [vite] dist/_astro/index.BeFKMXcz.css 193.09 kB │ gzip: 22.30 kB 22:54:47 [vite] dist/_astro/client.BZfCgiig.js 1.56 kB │ gzip: 0.81 kB 22:54:47 [vite] dist/_astro/DialogDemo.CqeHn6I6.js 131.82 kB │ gzip: 35.38 kB 22:54:47 [vite] dist/_astro/index.BG5Ro7KF.js 140.91 kB │ gzip: 45.31 kB 22:54:47 [vite] ✓ built in 1.02s

generating static routes Named export 'Button' not found. The requested module 'primereact/button/button.esm.js' 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 'primereact/button/button.esm.js'; const { Button } = pkg;

Stack trace: at ModuleJob._instantiate (node:internal/modules/esm/module_job:134:21) at async ModuleLoader.import (node:internal/modules/esm/loader:323:24) at async generatePages (file:///C:/dev/Demos/javascript/demo-astro-react-vite/node_modules/astro/dist/core/build/generate.js:164:9) at async AstroBuilder.build (file:///C:/dev/Demos/javascript/demo-astro-react-vite/node_modules/astro/dist/core/build/index.js:134:5) at async build (file:///C:/dev/Demos/javascript/demo-astro-react-vite/node_modules/astro/dist/core/build/index.js:46:3)

Any fix for this problem?

basshamut avatar Apr 23 '24 21:04 basshamut

No current fix other than I have realized Javascript packaging is a nightmare.

melloware avatar Apr 23 '24 21:04 melloware