Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a643852387 | |||
| e221252325 | |||
| 88f126e658 | |||
| 17af05acc8 | |||
| fd436a0d63 | |||
| 0d796b63c2 |
@@ -59,6 +59,7 @@ const chromeExtensionIds = [
|
||||
'macmkmchfoclhpbncclinhjflmdkaoom', // Wandpen - Instantly improve your writing with AI
|
||||
'lhmgechokhmdekdpgkkemoeecelcaonm', // YouTube Hider - Remove Comments By Keywords, Usernames & Tools
|
||||
'imgheieooppmahcgniieddodaliodeeg', // QA Compass - Record standardized bug reports easily
|
||||
'npgghjedpchajflknnbngajkjkdhncdo', // aesthetic Notion, styled
|
||||
];
|
||||
|
||||
const { data, err, isLoading } = useListExtensionDetails(chromeExtensionIds);
|
||||
|
||||
@@ -129,7 +129,7 @@ wxt zip
|
||||
|
||||
Firefox requires you to upload a ZIP of your source code. This allows them to rebuild your extension and review the code in a readable way. More details can be found in [Firefox's docs](https://extensionworkshop.com/documentation/publish/source-code-submission/).
|
||||
|
||||
When running `wxt zip -b firefox`, WXT will zip both your extension and sources. Certain files (such as config files, hidden files, and tests) are automatically excluded from your sources. However, it's important to manually check the ZIP to ensure it only contains the files necessary to rebuild your extension.
|
||||
When running `wxt zip -b firefox`, WXT will zip both your extension and sources. Certain files (such as config files, hidden files, tests, and excluded entrypoints) are automatically excluded from your sources. However, it's important to manually check the ZIP to ensure it only contains the files necessary to rebuild your extension.
|
||||
|
||||
To customize which files are zipped, add the `zip` option to your config file.
|
||||
|
||||
|
||||
@@ -1,5 +1,24 @@
|
||||
# Changelog
|
||||
|
||||
## v0.19.19
|
||||
|
||||
[compare changes](https://github.com/wxt-dev/wxt/compare/wxt-v0.19.18...wxt-v0.19.19)
|
||||
|
||||
### 🚀 Enhancements
|
||||
|
||||
- Keyboard shortcut to reopen the browser without restarting the dev command ([#1211](https://github.com/wxt-dev/wxt/pull/1211))
|
||||
|
||||
### 🩹 Fixes
|
||||
|
||||
- Prevent changing dev server port when reloading config ([#1241](https://github.com/wxt-dev/wxt/pull/1241))
|
||||
- Ensure content scripts are registered immediately in dev mode ([#1253](https://github.com/wxt-dev/wxt/pull/1253))
|
||||
- Exclude skipped entrypoints from Firefox sources zip ([#1238](https://github.com/wxt-dev/wxt/pull/1238))
|
||||
|
||||
### ❤️ Contributors
|
||||
|
||||
- Nishu ([@nishu-murmu](http://github.com/nishu-murmu))
|
||||
- Aaron ([@aklinker1](http://github.com/aklinker1))
|
||||
|
||||
## v0.19.18
|
||||
|
||||
[compare changes](https://github.com/wxt-dev/wxt/compare/wxt-v0.19.17...wxt-v0.19.18)
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { TestProject } from '../utils';
|
||||
|
||||
describe('Dev Mode', () => {
|
||||
it('should not change ports when restarting the server', async () => {
|
||||
const project = new TestProject();
|
||||
project.addFile(
|
||||
'entrypoints/background.ts',
|
||||
'export default defineBackground(() => {})',
|
||||
);
|
||||
|
||||
const server = await project.startServer({
|
||||
runner: {
|
||||
disabled: true,
|
||||
},
|
||||
});
|
||||
const initialPort = server.port;
|
||||
await server.restart();
|
||||
const finalPort = server.port;
|
||||
await server.stop();
|
||||
|
||||
expect(finalPort).toBe(initialPort);
|
||||
});
|
||||
});
|
||||
@@ -154,7 +154,7 @@ describe('Hooks', () => {
|
||||
'build:publicAssets': true,
|
||||
'build:manifestGenerated': true,
|
||||
'entrypoints:grouped': true,
|
||||
'entrypoints:resolved': true,
|
||||
'entrypoints:resolved': 2,
|
||||
'vite:build:extendConfig': 1,
|
||||
'vite:devServer:extendConfig': false,
|
||||
'zip:start': true,
|
||||
|
||||
@@ -181,6 +181,42 @@ describe('Zipping', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('should exclude skipped entrypoints from respective browser sources zip', async () => {
|
||||
const project = new TestProject({
|
||||
name: 'test',
|
||||
version: '1.0.0',
|
||||
});
|
||||
project.addFile(
|
||||
'entrypoints/not-firefox.content.ts',
|
||||
`export default defineContentScript({
|
||||
matches: ['*://*/*'],
|
||||
exclude: ['firefox'],
|
||||
main() {},
|
||||
});`,
|
||||
);
|
||||
project.addFile(
|
||||
'entrypoints/all.content.ts',
|
||||
`export default defineContentScript({
|
||||
matches: ['*://*/*'],
|
||||
main(ctx) {},
|
||||
});
|
||||
`,
|
||||
);
|
||||
const unzipDir = project.resolvePath('.output/test-1.0.0-sources');
|
||||
const sourcesZip = project.resolvePath('.output/test-1.0.0-sources.zip');
|
||||
|
||||
await project.zip({
|
||||
browser: 'firefox',
|
||||
});
|
||||
await extract(sourcesZip, { dir: unzipDir });
|
||||
expect(
|
||||
await project.fileExists(unzipDir, 'entrypoints/not-firefox.content.ts'),
|
||||
).toBe(false);
|
||||
expect(
|
||||
await project.fileExists(unzipDir, 'entrypoints/all.content.ts'),
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
it.each(['firefox', 'opera'])(
|
||||
'should create sources zip for "%s" browser when sourcesZip is undefined',
|
||||
async (browser) => {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "wxt",
|
||||
"type": "module",
|
||||
"version": "0.19.18",
|
||||
"version": "0.19.19",
|
||||
"description": "Next gen framework for developing web extensions",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
||||
@@ -27,6 +27,7 @@ import {
|
||||
getContentScriptJs,
|
||||
mapWxtOptionsToRegisteredContentScript,
|
||||
} from './utils/content-scripts';
|
||||
import { createKeyboardShortcuts } from './keyboard-shortcuts';
|
||||
|
||||
/**
|
||||
* Creates a dev server and pre-builds all the files that need to exist before loading the extension.
|
||||
@@ -96,21 +97,27 @@ async function createServerInternal(): Promise<WxtDevServer> {
|
||||
wxt.logger.success(`Started dev server @ ${server.origin}`);
|
||||
await wxt.hooks.callHook('server:started', wxt, server);
|
||||
|
||||
await buildAndOpenBrowser();
|
||||
|
||||
// Register content scripts for the first time after the background starts up since they're not
|
||||
// listed in the manifest
|
||||
// Register content scripts for the first time after the background starts
|
||||
// up since they're not listed in the manifest.
|
||||
// Add listener before opening the browser to guarentee it is present when
|
||||
// the extension sends back the initialization message.
|
||||
server.ws.on('wxt:background-initialized', () => {
|
||||
if (server.currentOutput == null) return;
|
||||
reloadContentScripts(server.currentOutput.steps, server);
|
||||
});
|
||||
|
||||
await buildAndOpenBrowser();
|
||||
|
||||
// Listen for file changes and reload different parts of the extension accordingly
|
||||
const reloadOnChange = createFileReloader(server);
|
||||
server.watcher.on('all', reloadOnChange);
|
||||
keyboardShortcuts.start();
|
||||
keyboardShortcuts.printHelp();
|
||||
},
|
||||
|
||||
async stop() {
|
||||
wasStopped = true;
|
||||
keyboardShortcuts.stop();
|
||||
await runner.closeBrowser();
|
||||
await builderServer.close();
|
||||
await wxt.hooks.callHook('server:closed', wxt, server);
|
||||
@@ -136,11 +143,14 @@ async function createServerInternal(): Promise<WxtDevServer> {
|
||||
},
|
||||
async restartBrowser() {
|
||||
await runner.closeBrowser();
|
||||
keyboardShortcuts.stop();
|
||||
await wxt.reloadConfig();
|
||||
runner = await createExtensionRunner();
|
||||
await runner.openBrowser();
|
||||
keyboardShortcuts.start();
|
||||
},
|
||||
};
|
||||
const keyboardShortcuts = createKeyboardShortcuts(server);
|
||||
|
||||
const buildAndOpenBrowser = async () => {
|
||||
// Build after starting the dev server so it can be used to transform HTML files
|
||||
@@ -230,6 +240,7 @@ function createFileReloader(server: WxtDevServer) {
|
||||
break;
|
||||
case 'content-script-reload':
|
||||
reloadContentScripts(changes.changedSteps, server);
|
||||
|
||||
const rebuiltNames = changes.rebuildGroups
|
||||
.flat()
|
||||
.map((entry) => entry.name);
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
import readline from 'node:readline';
|
||||
import { WxtDevServer } from '../types';
|
||||
import { wxt } from './wxt';
|
||||
import pc from 'picocolors';
|
||||
|
||||
export interface KeyboardShortcutWatcher {
|
||||
start(): void;
|
||||
stop(): void;
|
||||
printHelp(): void;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function that creates a keyboard shortcut handler for the extension.
|
||||
*/
|
||||
export function createKeyboardShortcuts(
|
||||
server: WxtDevServer,
|
||||
): KeyboardShortcutWatcher {
|
||||
let isWatching = false;
|
||||
let rl: readline.Interface | undefined;
|
||||
|
||||
const handleInput = (line: string) => {
|
||||
// Only handle our specific command
|
||||
if (line.trim() === 'o') {
|
||||
server.restartBrowser();
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
start() {
|
||||
if (isWatching) return;
|
||||
|
||||
rl = readline.createInterface({
|
||||
input: process.stdin,
|
||||
terminal: false, // Don't intercept ctrl+C, ctrl+Z, etc
|
||||
});
|
||||
|
||||
rl.on('line', handleInput);
|
||||
isWatching = true;
|
||||
},
|
||||
|
||||
stop() {
|
||||
if (!isWatching) return;
|
||||
|
||||
if (rl) {
|
||||
rl.close();
|
||||
rl = undefined;
|
||||
}
|
||||
|
||||
isWatching = false;
|
||||
},
|
||||
|
||||
printHelp() {
|
||||
if (!wxt.config.runnerConfig.config.disabled) {
|
||||
wxt.logger.info(
|
||||
`${pc.dim('Press')} ${pc.bold('o + enter')} ${pc.dim('to reopen the browser')}`,
|
||||
);
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -36,6 +36,14 @@ export async function registerWxt(
|
||||
return config.logger;
|
||||
},
|
||||
async reloadConfig() {
|
||||
// Prevent changing the server port when resolving config multiple times
|
||||
// get-port-please doesn't always return the same port if it was recently closed.
|
||||
if (wxt.config.dev.server?.port) {
|
||||
inlineConfig.dev ??= {};
|
||||
inlineConfig.dev.server ??= {};
|
||||
inlineConfig.dev.server.port = wxt.config.dev.server.port;
|
||||
}
|
||||
|
||||
wxt.config = await resolveConfig(inlineConfig, command);
|
||||
await wxt.hooks.callHook('config:resolved', wxt);
|
||||
},
|
||||
|
||||
@@ -6,7 +6,7 @@ import { getPackageJson } from './utils/package';
|
||||
import { minimatch } from 'minimatch';
|
||||
import { formatDuration } from './utils/time';
|
||||
import { printFileList } from './utils/log/printFileList';
|
||||
import { internalBuild } from './utils/building';
|
||||
import { findEntrypoints, internalBuild } from './utils/building';
|
||||
import { registerWxt, wxt } from './wxt';
|
||||
import JSZip from 'jszip';
|
||||
import glob from 'fast-glob';
|
||||
@@ -55,6 +55,14 @@ export async function zip(config?: InlineConfig): Promise<string[]> {
|
||||
await wxt.hooks.callHook('zip:extension:done', wxt, outZipPath);
|
||||
|
||||
if (wxt.config.zip.zipSources) {
|
||||
const entrypoints = await findEntrypoints();
|
||||
const skippedEntrypoints = entrypoints.filter((entry) => entry.skipped);
|
||||
const excludeSources = [
|
||||
...wxt.config.zip.excludeSources,
|
||||
...skippedEntrypoints.map((entry) =>
|
||||
path.relative(wxt.config.zip.sourcesRoot, entry.inputPath),
|
||||
),
|
||||
].map((paths) => paths.replaceAll('\\', '/'));
|
||||
await wxt.hooks.callHook('zip:sources:start', wxt);
|
||||
const { overrides, files: downloadedPackages } =
|
||||
await downloadPrivatePackages();
|
||||
@@ -65,7 +73,7 @@ export async function zip(config?: InlineConfig): Promise<string[]> {
|
||||
);
|
||||
await zipDir(wxt.config.zip.sourcesRoot, sourcesZipPath, {
|
||||
include: wxt.config.zip.includeSources,
|
||||
exclude: wxt.config.zip.excludeSources,
|
||||
exclude: excludeSources,
|
||||
transform(absolutePath, zipPath, content) {
|
||||
if (zipPath.endsWith('package.json')) {
|
||||
return addOverridesToPackageJson(absolutePath, content, overrides);
|
||||
|
||||
Reference in New Issue
Block a user