简体   繁体   English

Webpack dev服务器抛出错误 - 拒绝执行脚本,因为它的MIME类型('text / html')不可执行

[英]Webpack dev server throws error - Refused to execute script because its MIME type ('text/html') is not executable

I use Webpack bundler and Webpack dev server for local development. 我使用Webpack bundler和Webpack dev服务器进行本地开发。 The front-end is in React.js+Redux and the back-end in Node.js and koajs. 前端位于React.js + Redux中,后端位于Node.js和koajs中。

In back-end, I use passportjs library for user authentication and other libraries koa-passport , passport-facebook , passport-google-auth for authentication through Facebook or Google. 在后端,我使用passportjs库进行用户身份验证,其他库koa-passportpassport-facebookpassport-google-auth通过Facebook或Google进行身份验证。 Basically, I implemented koa-passport-example . 基本上,我实施了koa-passport-example

If my application wants to redirect user to Facebook or Google login page, Webpack dev server throws error: 如果我的应用程序想要将用户重定向到Facebook或Google登录页面,Webpack dev服务器会抛出错误:

GET http://localhost:8090/auth/bundle.js net::ERR_ABORTED

Refused to execute script from 'http://localhost:8090/auth/bundle.js' because its MIME type ('text/html') is not executable, and strict MIME type checking is enabled.

If I generate bundle by Webpack and host it on Node.js server, I don't get this error. 如果我通过Webpack生成bundle并将其托管在Node.js服务器上,我不会收到此错误。 I need to find out how to set up Webpack dev server to get rid of this error message. 我需要找出如何设置Webpack开发服务器以摆脱此错误消息。

package.json 的package.json

    "scripts": {
    "debug": "./node_modules/nodemon/bin/nodemon.js --inspect ./script/server.js",
    "webpack": "npm run serve | npm run dev",
    "start": "node ./script/server.js",
    "serve": "./node_modules/.bin/http-server -p 8080",
    "dev": "webpack-dev-server -d --progress --colors --port 8090 --hot --inline",
  },
        "dependencies": {
        "@koa/cors": "^2.2.1",
        "actions": "^1.3.0",
        "aws-s3-form": "^0.3.5",
        "aws-sdk": "^2.165.0",
        "axios": "^0.16.2",
        "bootstrap": "^3.3.7",
        "bootstrap-timepicker": "github:janzenz/bootstrap-timepicker#feature/compatibility-es6",
        "d3-ease": "^1.0.3",
        "d3-selection": "^1.1.0",
        "d3-shape": "^1.2.0",
        "d3-transition": "^1.1.0",
        "font-awesome": "^4.7.0",
        "http-server": "^0.10.0",
        "immutable": "^3.8.2",
        "jquery": "^3.2.1",
        "jquery-ui": "^1.12.1",
        "jquery.panzoom": "^3.2.2",
        "jsonwebtoken": "^8.1.0",
        "juration": "^0.1.0",
        "knex": "^0.14.2",
        "koa": "^2.3.0",
        "koa-body": "^2.5.0",
        "koa-bodyparser": "^4.2.0",
        "koa-logger": "^3.1.0",
        "koa-passport": "^4.0.1",
        "koa-ratelimit": "^4.0.0",
        "koa-router": "^7.2.1",
        "koa-send": "^4.1.1",
        "koa-session": "^5.5.1",
        "koa-static": "^4.0.2",
        "moment": "^2.18.1",
        "objection": "^0.9.2",
        "oembed-auto": "0.0.3",
        "passport": "^0.4.0",
        "passport-facebook": "^2.1.1",
        "passport-google-oauth": "^1.0.0",
        "passport-jwt": "^3.0.1",
        "pg": "^7.4.0",
        "probe-image-size": "^3.1.0",
        "puppeteer": "^0.12.0",
        "react": "^15.6.1",
        "react-dom": "^15.6.1",
        "react-dropzone": "^4.2.1",
        "react-facebook-login": "^3.6.2",
        "react-google-login": "^3.0.2",
        "react-modal": "^3.1.2",
        "react-redux": "^5.0.6",
        "react-router": "^4.2.0",
        "react-router-dom": "^4.2.2",
        "react-router-redux": "^4.0.8",
        "react-share": "^1.17.0",
        "react-transition-group": "^1.2.1",
        "react-twitter-widgets": "^1.7.1",
        "redux": "^3.7.2",
        "redux-thunk": "^2.2.0",
        "request": "^2.83.0",
        "request-promise-native": "^1.0.5",
        "select2": "^4.0.4",
        "select2-bootstrap-theme": "0.1.0-beta.10",
        "shave": "^2.1.3",
        "sqlite3": "^3.1.13",
        "sugar-date": "^2.0.4",
        "svg-url-loader": "^2.3.0",
        "twitter": "^1.7.1",
        "twitter-widgets": "^1.0.0",
        "unfluff": "^1.1.0"
      },
      "devDependencies": {
        "autoprefixer": "^7.1.4",
        "babel": "^6.23.0",
        "babel-core": "^6.26.0",
        "babel-loader": "^7.1.2",
        "babel-preset-es2015": "^6.24.1",
        "babel-preset-react": "^6.24.1",
        "css-loader": "^0.28.7",
        "duplicate-package-checker-webpack-plugin": "^2.0.2",
        "eslint": "^4.7.2",
        "eslint-config-airbnb": "^15.1.0",
        "eslint-plugin-import": "^2.7.0",
        "eslint-plugin-jsx-a11y": "^5.1.1",
        "eslint-plugin-react": "^7.4.0",
        "favicons-webpack-plugin": "0.0.7",
        "file-loader": "^0.11.2",
        "friendly-errors-webpack-plugin": "^1.6.1",
        "html-webpack-plugin": "^2.30.1",
        "less": "^2.7.2",
        "less-loader": "^4.0.5",
        "node-sass": "^4.5.3",
        "nodemon": "^1.12.1",
        "npm-install-webpack-plugin": "^4.0.5",
        "postcss": "^6.0.11",
        "postcss-loader": "^2.0.6",
        "sass-loader": "^6.0.6",
        "style-loader": "^0.18.2",
        "url-loader": "^0.5.9",
        "webpack": "^3.6.0",
        "webpack-dev-server": "^2.9.1",
        "webpack-merge": "^4.1.0",
        "webpack-notifier": "^1.5.0"
      }

