Webpack dev server React Content Security Policy error - reactjs

I have my single page app running on webpack-dev-server. I can load and reload my entry route over at localhost:8080 and it works every time. However i can load localhost:8080/accounts/login only via a link from within the app i.e whenever i reload localhost:8080/accounts/login from the browser refresh button i get
Cannot GET /accounts/login/
as the server response, and on the console i get
Content Security Policy: The page’s settings blocked the loading of a
resource at self (“default-src http://localhost:8080”). Source:
;(function installGlobalHook(window) { ....
This is my CSP header on the single page app's index.html
<meta http-equiv="Content-Security-Policy"
content="default-src * 'self' 'unsafe-inline' 'unsafe-eval'">
I am also not using any devtool on my webpack.config.json. What am i missing.

If you use Webpack in your project, please add output.publicPath = '/' and devServer.historyApiFallback = true in your webpack config file.
More info: React-router urls don't work when refreshing or writting manually

I struggled a couple hours to fix this issue. There is a just simple code that you have to add. Just follow the instruction of below. If you face problem to browse from specific url to another url, you will be able to fix that also. If you would like to configure from webpack config file, then write below's code.
devServer: {
historyApiFallback: true
}
And If you would like to run by cli command, then use the below's code.
"start": "webpack-dev-server --history-api-fallback"
It worked for me. I had not to do anything else to fix this issue like meta tag or something else.

If you're using Rails and Webpacker and get this error, note that the initializer config/initializers/content_security_policy.rb has a Content Security Policy for Rails.env.development. Changing :https to :http on that line solved the error for me. (And remember that localhost is not the same as 127.0.0.1 as far as the CSP is concerned.)

adding output: { ..., publicPath: "/", } and devServer: { historyApiFallback: true } worked
in webpack.config.js
const path = require("path");
module.exports = {
mode: "development",
entry: "./src/index.js",
output: {
path: path.resolve(__dirname, "public"),
filename: "main.js",
publicPath: "/", // ++
},
target: "web",
devServer: {
port: "6060",
static: ["./public"],
open: true,
hot: true,
liveReload: true,
historyApiFallback: true, // ++
},
resolve: {
extensions: [".js", ".jsx", ".json", ".ts"],
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: "babel-loader",
},
// CSS rules
{
test: /\.css$/i,
use: ["style-loader", "css-loader"],
},
],
},
};

I had similar issue. Had to remove the contentBase line from devServer configuration in webpack.config.js.
This is my webpack.config.js:
var path = require("path");
module.exports = {
devtool: 'inline-source-map',
entry: "./src/index.js",
output: {
path: path.resolve(__dirname, "dist"),
publicPath: "/assets/",
filename: "bundle.js"
},
devServer: {
port: 9002
},
module: {
rules: [
{ test: /\.js$/, use: 'babel-loader' }
]
}
};

Related

Why i get hashed .jpeg file when running 'npm run build' with webpack

Im a new beginner on develop react app.
Im trying to figure out how to set up my webpack.config.js file.
I have following ended up with this structure as you can see on the picture link below.
My question is: When im running 'npm run build' , its hashing the picture and put it into the /dist folder. How can i configure so it does not?
Because im using copyWebpackPlugin() to copy my images and push it to the dist folder, but i dont want the picture which i marked with arrow.
If anyone have some advice just bring it on.
This is how my webpack.config.js file look like:
const path = require("path");
const webpack = require("webpack");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const CleanWebpackPlugin = require("clean-webpack-plugin");
const CopyWebpackPlugin = require("copy-webpack-plugin");
module.exports = {
entry: "./src/index.js",
mode: "development",
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /(node_modules|bower_components)/,
loader: "babel-loader"
},
{
test: /\.s?css$/,
loader: ["style-loader", "css-loader"]
},
{
test: /\.(jpe?g|png|gif|woff|woff2|eot|ttf|svg)(\?[a-z0-9=.]+)?$/,
loader: "url-loader?limit=100000"
}
]
},
resolve: { extensions: [".js", ".jsx"] },
output: {
path: path.resolve(__dirname, "dist/"),
filename: "bundle.js"
},
devtool: "cheap-module-eval-source-map",
devServer: {
contentBase: path.join(__dirname, "public/"),
proxy: {
"/api/*": {
target: "http://localhost:3000/",
secure: "true"
}
},
port: 4000,
publicPath: "http://localhost:4000/dist/",
hotOnly: true,
historyApiFallback: true
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new CleanWebpackPlugin(["dist"]),
new HtmlWebpackPlugin({
filename: "index.html",
template: "./public/index.html"
}),
new CopyWebpackPlugin([{ from: "public/images", to: "images" }])
]
};
I would suggest instead of copy-webpack-plugin use file-loader to copy images
{
test: /\.(png|jpg|gif|jpeg)$/,
use: [{
loader: 'file-loader',
options: {
name: 'images/[name].[ext]',
}
}]
}
if you want hash instead of name
name: 'images/[hash].[ext]',
Package
npm install --save-dev file-loader
It is because the url-loader has a default fallback to file-loader. So if your image is bigger than the limit you have set for url-loader, it does not rewrite the image to base64 data:image in your css, instead gives it to file-loader and it copies that image to your dist folder (output path).
So if you do not want this, disable the fallback option for url-loader
But I also think you should have configure your webpack to copy the files with file-loader properly instead that copy plugin. But you know...
I would give you an example based on your config but I am currently on mobile so I can't code right now.

Why is the client trying to require a library when I am doing server side rendering?

