primefaces / primereact

The Most Complete React UI Component Library
https://primereact.org
MIT License
6.9k stars 1.05k forks source link

SSR: Wrongly published ESM code #4675

Open brillout opened 1 year ago

brillout commented 1 year ago

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

melloware commented 1 year ago

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

melloware commented 1 year ago

I submitted a PR switching the ESM to .mjs.

cagataycivici commented 1 year ago

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

mertsincan commented 1 year ago

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/

vandinhhoangvu commented 1 year ago

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

melloware commented 1 year ago

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

melloware commented 1 year ago

OK try 10.0.2 please.

vandinhhoangvu commented 1 year ago

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.

melloware commented 1 year ago

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

zawasp commented 1 year ago

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.

xflysaround commented 1 year ago

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!

zawasp commented 1 year ago

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.

melloware commented 1 year ago

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 commented 12 months ago

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

basshamut commented 6 months ago

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

$ npm run build

demo-astro-react-vite@0.0.1 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?

melloware commented 6 months ago

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

ven0ms99 commented 1 month ago

Still have the same problem:

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;