Webpack/Babel转换的.js文件MIME类型错误致Chrome拒绝执行
这个问题我之前也碰到过,本质是你的Express服务器没有正确处理静态资源请求,导致.js文件被当成HTML返回了。下面给你拆解问题根源和更优雅的解决方案:
问题根源分析
你遇到的报错:Refused to execute script from ... because its MIME type ('text/html') is not executable,核心原因是Express的catch-all路由(app.get('*', ...))优先于静态资源处理逻辑。当浏览器请求transformed.js时,服务器直接返回了index.html的内容,所以MIME类型变成了text/html,浏览器自然拒绝执行。
你的临时手动判断文件后缀的方案虽然能工作,但不够健壮——后续如果新增.css、.png等其他静态资源,还要逐一添加判断,维护成本很高。
更优雅的解决方案
推荐使用Express官方提供的express.static中间件来处理静态资源,这是最标准、可靠的方式:
1. 调整server.js代码
把静态资源处理的代码放在catch-all路由之前,这样Express会先匹配静态资源请求,只有当请求的资源不存在时,才会走catch-all路由返回index.html(适合SPA单页应用场景):
const express = require('express'); const path = require('path'); const app = express(); // 第一步:配置静态资源目录,指向存放打包后文件的目录 app.use(express.static(path.join(__dirname, 'app'))); // 第二步:处理SPA路由,静态资源不存在时返回index.html app.get('*', function (req, res) { res.sendFile(path.join(__dirname, 'app', 'index.html')); }); const port = process.env.PORT || 3000; app.listen(port, () => { console.log(`Server running on port ${port}`); });
修改后,当浏览器请求transformed.js时,Express会自动从app目录找到该文件,并返回正确的application/javascript MIME类型,不需要手动设置头信息。
2. 优化Webpack配置(可选但推荐)
目前你把打包后的transformed.js输出到了app目录,建议改成单独的dist/client目录,避免源文件和打包文件混在一起,更符合项目规范:
修改webpack.config.js中client配置的output:
{ name: 'client', entry: path.join(__dirname, 'app/index.js'), output: { path: path.join(__dirname, 'dist/client'), // 输出到dist/client目录 filename: 'transformed.js' }, // ...其他配置不变 }
同时修改HTMLWebpackPlugin的生成路径:
const HTMLWebpackPluginConfig = new HTMLWebpackPlugin({ template: path.join(__dirname, 'app/index_template.html'), filename: path.join(__dirname, 'dist/client/index.html'), // 生成到dist/client inject: 'body' });
最后同步修改server.js的静态资源目录:
app.use(express.static(path.join(__dirname, 'dist/client'))); app.get('*', function (req, res) { res.sendFile(path.join(__dirname, 'dist/client', 'index.html')); });
这样项目结构更清晰,也能避免误删源文件。
额外小提示
- 运行
npm run build后,检查dist/client目录是否生成了transformed.js和index.html,确保打包流程正常。 - 开发阶段可以直接用
webpack-dev-server,它本身会处理静态资源,不需要依赖Express服务器,直接访问http://localhost:8080即可预览应用。
内容的提问来源于stack exchange,提问作者x77x

