[Question] HMR for Content Scripts - import.meta.hot undefined
Closed this issue · 5 comments
NOT A BUG - BUT A QUESTION
Summary
I'm trying to make HMR work for a content script. I do know that HMR is somewhat limited for content script, but an auto-reload would be satisifiable already. Unfortunately, I'm not able to make it work.
My current vite.config.js looks like this:
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import webExtension, { readJsonFile } from 'vite-plugin-web-extension';
import { viteStaticCopy } from 'vite-plugin-static-copy';
import path from 'path';
import dotenv from 'dotenv';
dotenv.config();
function getEnvVars() {
const env = Object
.entries(process.env)
.filter(([key]) => key.startsWith('REACT_APP_'))
.reduce((envVars, [key, value]) => {
envVars[`process.env.${key}`] = JSON.stringify(value);
return envVars;
}, {
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),
});
console.info("Injecting Env Vars:", Object.keys(env).join("\n"))
return env;
}
// acceptable TARGET: chrome, edge, firefox, opera
const browser = process.env.TARGET || 'chrome';
function generateManifest() {
const manifest = readJsonFile(`src/baseManifest_${browser}.json`);
const pkg = readJsonFile('package.json');
console.info(`Generating Manifest for ${browser}`);
console.info(`Name: ${pkg.name}`);
console.info(`Version: ${pkg.version}`);
return {
name: pkg.name,
description: pkg.description,
version: pkg.version,
...manifest,
};
}
// https://vitejs.dev/config/
export default defineConfig({
define: {
// see vite-env.d.ts
__APP_INFO__: { browser},
...getEnvVars(),
},
resolve: {
alias: {
modules: path.resolve(__dirname, 'src/modules'),
},
},
plugins: [
react(),
webExtension({
browser,
manifest: generateManifest,
}),
viteStaticCopy({
targets: [
{
src: 'src/assets/*',
dest: 'assets',
},
{
src: 'src/translations/*',
dest: '_locales',
},
],
}),
],
});
and I use the following snippet in my content script:
import browser from 'webextension-polyfill';
(()=> {
if (process.env.NODE_ENV === 'development') {
console.log("********************************************************\n", " DEVELOPMENT MODE \n","********************************************************")
console.log("import.meta", import.meta.hot)// <<<< this is always undefined
// HMR setup
import.meta.hot && import.meta.hot.accept(() => {
browser.runtime.sendMessage("@@RELOAD_CONTENT_SCRIPT").then(() => {
window.location.reload(); // Reload the content script
})
});
}
})()
But import.meta.hot
is always undefined.
Environment
System:
OS: Linux 5.15 Ubuntu 20.04.6 LTS (Focal Fossa)
CPU: (8) x64 Intel(R) Core(TM) i7-7700HQ CPU @ 2.80GHz
Memory: 21.20 GB / 31.19 GB
Container: Yes
Shell: 5.0.17 - /bin/bash
Binaries:
Node: 18.19.0 - ~/.nvm/versions/node/v18.19.0/bin/node
Yarn: 1.22.21 - ~/.nvm/versions/node/v18.19.0/bin/yarn
npm: 10.2.3 - ~/.nvm/versions/node/v18.19.0/bin/npm
Watchman: 20210523.214641.0 - /usr/local/bin/watchman
Browsers:
Brave Browser: 124.1.65.132
Chrome: 124.0.6367.207
And a follow up question: The auto open browser function always starts a "clean" browser instance. When using another browser instance the extension does not update automatically. How can I make auto-update work with my "own" browser instance.
Content scripts are always built using lib mode, so they never have access to import.meta.hot
.
The auto open browser function always starts a "clean" browser instance. When using another browser instance the extension does not update automatically. How can I make auto-update work with my "own" browser instance
This is something I found out recently that's not documented, but you can use chrome's --user-data-dir
and it will create a profile that remembers the website you're logged into for one project. You'll have to spend a couple minutes setting up that profile once you run it for the first time, but after that it will remember everything like a normal browser profile.
# ./.webextrc.yml
args:
- --user-data-dir=./chrome-data
Cool, the auto-extension update works nicely when using the auto-launched instance - and using the custom chrome data location improves the DX even more.
As for completion here is a list with chrome runner options: https://gist.github.com/dodying/34ea4760a699b47825a766051f47d43b
For those who wants to run in maximized mode, the following config works pretty nice (json5 format used here):
{
// look here for more options:
// https://vite-plugin-web-extension.aklinker1.io/guide/configure-browser-startup.html#available-options
// furthermore:
// chrome: https://gist.github.com/dodying/34ea4760a699b47825a766051f47d43b
"args": [
"--user-data-dir=./.chrome-data",
"--start-maximized=true"
]
}
@aklinker1 do you see a way to auto-reload the content script?
@aklinker1 do you see a way to auto-reload the content script?
https://vite-plugin-web-extension.aklinker1.io/guide/development.html#development-mode -- tried this, but the page is not being reloaded
will close for, as all answered