webpack dev server not allowing POST fetch request - react app - reactjs

I am developing my first webapack-react app using webpack-dev-server, however I am running into issues sending POST requests to my flask backend api as I keep getting a 400 bad request error. Here is my post request:
fetch('/api/login', {
method: 'post',
headers: {'Content-Type':'application/json'},
body: JSON.stringify({"first_name": "name"})
});
If I tweak the above to a GET request (and remove body), the request goes through fine and I the api returns data.
Digging a little deeper, it seems as though webpack-dev-server doesn't permit POST requests - have I understood that correctly and is there a workaround?
Here is my webpack dev configuration:
const merge = require('webpack-merge');
const common = require('./webpack.common.js');
const webpack = require('webpack');
module.exports = merge(common, {
mode: 'development',
devtool: 'inline-source-map',
devServer: {
contentBase: './dist',
host:'0.0.0.0',
hot: true,
historyApiFallback: true,
proxy: {
'/api': {
target: 'http://flaskapp:5090',
pathRewrite: {'^/api': ''},
secure: false,
}
},
},
plugins: [
new webpack.HotModuleReplacementPlugin()
]
});

This is by no means the accepted answer. I'm just sharing my Webpack file to how I got it to work.
Here is my webpack.config file. I had the same issue the other day with making fetch requests with POST. However, I looked online to see if I could remove the /api from my fetch requests so I tried the rewrite module and it didn't work for me so I just removed it. In my fetch requests if I wanted to fetch something for example it would be /api/signup for example and my fetch worked. I also set up my proxy in webpack not in package.json
const webpack = require('webpack');
const path = require('path');
const nodeExternals = require('webpack-node-externals');
const HtmlWebPackPlugin = require('html-webpack-plugin');
var browserConfig = {
devServer: {
historyApiFallback: true,
proxy: {
"/api": "http://localhost:3012"
}
},
entry: ['babel-polyfill', __dirname + '/src/index.js'],
output: {
path: path.resolve(__dirname + '/public'),
filename: 'bundle.js',
publicPath: '/'
},
module: {
rules: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
query: {
presets: ['react', 'env', 'stage-0']
}
}
}
]
},
plugins: [
new HtmlWebPackPlugin({
template: './public/index.html',
})
]
}
var serverConfig = {
target: 'node',
externals: [nodeExternals()],
entry: __dirname + '/server/main.js',
output: {
path: path.resolve(__dirname + '/public'),
filename: 'server.js',
publicPath: '/'
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
query: {
presets: ['react', 'env', 'stage-0']
}
}
}
]
}
}
module.exports = [browserConfig, serverConfig]

Related

Webpack running through grunt webpack doesn't error or complete, or do anything

