publicPath with react hot loader - javascript

I'm not quite sure what the publicPath in webpack does. Specifically, output.publicPath. In the github docs, I see this
https://github.com/webpack/docs/wiki/configuration#outputpublicpath
The output.path from the view of the Javascript / HTML page.
For reactjs hot loading, I have
output: {
path: path.resolve('./public/bundle/'),
// path: './public/bundle',
filename: 'main.js',
// Webpack dev server is bound to port 8080, we have to force use of absolute URL, using the publicPath property
publicPath: 'http://localhost:8080/public/bundle/'
},
Does this mean that the built webpack files (main.js) is placed in my dev-server http://localhost:8080/public/bundle/ ?

Yep, Webpack needs to know where you'll host the generated bundle file (or any other assets it generates) so that it can request additional chunks or files that are loaded from file-loader or url-loader. Hence in this case, when you start your webpack-dev-server, you'll be able to access your bundle file at: http://localhost:8080/public/bundle/main.js (any related assets like images, commonchunk, fonts, etc will be under that path)
Outside of dev-server, you can use it to define the location of your assets (from a custom directory or even a CDN)

Related

How to make webpack-dev-server serve my index.html

I'm trying to get an extremely simple bare-bones TypeScript project setup with Webpack and I'm having an incredibly hard time for some reason.
I followed this guide and everything is working. When I simply run webpack my files will bundle and compile and be outputted into the dist directory. From there I can host them on a local server and it all works fine.
However, I want to avoid having to manually bundle and compile my code every single time I make a change, and I'd like for this to be done automatically each time I save my files. As far as I can tell this is a common use for Webpack and so I'm not sure why I'm having such an incredibly hard time finding any good information on it.
I decided to use the webpack dev server to accomplish this, so I read this tutorial and for the life of me I can't find anybody who explains how to get it to also server my index.html? When I run webpack serve --mode=development all goes well, and when I navigate to the localhost port that I server to I get a 404 error.
One of the "tips" on the previously linked page reads
If you're having trouble, navigating to the /webpack-dev-server route will show where files are served. For example, http://localhost:9000/webpack-dev-server.
When I navigate to localhost:1234/webpack-dev-server it tells me that it's only serving a single file: bundle.js Clearly a JavaScript file alone is not going to work, and I need it to also serve the index.html file that's in my dist directory.
Now, my knowledge here is very limited as this is my first time working with Webpack, but here's all the detail I can give and hopefully it's not accidentally totally unrelated:
Whenever my dev server reloads itself (whenever it's booted up or if a watched file changes while it's running) it only updates the bundle.js file that it's serving. It doesn't update the bundle.js file stored in my dist directory on my hard drive. How can I make it update both?
And also, how do I make the server also serve my index.html file instead of only the bundle.js? Where is it even getting that bundle.js from? Is it compiling all of my code from scratch to create that js file or is it taking that out of the dist directory?
And additionally, am I going about this totally in the wrong way? Where should my index.html even go? I put my TypeScript files into a src directory and they're converted to .js files and moved into my dist directory... Should I also put my index.html inside src or does it belong in dist or somewhere else entirely? When I put index.html in src it doesn't get copied over into dist, it just ignores it completely. If my index.html file doesn't belong in src it must belong in dist, but if it belongs in dist then how can I expect the dev server to find it and serve it along with the other TypeScript files in src? Why can't the dev server just serve everything in dist and automatically compile everything from src into dist? I must be misunderstanding the flow of it all, but I have no idea where to look for an explanation and I've been at this for several hours now.
Just a general explanation of how it all works would be very helpful as well, as I can't find a single article or forum post anywhere that details all the spaghetti going on with Webpack. I've been avoiding bundlers and all this NPM mess for as long as I can because I constantly run into issues like this, but I finally decided to jump in and just push through all the mess and I'm already regretting it. If someone could just point me (and other people having similar problems) to some good resources for learning about all the automagic going on that would be hugely appreciated. The Webpack documentation and guides are very much worthless to a newbie.
My Webpack config file:
const path = require("path");
module.exports = {
entry: "./src/index.ts",
module: {
rules: [
{
test: /\.tsx?$/,
use: "ts-loader",
exclude: /node_modules/,
}
]
},
resolve: {
extensions: [".tsx", ".ts", ".js"]
},
output: {
filename: "bundle.js",
path: path.resolve(__dirname, "dist")
},
devServer: {
compress: false,
static: false,
client: {
logging: "warn",
overlay: {
errors: true,
warnings: false
},
progress: true
},
port: 1234, host: "0.0.0.0"
}
};
Is your entry set in webpack? So that it is included?
entry: {
main: 'path/to/index.ts'
},
You could also try adding to your index.ts file
require('file-loader?name=[name].[ext]!../index.html');
Or
require("./src/index.html");
// Then In your webpack config file add a loader
loaders : { { test: /\.html/, loader: 'file?name=[name].[ext]' } }
Otherwise you could always copy this file over with webpack copy plugin
{
plugins: [
new HtmlWebpackPlugin({
template: 'src/index.html'
})
]
}
will need to run npm install --save-dev html-webpack-plugin to install it. As well as move your index.html file into your src folder
Please visit localhost:1234/bundle (Where bundle.js is your bundled file) the magichHTML route, which will load the HTML file with the bundled script.

