Webpack dev VS production server - reactjs

Just like we have the webpack-dev-server (only for development), I was wondering, do we also have webpack for production server, something like webpack-prod-server. This is getting very confusing
module.exports = {
entry: [
'webpack-dev-server/client?http://localhost:8080', // WebpackDevServer host and port
'webpack/hot/only-dev-server',
'babel-polyfill',
'./js/app' // Your appʼs entry point
],
output: {
filename: "js/bundle.js"
},

You would run webpack -p and it would output a minified bundle.
You then use something like nginx or some other web server and load an html file that imports your minified JS bundle.
To skip having to edit an html file with the bundle location, you can use https://github.com/jantimon/html-webpack-plugin.

Related

How is this webpack devServer configured incorrectly?

I am running into issues with my webpack-dev-server. When i try to load at a specified route such as "http://localhost:3000/login" I get the following message "Cannot GET /login".
I've read through the docs and seen many different solutions, but I don't see the flaws in my config. I have my webpack setup like this.
webpack.config.js
module.exports = {
mode: 'development',
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'build'),
filename: 'bundle.js',
},
module: [ rules... ],
devServer: {
contentBase: path.join(__dirname, 'build'),
compress: true,
port: 3000
},
}
My scripts for the app look like this:
"build": "webpack",
"dev": "webpack-dev-server --open"
If I run dev the app will open to the initial route - "/". If I click on a link to login - "/login" that will load fine. But if I refresh the page on login it will throw the "Cannot GET /login" error.
Is there something I'm missing or have wrong in my webpack configuration?
webpack-dev-server only serves two things: bundled assets, and whatever is in the directory you gave it as the value for contentBase. things work the way you want when you browse to / then navigate to /login since I assume you have some kind of client-side routing framework in your webapp. none of that applies when you refresh your browser and ask the server for a page at /login .
w-d-s is 404ing on you since you don't have a file named "login" in your build directory (and I doubt you have a compiled bundle or chunk with that name either). do you have an index.html file in that directory? is that what you're served when you visit localhost:3000/ ? does that file have a <script> tag which loads your webapp?
what were you expecting to happen when you visited /login ? I'm assuming you wanted to display your webapp's login screen when you visit localhost:3000/login ? if so you'll most likely need to use a separate server like express.js to server-side-render your webapp. this server can either be on a different port from the server launched by w-d-s, or it can actually use w-d-s as middleware so you only need one server with one port.
this seems like a decent resource at first glance: Server side rendering with react, react-router, and express . but if it doesn't work for you, there are dozens more on SO already which might.

Serve multiple entry points with webpack dev server

I've got multiple entry points being generated with outputs successfully but what I'm not too sure on is if there is a way with the webpack dev server to serve these multiple entry points and somehow be able to work on them all at the same time?
Here is my basic setup right now, is there a way I can get webpack dev server to somehow serve these on different ports maybe or by changing the URL serve the different entry points?
I've tried changing the port number on one of the apps but it doesn't seem to run a server with that port, which I kind of figured it wouldn't
entry: {
dashboard: [
"webpack-dev-server/client?http://localhost:3000",
"webpack/hot/only-dev-server",
paths.appIndexJs
],
display: [
"webpack-dev-server/client?http://localhost:3000",
"webpack/hot/only-dev-server",
paths.displayJs
]
},
output: {
pathinfo: true,
filename: "static/js/[name].js",
chunkFilename: "static/js/[name].chunk.js",
publicPath: publicPath,
devtoolModuleFilenameTemplate: info =>
path.resolve(info.absoluteResourcePath).replace(/\\/g, "/")
},

where does /static/js folder come from?

