Failed to load module script: Expected a JavaScript module script but the server responded with a MIME type of "text/html". Strict MIME type

when i run my vite project i get error on the console . Failed to load module script: Expected a JavaScript module script but the server responded with a MIME type of "text/html". Strict MIME type checking is enforced for module scripts per HTML spec.

there is no other error

Upvotes: 15

Views: 67570

Answers (8)

Neder Pereira
Neder Pereira

Reputation: 11

I had this problem in a react + vite + firebase project. My solution was, I didn't notice that in vite.confing.js there was a line with

display: 'standalone',
start_url: '/'

and in base it was like this:

base: './',

the error was leaving the start_url and base with './'

in this the path in index.html inside the dist would be wrong, if in doubt check if the path inside index.html is correct example: If in doubt look at the assets folder inside the dist!

./assets/index-S0wHBz0d.js

Upvotes: 1

James Sullivan
James Sullivan

Reputation: 13

To anyone who uses Firebase Hosting I noticed this happening suddenly.

TLDR; firebase-tools may have caused issue; downgrading to 13.0.0 fixed the issue

What I did (Did Not Work for me)

  • delete .vite / .cache folders
  • Rollback and redeploy
  • Delete Build folder, delete .firebase folders
  • Changed firebase.json to force *.js files to appear as application/json
  • Delete vite.config.js "base"
  • Adding "base" back with "./" (And subsequently deleting it)
  • Hard Refresh / Incognito (Same result)

What I did before this happpend was I updated firebase-tools to the latest version (13.11.4 at time of writing), and the issue started after that.

I downgraded to 13.0.0 and the issue vanished. Perhaps an issue with the uploading method or something? Perhaps it didnt place the .js files in the hosting space and that was the entire issue, but I dont think you can check Firebase Hosting directly so cant confirm.

Upvotes: 0

Ben Matela
Ben Matela

Reputation: 72

I was getting this issue on Firebase + React + Vite + ts and after trying all sorts of things I went to Chrome Incognito only to find it running perfectly there. Back on Chrome I just opened a new tab and it started showing up.

Upvotes: 0

Helto
Helto

Reputation: 605

Was having the same error, but the build was fine, just needed a hard refresh. Found this gem from the Vite docs after trying a bunch of this stuff... [https://vitejs.dev/guide/build.html][1]

Vite emits vite:preloadError event when it fails to load dynamic imports. event.payload contains the original import error. If you call event.preventDefault(), the error will not be thrown.

window.addEventListener('vite:preloadError', (event) => {
    window.reload() // for example, refresh the page
})

When a new deployment occurs, the hosting service may delete the assets from previous deployments. As a result, a user who visited your site before the new deployment might encounter an import error. This error happens because the assets running on that user's device are outdated and it tries to import the corresponding old chunk, which is deleted. This event is useful for addressing this situation.

Upvotes: 3

mihaa123
mihaa123

Reputation: 1338

TL;DR - the error is misleading - the server is not finding the index.html file.

Explanation below assumes you are deploying the public dist folder as a sub directory of the server folder. Something like:

Project
|
+-- dist
|   |
|   +-- index.html
|   +-- assets
|   +-- |
|        +-- index-fb329e31.js
|        +-- index-ec6a2ce7.css
|
+-- index.html
+-- index.js

You have 3 modes of working with vite:

  1. development where vite server serves the static files
  2. development with built files - where your express server serves the static files
  3. production with built files - where your express server serves the static files

Case 1: development, 2 ports

In this scenario you work with 2 ports - vite (5173 by default) and your express server (let's say its 3002). You have hmr & all that fun stuff. Opening the browser on localhost:5173 goes to vite server. It knows how to load the correct static files. Inside your app you have API calls that go to localhost:3002.

In your express file your write a handler for it:

app.use('/hello', (req, res) => res.send('world'))

Everyone is happy :)

Case 2: development, 1 port

Now you want to build & test everything works before deploying to prod. You need to run your app as you'd run it in prod - where the express server is serving the static files.
  • you build the client static files with vite build. This generates a dist folder with all the static assets & index.html file
  • you run the server & run the app in the browser on localhost:3002

Now all requests go to the server, which wasn't the case before. You need to point express to your static folder like so:

// ++
app.use(express.static(path.join(__dirname, 'dist')))
// ++
app.use('/hello', (req, res) => res.send('world'))

Note: the actual path depends on your folder structure, so you might need to modify this a bit

Now going to localhost:3002 will serve your index.html file
Everyone is happy :)

Case 3: production

This works very similarly to case 2, as here also the express server is serving all the files.

Bonus: API requests & client router

Once you add a client router to your application (e.g. /profile page), you will need to tell express that this should serve a static file and not search for a /profile endpoint. Easiest way to do this is to prefix all api calls with something like /api, and tell express that all other requests not starting with /api (like /profile) should return the index.html.

Example:

app.use(express.static(path.join(__dirname, 'dist')))
// ++
app.get(/^(?!\/api).\*/, (req, res) => {
    res.sendFile(path.join(\_\_dirname, 'dist', 'index.html'))
})
// ++
app.use('/hello', (req, res) => res.send('world'))

Upvotes: 2

Mahesh Shitole
Mahesh Shitole

Reputation: 912

Changing

vite build --base=./

to

vite build --base=/

solve my problem.

Upvotes: 15

bramchi
bramchi

Reputation: 810

I had the same error and managed to fix it.

By default Vite builds html with absolute asset references into the dist directory, because it assumes you deploy the dist folder to a root domain.

But if your project lives in a subdirectory like mine does, the absolute asset references won't work correctly.

Vite has a base config option that you can tweak to have it build relative assets urls. Check the docs.

// vite.config.js
export default {
  base: './',
};

Or you can pass this config option when running the build command through the command line:

vite build --base=./

This works for Vite 4.3.9.

Upvotes: 12

Midiman
Midiman

Reputation: 173

I had this issue. For me what fixed it is my index.html elements that referred to the JS was using a leading / in front of 'assets'. I removed this to make it a relative path...

<script type="module" crossorigin src="assets/index-cd561.js"></script>
<link rel="stylesheet" href="assets/index-cd561.css">

Maybe this will help someone, maybe, in the current landscape of npm builders, it won't help and it's some completely different error.

Upvotes: 2

Related Questions