Compare commits

...

5 Commits

Author SHA1 Message Date
GitHub Actions 361bb2dcc8 chore(release): v0.6.1 2023-09-23 02:13:38 +00:00
Aaron 26fca5c0a2 feat: Add transformManifest option (#124) 2023-09-22 21:08:03 -05:00
Aaron 30a61f4384 fix: Don't open browser during development when using WSL (#123) 2023-09-22 20:32:31 -05:00
Aaron Klinker 8e0a189d77 docs: Load extension details from CWS 2023-09-22 14:37:20 -05:00
Aaron Klinker cae44c9732 Update changelog 2023-09-22 12:47:34 -05:00
19 changed files with 239 additions and 43 deletions
+23 -3
View File
@@ -1,5 +1,26 @@
# Changelog
## v0.6.1
[compare changes](https://github.com/wxt-dev/wxt/compare/v0.6.0...v0.6.1)
### 🚀 Enhancements
- Add `transformManifest` option ([#124](https://github.com/wxt-dev/wxt/pull/124))
### 🩹 Fixes
- Don't open browser during development when using WSL ([#123](https://github.com/wxt-dev/wxt/pull/123))
### 📖 Documentation
- Load extension details from CWS ([8e0a189](https://github.com/wxt-dev/wxt/commit/8e0a189))
### ❤️ Contributors
- Aaron <aaronklinker1@gmail.com>
- Aaron Klinker <aaronklinker1@gmail.com>
## v0.6.0
[compare changes](https://github.com/wxt-dev/wxt/compare/v0.5.6...v0.6.0)
@@ -16,12 +37,11 @@
#### ⚠️ Breaking Changes
- ⚠️ Require a function for `vite` configuration ([#121](https://github.com/wxt-dev/wxt/pull/121))
- ⚠️ The `vite` config option must now be a function. If you were using an object before, change it from `vite: { ... }` to `vite: () => ({ ... })`. ([#121](https://github.com/wxt-dev/wxt/pull/121))
### ❤️ Contributors
- Aaron Klinker <aaronklinker1@gmail.com>
- Aaron <aaronklinker1@gmail.com>
- Aaron Klinker ([@aklinker1](https://github.com/aklinker1))
## v0.5.6
+15 -11
View File
@@ -1,12 +1,11 @@
<script lang="ts" setup>
const extensions = [
{
name: 'GitHub: Better Line Counts',
description: 'Remove generated files from GitHub line counts.',
icon: 'https://lh3.googleusercontent.com/GcffNyCJaxT2G9dsQCJHhUEMlu_E0vEzph5cLPrQj7UHKat7QyCzGu69Dmp_DDUL8rY-bPMFJceQarS1wcqdwTalTg=s256',
link: 'https://chrome.google.com/webstore/detail/github-better-line-counts/ocfdgncpifmegplaglcnglhioflaimkd',
},
import useListExtensionDetails from '../composables/useListExtensionDetails';
const chromeExtensionIds = [
'ocfdgncpifmegplaglcnglhioflaimkd', // GitHub: Better Line Counts
];
const { data } = useListExtensionDetails(chromeExtensionIds);
</script>
<template>
@@ -14,10 +13,14 @@ const extensions = [
<div class="container">
<h2>Who's Using WXT?</h2>
<ul>
<li v-for="extension of extensions">
<img :src="extension.icon" :alt="`${extension.name} icon`" />
<a :href="extension.link" target="_blank">{{ extension.name }}</a>
<small>{{ extension.description }}</small>
<li v-for="extension of data">
<img
:src="extension.iconUrl"
:alt="`${extension.name} icon`"
referrerpolicy="no-referrer"
/>
<a :href="extension.storeUrl" target="_blank">{{ extension.name }}</a>
<small>{{ extension.shortDescription }}</small>
</li>
</ul>
<p>Open a PR to add your extension to the list!</p>
@@ -57,6 +60,7 @@ img {
width: 96px;
height: 96px;
margin-bottom: 16px;
border-radius: 8px;
}
ul {
@@ -0,0 +1,53 @@
import { ref } from 'vue';
export interface ChromeExtension {
id: string;
name: string;
iconUrl: string;
weeklyActiveUsers: number;
shortDescription: string;
storeUrl: string;
}
const operationName = 'WxtDocsUsedBy';
const query = `query ${operationName}($ids:[String!]!) {
chromeExtensions(ids: $ids) {
id
name
iconUrl
weeklyActiveUsers
shortDescription
storeUrl
}
}`;
export default function (ids: string[]) {
const data = ref<ChromeExtension[]>();
const err = ref<unknown>();
fetch('https://queue.wxt.dev/api', {
method: 'POST',
body: JSON.stringify({
operationName,
query,
variables: { ids },
}),
})
.then(async (res) => {
const {
data: { chromeExtensions },
} = await res.json();
data.value = chromeExtensions;
err.value = undefined;
})
.catch((error) => {
console.error(error);
data.value = undefined;
err.value = error;
});
return {
data,
err,
};
}
-6
View File
@@ -2,12 +2,6 @@
Bootstrap a new project, start from scratch, or migrate an existing project.
:::warning 🚧&ensp;WSL Support
**_WXT does not support [Windows Subsystem for Linux](https://learn.microsoft.com/en-us/windows/wsl/) yet_**. See [Issue #55](https://github.com/wxt-dev/wxt/issues/55) to track progress.
In the meantime, you can use `cmd` instead.
:::
## Bootstrap Project
:::code-group
+3 -1
View File
@@ -54,4 +54,6 @@ features:
details: 'TODO: Tools for analyizing the final extension bundle.'
---
<UsingWxtSection />
<ClientOnly>
<UsingWxtSection />
</ClientOnly>
+25
View File
@@ -306,4 +306,29 @@ describe('Manifest Content', () => {
js: ['content-scripts/one.js'],
});
});
it('should respect the transformManifest option', async () => {
const project = new TestProject();
project.addFile(
'wxt.config.ts',
`import { defineConfig } from 'wxt';
export default defineConfig({
transformManifest(manifest) {
manifest.author = "Custom Author"
}
})`,
);
await project.build();
const output = await project.serializeFile(
'.output/chrome-mv3/manifest.json',
);
expect(output).toMatchInlineSnapshot(`
".output/chrome-mv3/manifest.json
----------------------------------------
{\\"manifest_version\\":3,\\"name\\":\\"E2E Extension\\",\\"description\\":\\"Example description\\",\\"version\\":\\"0.0.0\\",\\"version_name\\":\\"0.0.0-test\\",\\"author\\":\\"Custom Author\\"}"
`);
});
});
+4 -2
View File
@@ -1,7 +1,7 @@
{
"name": "wxt",
"type": "module",
"version": "0.6.0",
"version": "0.6.1",
"description": "Next gen framework for developing web extensions",
"engines": {
"node": ">=18.16.0",
@@ -77,6 +77,8 @@
"fs-extra": "^11.1.1",
"get-port": "^7.0.0",
"giget": "^1.1.2",
"immer": "^10.0.2",
"is-wsl": "^3.0.0",
"jiti": "^1.19.1",
"json5": "^2.2.3",
"linkedom": "^0.15.1",
@@ -94,7 +96,6 @@
"@types/fs-extra": "^11.0.1",
"@types/lodash.merge": "^4.6.7",
"@types/node": "^20.4.5",
"@types/prettier": "^3.0.0",
"@types/prompts": "^2.4.4",
"@vitest/coverage-v8": "^0.34.1",
"execa": "^7.2.0",
@@ -111,6 +112,7 @@
"vitepress": "1.0.0-rc.10",
"vitest": "^0.34.1",
"vitest-mock-extended": "^1.1.4",
"vue": "^3.3.4",
"webextension-polyfill": "^0.10.0"
},
"peerDependencies": {
+26 -10
View File
@@ -44,6 +44,12 @@ importers:
giget:
specifier: ^1.1.2
version: 1.1.2
immer:
specifier: ^10.0.2
version: 10.0.2
is-wsl:
specifier: ^3.0.0
version: 3.0.0
jiti:
specifier: ^1.19.1
version: 1.19.1
@@ -90,9 +96,6 @@ importers:
'@types/node':
specifier: ^20.4.5
version: 20.5.9
'@types/prettier':
specifier: ^3.0.0
version: 3.0.0
'@types/prompts':
specifier: ^2.4.4
version: 2.4.4
@@ -141,6 +144,9 @@ importers:
vitest-mock-extended:
specifier: ^1.1.4
version: 1.2.1(typescript@5.1.6)(vitest@0.34.3)
vue:
specifier: ^3.3.4
version: 3.3.4
demo:
dependencies:
@@ -1004,13 +1010,6 @@ packages:
/@types/node@20.5.9:
resolution: {integrity: sha512-PcGNd//40kHAS3sTlzKB9C9XL4K0sTup8nbG5lC14kzEteTNuAFh9u5nA0o5TWnSG2r/JNPRXFVcHJIIeRlmqQ==}
/@types/prettier@3.0.0:
resolution: {integrity: sha512-mFMBfMOz8QxhYVbuINtswBp9VL2b4Y0QqYHwqLz3YbgtfAcat2Dl6Y1o4e22S/OVE6Ebl9m7wWiMT2lSbAs1wA==}
deprecated: This is a stub types definition. prettier provides its own type definitions, so you do not need this installed.
dependencies:
prettier: 3.0.3
dev: true
/@types/prompts@2.4.4:
resolution: {integrity: sha512-p5N9uoTH76lLvSAaYSZtBCdEXzpOOufsRjnhjVSrZGXikVGHX9+cc9ERtHRV4hvBKHyZb1bg4K+56Bd2TqUn4A==}
dependencies:
@@ -2482,6 +2481,10 @@ packages:
resolution: {integrity: sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==}
dev: false
/immer@10.0.2:
resolution: {integrity: sha512-Rx3CqeqQ19sxUtYV9CU911Vhy8/721wRFnJv3REVGWUmoAcIwzifTsdmJte/MV+0/XpM35LZdQMBGkRIoLPwQA==}
dev: false
/immutable@4.3.1:
resolution: {integrity: sha512-lj9cnmB/kVS0QHsJnYKD1uo3o39nrbKxszjnqS9Fr6NB7bZzW45U6WSGBPKXDL/CvDKqDNPA4r3DoDQ8GTxo2A==}
dev: true
@@ -2592,6 +2595,12 @@ packages:
hasBin: true
dev: false
/is-docker@3.0.0:
resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
hasBin: true
dev: false
/is-extglob@2.1.1:
resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
engines: {node: '>=0.10.0'}
@@ -2732,6 +2741,13 @@ packages:
is-docker: 2.2.1
dev: false
/is-wsl@3.0.0:
resolution: {integrity: sha512-TQ7xXW/fTBaz/HhGSV779AC99ocpvb9qJPuPwyIea+F+Z+htcQ1wouAA0xEQaa4saVqyP8mwkoYp5efeM/4Gbg==}
engines: {node: '>=16'}
dependencies:
is-docker: 3.0.0
dev: false
/is-yarn-global@0.4.1:
resolution: {integrity: sha512-/kppl+R+LO5VmhYSEWARUFjodS25D68gvj8W7z0I7OWhUla5xWu8KL6CtB2V0R6yqhnRgbcaREMr4EEM6htLPQ==}
engines: {node: '>=12'}
+16
View File
@@ -0,0 +1,16 @@
import { InternalConfig } from '../types';
import { ExtensionRunner } from './extension-runner';
import { createWslRunner } from './wsl';
import { createWebExtRunner } from './web-ext';
import { createSafariRunner } from './safari';
export async function createExtensionRunner(
config: InternalConfig,
): Promise<ExtensionRunner> {
if (config.browser === 'safari') return createSafariRunner();
const { default: isWsl } = await import('is-wsl'); // ESM only, requires dynamic import
if (isWsl) return createWslRunner();
return createWebExtRunner();
}
+21
View File
@@ -0,0 +1,21 @@
import { ExtensionRunner } from './extension-runner';
import { relative } from 'node:path';
/**
* The Safari runner just logs a warning message because `web-ext` doesn't work with Safari.
*/
export function createSafariRunner(): ExtensionRunner {
return {
async openBrowser(config) {
config.logger.warn(
`Cannot Safari using web-ext. Load "${relative(
process.cwd(),
config.outDir,
)}" as an unpacked extension manually`,
);
},
async closeBrowser() {
// noop
},
};
}
@@ -1,5 +1,5 @@
import type { WebExtRunInstance } from 'web-ext-run';
import { ExtensionRunner } from './ExtensionRunner';
import { ExtensionRunner } from './extension-runner';
/**
* Create an `ExtensionRunner` backed by `web-ext`.
@@ -9,10 +9,7 @@ export function createWebExtRunner(): ExtensionRunner {
return {
async openBrowser(config) {
if (config.browser === 'safari') {
config.logger.warn('Cannot open safari automatically.');
return;
}
config.logger.info('Opening browser...');
// Use the plugin's logger instead of web-ext's built-in one.
const webExtLogger = await import('web-ext-run/util/logger');
@@ -57,6 +54,8 @@ export function createWebExtRunner(): ExtensionRunner {
const webExt = await import('web-ext-run');
runner = await webExt.default.cmd.run(finalConfig, options);
config.logger.success('Opened!');
},
async closeBrowser() {
+21
View File
@@ -0,0 +1,21 @@
import { ExtensionRunner } from './extension-runner';
import { relative } from 'node:path';
/**
* The WSL runner just logs a warning message because `web-ext` doesn't work in WSL.
*/
export function createWslRunner(): ExtensionRunner {
return {
async openBrowser(config) {
config.logger.warn(
`Cannot open browser when using WSL. Load "${relative(
process.cwd(),
config.outDir,
)}" as an unpacked extension manually`,
);
},
async closeBrowser() {
// noop
},
};
}
+2 -4
View File
@@ -8,8 +8,8 @@ import * as vite from 'vite';
import { Scripting } from 'webextension-polyfill';
import { getEntrypointBundlePath } from './utils/entrypoints';
import { getContentScriptCssFiles } from './utils/manifest';
import { createWebExtRunner } from './runners/createWebExtRunner';
import { buildInternal } from './build';
import { createExtensionRunner } from './runners';
export async function getServerInfo(): Promise<ServerInfo> {
const { default: getPort, portNumbers } = await import('get-port');
@@ -34,7 +34,7 @@ export async function setupServer(
serverInfo: ServerInfo,
config: InternalConfig,
): Promise<WxtDevServer> {
const runner = createWebExtRunner();
const runner = await createExtensionRunner(config);
const viteServer = await vite.createServer(
vite.mergeConfig(serverInfo, await config.vite(config.env)),
@@ -45,9 +45,7 @@ export async function setupServer(
config.logger.success(`Started dev server @ ${serverInfo.origin}`);
server.currentOutput = await buildInternal(config);
config.logger.info('Opening browser...');
await runner.openBrowser(config);
config.logger.success('Opened!');
};
const reloadExtension = () => {
+17
View File
@@ -155,6 +155,23 @@ export interface InlineConfig {
*/
ignoredSources?: string[];
};
/**
* Transform the final manifest before it's written to the file system. Edit the `manifest`
* parameter directly, do not return a new object. Return values are ignored.
*
* @example
* defineConfig({
* // Add a CSS-only content script.
* transformManifest(manifest) {
* manifest.content_scripts.push({
* matches: ["*://google.com/*"],
* css: ["content-scripts/some-example.css"],
* });
* }
* })
*/
transformManifest?: (manifest: Manifest.WebExtensionManifest) => void;
}
export interface WxtInlineViteConfig
+2
View File
@@ -11,6 +11,7 @@ import {
} from './external';
import { UnimportOptions } from 'unimport';
import { ResolvedConfig } from 'c12';
import { Manifest } from 'webextension-polyfill';
export interface InternalConfig {
root: string;
@@ -41,6 +42,7 @@ export interface InternalConfig {
ignoredSources: string[];
sourcesRoot: string;
};
transformManifest: (manifest: Manifest.WebExtensionManifest) => void;
}
export type EntrypointGroup = Entrypoint | Entrypoint[];
+4
View File
@@ -100,6 +100,10 @@ export async function getInternalConfig(
vite: () => ({}), // Real value added after this object is initialized.
wxtDir,
zip: resolveInternalZipConfig(root, mergedConfig),
transformManifest(manifest) {
userConfig.transformManifest?.(manifest);
inlineConfig.transformManifest?.(manifest);
},
};
finalConfig.vite = (env) =>
+2 -1
View File
@@ -19,6 +19,7 @@ import {
import { getPackageJson } from './package';
import { normalizePath } from './paths';
import { writeFileIfDifferent } from './fs';
import { produce } from 'immer';
/**
* Writes the manifest to the output directory and the build output.
@@ -89,7 +90,7 @@ export async function generateMainfest(
);
}
return manifest;
return produce(manifest, config.transformManifest);
}
/**
+1
View File
@@ -235,5 +235,6 @@ export const fakeInternalConfig = fakeObjectCreator<InternalConfig>(() => {
sourcesTemplate: '{{name}}-sources.zip',
name: faker.person.firstName().toLowerCase(),
},
transformManifest: () => {},
};
});