Trying to convert an old system off bower into npm using webpack, and grunt webpack. Just trying to use webpack to load in NPM files, not run anything else, and the rest of the grunt file finishes loading and uglifying and stuff, and runs its own node server. It gets to this point and freezes and never comes back.
Loading "grunt-webpack" plugin
Registering "/Users/***/***/***/node_modules/grunt-webpack/tasks" tasks.
Loading "webpack-dev-server.js" tasks...OK
+ webpack-dev-server
Loading "webpack.js" tasks...OK
+ webpack
Running "webpack" task
Here's my grunt code (super basic obviously)
webpack: {
options: require("./config/webpack.dev.js"),
},
Here's that dev file
const webpack = require('webpack');
const helpers = require('./helpers');
const merge = require('webpack-merge');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { BaseHrefWebpackPlugin } = require('base-href-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const ConcatPlugin = require('webpack-concat-plugin');
const ngInventory = require('./ng1-vendor-index.js');
const common = require('./webpack.common.js');
const ENV = process.env.NODE_ENV = process.env.ENV = 'dev';
module.exports = merge(common(ENV), {
devtool: 'source-map',
module: {
rules: [
{
test: /\.(ts|js)$/,
loaders: ['angular-router-loader'],
},
{
test: /\.((s*)css)$/,
use: [{
loader: 'style-loader',
},{
loader: 'css-loader',
},{
loader: 'sass-loader',
}]
},
{
test: /src\/.+\.(ts|js)$/,
exclude: /(node_modules|\.spec\.ts$)/,
loader: 'istanbul-instrumenter-loader',
enforce: 'post',
options: {
esModules: true
}
}
]
},
debug: true,
devTool: 'eval',
plugins: [
new ConcatPlugin({
uglify: false,
sourceMap: true,
name: 'vendor',
outputPath: './',
fileName: '[name].[hash].js',
filesToConcat: ngInventory.vendor1
}),
new BaseHrefWebpackPlugin({ baseHref: '/'}),
new HtmlWebpackPlugin({
favicon: helpers.root('client/assets/image/favicon.png'),
template: "./client/index.html",
filename: "./client/index.html",
}),
new webpack.NoEmitOnErrorsPlugin(),
],
});
And here is the common file:
const path = require('path');
const webpack = require('webpack');
const nodeExternals = require('webpack-node-externals')
const helpers = require('./helpers');
module.exports = env => ({
entry: {
server: './server/app.js',
},
resolve: {
extensions: ['.ts', '.js']
},
output: {
path: helpers.root(`dist/${env}`),
publicPath: '/',
filename: '[name].js'
},
target: 'node',
node: {
// Need this when working with express, otherwise the build fails
__dirname: false, // if you don't put this is, __dirname
__filename: false, // and __filename return blank or /
},
externals: [nodeExternals()],
module: {
rules: [
{
// Transpiles ES6-8 into ES5
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
},
{
test: /\.html$/,
include: [
helpers.root('client'),
],
loader: 'html-loader'
},
{
test: /\.((s*)css)%/,
include: [
helpers.root('client/app'),
helpers.root('client/components'),
],
exclude: 'node_modules/',
loaders: ['to-string-loader', 'css-loader', 'sass-loader']
},
{
test: /\.(woff|woff2|eot|tts)$/,
use: [{
loader: 'file-loader'
}]
}
]
},
plugins: [
new webpack.DefinePlugin({
'process.env': {
'ENV': JSON.stringify(env)
}
}),
new webpack.ContextReplacementPlugin(/\#angular(\\|\/)core(\\|\/)esm5/, path.join(__dirname, './client')),
]
});
A sample from the vendor index file:
const helper = require('./helpers');
exports.vendor1 = [
helper.root('node_modules/lodash/lodash.js'),
helper.root('node_modules/lodash-deep/lodash-deep.js'),
...
...
]
I'm just really not sure what to do, couldn't bring up any google results or stack results because theres no errors happening either. I've tried all verbose levels of logging all to no avail. What in the world am I missing?
As the documentation shows, you haven't configured any targets, like dev or prod. You've only specified options. You want
webpack: {
options: {},
dev: require("./config/webpack.dev.js"),
},
As an aside, there's no benefit to using Webpack with Grunt.

React app looking for bundle.js in component folder not project root

The errors I get below are shown in the console after I refresh on a nested route (register/email-confirmation). Whereas non-nested routes do not get this error.
I think the main problem is that it's searching for bundle.js and the image in the nested route path, as opposed to the root path.
The errors in my console:
GET http://localhost:3002/register/bundle.js net::ERR_ABORTED
Refused to execute script from 'http://localhost:3002/register/bundle.js' because its MIME type ('text/html') is not executable, and strict MIME type checking is enabled.
GET http://localhost:3002/register/a5e694be93a1c3d22b85658bdc30008b.png 404 (Not Found)
My webpack.config.js:
const webpack = require('webpack');
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const BUILD_PATH = path.resolve( __dirname, "./client/build" );
const SOURCE_PATH = path.resolve( __dirname, "./client/src" );
const PUBLIC_PATH = "/";
...
module.exports = {
devtool: 'eval-source-map',
context: SOURCE_PATH,
entry: ['babel-polyfill', SOURCE_PATH + '/index.jsx'],
module: {
rules: [
{
test: /\.jsx?$/,
exclude: [/node_modules/, /server/],
use: {
loader: 'babel-loader',
options: {
presets: ['env', 'es2015', 'react', 'stage-1', 'stage-0', 'stage-2'],
plugins: [
'transform-decorators-legacy',
'transform-es2015-destructuring',
'transform-es2015-parameters',
'transform-object-rest-spread'
]
}
}
},
{
test: /\.scss$/,
use: [{
loader: "style-loader"
}, {
loader: "css-loader"
}, {
loader: "sass-loader"
}]
},
{
test: /\.(png|jpg|gif)$/,
use: [
{
loader: 'file-loader',
options: {}
}
]
},
],
},
output: {
path: BUILD_PATH,
filename: "bundle.js",
},
devServer: {
compress: true,
port: 3002,
historyApiFallback: true,
contentBase: BUILD_PATH,
publicPath: PUBLIC_PATH,
},
plugins: [
new webpack.DefinePlugin(appConstants),
new HtmlWebpackPlugin({
filename: 'index.html',
template: path.resolve(__dirname, 'client/src/index.html'),
inject: true
}),
],
watch: true,
}
I don't know about this bug, but I highly recommend using fuse-box
fuse-box is the future of the build systems, within few minutes you will be running your project with high speed hot reload and many others utitilites...
check this react example seed, it's incredibly amazing..

Accessing environment variables via webpack

I have developed a react webpack application and I have implemented as follows to access environment variables.
webpack.config.js
const webpack = require('webpack');
var config = {
entry: './main.js',
output: {
filename: 'bundle.js',
},
devServer: {
inline: true,
disableHostCheck: true,
host: '0.0.0.0',
port: 8080
},
module: {
loaders: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
loader: 'babel-loader',
query: {
presets: ['es2015', 'react']
}
}
]
},
plugins: [
new webpack.DefinePlugin({
'process.env': {
ENV_VAR: JSON.stringify(process.env.ENV_VAR)
}
})
]
};
module.exports = config;
and in my config.js I have implemented as follows to maintain my config structure.
export default () => {
return {
"configFromEnvVar": {
"url": process.env.ENV_VAR || "http://url:8080"
}
}
};
I want to know if there is a better way to do this without having to use process.env in multiple locations. Any documentation or advice is greatly appreciated.
Thanks alot

