webpack 5 / webpack-dev-server: how to serve other file then index.html - webpack-dev-server

When i was using webpack 4 (4.44.1) with webpack-dev-server (3.11.0) i had a setting
devServer: {
index: 'other_filename.html'
}
and thanks to that setting dev server was serving that file at / instead of index.html (which is not generated in the build process in my project). How can i get that result with latest versions (5.73.0 / 4.9.2) as index property is not valid anymore (get a build error)? I can't really see any entry that would match that setting in latest docs.
Thanks in advance

I found it:
devServer: {
devMiddleware: {
index: 'filename.html',
},
},

Related

React/vite app with base URL that does not apply to static links in the main HTML file

I have a question, around base urls. I have a React/Vite application that will get deployed into a webserver that hosts many other web-properties, and as part of this, all web-properties include shared JS and CSS. These shared JS/CSS are all served off the root do the domain (ex. https://www.my-domain.com/assets/shared.js). These includes are just hard coded into my main HTML file (usually index.html, but in my case root.html)
My React app however is served from https://www.my-domain.com/apps/catalog/root.html.
If i run my app locally with just npm run dev, everything works - but but my app is served off the root. I thought the right way to have this all run off my /apps/catalog/ based URL was to run all my vite commands with --base=/apps/catalog which seems to almost work; the problem is it rewrites thee static shared includes, which break them, since theyre expected to be served off the root.
I think, i need to figure out how to mark specific includes as not being effected by the base URL rewrite? Or, is there a better way to approach this?
My HTML file w/ the static includes of the "shared" assets. I dont want to hardcode the "real" domain in the src URLs since then my local proxy can't trap them and grab them serverside preventing CORS issues.
// /src/root.html
<html>
<head>
<!-- served from: https://www.my-domain.com/assets/shared.js -->
<script src="/assets/shared.js"/>
<!-- served from: https://www.my-domain.com/api/shared.js -->
<script src="/api/shared.js"/>
.. etc ..
</head>
<div id="app"></div>
</html>
My vite.config.js where i start to try to introduce the notion of a base url (and a non-index.html named "main" file)
The local proxy so these static includes resolved without CORS issues, for local dev (it proxies these static assets out to the Shared host, and everything works well locally).
// src/vite.config.js
export default defineConfig({
plugins: [react()],
build: {
assetsDir: 'static-assets',
rollupOptions: {
input: {
app: './root.html',
},
},
},
base: '/apps/catalog/',
server: {
open: '/root.html',
proxy: {
'^/assets/.*|^/api/.*': {
target: 'https://www.my-domain.com',
changeOrigin: true
}
}
}
})
And my package.json where i tried to also set the base URL.
// package.json scripts
"dev": "vite --base=/apps/catalog/",
"build": "vite build --base=/apps/catalog/"
I had the same problem with Laravel 9 + vite v3.2.5.
I fixed it (after hours) with the experimental renderBuiltUrl:
import {defineConfig, loadEnv} from 'vite';
// load env variables to get base url
process.env = Object.assign(process.env, loadEnv('production', process.cwd(), ''));
export default defineConfig({
// ...
experimental: {
renderBuiltUrl(filename) {
// here we set the base url. You might have to change this for react:
return process.env.APP_URL + '/build/' + filename;
}
}
}
Note the warning in the documentation:
This feature is experimental, the API may change in a future minor without following semver. Please always pin Vite's version to a minor when using it.

PM2 serve SPA build folder. It works but has tons of errors like "Error while serving ... ENOENT: no such file or directory..."

The problem is that the logs are flooded, but it works fine.
The build folder contains the build from React using CRA (Create React App).
So from the PM2 Docs I have this:
ecosystem.config.js
module.exports = {
name: "projectName",
script: "serve",
watch: true,
env: {
NODE_ENV: "production",
PM2_SERVE_PATH: './build',
PM2_SERVE_PORT: 5001,
PM2_SERVE_SPA: 'true',
PM2_SERVE_HOMEPAGE: './index.html'
},
}
I'm using PM2 serve command.
Command to start PM2 process:
pm2 start
Errors
Only happens when I enter for the first time or when I reload.
Error while serving /.../projectName/build/routeX with content-type text/plain : ENOENT: no such file or directory, open '/.../projectName/build/routeX'
I think you have to find the nature of those requests leading to an error. If they are originated from your app, then you have either to put away what causes that request or let something to be in that place inside of your build folder (depends on request's reason). If they are originated not from your app, then you should figure out where they come from. "Network" Tab of DevTools should help you in both cases
This issue is fixed in pm2 v5.2.0
https://github.com/Unitech/pm2/pull/5272

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.

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

Resources