react-helmet-async icon indicating copy to clipboard operation
react-helmet-async copied to clipboard

Vite SSG: The requested module 'react-helmet-async' does not provide an export named 'HelmetProvider'

Open HHogg opened this issue 1 year ago • 10 comments

I'm using the SSG approach that the Vite docs link to, which produces an ESNext build that is then reimported for pre-rendering routes. After adding in react-helmet-async, this approach fails with

import { HelmetProvider } from "react-helmet-async";
         ^^^^^^^^^^^^^^
SyntaxError: Named export 'HelmetProvider' not found. The requested module 'react-helmet-async' 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-helmet-async';
const { HelmetProvider } = pkg;

I tried all the variations of defining the import (default, * as) and none of these had any effect.

Workaround Vite has a ssr.noexternal config, which fixed it for me.

export default defineConfig({
  plugins: [react()],
  ssr: {
    noExternal: ['react-helmet-async'],
  },
});

I also played about with react-helment-async's package.json locally to point the main at the esm build this resolved the issue for me. I also separately defined this package as "type": "module" and specified the "exports" field and this also worked. So I think there's a referencing config that isn't playing nicely with the vite ssg approach.

The vite config is fine for me now so I'm not going to look into this further, but hopefully this issue helps someone else looking in the future.

HHogg avatar Dec 03 '23 22:12 HHogg

Same effect here and thanks for providing the ssr.noExternal workaround (which works for me as well).

AvalonCV avatar Dec 06 '23 13:12 AvalonCV

Same problem if this gets imported into something being ran through tsx

alexturpin avatar Jan 11 '24 01:01 alexturpin

Note that this same issue occurs when importing via an ESM file in Node.

> node asdf.mjs
file:///V:/scratch/asdf.mjs:1
import { HelmentProvider } from "react-helmet-async"
         ^^^^^^^^^^^^^^^
SyntaxError: Named export 'HelmentProvider' not found. The requested module 'react-helmet-async' 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:

The issue is the CJS exports are not statically analyzable:

var src_exports = {};
__export(src_exports, {
  Helmet: () => Helmet,
  HelmetData: () => HelmetData,
  HelmetProvider: () => HelmetProvider
});
module.exports = __toCommonJS(src_exports);

dsherret avatar May 01 '24 22:05 dsherret

We fixed it by patching package.json.

diff --git a/package.json b/package.json
index bc9cb36d157e5db2a7614d028a5a59262c8711f6..d9271fd0f0c7489f91ad6ada3fb130a6ddc0a051 100644
--- a/package.json
+++ b/package.json
@@ -3,8 +3,7 @@
   "version": "2.0.3",
   "description": "Thread-safe Helmet for React 16+ and friends",
   "sideEffects": false,
-  "main": "./lib/index.js",
-  "module": "./lib/index.esm.js",
+  "main": "./lib/index.esm.js",
   "typings": "./lib/index.d.ts",
   "repository": "http://github.com/staylor/react-helmet-async",
   "author": "Scott Taylor <[email protected]>",
@@ -12,6 +11,7 @@
   "files": [
     "lib/"
   ],
+  "type": "module",
   "dependencies": {
     "invariant": "^2.2.4",
     "react-fast-compare": "^3.2.2",

gajus avatar May 03 '24 22:05 gajus

@gajus thanks for your pointer! I have submitted a PR #230 to address this issue. There is some module resolution issue that caused the CI to fail, maybe you could take a look?

geyang avatar Aug 10 '24 10:08 geyang