I recently migrated a project from Vue2 + Webpack + Storybook 6.4 to Vue3 + Vite + Storybook 7.0.0-beta. After the migration, I encountered an issue where my Storybook deployment failed, and I received the following error in 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."
After some investigation, I determined that the problem had to do with how ViteFinal in the main.ts file in .storybook was resolving extensions when merging Config.
Here's an example of how your main.ts in storybook subfolder could look like:
import type { StorybookConfig } from '@storybook/vue3-vite'
const config: StorybookConfig = {
stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|ts|tsx)'],
addons: [
'@storybook/addon-links',
'@storybook/addon-essentials',
'@storybook/addon-interactions'
],
framework: {
name: '@storybook/vue3-vite',
options: {}
},
core: {
builder: "@storybook/builder-vite",
},
docs: {
autodocs: 'tag'
}
}
export default config
And here are the extensions in my vite.config.ts:
export default defineConfig({
css: {
preprocessorOptions: {
scss: {
additionalData: `
@import "./src/styles/_animations.scss";
@import "./src/styles/_variables.scss";
@import "./src/styles/_mixins.scss";
@import "./src/styles/_helpers.scss";
`,
},
},
},
plugins: [
vue(),
],
define: { 'process.env': {} },
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url)),
},
extensions: ['.js', '.json', '.jsx', '.mjs', '.ts', '.tsx', '.vue'],
},
test: {
environment: 'jsdom',
deps: {
inline: true,
},
},
});
To fix the issue, I added the following code to my Web.config file:
<system.webServer>
<staticContent>
<mimeMap fileExtension=".mjs" mimeType="text/javascript" />
</staticContent>
</system.webServer>
However, this gave me an error 500. After further research, I found an answer provided by Eric Barr on another Stack Overflow question which explained that IIS 8 and above are duplicating the mimeType. To fix this, I removed and then added the mimeType as shown below:
<system.webServer>
<staticContent>
<remove fileExtension=".mjs" />
<mimeMap fileExtension=".mjs" mimeType="text/javascript" />
</staticContent>
</system.webServer>
For those who are not familiar with MIME types, they are a standard way to indicate the type of content that is being served by a web server. Common MIME types include text/html, text/css, and application/json, among others.
In summary, if you encounter the "Failed to load module script" error when deploying Storybook using Vite, check that your MIME types are set up correctly and make sure to remove and then add the mimeType when working with IIS 8 and above.
I hope this article helps others who may encounter a similar issue!
By following these steps, you should be able to fix the MIME type error and successfully deploy Storybook with Vue3 and Vite. If you encounter any issues or have any questions, feel free to leave a comment below.
Top comments (3)
I've been stymied by this for (literally) days! But. Where do you put the Web.config file and how does vite.js know about it? I didn't see any references to it... (and haven't run across a Web.config file in other work)
Thx for the article! If I can understand the config file I'll be golden.
Web.config file is used for configuring settings and behaviors for the application when hosted on the IIS. Vue.js does not directly know or care about Web.config file.
This file need to be accessible to web server. The best place to put this file is in public folder, since public folder is default location for static assets. There your server can easily access them and serve them to the client.
Nice post!
You made my Pi day even better! :D