Configure Webpack to serve react at relative path

I have a koajs server that serves react as static files from the /dist folder.
const static_pages = new Koa();
static_pages.use(serve(process.env.PWD + "/dist"));
app.use(mount("/app", static_pages));
The problem is that, I want to mount the index.html from /dist at the relative path "/app" because at "/" i have something else.
My webpack.config.js looks like this:
entry: "./static/index.js",
output: {
path: path.join(__dirname, 'dist'),
filename: "[name].js"
},
where static/index.js is my react app. And when i open the browser i get an 500 error
"http://localhost:4000/main.js net::ERR_ABORTED 500 (Internal Server
Error)"
But if i go to localhost:4000/app/main.js it works, i get the main.js bundled file, but my index.html from dist tries to get main.js not /app/main.js.
How I'm supposed to change the webpack config file bundle it so that my app will be mounted at relative path?
If you're willing to use React + Koa at the development you should use webpack-dev-server to serve you're react bundle with HRM on a specified PORT, otherwise if you're willing to sever static build from React.js files you should use koa-static middleware which will allow you to serve bundle.
According to your webpack configuration, you're missing important html-webpack-plugin which will generate an index.html in your bundle (without that koa isn't able to serve content on specified path).
const htmlPlugin = new HtmlWebPackPlugin({
template: "./static/index.html",
filename: "./index.html"
});
This is my HtmlWbpackPlugin configuration. I've managed to solve the issue by adding publigPath to the output like that:
output: {
path: path.join(__dirname, 'dist'),
filename: "[name].js",
publicPath: '/app'
},
I don't know if this is the best solution but it works

Webpack: output.path, publicPath and chunkFilename selecting concept for projects where html and js files are not in the same folder

From the webpack documentation for output.publicPath:
Simple rule: The URL of your output.path from the view of the HTML
page.
module.exports = {
output: {
path: path.resolve(__dirname, 'public/assets'),
publicPath: 'https://cdn.example.com/assets/'
}
};
Above rule is actual for single-page applications, where usually index.html and index.js are in the same folder. However, in the projects of multi page websites, usually special folder like js or scripts is being created. So the file structure of output folder of project could be like:
I tried a lot of combinations of output.path output.publicPath and output.chunkFilename, however still do not understand, how to correctly select the combination of above parameters to make dynamic load works (e. g. const MODULE = import('./loadOnDemand/testModule') which is chunks/chunk__0.js in output folder). Please tell me the concept, how to select output.path publicPath and chunkFilename, which will works for above file system, and also could be scaled on below file system:
Have you tried webpack magic comments to automatically target the chunk names?
https://medium.com/faceyspacey/how-to-use-webpacks-new-magic-comment-feature-with-react-universal-component-ssr-a38fd3e296a
const MODULE = import(/* webpackChunkName: 'test' */'./loadOnDemand/testModule')