I am trying to implement server side rendering on my react app, but having trouble with this one error.
this is my webpack.config.js file. When I run the script npm start everything compiles correctly.
var fs = require('fs');
var nodeModules = {};
fs.readdirSync('node_modules')
.filter(function(x) {
return ['.bin'].indexOf(x) === -1;
})
.forEach(function(mod) {
nodeModules[mod] = 'commonjs ' + mod;
});
module.exports = {
entry: [
'./server.js'
],
target: 'node',
output: {
path: __dirname,
publicPath: '/',
filename: 'bundle.js'
},
externals: nodeModules,
module: {
loaders: [{
exclude: /node_modules/,
loader: 'babel',
query: {
presets: ['react', 'es2015', 'stage-1']
}
}]
},
resolve: {
extensions: ['', '.js', '.jsx']
},
devServer: {
historyApiFallback: true,
contentBase: './'
}
};
I believe the main issue is that webpack thinks bundle.js is build for node environment. Therefore it assumes that require is available. However it is meant for the browser, it will throw an error since require is not available. I'm not really sure if your webpack.config.js is for the server or the browser, since the entry point is the server.js and yet the output is for bundle.js, which I assume meant for the browser.
Have a look on server rendering tutorial here. Basically, you have to have a webpack config file for server and the browser. The server webpack config file would have an entry point where your server is defined. Whereas the browser webpack config file would have an entry point where react-dom render method is called. Then, make sure that the output of the browser webpack config is the one that is used in the html and not the server one.

Webpack slows down page

I have the following config for my webpack:
var path = require('path');
var webpack = require('webpack');
var config = {
entry: {
login: path.join(__dirname, 'src' , 'entry' , 'login.js'),
register: path.join(__dirname, 'src', 'entry', 'register'),
faqLogged: path.join(__dirname, 'src', 'entry', 'faqLogged'),
content: path.join(__dirname, 'src', 'entry', 'content'),
},
output: {
path: path.join(__dirname, 'build'),
filename: '[name].js',
},
module: {
loaders: [
{
test: /.jsx?$/,
loader: 'babel-loader',
exclude: /node_modules/,
query: {
presets: ['es2015', 'react']
}
}
]
},
}
module.exports = config;
In my app I use AJAX and I ought use babel-loader. The problem is, if I use the cdnjs for babel-loader, and therefore no import statements in my app, the page loads almost instantly.
On the other hand, if I use webpack to bundle my page, now being able to use import, and doing so, will result in my page load time being over 4 seconds and I receive the following error in my browser's console ( Chrome ) :
[BABEL] Note: The code generator has deoptimised the styling of "http://localhost/build/content.js" as it exceeds the max of "100KB".
I have tried to minify the bundled file but that does not seem to be the issue. The fact that it has over 100kb doesn't bother me, what does is the absurd load time.

Why does browser keep showing same version with webpack?

I am using gulp& webpack to run my reactjs app. At the moment I have an issue that when I delete a file from my app it is still present in the browser chrome devtools. This is my webpack.config.js:
var path = require('path');
var webpack = require('webpack');
module.exports = {
entry: "./app/app.js",
output: {
path: path.resolve(__dirname, "dist"),
publicPath: "/dist/",
filename: "myapp.js",
sourceMapFilename: "myapp.map"
},
devtool: '#source-map',
module: {
loaders: [{
loader: 'babel',
exclude: /node_modules/
}]
},
devServer: {
inline: true
}
}
Even when I delete the dist folder completely the browser still shows the app? I have turned the cache off for chrome devtools. How can I show the latest version of my app with webpack?

Turn off hot reloading on webpack

I created a reactjs app with webpack. Everything works fine on local. Just by using npm start. I want to deploy a simple package for prod with webpack -p command. it gave me a bundle.js I appended it, and it works fine too. but it is still looking for my local server running as part of hot reloading config. I changed hot:false, but its still looking for it.
here is my webpack.config.js
var path = require('path');
var webpack = require('webpack');
module.exports = {
devtool: 'eval',
entry: [
'webpack-dev-server/client?http://csd.local.com:3000',
'webpack/hot/only-dev-server',
'./src/index'
],
output: {
path: path.join(__dirname, 'dist'),
filename: 'bundle.js',
publicPath: '/static/'
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new webpack.DefinePlugin({'process.env.NODE_ENV': JSON.stringify('production')})
],
module: {
loaders: [{
test: /\.js$/,
loaders: ['react-hot', 'babel'],
include: path.join(__dirname, 'src')
},
{ test: /\.scss$/,
loaders: ["style", "css", "sass"],
include: path.join(__dirname, 'src')
}
]
}
};
And here is my server.js
var webpack = require('webpack');
var WebpackDevServer = require('webpack-dev-server');
var config = require('./webpack.config');
new WebpackDevServer(webpack(config), {
publicPath: config.output.publicPath,
hot: false,
historyApiFallback: true
}).listen(3000, 'localhost', function (err, result) {
if (err) {
return console.log(err);
}
console.log('Listening at http://csd.local.com:3000/');
});
All I want is, turn off hot reloading in prod.
That's because you're telling webpack to bundle HMRE's client-side scripts together with your app:
'webpack-dev-server/client?http://csd.local.com:3000',
'webpack/hot/only-dev-server',**strong text**
The solution would be to detect wether you're in "development" or "production" environment. To do so you can use "yargs" to parse your cli arguments (it's a webpack dependency so you don't even have to install it), and use the result to dynamically build your config.
var production = require('yargs').argv.p;
See a complete example at http://pastie.org/10895795

Resources