Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| cf7f23d4c3 | |||
| 62ecb6f41e | |||
| fc45c37f22 | |||
| 68874e607e | |||
| 35865adcb2 | |||
| 3b63a51475 | |||
| d32e59e38f | |||
| dab8efa140 |
@@ -1,5 +1,26 @@
|
||||
# Changelog
|
||||
|
||||
## v0.14.7
|
||||
|
||||
[compare changes](https://github.com/wxt-dev/wxt/compare/v0.14.6...v0.14.7)
|
||||
|
||||
### 🩹 Fixes
|
||||
|
||||
- Improve error messages when importing and building entrypoints ([3b63a51](https://github.com/wxt-dev/wxt/commit/3b63a51))
|
||||
- **storage:** Throw better error message when importing outside a extension environment ([35865ad](https://github.com/wxt-dev/wxt/commit/35865ad))
|
||||
- Upgrade `web-ext-run` ([62ecb6f](https://github.com/wxt-dev/wxt/commit/62ecb6f))
|
||||
|
||||
### 📖 Documentation
|
||||
|
||||
- Add `matches` to content script examples ([dab8efa](https://github.com/wxt-dev/wxt/commit/dab8efa))
|
||||
- Fix incorrect sample code ([#372](https://github.com/wxt-dev/wxt/pull/372))
|
||||
- Document defined constants for the build target ([68874e6](https://github.com/wxt-dev/wxt/commit/68874e6))
|
||||
- Add missing `await` to `createShadowRootUi` examples ([fc45c37](https://github.com/wxt-dev/wxt/commit/fc45c37))
|
||||
|
||||
### ❤️ Contributors
|
||||
|
||||
- 東奈比 ([@dongnaebi](http://github.com/dongnaebi))
|
||||
|
||||
## v0.14.6
|
||||
|
||||
[compare changes](https://github.com/wxt-dev/wxt/compare/v0.14.5...v0.14.6)
|
||||
|
||||
@@ -21,6 +21,8 @@ Integrated content script UIs are injected alongside the content of a page. This
|
||||
```ts [Vanilla]
|
||||
// entrypoints/example-ui.content.ts
|
||||
export default defineContentScript({
|
||||
matches: ['<all_urls>'],
|
||||
|
||||
main(ctx) {
|
||||
const ui = createIntegratedUi(ctx, {
|
||||
position: 'inline',
|
||||
@@ -45,6 +47,8 @@ import { createApp } from 'vue';
|
||||
import App from './App.vue';
|
||||
|
||||
export default defineContentScript({
|
||||
matches: ['<all_urls>'],
|
||||
|
||||
main(ctx) {
|
||||
const ui = createIntegratedUi(ctx, {
|
||||
position: 'inline',
|
||||
@@ -73,6 +77,8 @@ import ReactDOM from 'react-dom/client';
|
||||
import App from './App.tsx';
|
||||
|
||||
export default defineContentScript({
|
||||
matches: ['<all_urls>'],
|
||||
|
||||
main(ctx) {
|
||||
const ui = createIntegratedUi(ctx, {
|
||||
position: 'inline',
|
||||
@@ -100,6 +106,8 @@ export default defineContentScript({
|
||||
import App from './App.svelte';
|
||||
|
||||
export default defineContentScript({
|
||||
matches: ['<all_urls>'],
|
||||
|
||||
main(ctx) {
|
||||
const ui = createIntegratedUi(ctx, {
|
||||
position: 'inline',
|
||||
@@ -128,6 +136,8 @@ export default defineContentScript({
|
||||
import { render } from 'solid-js/web';
|
||||
|
||||
export default defineContentScript({
|
||||
matches: ['<all_urls>'],
|
||||
|
||||
main(ctx) {
|
||||
const ui = createIntegratedUi(ctx, {
|
||||
position: 'inline',
|
||||
@@ -174,6 +184,7 @@ To use `createShadowRootUi`, follow these steps:
|
||||
import './style.css';
|
||||
|
||||
export default defineContentScript({
|
||||
matches: ['<all_urls>'],
|
||||
// 2. Set cssInjectionMode
|
||||
cssInjectionMode: 'ui',
|
||||
|
||||
@@ -182,7 +193,7 @@ export default defineContentScript({
|
||||
const ui = await createShadowRootUi(ctx, {
|
||||
name: 'example-ui',
|
||||
anchor: '#anchor',
|
||||
type: 'inline',
|
||||
position: 'inline',
|
||||
onMount(container) {
|
||||
// Define how your UI will be mounted inside the container
|
||||
const app = document.createElement('p');
|
||||
@@ -204,6 +215,7 @@ import { createApp } from 'vue';
|
||||
import App from './App.vue';
|
||||
|
||||
export default defineContentScript({
|
||||
matches: ['<all_urls>'],
|
||||
// 2. Set cssInjectionMode
|
||||
cssInjectionMode: 'ui',
|
||||
|
||||
@@ -212,7 +224,7 @@ export default defineContentScript({
|
||||
const ui = await createShadowRootUi(ctx, {
|
||||
name: 'example-ui',
|
||||
anchor: '#anchor',
|
||||
type: 'inline',
|
||||
position: 'inline',
|
||||
onMount: (container) => {
|
||||
// Define how your UI will be mounted inside the container
|
||||
const app = createApp(App);
|
||||
@@ -238,12 +250,13 @@ import ReactDOM from 'react-dom/client';
|
||||
import App from './App.tsx';
|
||||
|
||||
export default defineContentScript({
|
||||
matches: ['<all_urls>'],
|
||||
// 2. Set cssInjectionMode
|
||||
cssInjectionMode: 'ui',
|
||||
|
||||
main(ctx) {
|
||||
async main(ctx) {
|
||||
// 3. Define your UI
|
||||
const ui = createShadowRootUi(ctx, {
|
||||
const ui = await createShadowRootUi(ctx, {
|
||||
name: 'example-ui',
|
||||
position: 'inline',
|
||||
anchor: '#anchor',
|
||||
@@ -271,12 +284,13 @@ import './style.css';
|
||||
import App from './App.svelte';
|
||||
|
||||
export default defineContentScript({
|
||||
matches: ['<all_urls>'],
|
||||
// 2. Set cssInjectionMode
|
||||
cssInjectionMode: 'ui',
|
||||
|
||||
main(ctx) {
|
||||
async main(ctx) {
|
||||
// 3. Define your UI
|
||||
const ui = createShadowRootUi(ctx, {
|
||||
const ui = await createShadowRootUi(ctx, {
|
||||
name: 'example-ui',
|
||||
position: 'inline',
|
||||
anchor: '#anchor',
|
||||
@@ -305,12 +319,13 @@ import './style.css';
|
||||
import { render } from 'solid-js/web';
|
||||
|
||||
export default defineContentScript({
|
||||
matches: ['<all_urls>'],
|
||||
// 2. Set cssInjectionMode
|
||||
cssInjectionMode: 'ui',
|
||||
|
||||
main(ctx) {
|
||||
async main(ctx) {
|
||||
// 3. Define your UI
|
||||
const ui = createShadowRootUi(ctx, {
|
||||
const ui = await createShadowRootUi(ctx, {
|
||||
name: 'example-ui',
|
||||
position: 'inline',
|
||||
anchor: '#anchor',
|
||||
@@ -377,13 +392,14 @@ WXT provides a helper function, [`createIframeUi`](/api/wxt/client/functions/cre
|
||||
|
||||
```ts
|
||||
export default defineContentScript({
|
||||
// ...
|
||||
matches: ['<all_urls>'],
|
||||
|
||||
async main(ctx) {
|
||||
// Define the UI
|
||||
const ui = await createIframeUi(ctx, {
|
||||
page: '/example-iframe.html',
|
||||
anchor: '#anchor',
|
||||
type: 'inline',
|
||||
position: 'inline',
|
||||
onMount: (wrapper, iframe) => {
|
||||
// Add styles to the iframe like width
|
||||
iframe.width = 123;
|
||||
|
||||
@@ -17,11 +17,9 @@ Separate build targets are written to their own output directories:
|
||||
|
||||
To build for a specific browser, pass the `-b --browser` flag from the CLI:
|
||||
|
||||
```
|
||||
|
||||
```sh
|
||||
wxt --browser firefox
|
||||
wxt build --browser firefox
|
||||
|
||||
```
|
||||
|
||||
By default, it will build for `chrome`. When excluding the [manifest version flags](#target-manifest-version), it will default to the commonly accepted manifest version for that browser.
|
||||
@@ -112,3 +110,24 @@ export default defineContentScript({
|
||||
:::warning
|
||||
Only `defineBackground` and `defineContentScript` support per-browser options right now.
|
||||
:::
|
||||
|
||||
## Runtime
|
||||
|
||||
To determine the browser or manifest version at runtime, you can use any of the below variables:
|
||||
|
||||
- `__BROWSER__`: A string, the target browser, usually equal to the `--browser` flag
|
||||
- `__MANIFEST_VERSION__`: A number, either `2` or `3`, depending on the manifest version targetted
|
||||
- `__IS_CHROME__`: A boolean equivalent to `__BROWSER__ === "chrome"`
|
||||
- `__IS_FIREFOX__`: A boolean equivalent to `__BROWSER__ === "firefox"`
|
||||
- `__IS_EDGE__`: A boolean equivalent to `__BROWSER__ === "edge"`
|
||||
- `__IS_SAFARI__`: A boolean equivalent to `__BROWSER__ === "safari"`
|
||||
- `__IS_OPERA__`: A boolean equivalent to `__BROWSER__ === "opera"`
|
||||
- `__COMMAND__`: A string, `"serve"` when running `wxt` for development or `"build"` in all other cases.
|
||||
|
||||
:::info
|
||||
These variables are constants defined at build time based on the build target. They do not actually detect which browser the code is running in.
|
||||
|
||||
For example, if you build for `--browser chrome` and publish it on Edge, `__BROWSER__` will be `"chrome"`, not `"edge"`. You have to build a separate ZIP for `--browser edge` before `__BROWSER__` will be `"edge"`.
|
||||
|
||||
If you need to know the actual browser your code is being ran on, you should use a [user agent parser](https://www.npmjs.com/package/ua-parser-js).
|
||||
:::
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "wxt",
|
||||
"type": "module",
|
||||
"version": "0.14.6",
|
||||
"version": "0.14.7",
|
||||
"description": "Next gen framework for developing web extensions",
|
||||
"engines": {
|
||||
"node": ">=18",
|
||||
@@ -135,7 +135,7 @@
|
||||
"rollup-plugin-visualizer": "^5.9.2",
|
||||
"unimport": "^3.4.0",
|
||||
"vite": "^5.0.0",
|
||||
"web-ext-run": "^0.1.0",
|
||||
"web-ext-run": "^0.1.2",
|
||||
"webextension-polyfill": "^0.10.0",
|
||||
"zip-dir": "^2.0.0"
|
||||
},
|
||||
|
||||
Generated
+33
-24
@@ -105,8 +105,8 @@ importers:
|
||||
specifier: ^5.0.0
|
||||
version: 5.0.5(@types/node@20.10.3)(sass@1.69.5)
|
||||
web-ext-run:
|
||||
specifier: ^0.1.0
|
||||
version: 0.1.0
|
||||
specifier: ^0.1.2
|
||||
version: 0.1.2
|
||||
webextension-polyfill:
|
||||
specifier: ^0.10.0
|
||||
version: 0.10.0
|
||||
@@ -412,8 +412,8 @@ packages:
|
||||
'@babel/types': 7.23.5
|
||||
dev: true
|
||||
|
||||
/@babel/runtime@7.22.11:
|
||||
resolution: {integrity: sha512-ee7jVNlWN09+KftVOu9n7S8gQzD/Z6hN/I8VBRXW4P1+Xe7kJGXMwu8vds4aGIMHZnNbdpSWCfZZtinytpcAvA==}
|
||||
/@babel/runtime@7.23.9:
|
||||
resolution: {integrity: sha512-0CX6F+BI2s9dkUqr08KFrAIZgNFj75rdBU/DjCyYLIaV/quFjkk6T+EJ2LkZHyZTbEV4L5p97mNkUsHl2wLFAw==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
dependencies:
|
||||
regenerator-runtime: 0.14.0
|
||||
@@ -442,8 +442,8 @@ packages:
|
||||
engines: {node: '>= 0.10.4'}
|
||||
dev: false
|
||||
|
||||
/@devicefarmer/adbkit@3.2.5:
|
||||
resolution: {integrity: sha512-+J479WWZW3GU3t40flicDfiDrFz6vpiy2RcBQPEhFcs/3La9pOtr4Bgz2Q02E4luUG2RAL068rqIkKNUTy3tZw==}
|
||||
/@devicefarmer/adbkit@3.2.6:
|
||||
resolution: {integrity: sha512-8lO1hSeTgtxcOHhp4tTWq/JaOysp5KNbbyFoxNEBnwkCDZu/Bji3ZfOaG++Riv9jN6c9bgdLBOZqJTC5VJPRKQ==}
|
||||
engines: {node: '>= 0.10.4'}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
@@ -2380,8 +2380,8 @@ packages:
|
||||
dependencies:
|
||||
to-regex-range: 5.0.1
|
||||
|
||||
/firefox-profile@4.3.2:
|
||||
resolution: {integrity: sha512-/C+Eqa0YgIsQT2p66p7Ygzqe7NlE/GNTbhw2SBCm5V3OsWDPITNdTPEcH2Q2fe7eMpYYNPKdUcuVioZBZiR6kA==}
|
||||
/firefox-profile@4.5.0:
|
||||
resolution: {integrity: sha512-goE2XxbmYVSafvCjcy64/AK3xOr14HCUCD4+TpYWEIMy4nrJfNAacLGzwqKwZhCW0hHI2TYMGH+G/YBvOE8L6g==}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
adm-zip: 0.5.10
|
||||
@@ -2422,6 +2422,15 @@ packages:
|
||||
universalify: 2.0.0
|
||||
dev: false
|
||||
|
||||
/fs-extra@11.2.0:
|
||||
resolution: {integrity: sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==}
|
||||
engines: {node: '>=14.14'}
|
||||
dependencies:
|
||||
graceful-fs: 4.2.11
|
||||
jsonfile: 6.1.0
|
||||
universalify: 2.0.0
|
||||
dev: false
|
||||
|
||||
/fs-extra@9.0.1:
|
||||
resolution: {integrity: sha512-h2iAoN838FqAFJY2/qVpzFXy+EBxfVE220PalAqQLDVsFOHLJrZvut5puAbCdNv6WJk+B8ihI+k0c7JK5erwqQ==}
|
||||
engines: {node: '>=10'}
|
||||
@@ -2467,8 +2476,8 @@ packages:
|
||||
resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==}
|
||||
dev: true
|
||||
|
||||
/fx-runner@1.3.0:
|
||||
resolution: {integrity: sha512-5b37H4GCyhF+Nf8xk9mylXoDq4wb7pbGAXxlCXp/631UTeeZomWSYcEGXumY4wk8g2QAqjPMGdWW+RbNt8PUcA==}
|
||||
/fx-runner@1.4.0:
|
||||
resolution: {integrity: sha512-rci1g6U0rdTg6bAaBboP7XdRu01dzTAaKXxFf+PUqGuCv6Xu7o8NZdY1D5MvKGIjb6EdS1g3VlXOgksir1uGkg==}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
commander: 2.9.0
|
||||
@@ -3772,8 +3781,8 @@ packages:
|
||||
json-parse-better-errors: 1.0.2
|
||||
dev: true
|
||||
|
||||
/parse-json@7.1.0:
|
||||
resolution: {integrity: sha512-ihtdrgbqdONYD156Ap6qTcaGcGdkdAxodO1wLqQ/j7HP1u2sFYppINiq4jyC8F+Nm+4fVufylCV00QmkTHkSUg==}
|
||||
/parse-json@7.1.1:
|
||||
resolution: {integrity: sha512-SgOTCX/EZXtZxBE5eJ97P4yGM5n37BwRU+YMsH4vNzFqJV/oWFXXCmwFlgWUM4PrakybVOueJJ6pwHqSVhTFDw==}
|
||||
engines: {node: '>=16'}
|
||||
dependencies:
|
||||
'@babel/code-frame': 7.22.5
|
||||
@@ -5186,24 +5195,24 @@ packages:
|
||||
graceful-fs: 4.2.11
|
||||
dev: false
|
||||
|
||||
/web-ext-run@0.1.0:
|
||||
resolution: {integrity: sha512-42ezvTBirf1v2hw0q4FqYvAzh39bCn3cMQojTLlaE5Y8DWebVkRGdd0jdSJRzPkB5jZa0CHfnqe8gx6oUllqyw==}
|
||||
engines: {node: '>=16.0.0', npm: '>=8.0.0'}
|
||||
/web-ext-run@0.1.2:
|
||||
resolution: {integrity: sha512-VygO7lg10keonbku5Lbi21zEz1k91odkW+c6YB5DGb+mITcRMVM2zr/tJ+Suh6wxNUOOFNbinoqDlSUWdxt6YQ==}
|
||||
engines: {node: '>=18.0.0', npm: '>=8.0.0'}
|
||||
dependencies:
|
||||
'@babel/runtime': 7.22.11
|
||||
'@devicefarmer/adbkit': 3.2.5
|
||||
'@babel/runtime': 7.23.9
|
||||
'@devicefarmer/adbkit': 3.2.6
|
||||
bunyan: 1.8.15
|
||||
chrome-launcher: 0.15.1
|
||||
debounce: 1.2.1
|
||||
es6-error: 4.1.1
|
||||
firefox-profile: 4.3.2
|
||||
fs-extra: 11.1.1
|
||||
fx-runner: 1.3.0
|
||||
firefox-profile: 4.5.0
|
||||
fs-extra: 11.2.0
|
||||
fx-runner: 1.4.0
|
||||
mkdirp: 1.0.4
|
||||
multimatch: 6.0.0
|
||||
mz: 2.7.0
|
||||
node-notifier: 10.0.1
|
||||
parse-json: 7.1.0
|
||||
parse-json: 7.1.1
|
||||
promise-toolbox: 0.21.0
|
||||
source-map-support: 0.5.21
|
||||
strip-bom: 5.0.0
|
||||
@@ -5211,7 +5220,7 @@ packages:
|
||||
tmp: 0.2.1
|
||||
update-notifier: 6.0.2
|
||||
watchpack: 2.4.0
|
||||
ws: 8.13.0
|
||||
ws: 8.16.0
|
||||
zip-dir: 2.0.0
|
||||
transitivePeerDependencies:
|
||||
- bufferutil
|
||||
@@ -5364,8 +5373,8 @@ packages:
|
||||
typedarray-to-buffer: 3.1.5
|
||||
dev: false
|
||||
|
||||
/ws@8.13.0:
|
||||
resolution: {integrity: sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==}
|
||||
/ws@8.16.0:
|
||||
resolution: {integrity: sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==}
|
||||
engines: {node: '>=10.0.0'}
|
||||
peerDependencies:
|
||||
bufferutil: ^4.0.1
|
||||
|
||||
@@ -18,12 +18,15 @@ export async function buildEntrypoints(
|
||||
const steps: BuildStepOutput[] = [];
|
||||
for (let i = 0; i < groups.length; i++) {
|
||||
const group = groups[i];
|
||||
const groupNames = [group]
|
||||
.flat()
|
||||
.map((e) => e.name)
|
||||
.join(pc.dim(', '));
|
||||
spinner.text = pc.dim(`[${i + 1}/${groups.length}]`) + ` ${groupNames}`;
|
||||
steps.push(await config.builder.build(group));
|
||||
const groupNames = [group].flat().map((e) => e.name);
|
||||
const groupNameColored = groupNames.join(pc.dim(', '));
|
||||
spinner.text =
|
||||
pc.dim(`[${i + 1}/${groups.length}]`) + ` ${groupNameColored}`;
|
||||
try {
|
||||
steps.push(await config.builder.build(group));
|
||||
} catch (err) {
|
||||
throw Error(`Failed to build ${groupNames.join(', ')}`, { cause: err });
|
||||
}
|
||||
}
|
||||
const publicAssets = await copyPublicDirectory(config);
|
||||
|
||||
|
||||
@@ -89,16 +89,16 @@ export async function importEntrypointFile<T>(
|
||||
const res = await jiti(path);
|
||||
return res.default;
|
||||
} catch (err) {
|
||||
const filePath = relative(config.root, path);
|
||||
if (err instanceof ReferenceError) {
|
||||
// "XXX is not defined" - usually due to WXT removing imports
|
||||
const variableName = err.message.replace(' is not defined', '');
|
||||
const filePath = relative(config.root, path);
|
||||
throw Error(
|
||||
`${filePath}: Cannot use imported variable "${variableName}" outside the main function. See https://wxt.dev/guide/entrypoints.html#side-effects`,
|
||||
{ cause: err },
|
||||
);
|
||||
} else {
|
||||
throw err;
|
||||
throw Error(`Failed to load entrypoint: ${filePath}`, { cause: err });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+11
-1
@@ -308,10 +308,20 @@ function createDriver(
|
||||
storageArea: 'local' | 'session' | 'sync' | 'managed',
|
||||
): WxtStorageDriver {
|
||||
const getStorageArea = () => {
|
||||
if (browser.storage == null)
|
||||
if (browser.runtime == null) {
|
||||
throw Error(
|
||||
[
|
||||
"'wxt/storage' must be loaded in a web extension environment",
|
||||
'\n - If thrown during a build, see https://github.com/wxt-dev/wxt/issues/371',
|
||||
" - If thrown during tests, mock 'wxt/browser' correctly. See https://wxt.dev/guide/testing.html\n",
|
||||
].join('\n'),
|
||||
);
|
||||
}
|
||||
if (browser.storage == null) {
|
||||
throw Error(
|
||||
"You must add the 'storage' permission to your manifest to use 'wxt/storage'",
|
||||
);
|
||||
}
|
||||
|
||||
return browser.storage[storageArea];
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user