Webpack less-loader Missing Base Path on Production Build

I've got a vue-js app that uses webpack. Everything works fine in development and test environments, but I'm having trouble getting it to build for production.
I've got background images in the LESS files. The image files are in /static. (I'm not sure whether that's kosher or if they should be in side src/assets.)
At any rate, when the LESS has something like this:
background-url: url("/static/img/foobar/my-image.svg")
Then the compilted CSS will have the same url
background-url: url("/static/img/foobar/my-image.svg")
When the browser loaders, it can't find that imgate file. The browser is attempting to find the file here:
file:///static/img/foobar/my-image.svg
Can anyone recommend a way to prepend the absolute path when the app builds for production?
Do you have your static assets outside of our project directory in /static ?
Otherwise I don't get why your browser is trying to request it from file:///static/img/foobar/my-image.svg
anyway, your static assets should be part of your repo/project. They do not need to be in src directory, a /static folder within the root of your project is just fine.
when you compile your application - let's say into a dist folder - you should copy the images also in that dist folder. In my app I use the copy-webpack-plugin for that task (I have my images in ./public/assets/img/.. and I reference them as /assets/img/..)
const CopyWebpackPlugin = require('copy-webpack-plugin');
...
plugins: [
...
/** copy all files from the public folder to the compilation root */
new CopyWebpackPlugin([{
from: 'public',
to : ''
}]),
...
also you should make sure that you have the file-loader in place for your static assets. I use it like so:
{
test: /\.(png|jpe?g|gif|svg|woff|woff2|ttf|eot|ico)(\??\#?v=[.0-9]+)?$/,
use : 'file-loader?name=assets/[name].[hash].[ext]'
}
I hope this will help you to resolve your problem.
I ended up moving the images into assets/img and then updating my webpack config to specify the directory using publicPath. Here's what it ended up looking like:
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
loader: 'file-loader',
include: [resolve('src')],
options: {
limit: 10000,
name: '/[name].[hash:7].[ext]',
publicPath: path.resolve(__dirname, 'app')
}

Webpack-dev-server doesn't build files on change

So I have the following webpack configuration :
import path from 'path';
module.exports = {
entry: {
index: './dev/index.js'
},
output: {
path: path.join(__dirname, 'dist'),
publicPath: './dist/',
filename: 'bundle.js',
chunkFilename: '[id].bundle.js'
},
module:{
loader:{
test: /\.js$/,
exclude:path.resolve(__dirname, "node_modules"),
loader: 'js'
}
}
};
The problem is that when I do webpack --watchthe file does build in the /dist/ folder at every change. Yet when I run the webpack-dev-server the files don't even build. Why is that?
Please help.
The reason you are not seeing files emitted into your dist folder is because webpack-dev-server uses an in-memory filesystem
This allows for extremely fast incremental builds when your code changes. This was an intentional design on our part. You can view the resulting code in your browser and never need to reference those files.
It is not recommended by us, for the sake of build performance, but you can look in to plugins like write-file-webpack-plugin if you need this feature.
'webpack' writes your bundle to disk, whereas 'webpack-dev-server' loads the bundle into memory. So when running the latter command you wont see a new 'bundle.js' file appear in your file system, even though you should see output to the console reporting the bundling and the start up of the dev server).
The output.publicPath config key determines the location of the in-memory bundle on the host dev server. So if you set the publicPath to 'dist' then the index.html served by the webpack dev server will need a script tag in order to reference the bundle.

Categories