Webpack dev server выдает ошибку-отказался выполнять скрипт, потому что его тип MIME ('text / html') не является исполняемым

я использую webpack bundler и Webpack dev server для локальной разработки. Передняя часть находится в React.JS + Redux и back-end в узле.js и koajs.

в задней части, я использую passportjs библиотека для аутентификации пользователей и других библиотеки КоА-паспорт, паспорт-facebook, паспорт-google-auth для аутентификации через Facebook или Google. В основном, я реализовал koa-паспорт-пример.

если мое приложение хочет перенаправить пользователя на страницу входа Facebook или Google, Webpack dev server выдает ошибку:

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.

если я создаю пакет Webpack и размещаю его на узле.JS server, я не получаю эту ошибку. Мне нужно узнать, как настроить сервер webpack dev, чтобы избавиться от этой ошибки сообщение.

пакета.в 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.конфиг.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,
    },
  });
}

логин.jsx

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

сервер.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');
}

2 ответов


глядя в Webpack далее, мы должны быть ясны о том, что такое Webpack и для чего он используется. Webpack-это инструмент переднего плана, он будет строить проекты переднего плана и имеет возможность управлять задачами, подобными gulp/grunt. Это может быть сервер для обслуживания статического контента. Но что это не полноценный сервер. Вы не можете легко построить back end API и управлять сложной маршрутизацией. Это включает в себя такие вещи, как функциональность входа. Вместо изобретения колеса используйте Webpack в качестве инструмента разработки легко изменить и увидеть обновленный результат для веб-дизайна. И если вам нужно больше функциональности, интегрируйте Webpack, запустив его в режиме просмотра и одновременно запустите сервер back end и настройте прокси-сервер, чтобы Webpack отложился до сервера back end для сложной маршрутизации. Вы можете использовать любую технологию back end, хотя Webpack построен на общем.библиотека js так интегрирует ее в узел.js и express кажутся самыми простыми, потому что они являются частью экосистемы javascript.

Если Я мог бы прокомментировать я бы, так или иначе, я читал документы webpack для DevServer, и я думаю, что сервер отвечает с неправильным типом MIME, возможно, потому что он не находит пакет.сценарий js, где он его ожидает. Я заметил, что вывод консоли"http://localhost:8090/auth/bundle.js' и в документации dev-сервер ожидает его в корне. Я думаю, что если бандл.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
},

как я понимаю, сервер webpack dev, пакет.js не записывается на диск. Он подается практически.

теперь со всем этим есть необходимость либо прокси уже построенный узел.JS server или построить один для обработки только api, который вам нужно использовать. Webpack обеспечивает модуль промежуточного разработки для использования в качестве промежуточного слоя в базовый узел.сервер JS express. Вы можете увидеть основы middleware здесь. Что тебе действительно нужно? для начала из документации устанавливается через npm webpack-dev-middleware и express

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

затем создайте новый файл сервера, такой как index.js в корне проекта, потому что у вас уже есть сервер.js. Теперь создайте базовый сервер, который вам нужен, только с маршрутизацией и пакетами, необходимыми для обработки вызовов 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');
});

это с веб-сайта webpack, и вам нужно будет сделать свою собственную маршрутизацию api. И вы бы запустили проект, как обычный проект узла, и он должен обрабатывать пакет.Яш запросы.

и давайте не забывать, что есть plubin для КоА koa-webpack-dev.Я лично не использовал КоА, но если вам это нужно, вы можете увидеть, как его использовать здесь.


у меня была аналогичная проблема, и я думал, что опубликую свое решение, если у кого-то была аналогичная проблема. в принципе, я пытался обновить свое приложение на динамической подпространстве,localhost:3000/route/dynamicRoute, и он устраивал подобную ошибку. я решил свою проблему, добавив publicPath: '/' мой output настройки в моей конфигурации webpack. следующее мое 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'
  })
 ]
};