Webpack 开发服务器抛出错误 - 拒绝执行脚本,因为它的 MIME 类型 ('text/html') 不可执行
Webpack dev server throws error - Refused to execute script because its MIME type ('text/html') is not executable
我使用 Webpack bundler 和 Webpack dev server 进行本地开发。前端在React.js+Redux,后端在Node.js和koajs.
在后端,我使用passportjs library for user authentication and other libraries koa-passport, passport-facebook, passport-google-auth for authentication through Facebook or Google. Basically, I implemented koa-passport-example。
如果我的应用程序想要将用户重定向到 Facebook 或 Google 登录页面,Webpack 开发服务器会抛出错误:
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 生成包并将其托管在 Node.js 服务器上,我不会收到此错误。我需要了解如何设置 Webpack 开发服务器以消除此错误消息。
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
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
...
<a href="/auth/facebook" className="btn btn--secondary ut-font-decima">Login</a>
...
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');
}
进一步研究Webpack,我们应该清楚Webpack是什么以及它的用途。 Webpack 是前端工具,它会构建前端项目,并具有类似于 gulp/grunt 的管理任务的能力。它可以是提供静态内容的服务器。但它不是一个完整的后端服务器。您无法轻松构建后端 API 和管理复杂的路由。这包括登录功能之类的东西。与其重新发明轮子,不如使用 Webpack 作为开发工具来轻松修改并查看网页设计的更新结果。如果您需要更多功能,请通过 运行 以监视模式集成 Webpack 并同时 运行 后端服务器并设置代理,以便 Webpack 将推迟到后端服务器进行复杂路由.您可以使用任何后端技术,尽管 Webpack 是建立在 Common.js 库上的,因此将它集成到 node.js 和 express 中似乎是最简单的,因为它们是 javascript 生态系统的一部分。
如果我可以发表评论,无论如何,我正在阅读 DevServer 的 webpack 文档,我认为服务器正在响应不正确的 MIME 类型,可能是因为它没有找到 bundle.js它期望它的脚本。我注意到控制台输出为“http://localhost:8090/auth/bundle.js”,并且在文档中开发服务器期望它位于根目录中。我认为如果 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
},
据我了解 webpack 开发服务器,bundle.js 没有写入光盘。它以虚拟方式提供。
现在有了所有这些,就需要代理已经构建的 node.js 服务器或构建一个来处理您需要使用的 api。 Webpack 提供了一个开发中间件模块,用作基本 node.js 快速服务器中的中间件。可以看看中间件的基础知识here。你真正需要从文档开始的是通过 npm webpack-dev-middleware 和 express
安装
npm install --save-dev webpack-dev-middleware express
然后在项目的根目录中创建一个新的服务器文件,例如index.js,因为您已经有一个server.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 路由。你会 运行 这个项目就像一个普通的节点项目,它应该处理 bundle.js 个请求。
别忘了还有koa的插件koa-webpack-dev
。我个人没有用过koa,但如果你需要的话可以看看如何使用它here。
我有一个类似的问题,我想我会 post 我的解决方案,以防有人遇到同样的问题。基本上,我试图在动态子路径 localhost:3000/route/dynamicRoute
上刷新我的应用程序,它抛出了与问题中提到的类似的错误。我通过将 publicPath: '/'
添加到我的 webpack 配置中的 output
设置来解决我的问题。以下是我的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'
})
]
};
我使用 Webpack bundler 和 Webpack dev server 进行本地开发。前端在React.js+Redux,后端在Node.js和koajs.
在后端,我使用passportjs library for user authentication and other libraries koa-passport, passport-facebook, passport-google-auth for authentication through Facebook or Google. Basically, I implemented koa-passport-example。
如果我的应用程序想要将用户重定向到 Facebook 或 Google 登录页面,Webpack 开发服务器会抛出错误:
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 生成包并将其托管在 Node.js 服务器上,我不会收到此错误。我需要了解如何设置 Webpack 开发服务器以消除此错误消息。
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
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
...
<a href="/auth/facebook" className="btn btn--secondary ut-font-decima">Login</a>
...
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');
}
进一步研究Webpack,我们应该清楚Webpack是什么以及它的用途。 Webpack 是前端工具,它会构建前端项目,并具有类似于 gulp/grunt 的管理任务的能力。它可以是提供静态内容的服务器。但它不是一个完整的后端服务器。您无法轻松构建后端 API 和管理复杂的路由。这包括登录功能之类的东西。与其重新发明轮子,不如使用 Webpack 作为开发工具来轻松修改并查看网页设计的更新结果。如果您需要更多功能,请通过 运行 以监视模式集成 Webpack 并同时 运行 后端服务器并设置代理,以便 Webpack 将推迟到后端服务器进行复杂路由.您可以使用任何后端技术,尽管 Webpack 是建立在 Common.js 库上的,因此将它集成到 node.js 和 express 中似乎是最简单的,因为它们是 javascript 生态系统的一部分。
如果我可以发表评论,无论如何,我正在阅读 DevServer 的 webpack 文档,我认为服务器正在响应不正确的 MIME 类型,可能是因为它没有找到 bundle.js它期望它的脚本。我注意到控制台输出为“http://localhost:8090/auth/bundle.js”,并且在文档中开发服务器期望它位于根目录中。我认为如果 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
},
据我了解 webpack 开发服务器,bundle.js 没有写入光盘。它以虚拟方式提供。
现在有了所有这些,就需要代理已经构建的 node.js 服务器或构建一个来处理您需要使用的 api。 Webpack 提供了一个开发中间件模块,用作基本 node.js 快速服务器中的中间件。可以看看中间件的基础知识here。你真正需要从文档开始的是通过 npm webpack-dev-middleware 和 express
安装npm install --save-dev webpack-dev-middleware express
然后在项目的根目录中创建一个新的服务器文件,例如index.js,因为您已经有一个server.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 路由。你会 运行 这个项目就像一个普通的节点项目,它应该处理 bundle.js 个请求。
别忘了还有koa的插件koa-webpack-dev
。我个人没有用过koa,但如果你需要的话可以看看如何使用它here。
我有一个类似的问题,我想我会 post 我的解决方案,以防有人遇到同样的问题。基本上,我试图在动态子路径 localhost:3000/route/dynamicRoute
上刷新我的应用程序,它抛出了与问题中提到的类似的错误。我通过将 publicPath: '/'
添加到我的 webpack 配置中的 output
设置来解决我的问题。以下是我的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'
})
]
};