Webpack Dev Server - favicon not showing on localhost but works on external URL - webpack-dev-server

I have a strange problem, I was wondering if anyone has experienced this. I have webpack in my app to bundle, serve and everything in between. I have noticed that when I compile and run webpack-devserver from my gulp file everything goes as expected and in my terminal I get the following:
webpack: Compiled successfully.
2017-11-30T11:46:05.288Z - error:
[Browsersync] Proxying: http://localhost:3001
[Browsersync] Access URLs:
--------------------------------------
Local: http://localhost:3002
External: http://10.101.51.117:3002
--------------------------------------
UI: http://localhost:3003
UI External: http://10.101.51.117:3003
--------------------------------------
Now when I access my app via 'localhost' no Favicon is shown in the browser tab for that page, there is no 404 in the console and there is no request for the favicon in the Developer Tools Network Tab? Now should I use the external URL and type http://10.101.51.117:3002 into the browser the Favicon is there in the page tab however there is no request for the favicon in the Developer Tools Network Tab.
Now when I make a direct call in the browser to the favicon to http://localhost:3002/assets/favicon.ico the favicon is served in the browser window so it seems like server is bundling the Favicon?
In my HTML I have the tag <link rel="shortcut icon" href="assets/favicon.ico"> nothing strange there and in my webpack.common.js file I have the following (I have removed some items here for simplicity)
module.exports = {
// lots of things here..
module: {
rules: [
// stuff here has been removed
{
test: /\.html$/,
use: 'html-loader'
},
{
test: /\.(png|jpe?g|gif|svg|woff|woff2|ttf|eot)$/,
use: 'file-loader?name=assets/[name].[hash].[ext]'
},
{
test: /\.(ico)$/,
use: 'file-loader?name=assets/[name].[ext]'
},
I can't think what or why the favicon isn't being shown in the tab when I use the localhost URL? If anyone has experienced this and resolved the issue and advice would be appreciated.
Please note that the Favicon is not cached from before as I have changed the favicon name, location and I cleared the browser cache.

If you are using HtmlWebpackPlugin then you can include favicon: './src/assets/favicon.ico', property there.
plugins: [
new HtmlWebpackPlugin({
template: './src/template.html',
favicon: './src/assets/favicon.ico',
filename: './index.html',
}),
],
BTW - starting from Chrome 80 you can use favicon.svg favicons as well.

Apparently your favicon should work but doesn't. Two things you may want to try:
Favicon caching is VERY nasty. I suggest you to test your favicon with a browser you normally don't use (so it didn't cache your icon).
Run the favicon checker. As your site is hosted locally, you will have to use ngrok to make is accessible from outside.
Disclosure: I'm the author of RealFaviconGenerator

I would use the file loader like this:
Install the package
npm i --save-dev file-loader
Then add the following to your webpack config (default webpack.config.js)
{
test: /\.(png|svg|jpg|gif|ico)$/,
use: ['file-loader?name=[name].[ext]']
}
This should move the files to your dist folder.

How about copying favicon.ico by using copy-webpack-plugin.
// File: webpack.config.js
const CopyPlugin = require("copy-webpack-plugin");
module.exports = {
...
plugins: [
new CopyPlugin({
patterns: [
{ from: "favicon.ico" },
],
}),
]
}
Don't forget to reload browser page ignoring caches.

Related

Vite pwa plugin not working in development environment for react apps

I'v already migrated from webpack to vite and used vite pwa plugin to register a service worker.
My problem is that when I try to use a custom path for service worker, Vite will work fine in production, but in development cause 404 error.
here is my VitePwa vite.config.js:
VitePWA({
srcDir: 'src',
filename: 'sw.js',
devOptions: {
enabled: true,
},
strategies: 'injectManifest',
injectManifest: {
injectionPoint: undefined
}
}),
I already got that, in the development environment, vite pwa plugin is looking for sw.js in the public directory but I want it to get it from src
I got the solution
First, setting type as module is needed in vitePwaPlugin config in devOptions:
devOptions: {
enabled: true,
type: 'module',
},
and vitePwaPlugin will try to install dev-sw.js?dev-sw file as service worker
Second, for handling registeration I used registerSW from virtual:pwa-register
import { registerSW } from 'virtual:pwa-register';
if ('serviceWorker' in navigator) {
registerSW();
}

Hot reloading React + Redux + SSR with Webpack, how to do it?

I'm trying to implement hot reloading in my company's project. The projet works with React, Redux and .NET with Serverside Rendereing (SSR). I want my project to hot reload when I'm working on my React and SCSS files and keep my state as is (so I don't have to redo the clicks etc. on my app).
To achieve that, I tried to use the devServer conf from Webpack, like so :
devServer: {
static: distFolder,
devMiddleware: {
writeToDisk: true,
serverSideRender: true,
publicPath: distFolder
},
proxy: {
context: () => true,
target: 'http://localhost:5000',
},
hot: true,
port: 3000
},
The webpack dev server is running well, but I have an error on my app :
Error
Note that I tried several options, with or without proxy, with or without serverSideRender, with or without static... I can't find any way to solve this on the webpack documentation, so I'm looking for people who had the same issues and who managed to resolve it.
Thanks !

webpack-dev-server - Remove URI fragment from URL when live reloading

I'm dealing with an Angular 1 application that uses URI fragments for routing purposes.
For example:
http://localhost:3000/#/home
http://localhost:3000/#/menu
http://localhost:3000/#/list
Rather than:
http://localhost:3000/home
http://localhost:3000/menu
http://localhost:3000/list
When I'm using Webpack Dev Server to launch a local server with hot reloading, every time I apply some changes, Webpack reloads the URL but keeping the "/#/route" part.
Unfortunately, due to some code restrictions, I need to always reload the page from "/" because some redirections are applied internally when the app launches the first time and the app will crash if you try to start directly from any URI fragment.
I tried to use the "proxy" and "historyApiFallback" configurations in webpack.config.js like:
devServer: {
proxy: {
'/#': {
target: 'http://localhost:3000',
pathRewrite: { '^/#': '' }
}
}
And:
devServer: {
historyApiFallback: {
verbose: true,
rewrites: [{ from: /^\/#/, to: '/' }]
}
}
But so far, I didn't have any luck. The URL keeps the hash when reloading.
Any suggestions or ideas to configure Webpack Dev Server to always start from "/" and remove the hash URI?

After deploy projects configured with Vercel or Nextjs rewriting can't find assets path

I have the following structure to use one domain to multiple projects:
A repo that contains a single vercel.json file to configure path to others projects
A repo that contains a home app example
A repo that contains a checkout app example
The vercel.json works pretty great and is deployed in nizen.com.br, here is how is it:
// vercel.json
{
"rewrites": [
{
"source": "/checkout",
"destination": "https://checkout.nizen.com.br/checkout"
},
{
"source": "/",
"destination": "https://home.nizen.com.br"
}
]
}
So if we go to nizen.com.br we get the home app example without styles and a bunch of errors in console trying to get the assets of home.nizen.com.br in nizen.com.br and the same happens to checkout app.
Here is one of the similar errors that appear in console on Home app:
And here is the checkout app:
About the app next.config.js files, only Home app stays untouched and Checkout app has a basePath added with value "/checkout" as follows:
// Checkout app next.config.js
module.exports = {
reactStrictMode: true,
basePath: "/checkout",
};
I have tried to use the Next rewrites in hope that will solve the problem but it didn't work.
// example of rewrite that I did
module.exports = {
async rewrites() {
return [
{
source: "/",
destination: "https://home.nizen.com.br",
},
];
},
};
I tried to pass :path* and :path in source and destination, as well use fallback and even change the destination to checkout app to see if something change and none of that worked.
If I got to https://home.nizen.com.br the app runs perfect and same to checkout. What am I doing wrong?
I have solved this question changing the strategy. Instead of using a repo with vercel.json to route the micro-frontends, I'm using the home app as the project hosted in nizen.com.br and it's next.config.js file is the one who makes the magic happen!
//Home App next.config.js file
module.exports = {
reactStrictMode: true,
async rewrites() {
return {
fallback: [
{
source: "/checkout",
destination: "https://checkout.nizen.com.br/checkout",
},
{
source: "/checkout/:path*",
destination: "https://checkout.nizen.com.br/checkout/:path*",
},
],
};
},
};
Both the source and destination must point to the same sub-path (/checkout) and both fallback blocks are necessary. I'm using Next version 12 by the time I'm writing this.

Matching root route in webpack-dev-server's historyApiFallback`

Sample repo demonstrating the issue is here.
I'm trying to set up webpack dev server so that:
Requests to / are served by public/landing.html (a static landing page)
Requests to anything else are served by my React app
Using create-react-app, and based on webpack-dev-server's options, I've set up my webpackDevServer.config.js as follows:
historyApiFallback: {
// Paths with dots should still use the history fallback.
// See https://github.com/facebookincubator/create-react-app/issues/387.
disableDotRule: true,
rewrites: [
// shows views/landing.html as the landing page
{ from: /^\/$/, to: 'landing.html' },
// shows views/subpage.html for all routes starting with /subpage
{ from: /^\/subpage/, to: 'subpage.html' },
// shows views/404.html on all other pages
{ from: /./, to: '404.html' },
],
},
And when I start webpack here's what I see:
Requests to /subpage are routed correctly to subpage.html
Requests to /foo are routed correctly to 404.html. Eventually, these would be handled by my React app.
Requests to / are routed incorrectly to my React app.
How can I get landing.html to respond to requests at /?
I ended up opening a bug request with webpack-dev-middleware and discovered it was not a bug but a failure of configuration.
Specifically, the issue is using HtmlWebpackPlugin alongside historyApiFallback. I believe plugins are processed before the regex matching, and HtmlWebpackPlugin's default file output is index.html; this means that out of the box, / will always be routed to the HtmlWebpackPlugin output file.
The solution to this is to set a custom filename in HtmlWebpackPlugin, which allows you to control the matching again. Here's a sample repo demonstrating the fix and here's the webpack config:
module.exports = {
context: __dirname,
entry: [
'./app.js',
],
output: {
path: __dirname + "/dist",
filename: "bundle.js"
},
devServer: {
publicPath: "/",
// contentBase: "./public",
// hot: true,
historyApiFallback: {
// disableDotRule: true,
rewrites: [
{ from: /^\/$/, to: '/public/index.html' },
{ from: /^\/foo/, to: '/public/foo.html' },
{ from: /(.*)/, to: '/test.html' },
],
}
},
plugins: [
new HtmlWebpackPlugin({
title: "Html Webpack html",
hash: true,
filename: 'test.html',
template: 'public/plugin.html',
}),
],
};
Two thoughts come to mind:
What you want to do is not possible with Webpack Dev Server (as far as I'm aware)
And, once npm run build is run and deployed the deployed app would not follow the same rules as configured in Webpack Dev Server
Even if I'm mistaken on #1, #2 seems like a bigger issue if you ever plan to deploy the app. This leads me to recommend an alternate setup which will work on dev and production (or wherever it's deployed).
A few options:
setup the app as a single-page app (SPA) and use React Router to serve the static routes (/ and /subpage) and wildcards (everything else)
setup node (or another server) to serve the static routes (/ and /subpage) and wildcards (everything else)
An Attempt
In an attempt to setup the routes I was able to achieve this setup:
Display landing.html when / is requested
Display subpage.html when /subpage is requested
Display the React App at a specific path, like app.html
To do this make the following changes:
Move /public/index.html to /public/app.html
mv ./public/index.html ./public/app.html
In /config/webpackDevServer.config.js, update historyApiFallback to:
historyApiFallback: {
// Paths with dots should still use the history fallback.
// See https://github.com/facebookincubator/create-react-app/issues/387.
disableDotRule: true,
rewrites: [
// shows views/landing.html as the landing page
{ from: /^\/$/, to: "landing.html" },
// shows views/subpage.html for all routes starting with /subpage
{ from: /^\/subpage/, to: "subpage.html" },
// shows views/app.html on all other pages
// but doesn't work for routes other than app.html
{ from: /./, to: "app.html" }
]
}
In /config/paths.js update appHTML to:
appHtml: resolveApp("public/app.html")
In /config/webpack.config.dev.js, updateplugins` to include:
new HtmlWebpackPlugin({
filename: "app.html",
inject: true,
template: paths.appHtml
})
Requesting a random URL, like localhost:3000/foo will return a blank page but contains the HTML from the app.html page without the bundled <script> tags injected. So maybe you can find a solution to this final hurdle.

Resources