webpack.config.js webpack.config.js

const webpack = require('webpack');
const webpackMerge = require('webpack-merge');
const path = require('path');
const WebpackNotifierPlugin = require('webpack-notifier');
const autoprefixer = require('autoprefixer');

const TARGET = process.env.npm_lifecycle_event;
console.log(`target event is ${TARGET}`);

let outputFileName = 'app';
outputFileName += TARGET === 'prod' ? '.min.js' : '.js';

const common = {
  entry: {
    app: './index.jsx',
  },
  module: {
    rules: [
      {
        test: /\.js[x]?$/,
        exclude: /(node_modules|bower_components)/,
        use: {
          loader: 'babel-loader?presets[]=es2015&presets[]=react',
        },
      },
      {
        test: /\.scss$/,
        loaders: [
          'style-loader',
          'css-loader',
          'sass-loader',
        ],
      },
      {
        test: /\.less$/,
        loaders: ['style-loader', 'css-loader', 'less-loader'],
      },
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader'],
      },
      {
        test: /\.(eot|ttf|svg|gif|png|jpg|otf|woff|woff2)$/,
        loader: 'url-loader',
      },
    ],
  },
  plugins: [
    new webpack.ProvidePlugin({
      jQuery: 'jquery',
      $: 'jquery',
      jquery: 'jquery',
      'window.jQuery': 'jquery',
    }),
    new webpack.LoaderOptionsPlugin({
      options: {
        postcss: [
          autoprefixer({
            browsers: ['last 3 versions'],
          }),
        ],
      },
    }),
    new WebpackNotifierPlugin(),
  ],
};

if (TARGET === 'dev' || !TARGET) {
  module.exports = webpackMerge(common, {
    devtool: 'eval-source-map',
    output: {
      filename: 'bundle.js',
      sourceMapFilename: '[file].map',
    },
    devServer: {
      contentBase: path.resolve(__dirname), // New
      historyApiFallback: true,
    },
  });
}

login.jsx login.jsx

...
    <a href="/auth/facebook" className="btn btn--secondary ut-font-decima">Login</a>
...

server.js server.js

const Koa = require('koa');
const Router = require('koa-router');
const logger = require('koa-logger');
const cors = require('@koa/cors');
const bodyParser = require('koa-bodyparser');
const serve = require('koa-static');
const path = require('path');
const session = require('koa-session');

const app = new Koa();
// trust proxy
app.proxy = true;

const router = new Router();

// sessions
app.keys = ['your-session-secret'];
app.use(session({}, app));

app.use(logger());
app.use(cors());
app.use(bodyParser());

require('./controllers/auth');
const passport = require('koa-passport');

app.use(passport.initialize());
app.use(passport.session());

app.use(serve(path.join(process.env.PWD, '/dist')));

router
  .get('/auth/facebook', passport.authenticate('facebook'))
  .get(
    '/auth/facebook/callback',
    passport.authenticate('facebook', {
      successRedirect: '/podcast',
      failureRedirect: '/',
    }),
  );

app.use(router.routes()).use(router.allowedMethods());

