Skip to content

Commit 7fd35a4

Browse files
committed
fix(build): fix hmr and add service worker
1 parent c9e086d commit 7fd35a4

File tree

7 files changed

+58
-44
lines changed

7 files changed

+58
-44
lines changed

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@
6161
"npm-run-all": "^4.1.5",
6262
"prettier": "^2.8.4",
6363
"rimraf": "^4.4.0",
64+
"rollup": "^3.19.1",
6465
"standard-version": "^9.5.0",
6566
"stylelint": "^14.16.1",
6667
"typescript": "~4.9.5",

pnpm-lock.yaml

+5-5
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

scripts/manifest.ts

+6-20
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import fs from 'fs-extra';
22

33
import pkg from '../package.json';
44

5-
import { isDev, port, r } from './utils';
5+
import { isDev, port, resolveParent } from './utils';
66

77
import type { Manifest } from 'webextension-polyfill';
88

@@ -26,6 +26,9 @@ export const manifest: Manifest.WebExtensionManifest = {
2626
default_icon: 'icons/icon-512.png',
2727
default_popup: 'views/popup/index.html',
2828
},
29+
background: {
30+
service_worker: 'script/background.js',
31+
},
2932
permissions: ['storage'],
3033
content_security_policy: {
3134
// Adds localhost for vite hot reload
@@ -35,26 +38,9 @@ export const manifest: Manifest.WebExtensionManifest = {
3538
},
3639
};
3740

