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
Related
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.
I read https://www.gatsbyjs.org/docs/path-prefix/ and I added the following to gatsby-configs.js.
{
pathPrefix: "/modules/custom/gatsby/gatsby-shopify-starter/public",
},
And, I execute sudo gatsby build --prefix-paths on terminal.
But, I got this error message.
ERROR
The "path" argument must be of type string. Received an instance of Object
Error: TypeError [ERR_INVALID_ARG_TYPE]: The "path" argument must be of type s tring. Received an instance of Object
What am I doing wrong?
Gatsby's pathPrefix only prepends a string to your projects routes (url). Your deployment script(s) should handle where the public folder ends up on your server. If you really want to publish your gatsby project to somewhere other than /public (locally) You will propbably need to do something like use fs and path in onPostBuild in gatsby-node.js to move everything over to another directory. At the time or writing this, Gatsby doesn't directly support alternative build directories so you are on your own when using gatsby develop or gatsby serve to view this locally.
Try something like this in gatsby-node.js but change the paths to serve your needs. This example will publish your project to /public/blog rather than the default /public and is just a proof of concept but I tested it and it works:
const path = require('path');
const fs = require('fs');
exports.onPostBuild = function() {
fs.renameSync(path.join(__dirname, 'public'), path.join(__dirname, 'public-blog'));
fs.mkdirSync(path.join(__dirname, 'public'));
fs.renameSync(path.join(__dirname, 'public-blog'), path.join(__dirname, 'public', 'blog'));
};
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, "/")
},
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.
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.