// don't listen to this port if the app is required from a test script
if (!module.parent) {
  app.listen(process.env.PORT || 1337);
  console.log('app listen on port: 1337');
}

Looking into Webpack further we should be clear about what Webpack is and what it is used for. 进一步研究Webpack,我们应该清楚Webpack是什么以及它用于什么。 Webpack is front end tool, it will build front end projects and has the capability of managing tasks similar to gulp/grunt. Webpack是前端工具,它将构建前端项目,并具有管理类似于gulp / grunt的任务的能力。 It can be a server to serve static content. 它可以是服务静态内容的服务器。 But what it is not is a full fledged back end server. 但它不是一个完整的后端服务器。 You can't easily build back end API and manage complex routing. 您无法轻松构建后端API并管理复杂的路由。 This includes things like login functionality. 这包括登录功能等。 Instead of reinventing the wheel, use Webpack as a dev tool to easily modify and see the updated result for web design. 而不是重新发明轮子,使用Webpack作为开发工具,轻松修改和查看网页设计的更新结果。 And if you need more functionality integrate Webpack by running it in watch mode and run the back end server at the same time and setup a proxy so that Webpack will defer to the back end server for complex routing. 如果您需要更多功能,请通过在监视模式下运行Webpack来集成Webpack,同时运行后端服务器并设置代理,以便Webpack将遵循后端服务器进行复杂路由。 You can use any back end technology, though Webpack is built on Common.js library so integrating it into node.js and express seems to be the easiest because they are part of a javascript ecosystem. 你可以使用任何后端技术,虽然Webpack是在Common.js库上构建的,因此将它集成到node.js和express中似乎是最简单的,因为它们是javascript生态系统的一部分。

If I could comment I would, anyhow, I was reading through the webpack docs for the DevServer and I Think that the server is responding with the incorrect MIME type possibly because it isn't finding the bundle.js script where it is expecting it. 如果我可以发表评论,无论如何,我正在阅读DevServer的webpack文档,我认为服务器正在使用不正确的MIME类型进行响应,可能是因为它没有找到它所期望的bundle.js脚本。 I noticed the console output being ' http://localhost:8090/auth/bundle.js ' and in the documentation the dev server expects it in the root. 我注意到控制台输出是' http:// localhost:8090 / auth / bundle.js ',并且在文档中dev服务器期望它在根目录中。 I think that if bundle.js is really in the auth directory that you may need to tell the server where it is with the publicPath option. 我认为如果bundle.js真的在auth目录中,你可能需要通过publicPath选项告诉服务器它在哪里。