38-
/**
39-
* Manifest V2 version for hot reload
40-
* @see https://bugs.chromium.org/p/chromium/issues/detail?id=1247690
41-
* @todo Remove when MV3 hot reload is fixed
42-
*/
43-
export const manifestV2: Manifest.WebExtensionManifest = {
44-
manifest_version: 2,
45-
name: manifest.name,
46-
version: manifest.version,
47-
description: manifest.description,
48-
browser_action: manifest.action,
49-
options_ui: manifest.options_ui,
50-
icons: manifest.icons,
51-
permissions: manifest.permissions,
52-
content_security_policy: (manifest.content_security_policy as { extension_pages: string })?.extension_pages,
53-
};
54-
5541
export async function writeManifest() {
56-
fs.ensureDirSync(r(`dist`));
57-
fs.writeJSONSync(r('dist/manifest.json'), isDev ? manifestV2 : manifest, {
42+
fs.ensureDirSync(resolveParent(`dist`));
43+
fs.writeJSONSync(resolveParent('dist/manifest.json'), manifest, {
5844
spaces: 2,
5945
});
6046
console.log(`Writing manifest.json to '${__dirname}/dist/manifest.json'`);

scripts/prepare.ts

+21-9
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,22 @@
1+
import { exec } from 'child_process';
2+
13
import { watch } from 'chokidar';
24
import fs from 'fs-extra';
35

46
import { writeManifest } from './manifest';
5-
import { isDev, port, r } from './utils';
7+
import { isDev, port, resolveParent } from './utils';
68

79
/**
810
* Replace index.html with link to vite localhost for hot reload
911
* @param view the view to replace
1012
*/
1113
const copyIndexHtml = async (view: string) => {
12-
fs.ensureDirSync(r(`dist/views/${view}`));
14+
fs.ensureDirSync(resolveParent(`dist/views/${view}`));
1315
const data = fs
14-
.readFileSync(r(`src/views/${view}/index.html`), 'utf-8')
16+
.readFileSync(resolveParent(`src/views/${view}/index.html`), 'utf-8')
1517
.replace('"./main.ts"', `"http://localhost:${port}/views/${view}/main.ts"`)
1618
.replace('<div id="app"></div>', '<div id="app">Vite server did not start</div>');
17-
fs.writeFileSync(r(`dist/views/${view}/index.html`), data, 'utf-8');
19+
fs.writeFileSync(resolveParent(`dist/views/${view}/index.html`), data, 'utf-8');
1820
console.log(`Stubbing '${view}' to '${__dirname}/dist/views/${view}/index.html'`);
1921
};
2022

@@ -26,12 +28,13 @@ const copyViews = async (views = ['options', 'popup']) => views.map(copyIndexHtm
2628
/**
2729
* Copy extension icons to dist folder
2830
*/
29-
const copyIcons = async () => (isDev ? fs.symlink(r('icons'), r('dist/icons'), 'junction') : fs.copySync('icons', 'dist/icons', { overwrite: true }));
31+
const copyIcons = async () =>
32+
isDev ? fs.symlink(resolveParent('icons'), resolveParent('dist/icons'), 'junction') : fs.copySync('icons', 'dist/icons', { overwrite: true });
3033

3134
/**
3235
* Copy extension icons to dist folder
3336
*/
34-
const copyAssets = async () => fs.symlink(r('src/assets'), r('dist/assets'), 'junction');
37+
const copyAssets = async () => fs.symlink(resolveParent('src/assets'), resolveParent('dist/assets'), 'junction');
3538

3639
/**
3740
* Prepare dist folder with manifest.json and views
@@ -45,15 +48,24 @@ const prepare = async (hmr = isDev) => {
4548
console.log('Watching changes ...');
4649

4750
copyViews().catch(e => console.error('Failed to copy html', e));
48-
watch(r('src/**/*.html')).on('change', () => {
51+
watch(resolveParent('src/**/*.html')).on('change', () => {
4952
copyViews().catch(e => console.error('Failed to copy html', e));
5053
});
5154

52-
watch([r('src/manifest.ts'), r('package.json')]).on('change', () => {
55+
watch([resolveParent('src/manifest.ts'), resolveParent('package.json')]).on('change', () => {
5356
writeManifest().catch(e => console.error('Failed to write manifest.json', e));
5457
});
5558

56-
copyAssets().catch(e => console.error('Failed to write manifest.json', e));
59+
exec('vite build');
60+
watch(resolveParent('src/script/**/*.ts')).on('change', () => {
61+
try {
62+
exec('vite build');
63+
} catch (e) {
64+
console.error('Failed to write manifest.json', e);
65+
}
66+
});
67+
68+
copyAssets().catch(e => console.error('Failed to write assets', e));
5769
}
5870
};
5971

scripts/utils.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,4 @@ export const enum environment {
77

88
export const isDev = process.env.NODE_ENV === environment.dev;
99
export const port = parseInt(process.env.PORT || '', 10) || 3303;
10-
export const r = (...args: string[]) => resolve(__dirname, '..', ...args);
10+
export const resolveParent = (...args: string[]) => resolve(__dirname, '..', ...args);

src/script/background/index.ts

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export {};
2+
3+
console.debug('Background script started');

vite.config.ts

+21-9
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,26 @@ import { dirname, relative } from 'path';
22
import { fileURLToPath, URL } from 'url';
33

44
import vue from '@vitejs/plugin-vue';
5+
56
import { defineConfig } from 'vite';
67

7-
import { isDev, port, r } from './scripts/utils';
8+
import { isDev, port, resolveParent } from './scripts/utils';
9+
10+
import type { InputOption } from 'rollup';
11+
12+
const getInput = (hmr: boolean): InputOption =>
13+
isDev
14+
? {
15+
background: resolveParent('src/script/background/index.ts'),
16+
}
17+
: {
18+
background: resolveParent('src/script/background/index.ts'),
19+
options: resolveParent('src/views/options/index.html'),
20+
popup: resolveParent('src/views/popup/index.html'),
21+
};
822

923
export default defineConfig(({ command }) => ({
10-
root: r('src'),
24+
root: resolveParent('src'),
1125
resolve: {
1226
alias: {
1327
'~': fileURLToPath(new URL('./src', import.meta.url)),
@@ -24,9 +38,7 @@ export default defineConfig(({ command }) => ({
2438
name: 'assets-rewrite',
2539
enforce: 'post',
2640
apply: 'build',
27-
transformIndexHtml(html, { path }) {
28-
return html.replace(/"\/assets\//g, `"${relative(dirname(path), '/assets').replace(/\\/g, '/')}/`);
29-
},
41+
transformIndexHtml: (html, { path }) => html.replace(/"\/assets\//g, `"${relative(dirname(path), '/assets').replace(/\\/g, '/')}/`),
3042
},
3143
],
3244
base: command === 'serve' ? `http://localhost:${port}/` : '/',
@@ -37,12 +49,12 @@ export default defineConfig(({ command }) => ({
3749
},
3850
},
3951
build: {
40-
outDir: r('dist'),
52+
outDir: resolveParent('dist'),
4153
sourcemap: isDev ? 'inline' : false,
4254
rollupOptions: {
43-
input: {
44-
options: r('src/views/options/index.html'),
45-
popup: r('src/views/popup/index.html'),
55+
input: getInput(isDev),
56+
output: {
57+
entryFileNames: entry => (entry.name === 'background' ? 'script/[name].js' : 'assets/[name]-[hash].js'),
4658
},
4759
},
4860
},

0 commit comments

Comments
 (0)