I'm new to React, just a question on the bundle js files produced by webpack.
Currently when I I run my app, and I check chrome dev tool, I found 0.chunk.js, bundle.js, main.chunk.js are under localhost/static/js, I don't have static folder in my react app, so where does /static/js folder come from? was it create by chrome?
Those files are generated by webpack.
To specify, you can run command npm run eject then you can see a folder named scripts.
In this folder, first let's check file start.js where run when you run npm start.
const devServer = new WebpackDevServer(compiler, serverConfig);
It using WebpackDevServer create a dev server run on your local to host your app, so you can access app through localhost:3000. Next let's check compiler parameter.
const compiler = createCompiler({
appName,
config,
devSocket,
urls,
useYarn,
useTypeScript,
webpack,
});
Inspect config you can see it created from configFactory
const config = configFactory('development');
Check configFactory you can see it is a function return server configuration as an object include property named output.
output: {
...
filename: isEnvProduction
? 'static/js/[name].[contenthash:8].js'
: isEnvDevelopment && 'static/js/bundle.js',
// TODO: remove this when upgrading to webpack 5
futureEmitAssets: true,
// There are also additional JS chunk files if you use code splitting.
chunkFilename: isEnvProduction
? 'static/js/[name].[contenthash:8].chunk.js'
: isEnvDevelopment && 'static/js/[name].chunk.js',
}
Here is what you are looking for.

Webpack Dev Server Issues

I am building a web application using Express + React.
I am dealing with a issue with WEbpack Dev Server.
My Webpack Dev Server builds the bundles just fine!
But, I have an issue with the way the files are served.
Usually , we name the root html file as index.html, but because of my Web application architecture , I cannot use index.html and have instead name it client.html.
This brings me to the problem that I am facing, the webpack dev server looks for the index.html when I go to localhost:8080, as I am using client.html the webpack dev serves asks me to select my file.
Webpack Static file select screen
So , is there a way to load client.html directly when I access localhost:8080(Webpack Dev Server).
Thanks in Advance!
In your webpack.config.js file you can add the configurations for the webpack dev server
devServer: {
historyApiFallback: {
rewrites : [
{from: /^\/$/, to: './client.html'}
]
}
}
This will redirect your default index.html to the client.html
For more details see the DevServer documentation

Webpack dev server cannot get `http://localhost/8080/bundle.js`

Given this config:
var webpack = require('webpack');
const path = require('path')
module.exports = {
entry: "./src/index.js",
output: {
path: path.join(__dirname, 'dist'),
publicPath: path.join(__dirname, 'dist'),
filename: "bundle.js"
},
devServer: {
contentBase: "./dist",
// hot: true,
}
}
Why won't webpack-dev-server server my app properly? I have 0% understanding of localhost, vs localhost/webpack-dev-server, vs publicPath, vs contentBase, etc.. I know all of these paths, and configuration keys are important to setting up my project properly but despite hours of reading about them, they remain as confusing as when I started.
If I go to localhost:8080/webpack-dev-server I see Get http://localhost:8080/bundle.js net:ERR_ABORTED` in the console.
Below are simple and straight forward rules for webpack & webpack-dev-server :
output.path : It needs to be an absolute path or /. You can get it easily using path.join
output.filename : This needs to be the name of output file without any extra file path.
devServer.contentBase : It is the physical location on the disk which is served as the root directory of webpack-dev-server when you open http://localhost:8080
By convention, we keep both output.path and devServer.contentBase same.
The tricky part is when you run webpack cmd, it generates the physical bundle.js file.
But when you run webpack-dev-server, NO PHYSICAL OUTPUT file is generated, rather it keeps the generated output in memory to avoid File-Write operate which in turn helps in faster development/debugging cycle.
So any change you make in src.js or main.js file, it will generate the output but won't write that to disk and wepack-dev-server reads that directly from the memory.
output.publicPath : This is used by webpack, webpack-dev-server & other plug-in to generate the output or serve the generated bundle.
The default value is /.
It is VIRTUAL PATH and need not be present on the physical
disk. Example : final application name if multiple apps are
hosted on the same server like /app1, /app2, or some external CDN path
/CDN-Path.
It is also helpful for React-Router <BrowserRouter basename='/app1'>
Now to refer the bundle output file that is generated & kept in the memory , you need to append the output.publicPath i.e. Virtual Path in the browser's URL.
The final URL for webpack-dev-server will be :
http://localhost:8080/<output.publicPath>/<output.filename>
In your case, either you change the
publicPath: path.join(__dirname, 'dist')
to
publicPath: '/dist' if it contains any spaces.
You can check it by printing the value of path.join(__dirname, 'dist') which returns the absolve path [different on MacOS & Window system].
http://localhost:8080/dist/bundle.js
If you want to dig further deeper, then here is the URL
https://medium.com/p/webpack-understanding-the-publicpath-mystery-aeb96d9effb1

Resources