output: {
  filename: 'bundle.js',
  sourceMapFilename: '[file].map',
  path: path.resolve('build/js/),// moves the bundle.js out of the root
  publicPath: '/auth/' // it is recommended that the publicPath is declared in both output and devServer
  // publicPath links the path of bundle.js to this path in the html.
},
devServer: {
  contentBase: path.resolve(__dirname), // New
  historyApiFallback: true,
  publicPath: "/auth/" // Both publicPath options should be the same as what is in your html loading the scripts
},

As I understand the webpack dev server, the bundle.js is not written to disc. 据我所知,webpack dev服务器,bundle.js不会写入光盘。 It is served virtually. 几乎是服务。

Now with all of this there is a need to either proxy the already built node.js server or build one to handle just the api you need to use. 现在有了所有这些,需要代理已经构建的node.js服务器或构建一个来处理你需要使用的api。 Webpack provides a dev middleware module to use as middleware in a basic node.js express server. Webpack提供了一个开发中间件模块,用作基本node.js express服务器中的中间件。 You can see the basics of the middleware here . 您可以在此处查看中间件的基础知识。 What you really need to start with from the documentation is installing via npm webpack-dev-middleware and express 您真正需要从文档开始的是通过npm webpack-dev-middleware和express安装

npm install --save-dev webpack-dev-middleware express

Then create a new server file like index.js in the root of the project because you already have a server.js. 然后在项目的根目录中创建一个新的服务器文件,如index.js,因为您已经有了server.js。 Now create the basic server that you need with only the routing and packages you need to handle the api calls. 现在创建您需要的基本服务器,只需要处理api调用所需的路由和包。

const express = require('express');
const webpack = require('webpack');
const webpackDevMiddleware = require('webpack-dev-middleware');

const app = express();
const config = require('./webpack.config.js');
const compiler = webpack(config);

// Tell express to use the webpack-dev-middleware and use the webpack.config.js
// configuration file as a base.
app.use(webpackDevMiddleware(compiler, {
  publicPath: config.output.publicPath
}));

// Serve the files on port 3000.
app.listen(3000, function () {
  console.log('Example app listening on port 3000!\n');
});

This is from the webpack website and you will need to do your own api routing. 这是来自webpack网站,您需要自己进行api路由。 And you would run the project like a normal node project and it should handle the bundle.js requests. 您将像普通节点项目一样运行项目,它应该处理bundle.js请求。

And let's not forget that there is a plubin for koa koa-webpack-dev .I haven't personally used koa, but if you need it you can see how to use it here . 让我们不要忘记koa koa-webpack-dev有一个插件。我没有亲自使用过koa,但如果你需要它,你可以在这里看到如何使用它。

i had a similar issue and thought i'd post my solution incase anyone had a similar issue. 我有一个类似的问题,并认为我发布我的解决方案,任何人都有类似的问题。 basically, i was trying to refresh my app on a dynamic subroute, localhost:3000/route/dynamicRoute , and it was throwing a similar error. 基本上,我试图在动态子路由, localhost:3000/route/dynamicRoute上刷新我的应用程序,并且它抛出了类似的错误。 i solved my issue by adding publicPath: '/' to my output settings in my webpack config. 我解决了我的问题,通过增加publicPath: '/'我的output设置,在我的WebPack配置。 the following is my webpack.config.js for reference. 以下是我的webpack.config.js供参考。

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');

const outputDirectory = 'dist';

module.exports = {
 entry: ['babel-polyfill', './src/client/index.js'],
 output: {
  path: path.join(__dirname, outputDirectory),
  filename: 'bundle.js',
  publicPath: '/'
 },
 module: {
  rules: [
   {
    test: /\.js$/,
    exclude: /node_modules/,
    use: {
     loader: 'babel-loader'
    }
  },
  {
   test: /\.css$/,
   use: ['style-loader', 'css-loader']
  },
  {
   test: /\.(pdf|jpg|png|gif|svg|ico)$/,
    use: [
     {
      loader: 'url-loader'
     },
    ]
   }
 ]
},
devServer: {
  port: 3000,
  open: true,
  proxy: {
   '/api': 'http://localhost:8080'
  },
  historyApiFallback: true,
  contentBase: './public/index.html',
  hot: true
 },
 plugins: [
  new CleanWebpackPlugin([outputDirectory]),
  new HtmlWebpackPlugin({
   template: './public/index.html',
   favicon: './public/favicon.ico'
  })
 ]
};

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 拒绝从“http://127.0.0.1:5500/”执行脚本,因为它的 MIME 类型(“text/html”)不可执行 - Refused to execute script from 'http://127.0.0.1:5500/' because its MIME type ('text/html') is not executable 将 jQuery 插件导入 Angular 2+ 拒绝执行脚本,因为其 MIME 类型('text/html')不可执行 - Importing jQuery plugin into Angular 2+ Refused to execute script because its MIME type ('text/html') is not executable 拒绝从 &#39;URL&#39; 执行脚本,因为它的 MIME 类型 (&#39;text/html&#39;) 不可执行,并且启用了严格的 MIME 类型检查 - Refused to execute script from 'URL' because its MIME type ('text/html') is not executable, and strict MIME type checking is enabled 拒绝从“ file_name.php”执行脚本,因为其MIME类型(“ text / html”)不可执行,并且启用了严格的MIME类型检查 - Refused to execute script from 'file_name.php' because its MIME type ('text/html') is not executable, and strict MIME type checking is enabled 拒绝执行脚本,因为 MIME 类型('text/html')不可执行,并且启用了严格的 MIME 类型检查 - Refused to execute script because MIME type ('text/html') is not executable, and strict MIME type checking is enabled 拒绝执行脚本,因为其 MIME 类型 (&#39;image/gif&#39;) 不可执行 - Refused to execute script because its MIME type ('image/gif') is not executable Angular 6:拒绝从“URL”执行脚本,因为它的 MIME 类型()不可执行,并且启用了严格的 MIME 类型检查 - Angular 6 : Refused to execute script from 'URL' because its MIME type( ) is not executable, & strict MIME type checking is enabled 拒绝执行脚本,因为它的 MIME 类型 ('application/gzip') 不可执行,并且启用了严格的 MIME 类型检查 - Refused to execute script because its MIME type ('application/gzip') is not executable, and strict MIME type checking is enabled 拒绝从&#39;*&#39;执行脚本,因为它的MIME类型(&#39;application / json&#39;)不可执行,并且严格的MIME类型为che - getting Refused to execute script from '*' because its MIME type ('application/json') is not executable, and strict MIME type che GeoJSON 文件:拒绝执行脚本,因为其 MIME 类型 (&#39;&#39;) 不可执行,并且启用了严格的 MIME 类型检查 - GeoJSON file: Refused to execute script from because its MIME type ('') is not executable, and strict MIME type checking is enabled
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM