NPM import - Uncaught SyntaxError: Cannot use import statement outside a module

Hi! I’ve been really looking for an answer to this one on my own and I come to the community because I’m out of options :slight_smile: So thanks in advance for any hints.

I’m trying to import AOS into my project.
So I went ahead and installed it:

npm install --save aos@next

and then added this to my script.js in assets

import AOS from 'aos';
import 'aos/dist/aos.css'; 

AOS.init();

Finally I added this to my footer:

{{ $script := resources.Get "js/script.js" | minify}}
<script src="{{ $script.Permalink }}"></script>

All I’m getting in the console is this:

Uncaught SyntaxError: Cannot use import statement outside a module

Help? What am I doing wrong?

You call js.Build first to build your js.

2 Likes

Thanks, that is the right resource.

Yet it doesn’t seem clear to my how I should handle CSS via import.

{{ $built := resources.Get "js/script.js" | js.Build "main.js" }}
<script src="{{ $built.Permalink }}"></script>

JS File:

import { AOS } from 'aos';
import * as data from 'aos/dist/aos.css';

AOS.init();

Error:

Cannot import "node_modules/aos/dist/aos.css" into a 
JavaScript file without an output path configured

@SuperSonicSites I would not try to import the stylesheet in your JS file.

Instead, I would @import it using Scss, or Concat it into your stylesheet bundle.

@SuperSonicSites

I had the same issue with fullcalendar.io. The main.js file in the common folder included an import of a css file. I deleted that single line and it worked. Likely aos has the same issue.


Edit: Of course, you would then have to manually copy the css file from the import into your build directory, which obviously does not make sense, and you would not be able to easily import the modules without taking these steps every time. It was late and this does not solve the problem. I have been looking for a solution all morning but have not found one if anyone else sees this and knows what to do.

The error arises from esbuild, specifically seen in this test case.
esbuild bundler tests

func TestImportCSSFromJSWriteToStdout(t *testing.T) {
	css_suite.expectBundled(t, bundled{
		files: map[string]string{
			"/entry.js": `
				import "./entry.css"
			`,
			"/entry.css": `
				.entry { color: red }
			`,
		},
		entryPaths: []string{"/entry.js"},
		options: config.Options{
			Mode:          config.ModeBundle,
			WriteToStdout: true,
		},
		expectedScanLog: `entry.js: error: Cannot import "entry.css" into a JavaScript file without an output path configured
`,
	})
}

I may not have time to test this and I have not looked at the Hugo source code to see, but the error arises from writing to standard output. It will work if an output directory is configured. I do not know if you can specific the targetpath option for js.Build to a directory or only a file. I am posting this here in case someone else has time to check before I get to it. ESBuild should be able to output a css file next to the js file.

I was having the same problem. By the looks of it esbuild does not support this, I did
read their docs but I couldn’t get it work.

Solution

The solution for me was to not even worry about that. All I did was drag and drop my svg and css in to the static folder and called it done.

I even tried executing a template on a jsx file and got it working but couldn’t do safehtml. If you want to see my react.html partial here it is, I don’t really need execute template since
I could not get it to work I just moved the svg to my images and called it done.
This is the react code in a hugo partial which works great. The only problem is the transferring of css and images which is not a big deal. I ended up doing drag and drop for the images.

baseof.html

{{/* xfer css/images  - Esbuild won't do import */}}
{{partial "react/react.html"  (dict  "jsx" "react/index.jsx" "css" "react/App.css" "page" .) }}

react/react.html

<script src="https://unpkg.com/react@17/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js" crossorigin></script>

{{$react_file := .jsx }}
{{ $externals := slice "react" "react-dom" }}
{{ $defines := dict "process.env.NODE_ENV" `"development"` }}
{{ $opts := dict "targetPath" "out.js" "externals" $externals "defines" $defines }}
{{ $built := resources.Get $react_file |  js.Build $opts }}
{{/* Could not figure out how to xfer images with ExecuteAsTempalate solution: drag and drop.*/}}
{{/* $built := resources.Get $react_file | ExecuteAsTemplate "out.jsx" . |  js.Build $opts */}}
<script type="text/javascript" src="{{ $built.RelPermalink }}" defer></script>

{{with .css}}
{{$react_css := resources.Get .}}
{{ $css := slice $react_css | resources.Concat "out.css" }}
<link rel='stylesheet' href='{{$css.RelPermalink}}' type='text/css' media='all' />
{{end}}

Hopefully this helps someone out there who was in my situation. :slight_smile:

Hey! did your find a solution? I have the exact same problem and I would love to not modify the package :slight_smile:

1 Like

The “cannot use import statement outside a module” error occurs in JavaScript because import statements are only supported in ECMAScript modules (i.e. modules with the .mjs extension), and not in regular scripts (i.e. scripts with the .js extension).

If you are trying to use an import statement in a regular script, you will need to use a different approach to include the required code, such as using a CommonJS require statement, or using a bundler such as Webpack or Rollup.

Here’s an example of using a CommonJS require statement to include the code from another module:

// myModule.js
export const greeting = 'Hello, World!';

// index.js
const myModule = require('./myModule.js');

console.log(myModule.greeting);