Closed mttzr closed 3 years ago
Hi @mttzr, it sounds like this might be a problem with how you have your project set up rather than with this package. Do you have any snippets or a link you could post to help investigate?
@mttzr were you able to solve your issue?
Hello @DomParfitt,
I've got the same error message.
/home/cs/osequi/coco/node_modules/graphviz-react/lib/Graphviz.js:1
import * as React from 'react';
^^^^^^
SyntaxError: Cannot use import statement outside a module
at Object.compileFunction (node:vm:355:18)
at wrapSafe (node:internal/modules/cjs/loader:1022:15)
at Module._compile (node:internal/modules/cjs/loader:1056:27)
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1121:10)
at Module.load (node:internal/modules/cjs/loader:972:32)
at Function.Module._load (node:internal/modules/cjs/loader:813:14)
at Module.require (node:internal/modules/cjs/loader:996:19)
at require (node:internal/modules/cjs/helpers:92:18)
at eval (webpack-internal:///graphviz-react:1:18)
at Object.graphviz-react (/home/cs/osequi/coco/.next/server/pages/index.js:1941:1)
at __webpack_require__ (/home/cs/osequi/coco/.next/server/pages/index.js:23:31)
at eval (webpack-internal:///./src/apps/studies/ds/Home/Home.tsx:13:72)
at Module../src/apps/studies/ds/Home/Home.tsx (/home/cs/osequi/coco/.next/server/pages/index.js:530:1)
at __webpack_require__ (/home/cs/osequi/coco/.next/server/pages/index.js:23:31)
at eval (webpack-internal:///./src/apps/studies/ds/Home/index.ts:2:63)
at Module../src/apps/studies/ds/Home/index.ts (/home/cs/osequi/coco/.next/server/pages/index.js:542:1)
And this is the call:
const dot = `graph {
"1" [id="1",label=A]
"2" [id="2",label=B]
"1" -- "2" [source="1",target="2"]
}`;
...
<Graphviz dot={dot} />
I've just cloned your repo, built the package, run the demo, and all's fine.
Perhaps my problem comes from Next.js.
Hi @osequi.
Your problem most likely is caused by some configuration in your project rather than this package. Are you using NextJS with Typescript? The instructions in the README are for using the package with ES6-style imports, which is the standard way of performing imports in Typescript but if you are not using Typescript then you may need to use the older requires
syntax.
Hope that helps.
Thanks @DomParfitt,
I've checked the tsconfig.json
in your demo and it's very similar to my project's config:
{
"compilerOptions": {
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"strict": false,
"forceConsistentCasingInFileNames": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"baseUrl": "./src",
"paths": {
"@apps/*": ["apps/*"],
"@components": ["components"],
"@tokens": ["tokens/"]
},
"downlevelIteration": true
},
"include": ["next-env.d.ts", "mdx.d.ts", "**/*.ts", "**/*.tsx"],
"exclude": ["node_modules"]
}
This is your config:
{
"compilerOptions": {
"target": "es5",
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "preserve"
},
"include": [
"src"
]
}
The only difference was strict:false
and "allowSyntheticDefaultImports": true
. I've changed my config accordingly, and still the same error message ....
Another finding that might help.
I've created a new CRA/Typescript project, and added Graphviz. All works fine!. However when I run the tests, I'm getting the same error message:
Jest encountered an unexpected token
This usually means that you are trying to import a file which Jest cannot parse, e.g. it's not plain JavaScript.
By default, if Jest sees a Babel config, it will use that to transform your files, ignoring "node_modules".
Here's what you can do:
• If you are trying to use ECMAScript Modules, see https://jestjs.io/docs/en/ecmascript-modules for how to enable it.
• To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
• If you need a custom transformation specify a "transform" option in your config.
• If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.
You'll find more details and examples of these config options in the docs:
https://jestjs.io/docs/en/configuration.html
Details:
/home/cs/osequi/test-graphviz-cra/node_modules/graphviz-react/lib/Graphviz.js:1
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){import * as React from 'react';
^^^^^^
SyntaxError: Cannot use import statement outside a module
1 | import logo from "./logo.svg";
2 | import "./App.css";
> 3 | import { Graphviz } from "graphviz-react";
| ^
4 |
5 | /* eslint-disable import/no-webpack-loader-syntax */
6 | import Content from "!babel-loader!@mdx-js/loader!./App.mdx";
at Runtime.createScriptFromCode (node_modules/jest-runtime/build/index.js:1350:14)
at Object.<anonymous> (src/App.tsx:3:1)
This tells me the package works in CRA, and gives the same error in other two environments like Next.js and Jest. However I might be wrong.
@osequi what does your package.json
look like?
For the Nextjs app:
{
"name": "osequi",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"test": "jest",
"docs": "typedoc src/**/*.ts"
},
"dependencies": {
"@emotion/css": "^11.1.3",
"@emotion/react": "^11.1.4",
"@mdx-js/loader": "^1.6.22",
"@next/mdx": "^10.0.5",
"@react-aria/ssr": "^3.0.1",
"@react-aria/utils": "^3.6.0",
"graphviz-react": "^1.1.1",
"jsdom": "^16.4.0",
"lodash": "^4.17.20",
"modularscale-js": "^3.0.1",
"next": "^10.0.0",
"next-seo": "^4.24.0",
"normalize.css": "^8.0.1",
"react": "17.0.1",
"react-dom": "17.0.1",
"react-svg": "^13.0.1",
"slugify": "^1.5.0"
},
"devDependencies": {
"@testing-library/jest-dom": "^5.11.9",
"@testing-library/react": "^11.2.3",
"@types/jest": "^26.0.20",
"@types/lodash": "^4.14.168",
"@types/marked": "^1.2.2",
"@types/node": "^14.14.22",
"@types/react": "^17.0.0",
"jest": "^26.6.3",
"jest-environment-jsdom-fifteen": "^1.0.2",
"ts-jest": "^26.4.4",
"typedoc": "^0.20.21",
"typescript": "^4.1.3"
}
}
Thanks @osequi.
I've done a bit of digging and this is actually being caused by an interaction with NextJS that isn't particularly clear from the error message.
The TL;DR is that, by default, Next pre-renders every page but, unfortunately, graphviz-react
relies on some client-side stuff which won't be available when Next tries to do its pre-rendering. The workaround for this is to have Next dynamically import graphviz-react
so that it doesn't do this pre-rendering.
To do this, you will need to create a component file that simply re-exports graphviz-react
as a default
export:
components/Graphviz.tsx
import { Graphviz } from 'graphviz-react';
export default Graphviz;
This is because, unfortunately, Next is very opinionated about using default
exports, but graphviz-react
uses named exports.
Then in the page (or pages) you want to use the Graphviz
component on you need to import it using Next's dynamic
import, like so:
pages/graphviz
import dynamic from 'next/dynamic';
const Graphviz = dynamic(() => import('../components/Graphviz'), {ssr: false});
const GraphvizPage = () => {
const dot = 'graph{a--b}';
return <Graphviz dot={dot} />;
}
export default GraphvizPage;
This tells Next to import the re-exported component with server-side rendering disabled (because of the client-side requirement).
I'll add this to the README and will also update the graphviz-react
to include a default
export as well as the named exports, which will remove the need to do the re-export in components/Graphviz.tsx
.
Hi @osequi, is your component that re-exports Graphviz
under the pages
directory in your project structure? If so you will need to move it (I think the usual structure for Next is to have a components
directory in the root of the project). Next tries to pre-render everything that is in the pages
directory, so the component that re-exports Next can't live in the pages
directory.
I've got it working with a similar setup and am putting some changes in that should release soon to include a default
export alongside the named exports, which will remove the need for the re-exporting component and allow you to just dynamically import Graphviz
.
@osequi I've just released a new version (1.2.0
) that includes a default
export for the Graphviz
component. You should now be able to import the component in a NextJS page like so:
import dynamic from 'next/dynamic'
const Graphviz = dynamic(() => import('graphviz-react'), {ssr: false});
const GraphvizPage = () => {
const dot = 'graph{a--b--c}';
return <Graphviz dot={dot} />;
}
export default GraphvizPage;
@DomParfitt Thanks for the great help,
Now all works very fine :)
Keep up!
@osequi @DomParfitt Did you manage to find a work around for the testing issue with CRA?
I've created a new CRA/Typescript project, and added Graphviz. All works fine!. However when I run the tests, I'm getting the same error message
I'm running into the same problem that the project builds fine, apart from when running the jest tests, but since I am using create-react-app rather than Next, I can't add in the import dynamically.
@jake-goldsmith Can you open a new issue with some steps to reproduce. Thanks
Hi there,
after installing from npm and importing into my react project I'm seeing the following error:
SyntaxError: Cannot use import statement outside a module
Have others reported this?