Configure react webpack for deploy

need a little help.
We had tried to deploy a react project, but we are unable to configure it.
We use: es6, webpack, redux, react, babel.
this is webpack base:
import ExtractTextPlugin from 'extract-text-webpack-plugin';
import HtmlWebpackPlugin from 'html-webpack-plugin';
export default {
entry: './app/app.js',
output: {
path: './app/App/dist',
filename: '/bundle.js',
},
module: {
loaders: [
{
test: /\.json$/,
loader: 'json',
},
{
test: /\.scss$/,
loader: ExtractTextPlugin.extract('css!sass'),
},
{
test: /\.css$/,
loader: ExtractTextPlugin.extract('css!sass'),
},
{
test: /\.jsx?$/,
exclude: /node_modules/,
loader: 'babel-loader',
},
{
test: /\.svg$/,
loader: 'babel?presets[]=es2015,presets[]=react!svg-react',
},
],
},
plugins: [
new HtmlWebpackPlugin({
template: './app/App/index.html',
}),
new ExtractTextPlugin('/app/App/css/default.css', {
allChunks: true,
}),
],
};
webpack dev:
import webpack from 'webpack';
import baseConfig from './webpack.config.base';
const config = {
...baseConfig,
debug: true,
devtool: 'cheap-module-eval-source-map',
plugins: [
...baseConfig.plugins,
new webpack.HotModuleReplacementPlugin(),
],
devServer: {
colors: true,
historyApiFallback: true,
inline: true,
hot: true,
},
};
export default config;
webpack prod:
import webpack from 'webpack';
import baseConfig from './webpack.config.base';
const config = {
...baseConfig,
plugins: [
...baseConfig.plugins,
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: JSON.stringify('production'),
},
}),
new webpack.optimize.OccurrenceOrderPlugin(),
new webpack.optimize.UglifyJsPlugin({
compressor: {
screw_ie8: true,
warnings: false,
},
}),
],
};
export default config;
This is our actual webpack, we are trying to deploy the project with it, but does not work.
Does anyone have an idea how to configure it?
So, it's a server problem probably. You need a HTTP server in order to server the static files (your app basically). I recommend the Ngxin, very easy to configure and use.
After install nginx, delete the /etc/nginx/sites-enable/default file and create a new one (you can use whatever name you want here). Here's the config I use:
server {
listen 80;
listen [::]:80;
server_name example.com;
location / {
root /var/html/myProject/;
try_files $uri /index.html;
}
}
after that, restart nginx and should be ready to go.
for webpack, I have a simpler config that works well:
const path = require("path");
const webpack = require("webpack");
const ExtractTextPlugin = require("extract-text-webpack-plugin");
const HtmlWebpackPlugin = require('html-webpack-plugin');
const isProd = process.env.NODE_ENV && process.env.NODE_ENV.toLowerCase() == 'production';
const plugins = [
new ExtractTextPlugin(isProd ? 'bundle.[hash].css' : 'bundle.css', { allChunks: true }),
new HtmlWebpackPlugin({
template: 'index.html',
inject: 'body',
filename: 'index.html'
}),
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'development')
})
];
const prodPlugins = [
new webpack.optimize.DedupePlugin(),
new webpack.optimize.UglifyJsPlugin(),
new webpack.optimize.AggressiveMergingPlugin()
];
module.exports = {
devtool: isProd ? 'cheap-module-source-map' : 'eval',
entry: [
'./src/index.jsx'
],
output: {
path: isProd ? path.join(__dirname, 'dist') : __dirname,
publicPath: '/',
filename: isProd ? 'bundle.[hash].js' : 'bundle.js'
},
module: {
loaders: [{
exclude: /node_modules/,
loader: 'babel',
query: {
presets: ['react', 'es2015', 'stage-1']
}
},
{
test: /\.(scss|css|sass)$/,
loader: ExtractTextPlugin.extract('css!sass')
},
{
test: /\.(png|woff|woff2|eot|ttf|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
loader: 'url'
},
{
test: /\.html$/,
loader: 'html'
}]
},
resolve: {
extensions: ['', '.js', '.jsx']
},
devServer: {
historyApiFallback: true,
contentBase: './'
},
plugins: isProd ? prodPlugins.concat(plugins) : plugins
};
A few points:
I'm using SASS
Check the path's before run anything
To compile for production, just run NODE_ENV=production webpack -p
I'm using a few plugins for Uglify JS and compress files.
I think that's it! Cheers!
sure I think the fastest way to solve your problem is to click on this link:
React starter kit
and select any starters that matches your technologies!
I think you are looking for this one : react-boilerplate

Webpack Dev Server with React Hot Loader

I have a webpack configuration that works perfect in itself. I'm trying to install React Hot Loader together with HMR as suggested, which require webpack-dev-server. Here I cannot get it to work. I can not find where my bundle is located. I want it to be just at localhost:3000.
My webpack.config.js:
var webpack = require('webpack');
var path = require('path');
module.exports = {
watch: true,
devtool: 'eval',
// entry: './src/main.js', This runs just for webpack bundling
entry:[
'webpack-dev-server/client?http:localhost:9000', // WebpackDevServer host and port
'webpack/hot/only-dev-server', // "only" prevents reload on syntax errors
'./src/main.js' // Your appʼs entry point
],
output: {
path: path.resolve(__dirname, 'public', 'dist'),
filename: 'main.js'/*,
publicPath: '/dist/'*/
},
module: {
loaders: [{
test: /\.js$/,
loaders: ['react-hot', 'babel-loader?cacheDirectory=true,presets[]=react,presets[]=es2015'],
exclude: function(path) {
var isModule = path.indexOf('node_modules') > -1;
var isJsaudio = path.indexOf('jsaudio') > -1;
if (isModule && !isJsaudio) {
return true;
}
}
}, {
test: /\.json$/,
loader: "json-loader"
}]
},
plugins: [
new webpack.HotModuleReplacementPlugin()
],
resolve: {
extensions: ['', '.js', '.json', 'index.js'],
root: [
path.resolve(__dirname, 'src'),
path.resolve(__dirname, 'node_modules'),
path.resolve(__dirname, 'node_modules', 'jsaudio', 'src')
]
},
target: 'web',
node: {
fs: 'empty',
net: 'empty',
tls: 'empty'
}
};
And the webpack-server.js:
var webpack = require('webpack');
var WebpackDevServer = require('webpack-dev-server');
var config = require('./webpack.config');
new WebpackDevServer(webpack(config), {
publicPath: '/dist/',
hot: true,
historyApiFallback: true
}).listen(9000, 'localhost', function (err, result) {
if (err) {
return console.log(err);
}
console.log('Listening at http://localhost:9000/');
});
Update: The linked question does not help, especially since it does not even have a confirmed answer.
I would suggest trying out react-hot-loader v3 as the updates to get hot-reloading working have been simplified (in my opinion!).
in webpack then try point now only needs:
entry: {
app: [
'react-hot-loader/patch',
'webpack-hot-middleware/client',
`${SRC}/client-entry.js`
]
}
here is a link to an example app, react-lego that i've created to help people add react-hot-loader v3 to their apps. hope it helps

Resources