Compare commits
25 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 55444858bc | |||
| 771ea03069 | |||
| 38b71d1350 | |||
| cb781aceb5 | |||
| d53c792218 | |||
| 907f4d3672 | |||
| 8432d73a6b | |||
| 94a5435089 | |||
| edf3cf3f17 | |||
| 48783baec3 | |||
| c70f047696 | |||
| e6e0c713bc | |||
| 3691554a73 | |||
| 1a3436606b | |||
| 2c9e7750ec | |||
| fa67910007 | |||
| c77773eb20 | |||
| 148f3d53a6 | |||
| c7af789173 | |||
| 274d39b9a4 | |||
| d1edb2da0e | |||
| ed860027ef | |||
| 488fa6e773 | |||
| ea51cc04a9 | |||
| 6d1761533f |
@@ -8,6 +8,10 @@ on:
|
||||
type: choice
|
||||
options:
|
||||
- wxt
|
||||
- module-react
|
||||
- module-vue
|
||||
- module-svelte
|
||||
- module-solid
|
||||
|
||||
jobs:
|
||||
validate:
|
||||
|
||||
@@ -8,17 +8,17 @@ on:
|
||||
type: choice
|
||||
options:
|
||||
- wxt
|
||||
- module-react
|
||||
- module-vue
|
||||
- module-svelte
|
||||
- module-solid
|
||||
|
||||
jobs:
|
||||
sync:
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: pnpm/action-setup@v4
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 18
|
||||
cache: pnpm
|
||||
- uses: ./.github/actions/setup
|
||||
- run: pnpm tsx scripts/sync-releases.ts ${{ inputs.package }}
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
@@ -13,6 +13,12 @@ jobs:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: ./.github/actions/setup
|
||||
- run: pnpm check
|
||||
builds:
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: ./.github/actions/setup
|
||||
- run: pnpm -r --sequential build
|
||||
build-demo:
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
|
||||
@@ -20,3 +20,4 @@ templates/*/package-lock.json
|
||||
docs/api/reference
|
||||
stats.html
|
||||
.tool-versions
|
||||
.cache
|
||||
|
||||
@@ -112,3 +112,20 @@ cp -r templates/vanilla templates/<new-template-name>
|
||||
```
|
||||
|
||||
That's it. Once your template is merged, it will be available inside `wxt init` immediately. You don't need to release a new version of WXT to release a new template.
|
||||
|
||||
## Releasing Updates
|
||||
|
||||
Releases are done with GitHub actions:
|
||||
|
||||
- Use the [Release workflow](https://github.com/wxt-dev/wxt/actions/workflows/release.yml) to release a single package in the monorepo. This automatically detects the version change with conventional commits, builds and uploads the package to NPM, and creates a GitHub release.
|
||||
- Use the [Sync Releases workflow](https://github.com/wxt-dev/wxt/actions/workflows/sync-releases.yml) to sync the GitHub releases with changes to the changelog. To change a release, update the `CHANGELOG.md` file and run the workflow. It will sync the releases of a single package in the monorepo.
|
||||
|
||||
## Upgrading Dependencies
|
||||
|
||||
Use [`taze`](https://www.npmjs.com/package/taze) to upgrade dependencies throughout the entire monorepo.
|
||||
|
||||
```ts
|
||||
pnpm dlx taze -r
|
||||
```
|
||||
|
||||
Configuration is in [`taze.config.ts`](./taze.config.ts).
|
||||
|
||||
+22
-17
@@ -5,9 +5,9 @@
|
||||
"node": ">=18.20.3",
|
||||
"pnpm": "^8.6.3"
|
||||
},
|
||||
"packageManager": "pnpm@8.6.3",
|
||||
"packageManager": "pnpm@8.15.8",
|
||||
"scripts": {
|
||||
"check": "check && pnpm -r run check",
|
||||
"check": "check && pnpm -r --sequential run check",
|
||||
"test": "vitest",
|
||||
"test:coverage": "vitest run --coverage.enabled \"--coverage.include=packages/wxt/src/**\" \"--coverage.exclude=packages/wxt/src/core/utils/testing/**\" \"--coverage.exclude=**/*.d.ts\" \"--coverage.exclude=**/fixtures/**\"",
|
||||
"prepare": "simple-git-hooks",
|
||||
@@ -15,31 +15,36 @@
|
||||
"docs:gen": "typedoc --options docs/typedoc.json",
|
||||
"docs:dev": "pnpm -s docs:gen && vitepress dev docs",
|
||||
"docs:build": "pnpm -s docs:gen && vitepress build docs",
|
||||
"docs:preview": "pnpm -s docs:gen && vitepress preview docs"
|
||||
"docs:preview": "pnpm -s docs:gen && vitepress preview docs",
|
||||
"build-deps": "pnpm tsx scripts/build-deps.ts"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@aklinker1/check": "^1.1.1",
|
||||
"@aklinker1/check": "^1.3.1",
|
||||
"@types/fs-extra": "^11.0.4",
|
||||
"@vitest/coverage-v8": "^1.0.1",
|
||||
"@vitest/coverage-v8": "^1.6.0",
|
||||
"changelogen": "^0.5.5",
|
||||
"consola": "^3.2.3",
|
||||
"execa": "^9.1.0",
|
||||
"fs-extra": "^11.1.1",
|
||||
"lint-staged": "^15.2.0",
|
||||
"dependency-graph": "^1.0.0",
|
||||
"execa": "^9.2.0",
|
||||
"fast-glob": "^3.3.2",
|
||||
"fs-extra": "^11.2.0",
|
||||
"hasha": "^6.0.0",
|
||||
"lint-staged": "^15.2.7",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"prettier": "^3.3.0",
|
||||
"simple-git-hooks": "^2.9.0",
|
||||
"tsx": "^4.11.2",
|
||||
"prettier": "^3.3.2",
|
||||
"simple-git-hooks": "^2.11.1",
|
||||
"tsx": "^4.15.4",
|
||||
"typedoc": "^0.25.4",
|
||||
"typedoc-plugin-markdown": "4.0.0-next.23",
|
||||
"typedoc-vitepress-theme": "1.0.0-next.3",
|
||||
"typescript": "^5.3.2",
|
||||
"vitepress": "^1.2.2",
|
||||
"vitest": "^1.5.3",
|
||||
"typescript": "^5.4.5",
|
||||
"vitepress": "^1.2.3",
|
||||
"vitest": "^1.6.0",
|
||||
"vitest-mock-extended": "^1.3.1",
|
||||
"vitest-plugin-random-seed": "^1.0.2",
|
||||
"vue": "^3.3.10",
|
||||
"wxt": "workspace:*"
|
||||
"vitest-plugin-random-seed": "^1.1.0",
|
||||
"vue": "^3.4.27",
|
||||
"wxt": "workspace:*",
|
||||
"yaml": "^2.4.5"
|
||||
},
|
||||
"simple-git-hooks": {
|
||||
"pre-commit": "pnpm lint-staged"
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
# `@wxt-dev/module-react`
|
||||
|
||||
Enables the use of [React](https://react.dev/) in your web extension, in HTML pages and content scripts.
|
||||
|
||||
This plugin makes a few changes:
|
||||
|
||||
1. Adds `@vitejs/plugin-react` to vite
|
||||
2. Adds the [`react` preset](https://github.com/unjs/unimport/blob/main/src/presets/react.ts) to auto-imports
|
||||
|
||||
## Usage
|
||||
|
||||
```sh
|
||||
pnpm i react react-dom
|
||||
pnpm i -D @wxt-dev/module-react
|
||||
```
|
||||
|
||||
Then add the module to your config:
|
||||
|
||||
```ts
|
||||
// wxt.config.ts
|
||||
export default defineConfig({
|
||||
// Required
|
||||
modules: ['@wxt-dev/module-react'],
|
||||
|
||||
// Optional: Pass options to the module:
|
||||
react: {
|
||||
vite: {
|
||||
// ...
|
||||
},
|
||||
},
|
||||
});
|
||||
```
|
||||
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"name": "@wxt-dev/module-react",
|
||||
"version": "1.0.0",
|
||||
"type": "module",
|
||||
"main": "./dist/index.cjs",
|
||||
"module": "./dist/index.mjs",
|
||||
"types": "./dist/index.d.ts",
|
||||
"exports": {
|
||||
".": {
|
||||
"import": {
|
||||
"types": "./dist/index.d.mts",
|
||||
"default": "./dist/index.mjs"
|
||||
},
|
||||
"require": {
|
||||
"types": "./dist/index.d.cts",
|
||||
"default": "./dist/index.cjs"
|
||||
}
|
||||
}
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "pnpm -s build-deps && unbuild",
|
||||
"check": "pnpm -s build-deps && check",
|
||||
"build-deps": "pnpm -ws build-deps @wxt-dev/module-react"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"wxt": ">=0.18.5"
|
||||
},
|
||||
"dependencies": {
|
||||
"@vitejs/plugin-react": "^4.3.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@aklinker1/check": "^1.3.1",
|
||||
"publint": "^0.2.8",
|
||||
"typescript": "^5.4.5",
|
||||
"unbuild": "^2.0.0",
|
||||
"wxt": "workspace:*"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
import 'wxt';
|
||||
import { addImportPreset, addViteConfig, defineWxtModule } from 'wxt/modules';
|
||||
import react, { Options as PluginOptions } from '@vitejs/plugin-react';
|
||||
|
||||
export default defineWxtModule<ReactModuleOptions>({
|
||||
name: '@wxt-dev/module-react',
|
||||
configKey: 'react',
|
||||
setup(wxt, options) {
|
||||
const { vite } = options ?? {};
|
||||
|
||||
addViteConfig(wxt, () => ({
|
||||
plugins: [react(vite)],
|
||||
}));
|
||||
|
||||
addImportPreset(wxt, 'react');
|
||||
},
|
||||
});
|
||||
|
||||
export interface ReactModuleOptions {
|
||||
vite?: PluginOptions;
|
||||
}
|
||||
|
||||
declare module 'wxt' {
|
||||
export interface InlineConfig {
|
||||
react?: ReactModuleOptions;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"exclude": ["node_modules/**", "dist/**"]
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
# `@wxt-dev/module-solid`
|
||||
|
||||
Enables the use of [SolidJS](https://www.solidjs.com/) in your web extension, in HTML pages and content scripts.
|
||||
|
||||
This plugin makes a few changes:
|
||||
|
||||
1. Adds `vite-plugin-solid` to vite
|
||||
2. Adds the [`solid-js` preset](https://github.com/unjs/unimport/blob/main/src/presets/solid.ts) to auto-imports
|
||||
|
||||
## Usage
|
||||
|
||||
```sh
|
||||
pnpm i solid-js
|
||||
pnpm i -D @wxt-dev/module-solid
|
||||
```
|
||||
|
||||
Then add the module to your config:
|
||||
|
||||
```ts
|
||||
// wxt.config.ts
|
||||
export default defineConfig({
|
||||
// Required
|
||||
modules: ['@wxt-dev/module-solid'],
|
||||
|
||||
// Optional: Pass options to the module:
|
||||
solid: {
|
||||
vite: {
|
||||
// ...
|
||||
},
|
||||
},
|
||||
});
|
||||
```
|
||||
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"name": "@wxt-dev/module-solid",
|
||||
"version": "1.0.0",
|
||||
"type": "module",
|
||||
"main": "./dist/index.cjs",
|
||||
"module": "./dist/index.mjs",
|
||||
"types": "./dist/index.d.ts",
|
||||
"exports": {
|
||||
".": {
|
||||
"import": {
|
||||
"types": "./dist/index.d.mts",
|
||||
"default": "./dist/index.mjs"
|
||||
},
|
||||
"require": {
|
||||
"types": "./dist/index.d.cts",
|
||||
"default": "./dist/index.cjs"
|
||||
}
|
||||
}
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "pnpm -s build-deps && unbuild",
|
||||
"check": "pnpm -s build-deps && check",
|
||||
"build-deps": "pnpm -ws build-deps @wxt-dev/module-solid"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"wxt": ">=0.18.5"
|
||||
},
|
||||
"dependencies": {
|
||||
"vite-plugin-solid": "^2.10.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@aklinker1/check": "^1.3.1",
|
||||
"publint": "^0.2.8",
|
||||
"typescript": "^5.4.5",
|
||||
"unbuild": "^2.0.0",
|
||||
"wxt": "workspace:*"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
import 'wxt';
|
||||
import { addImportPreset, addViteConfig, defineWxtModule } from 'wxt/modules';
|
||||
import solid, { Options as PluginOptions } from 'vite-plugin-solid';
|
||||
|
||||
export default defineWxtModule<SolidModuleOptions>({
|
||||
name: '@wxt-dev/module-solid',
|
||||
configKey: 'solid',
|
||||
setup(wxt, options) {
|
||||
const { vite } = options ?? {};
|
||||
|
||||
addViteConfig(wxt, () => ({
|
||||
plugins: [solid(vite)],
|
||||
}));
|
||||
|
||||
addImportPreset(wxt, 'solid-js');
|
||||
},
|
||||
});
|
||||
|
||||
export interface SolidModuleOptions {
|
||||
vite?: PluginOptions;
|
||||
}
|
||||
|
||||
declare module 'wxt' {
|
||||
export interface InlineConfig {
|
||||
solid?: SolidModuleOptions;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"exclude": ["node_modules/**", "dist/**"]
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
# `@wxt-dev/module-svelte`
|
||||
|
||||
Enables the use of [Svelte](https://svelte.dev/) in your web extension, in HTML pages and content scripts.
|
||||
|
||||
This plugin makes a few changes:
|
||||
|
||||
1. Adds `@sveltejs/vite-plugin-svelte` to vite
|
||||
2. Adds the [`svelte` preset](https://github.com/unjs/unimport/blob/main/src/presets/vue.ts) to auto-imports
|
||||
|
||||
## Usage
|
||||
|
||||
```sh
|
||||
pnpm i svelte
|
||||
pnpm i -D @wxt-dev/module-svelte
|
||||
```
|
||||
|
||||
Then add the module to your config:
|
||||
|
||||
```ts
|
||||
// wxt.config.ts
|
||||
export default defineConfig({
|
||||
// Required
|
||||
modules: ['@wxt-dev/module-svelte'],
|
||||
|
||||
// Optional: Pass options to the module:
|
||||
svelte: {
|
||||
vite: {
|
||||
// ...
|
||||
},
|
||||
},
|
||||
});
|
||||
```
|
||||
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"name": "@wxt-dev/module-svelte",
|
||||
"version": "1.0.0",
|
||||
"type": "module",
|
||||
"main": "./dist/index.cjs",
|
||||
"module": "./dist/index.mjs",
|
||||
"types": "./dist/index.d.ts",
|
||||
"exports": {
|
||||
".": {
|
||||
"import": {
|
||||
"types": "./dist/index.d.mts",
|
||||
"default": "./dist/index.mjs"
|
||||
},
|
||||
"require": {
|
||||
"types": "./dist/index.d.cts",
|
||||
"default": "./dist/index.cjs"
|
||||
}
|
||||
}
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "pnpm -s build-deps && unbuild",
|
||||
"check": "pnpm -s build-deps && check",
|
||||
"build-deps": "pnpm -ws build-deps @wxt-dev/module-svelte"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"wxt": ">=0.18.5"
|
||||
},
|
||||
"dependencies": {
|
||||
"@sveltejs/vite-plugin-svelte": "^3.1.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@aklinker1/check": "^1.3.1",
|
||||
"publint": "^0.2.8",
|
||||
"typescript": "^5.4.5",
|
||||
"unbuild": "^2.0.0",
|
||||
"wxt": "workspace:*"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
import 'wxt';
|
||||
import { addImportPreset, addViteConfig, defineWxtModule } from 'wxt/modules';
|
||||
import {
|
||||
svelte,
|
||||
vitePreprocess,
|
||||
Options as PluginOptions,
|
||||
} from '@sveltejs/vite-plugin-svelte';
|
||||
|
||||
export default defineWxtModule<SvelteModuleOptions>({
|
||||
name: '@wxt-dev/module-svelte',
|
||||
configKey: 'svelte',
|
||||
setup(wxt, options) {
|
||||
const { vite } = options ?? {};
|
||||
|
||||
addViteConfig(wxt, () => ({
|
||||
plugins: [
|
||||
svelte({
|
||||
// Using a svelte.config.js file causes a segmentation fault when importing the file
|
||||
configFile: false,
|
||||
preprocess: [vitePreprocess()],
|
||||
...vite,
|
||||
}),
|
||||
],
|
||||
}));
|
||||
|
||||
addImportPreset(wxt, 'svelte');
|
||||
},
|
||||
});
|
||||
|
||||
export interface SvelteModuleOptions {
|
||||
vite?: Partial<PluginOptions>;
|
||||
}
|
||||
|
||||
declare module 'wxt' {
|
||||
export interface InlineConfig {
|
||||
svelte?: SvelteModuleOptions;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"exclude": ["node_modules/**", "dist/**"]
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
# `@wxt-dev/module-vue`
|
||||
|
||||
Enables the use of [Vue](https://vuejs.org/) in your web extension, in HTML pages and content scripts.
|
||||
|
||||
This plugin makes a few changes:
|
||||
|
||||
1. Adds `@vitejs/plugin-vue` to vite config
|
||||
2. Adds the [`vue` preset](https://github.com/unjs/unimport/blob/main/src/presets/vue.ts) to auto-imports
|
||||
3. Applies sourcemap fix to prevent HMR errors during development
|
||||
4. Enable auto-imports in `.vue` files
|
||||
|
||||
## Usage
|
||||
|
||||
```sh
|
||||
pnpm i vue
|
||||
pnpm i -D @wxt-dev/module-vue
|
||||
```
|
||||
|
||||
Then add the module to your config:
|
||||
|
||||
```ts
|
||||
// wxt.config.ts
|
||||
export default defineConfig({
|
||||
// Required
|
||||
modules: ['@wxt-dev/module-vue'],
|
||||
|
||||
// Optional: Pass options to the module:
|
||||
vue: {
|
||||
vite: {
|
||||
script: {
|
||||
propsDestructure: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
```
|
||||
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"name": "@wxt-dev/module-vue",
|
||||
"version": "1.0.0",
|
||||
"type": "module",
|
||||
"main": "./dist/index.cjs",
|
||||
"module": "./dist/index.mjs",
|
||||
"types": "./dist/index.d.ts",
|
||||
"exports": {
|
||||
".": {
|
||||
"import": {
|
||||
"types": "./dist/index.d.mts",
|
||||
"default": "./dist/index.mjs"
|
||||
},
|
||||
"require": {
|
||||
"types": "./dist/index.d.cts",
|
||||
"default": "./dist/index.cjs"
|
||||
}
|
||||
}
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "pnpm -s build-deps && unbuild",
|
||||
"check": "pnpm -s build-deps && check",
|
||||
"build-deps": "pnpm -ws build-deps @wxt-dev/module-vue"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"wxt": ">=0.18.5"
|
||||
},
|
||||
"dependencies": {
|
||||
"@vitejs/plugin-vue": "^5.0.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@aklinker1/check": "^1.3.1",
|
||||
"publint": "^0.2.8",
|
||||
"typescript": "^5.4.5",
|
||||
"unbuild": "^2.0.0",
|
||||
"wxt": "workspace:*"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
import 'wxt';
|
||||
import { addImportPreset, addViteConfig, defineWxtModule } from 'wxt/modules';
|
||||
import vue, { Options as ViteOptions } from '@vitejs/plugin-vue';
|
||||
|
||||
export default defineWxtModule<VueModuleOptions>({
|
||||
name: '@wxt-dev/module-vue',
|
||||
configKey: 'vue',
|
||||
setup(wxt, options) {
|
||||
const { vite } = options ?? {};
|
||||
|
||||
// Add plugin & set sourcemap option
|
||||
addViteConfig(wxt, ({ command }) => ({
|
||||
// @ts-ignore: Ignore vite version issues
|
||||
plugins: [vue(vite)],
|
||||
build: {
|
||||
// Fixes known issue: https://github.com/wxt-dev/wxt/pull/607
|
||||
sourcemap: false,
|
||||
},
|
||||
}));
|
||||
|
||||
// Enable auto-imports in template files
|
||||
wxt.hooks.hook('ready', (wxt) => {
|
||||
if (!wxt.config.imports) return;
|
||||
|
||||
wxt.config.imports.addons ??= {};
|
||||
if (!Array.isArray(wxt.config.imports.addons)) {
|
||||
wxt.config.imports.addons.vueTemplate = true;
|
||||
} else {
|
||||
wxt.logger.warn(
|
||||
'Could not enable auto-imports in vue templates when using and array for imports.addons',
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
addImportPreset(wxt, 'vue');
|
||||
},
|
||||
});
|
||||
|
||||
export interface VueModuleOptions {
|
||||
vite?: ViteOptions;
|
||||
}
|
||||
|
||||
declare module 'wxt' {
|
||||
export interface InlineConfig {
|
||||
vue?: VueModuleOptions;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"exclude": ["node_modules/**", "dist/**"]
|
||||
}
|
||||
@@ -4,28 +4,28 @@
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "pnpm build:deps && wxt",
|
||||
"build:deps": "pnpm --filter wxt build",
|
||||
"build": "pnpm build:deps && wxt build",
|
||||
"build:all": "pnpm build:deps && run-s -s 'build:all:*'",
|
||||
"dev": "pnpm -s build-deps && wxt",
|
||||
"build": "pnpm -s build-deps && wxt build",
|
||||
"build:all": "pnpm -s build-deps && run-s -s 'build:all:*'",
|
||||
"build:all:chrome-mv3": "wxt build",
|
||||
"build:all:chrome-mv2": "wxt build --mv2",
|
||||
"build:all:firefox-mv3": "wxt build -b firefox --mv3",
|
||||
"build:all:firefox-mv2": "wxt build -b firefox",
|
||||
"test": "pnpm build:deps && vitest",
|
||||
"zip": "pnpm build:deps && wxt zip",
|
||||
"check": "pnpm build:deps && check",
|
||||
"postinstall": "pnpm build:deps && wxt prepare"
|
||||
"test": "pnpm -s build-deps && vitest",
|
||||
"zip": "pnpm -s build-deps && wxt zip",
|
||||
"check": "pnpm -s build-deps && check",
|
||||
"postinstall": "pnpm -s build-deps && wxt prepare",
|
||||
"build-deps": "pnpm -sw build-deps wxt-demo"
|
||||
},
|
||||
"dependencies": {
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0"
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/react": "^18.2.34",
|
||||
"@types/react-dom": "^18.2.14",
|
||||
"sass": "^1.69.5",
|
||||
"typescript": "^5.3.2",
|
||||
"@types/react": "^18.3.3",
|
||||
"@types/react-dom": "^18.3.0",
|
||||
"sass": "^1.77.5",
|
||||
"typescript": "^5.4.5",
|
||||
"wxt": "workspace:*"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,5 @@ export default defineProject({
|
||||
mockReset: true,
|
||||
restoreMocks: true,
|
||||
},
|
||||
// @ts-expect-error
|
||||
plugins: [WxtVitest()],
|
||||
});
|
||||
|
||||
@@ -1,8 +1,26 @@
|
||||
# Changelog
|
||||
|
||||
## v0.18.6
|
||||
|
||||
[compare changes](https://github.com/wxt-dev/wxt/compare/wxt-v0.18.5...wxt-v0.18.6)
|
||||
|
||||
### 🚀 Enhancements
|
||||
|
||||
- **modules:** Add new `addImportPreset` helper function ([#720](https://github.com/wxt-dev/wxt/pull/720))
|
||||
|
||||
### 🩹 Fixes
|
||||
|
||||
- **types:** Module `options` param is optional, but types did not reflect that ([#719](https://github.com/wxt-dev/wxt/pull/719))
|
||||
- **modules:** Re-export `WxtModule` type from `wxt/modules` to prevent TS2742 ([#721](https://github.com/wxt-dev/wxt/pull/721))
|
||||
- **modules:** Add modules to TS project so type augmentation works ([#722](https://github.com/wxt-dev/wxt/pull/722))
|
||||
|
||||
### 🏡 Chore
|
||||
|
||||
- **dev-deps:** Upgrade typescript to 5.4 ([#718](https://github.com/wxt-dev/wxt/pull/718))
|
||||
|
||||
## v0.18.5
|
||||
|
||||
[compare changes](https://github.com/wxt-dev/wxt/compare/0.18.4...0.18.5)
|
||||
[compare changes](https://github.com/wxt-dev/wxt/compare/wxt-v0.18.4...wxt-v0.18.5)
|
||||
|
||||
### 🚀 Enhancements
|
||||
|
||||
|
||||
@@ -280,8 +280,7 @@ describe('Output Directory Structure', () => {
|
||||
----------------------------------------
|
||||
import { l as logHello, i as initPlugins } from "./chunks/_virtual_wxt-plugins-OjKtWpmY.js";
|
||||
function defineBackground(arg) {
|
||||
if (typeof arg === "function")
|
||||
return { main: arg };
|
||||
if (typeof arg === "function") return { main: arg };
|
||||
return arg;
|
||||
}
|
||||
const definition = defineBackground({
|
||||
@@ -363,8 +362,7 @@ describe('Output Directory Structure', () => {
|
||||
var _background = function() {
|
||||
"use strict";
|
||||
function defineBackground(arg) {
|
||||
if (typeof arg === "function")
|
||||
return { main: arg };
|
||||
if (typeof arg === "function") return { main: arg };
|
||||
return arg;
|
||||
}
|
||||
function logHello(name) {
|
||||
|
||||
@@ -375,4 +375,9 @@ describe('TypeScript Project', () => {
|
||||
}"
|
||||
`);
|
||||
});
|
||||
|
||||
// TODO: Once a module has been published, use it here for testing - local files are never added to the .wxt/wxt.d.ts file
|
||||
it.todo(
|
||||
'should add modules from NPM to the TS project if they have a configKey',
|
||||
);
|
||||
});
|
||||
|
||||
+30
-29
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "wxt",
|
||||
"type": "module",
|
||||
"version": "0.18.5",
|
||||
"version": "0.18.6",
|
||||
"description": "Next gen framework for developing web extensions",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -102,61 +102,62 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@aklinker1/rollup-plugin-visualizer": "5.12.0",
|
||||
"@types/webextension-polyfill": "^0.10.5",
|
||||
"@types/webextension-polyfill": "^0.10.7",
|
||||
"@webext-core/fake-browser": "^1.3.1",
|
||||
"@webext-core/isolated-element": "^1.1.2",
|
||||
"@webext-core/match-patterns": "^1.0.3",
|
||||
"async-mutex": "^0.4.0",
|
||||
"c12": "^1.5.1",
|
||||
"async-mutex": "^0.4.1",
|
||||
"c12": "^1.11.1",
|
||||
"cac": "^6.7.14",
|
||||
"chokidar": "^3.5.3",
|
||||
"chokidar": "^3.6.0",
|
||||
"ci-info": "^4.0.0",
|
||||
"defu": "^6.1.3",
|
||||
"defu": "^6.1.4",
|
||||
"dequal": "^2.0.3",
|
||||
"esbuild": "^0.19.5",
|
||||
"fast-glob": "^3.3.1",
|
||||
"filesize": "^10.0.8",
|
||||
"fs-extra": "^11.1.1",
|
||||
"get-port": "^7.0.0",
|
||||
"giget": "^1.1.3",
|
||||
"esbuild": "^0.19.12",
|
||||
"fast-glob": "^3.3.2",
|
||||
"filesize": "^10.1.2",
|
||||
"fs-extra": "^11.2.0",
|
||||
"get-port": "^7.1.0",
|
||||
"giget": "^1.2.3",
|
||||
"hookable": "^5.5.3",
|
||||
"is-wsl": "^3.0.0",
|
||||
"jiti": "^1.21.0",
|
||||
"is-wsl": "^3.1.0",
|
||||
"jiti": "^1.21.6",
|
||||
"json5": "^2.2.3",
|
||||
"jszip": "^3.10.1",
|
||||
"linkedom": "^0.18.2",
|
||||
"linkedom": "^0.18.3",
|
||||
"magicast": "^0.3.4",
|
||||
"minimatch": "^9.0.3",
|
||||
"minimatch": "^9.0.4",
|
||||
"natural-compare": "^1.4.0",
|
||||
"normalize-path": "^3.0.0",
|
||||
"nypm": "^0.3.8",
|
||||
"ohash": "^1.1.3",
|
||||
"open": "^10.1.0",
|
||||
"ora": "^7.0.1",
|
||||
"picocolors": "^1.0.0",
|
||||
"picocolors": "^1.0.1",
|
||||
"prompts": "^2.4.2",
|
||||
"publish-browser-extension": "^2.1.3",
|
||||
"unimport": "^3.4.0",
|
||||
"vite": "^5.2.8",
|
||||
"unimport": "^3.7.2",
|
||||
"vite": "^5.3.0",
|
||||
"web-ext-run": "^0.2.0",
|
||||
"webextension-polyfill": "^0.10.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@aklinker1/check": "^1.1.1",
|
||||
"@faker-js/faker": "^8.3.1",
|
||||
"@aklinker1/check": "^1.3.1",
|
||||
"@faker-js/faker": "^8.4.1",
|
||||
"@types/fs-extra": "^11.0.4",
|
||||
"@types/lodash.merge": "^4.6.9",
|
||||
"@types/natural-compare": "^1.4.3",
|
||||
"@types/node": "^20.10.3",
|
||||
"@types/node": "^20.14.2",
|
||||
"@types/normalize-path": "^3.0.2",
|
||||
"@types/prompts": "^2.4.9",
|
||||
"execa": "^9.1.0",
|
||||
"execa": "^9.2.0",
|
||||
"extract-zip": "^2.0.1",
|
||||
"happy-dom": "^13.3.8",
|
||||
"happy-dom": "^13.10.1",
|
||||
"lodash.merge": "^4.6.2",
|
||||
"p-map": "^7.0.0",
|
||||
"publint": "^0.2.6",
|
||||
"tsup": "^8.0.1",
|
||||
"tsx": "^4.11.2",
|
||||
"typescript": "^5.3.2"
|
||||
"p-map": "^7.0.2",
|
||||
"publint": "^0.2.8",
|
||||
"tsup": "^8.1.0",
|
||||
"tsx": "^4.15.4",
|
||||
"typescript": "^5.4.5"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { fakeWxt } from '~/core/utils/testing/fake-objects';
|
||||
import { addViteConfig } from '../modules';
|
||||
import { addImportPreset, addViteConfig } from '../modules';
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { createHooks } from 'hookable';
|
||||
|
||||
@@ -37,4 +37,50 @@ describe('Module Utilities', () => {
|
||||
expect(actual).toEqual(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('addImportPreset', () => {
|
||||
it('should add the import to the config', async () => {
|
||||
const preset = 'vue';
|
||||
const wxt = fakeWxt({ hooks: createHooks() });
|
||||
|
||||
addImportPreset(wxt, preset);
|
||||
await wxt.hooks.callHook('ready', wxt);
|
||||
|
||||
expect(wxt.config.imports && wxt.config.imports.presets).toContain(
|
||||
preset,
|
||||
);
|
||||
});
|
||||
|
||||
it('should not add duplicate presets', async () => {
|
||||
const preset = 'vue';
|
||||
const wxt = fakeWxt({
|
||||
hooks: createHooks(),
|
||||
config: {
|
||||
imports: {
|
||||
presets: ['vue', 'react'],
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
addImportPreset(wxt, preset);
|
||||
await wxt.hooks.callHook('ready', wxt);
|
||||
|
||||
expect(wxt.config.imports && wxt.config.imports.presets).toHaveLength(2);
|
||||
});
|
||||
|
||||
it("should not enable imports if they've been disabled", async () => {
|
||||
const preset = 'vue';
|
||||
const wxt = fakeWxt({
|
||||
hooks: createHooks(),
|
||||
config: {
|
||||
imports: false,
|
||||
},
|
||||
});
|
||||
|
||||
addImportPreset(wxt, preset);
|
||||
await wxt.hooks.callHook('ready', wxt);
|
||||
|
||||
expect(wxt.config.imports).toBe(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -4,9 +4,10 @@ import { getEntrypointName } from '~/core/utils/entrypoints';
|
||||
import { parseHTML } from 'linkedom';
|
||||
import { dirname, relative, resolve } from 'node:path';
|
||||
import { normalizePath } from '~/core/utils/paths';
|
||||
import { murmurHash } from 'ohash';
|
||||
|
||||
// Cache the preamble script for all devHtmlPrerender plugins, not just one
|
||||
let reactRefreshPreamble = '';
|
||||
// Stored outside the plugin to effect all instances of the devHtmlPrerender plugin.
|
||||
const inlineScriptContents: Record<number, string> = {};
|
||||
|
||||
/**
|
||||
* Pre-renders the HTML entrypoints when building the extension to connect to the dev server.
|
||||
@@ -20,8 +21,9 @@ export function devHtmlPrerender(
|
||||
config.wxtModuleDir,
|
||||
'dist/virtual/reload-html.js',
|
||||
);
|
||||
const virtualReactRefreshId = '@wxt/virtual-react-refresh';
|
||||
const resolvedVirtualReactRefreshId = '\0' + virtualReactRefreshId;
|
||||
|
||||
const virtualInlineScript = 'virtual:wxt-inline-script';
|
||||
const resolvedVirtualInlineScript = '\0' + virtualInlineScript;
|
||||
|
||||
return [
|
||||
{
|
||||
@@ -76,22 +78,22 @@ export function devHtmlPrerender(
|
||||
const serverHtml = await server.transformHtml(url, html, originalUrl);
|
||||
const { document } = parseHTML(serverHtml);
|
||||
|
||||
// React pages include a preamble as an unsafe-inline type="module" script to enable fast refresh, as shown here:
|
||||
// https://github.com/wxt-dev/wxt/issues/157#issuecomment-1756497616
|
||||
// Since unsafe-inline scripts are blocked by MV3 CSPs, we need to virtualize it.
|
||||
const reactRefreshScript = Array.from(
|
||||
document.querySelectorAll('script[type=module]'),
|
||||
).find((script) => script.innerHTML.includes('@react-refresh'));
|
||||
if (reactRefreshScript) {
|
||||
// Save preamble to serve from server
|
||||
reactRefreshPreamble = reactRefreshScript.innerHTML;
|
||||
// Replace inline script with virtual module served via dev server.
|
||||
// Extension CSP blocks inline scripts, so that's why we're pulling them
|
||||
// out.
|
||||
const inlineScripts = document.querySelectorAll('script:not([src])');
|
||||
inlineScripts.forEach((script) => {
|
||||
// Save the text content for later
|
||||
const textContent = script.textContent ?? '';
|
||||
const hash = murmurHash(textContent);
|
||||
inlineScriptContents[hash] = textContent;
|
||||
|
||||
// Replace unsafe inline script
|
||||
const virtualScript = document.createElement('script');
|
||||
virtualScript.type = 'module';
|
||||
virtualScript.src = `${server.origin}/${virtualReactRefreshId}`;
|
||||
reactRefreshScript.replaceWith(virtualScript);
|
||||
}
|
||||
virtualScript.src = `${server.origin}/@id/${virtualInlineScript}?${hash}`;
|
||||
script.replaceWith(virtualScript);
|
||||
});
|
||||
|
||||
// Change /@vite/client -> http://localhost:3000/@vite/client
|
||||
const viteClientScript = document.querySelector<HTMLScriptElement>(
|
||||
@@ -112,18 +114,25 @@ export function devHtmlPrerender(
|
||||
name: 'wxt:virtualize-react-refresh',
|
||||
apply: 'serve',
|
||||
resolveId(id) {
|
||||
if (id === `/${virtualReactRefreshId}`) {
|
||||
return resolvedVirtualReactRefreshId;
|
||||
// Resolve inline scripts
|
||||
if (id.startsWith(virtualInlineScript)) {
|
||||
return '\0' + id;
|
||||
}
|
||||
// Ignore chunk contents when pre-rendering
|
||||
|
||||
// Ignore chunks during HTML file pre-rendering
|
||||
if (id.startsWith('/chunks/')) {
|
||||
return '\0noop';
|
||||
}
|
||||
},
|
||||
load(id) {
|
||||
if (id === resolvedVirtualReactRefreshId) {
|
||||
return reactRefreshPreamble;
|
||||
// Resolve virtualized inline scripts
|
||||
if (id.startsWith(resolvedVirtualInlineScript)) {
|
||||
// id="virtual:wxt-inline-script?<hash>"
|
||||
const hash = Number(id.substring(id.indexOf('?') + 1));
|
||||
return inlineScriptContents[hash];
|
||||
}
|
||||
|
||||
// Ignore chunks during HTML file pre-rendering
|
||||
if (id === '\0noop') {
|
||||
return '';
|
||||
}
|
||||
|
||||
@@ -49,7 +49,10 @@ try {
|
||||
const { document } = parseHTML(html);
|
||||
const script = document.createElement('script');
|
||||
script.type = 'module';
|
||||
script.src = 'virtual:wxt-html-plugins';
|
||||
script.src =
|
||||
config.command === 'serve'
|
||||
? `http://${config.dev.server?.hostname}:${config.dev.server?.port}/@id/${virtualHtmlModuleId}`
|
||||
: virtualHtmlModuleId;
|
||||
if (document.head == null) {
|
||||
const newHead = document.createElement('head');
|
||||
document.documentElement.prepend(newHead);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "yarn-ls",
|
||||
"packageManager": "yarn@1.22.19",
|
||||
"packageManager": "yarn@1.22.22",
|
||||
"dependencies": {
|
||||
"mime-types": "2.1.35"
|
||||
},
|
||||
|
||||
@@ -204,6 +204,16 @@ async function writeMainDeclarationFile(references: string[]): Promise<string> {
|
||||
(ref) =>
|
||||
`/// <reference types="./${normalizePath(relative(dir, ref))}" />`,
|
||||
),
|
||||
|
||||
// Add references to modules installed from NPM to the TS project so
|
||||
// their type augmentation can update InlineConfig correctly. Local
|
||||
// modules defined in <root>/modules are already apart of the project, so
|
||||
// we don't need to add them.
|
||||
...wxt.config.modules
|
||||
.filter(
|
||||
(module) => module.type === 'node_module' && module.configKey != null,
|
||||
)
|
||||
.map((module) => `/// <reference types="${module.id}" />`),
|
||||
].join('\n') + '\n',
|
||||
);
|
||||
return filePath;
|
||||
|
||||
@@ -11,6 +11,7 @@ import {
|
||||
Logger,
|
||||
WxtCommand,
|
||||
WxtModule,
|
||||
WxtModuleWithMetadata,
|
||||
} from '~/types';
|
||||
import path from 'node:path';
|
||||
import { createFsCache } from '~/core/utils/cache';
|
||||
@@ -380,15 +381,21 @@ export async function mergeBuilderConfig(
|
||||
export async function resolveWxtModules(
|
||||
modulesDir: string,
|
||||
modules: string[] = [],
|
||||
): Promise<WxtModule<any>[]> {
|
||||
// Resolve NPM packages
|
||||
const npmModules = await Promise.all(
|
||||
): Promise<WxtModuleWithMetadata<any>[]> {
|
||||
// Resolve node_modules modules
|
||||
const npmModules = await Promise.all<WxtModuleWithMetadata<any>>(
|
||||
modules.map(async (moduleId) => {
|
||||
const mod = await import(/* @vite-ignore */ moduleId);
|
||||
const mod: { default: WxtModule<any> } = await import(
|
||||
/* @vite-ignore */ moduleId
|
||||
);
|
||||
if (mod.default == null) {
|
||||
throw Error('Module missing default export: ' + moduleId);
|
||||
}
|
||||
return mod.default;
|
||||
return {
|
||||
...mod.default,
|
||||
type: 'node_module',
|
||||
id: moduleId,
|
||||
};
|
||||
}),
|
||||
);
|
||||
|
||||
@@ -397,10 +404,11 @@ export async function resolveWxtModules(
|
||||
cwd: modulesDir,
|
||||
onlyFiles: true,
|
||||
}).catch(() => []);
|
||||
const localModules = await Promise.all(
|
||||
const localModules = await Promise.all<WxtModuleWithMetadata<any>>(
|
||||
localModulePaths.map(async (file) => {
|
||||
const absolutePath = normalizePath(path.resolve(modulesDir, file));
|
||||
const { config } = await loadConfig<WxtModule<any>>({
|
||||
configFile: path.resolve(modulesDir, file),
|
||||
configFile: absolutePath,
|
||||
globalRc: false,
|
||||
rcFile: false,
|
||||
packageJson: false,
|
||||
@@ -413,10 +421,12 @@ export async function resolveWxtModules(
|
||||
);
|
||||
// Add name based on filename
|
||||
config.name ??= file;
|
||||
return config;
|
||||
return {
|
||||
...config,
|
||||
type: 'local',
|
||||
id: absolutePath,
|
||||
};
|
||||
}),
|
||||
);
|
||||
|
||||
// Execute modules
|
||||
return [...npmModules, ...localModules];
|
||||
}
|
||||
|
||||
@@ -13,6 +13,10 @@ import type {
|
||||
import * as vite from 'vite';
|
||||
import glob from 'fast-glob';
|
||||
import { resolve } from 'node:path';
|
||||
import type { UnimportOptions } from 'unimport';
|
||||
|
||||
// Re-export to prevent TS2742 type errors
|
||||
export { WxtModule };
|
||||
|
||||
export function defineWxtModule<TOptions extends WxtModuleOptions>(
|
||||
module: WxtModule<TOptions> | WxtModuleSetup<TOptions>,
|
||||
@@ -123,8 +127,50 @@ export function addViteConfig(
|
||||
* addWxtPlugin(wxt, "wxt-module-analytics/client-plugin");
|
||||
* });
|
||||
*/
|
||||
export function addWxtPlugin(wxt: Wxt, plugin: string) {
|
||||
export function addWxtPlugin(wxt: Wxt, plugin: string): void {
|
||||
wxt.hooks.hook('ready', (wxt) => {
|
||||
wxt.config.plugins.push(plugin);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an Unimport preset ([built-in](https://github.com/unjs/unimport?tab=readme-ov-file#built-in-presets),
|
||||
* [custom](https://github.com/unjs/unimport?tab=readme-ov-file#custom-presets),
|
||||
* or [auto-scanned](https://github.com/unjs/unimport?tab=readme-ov-file#exports-auto-scan)),
|
||||
* to the project's list of auto-imported utilities.
|
||||
*
|
||||
* Some things to note:
|
||||
* - This function will only de-duplicate built-in preset names. It will not
|
||||
* stop you adding duplicate custom or auto-scanned presets.
|
||||
* - If the project has disabled imports, this function has no effect.
|
||||
*
|
||||
* @param wxt The wxt instance provided by the module's setup function.
|
||||
* @param preset The preset to add to the project.
|
||||
*
|
||||
* @example
|
||||
* export default defineWxtModule((wxt) => {
|
||||
* // Built-in preset:
|
||||
* addImportPreset(wxt, "vue");
|
||||
* // Custom preset:
|
||||
* addImportPreset(wxt, {
|
||||
* from: "vue",
|
||||
* imports: ["ref", "reactive", ...],
|
||||
* });
|
||||
* // Auto-scanned preset:
|
||||
* addImportPreset(wxt, { package: "vue" });
|
||||
* });
|
||||
*/
|
||||
export function addImportPreset(
|
||||
wxt: Wxt,
|
||||
preset: UnimportOptions['presets'][0],
|
||||
): void {
|
||||
wxt.hooks.hook('ready', (wxt) => {
|
||||
if (!wxt.config.imports) return;
|
||||
|
||||
wxt.config.imports.presets ??= [];
|
||||
// De-dupelicate built-in named presets
|
||||
if (wxt.config.imports.presets.includes(preset)) return;
|
||||
|
||||
wxt.config.imports.presets.push(preset);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1185,7 +1185,7 @@ export interface ResolvedConfig {
|
||||
reloadCommand: string | false;
|
||||
};
|
||||
hooks: NestedHooks<WxtHooks>;
|
||||
modules: WxtModule<any>[];
|
||||
modules: WxtModuleWithMetadata<any>[];
|
||||
/**
|
||||
* An array of string to import plugins from. These paths should be
|
||||
* resolvable by vite, and they should `export default defineWxtPlugin(...)`.
|
||||
@@ -1300,7 +1300,7 @@ export type WxtModuleOptions = Record<string, any>;
|
||||
|
||||
export type WxtModuleSetup<TOptions extends WxtModuleOptions> = (
|
||||
wxt: Wxt,
|
||||
moduleOptions: TOptions,
|
||||
moduleOptions?: TOptions,
|
||||
) => void | Promise<void>;
|
||||
|
||||
export interface WxtModule<TOptions extends WxtModuleOptions> {
|
||||
@@ -1325,6 +1325,12 @@ export interface WxtModule<TOptions extends WxtModuleOptions> {
|
||||
setup?: WxtModuleSetup<TOptions>;
|
||||
}
|
||||
|
||||
export interface WxtModuleWithMetadata<TOptions extends WxtModuleOptions>
|
||||
extends WxtModule<TOptions> {
|
||||
type: 'local' | 'node_module';
|
||||
id: string;
|
||||
}
|
||||
|
||||
export interface ResolvedPublicFile {
|
||||
/**
|
||||
* The absolute path to the file that will be copied to the output directory.
|
||||
|
||||
Generated
+2125
-856
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,133 @@
|
||||
//
|
||||
// Build all workspace packages, or only dependencies of a specific package.
|
||||
// Kind of a simple version of nx/turborepo, but we can keep using PNPM to run
|
||||
// all commands.
|
||||
//
|
||||
// Usage:
|
||||
// pnpm tsx scripts/build-deps.ts # Builds all packages in repo
|
||||
// pnpm tsx scripts/build-deps.ts <packageName> # Builds only dependencies of <packageName>
|
||||
//
|
||||
|
||||
import glob from 'fast-glob';
|
||||
import { DepGraph } from 'dependency-graph';
|
||||
import fs from 'fs-extra';
|
||||
import YAML from 'yaml';
|
||||
import { execa } from 'execa';
|
||||
import consola from 'consola';
|
||||
import { hashFile, hash } from 'hasha';
|
||||
import { resolve } from 'node:path';
|
||||
|
||||
// Quick hack to prevent recursive calls to this script. If it's being called
|
||||
// from another instance of this script, the parent instance is already
|
||||
// preforming this build, so it can be skipped.
|
||||
if (process.env.BUILD_DEPS) process.exit(0);
|
||||
process.env.BUILD_DEPS = 'true';
|
||||
|
||||
// Parse args
|
||||
const packageToBuild = process.argv[2];
|
||||
if (packageToBuild == null) {
|
||||
consola.info('Building all packages...');
|
||||
} else {
|
||||
consola.info(`Building dependencies of \`${packageToBuild}\``);
|
||||
}
|
||||
|
||||
// Build graph
|
||||
const workspace: { packages: string[] } = YAML.parse(
|
||||
await fs.readFile('pnpm-workspace.yaml', 'utf8'),
|
||||
);
|
||||
const packageDirs = await glob(workspace.packages, { onlyDirectories: true });
|
||||
|
||||
const graph = new DepGraph<Record<string, any>>();
|
||||
// Add all packages to chart
|
||||
for (const packageDir of packageDirs) {
|
||||
try {
|
||||
const packageJson = await fs.readJson(`${packageDir}/package.json`);
|
||||
graph.addNode(packageJson.name, { ...packageJson, dir: packageDir });
|
||||
} catch {
|
||||
// Package missing package.json, ignore it
|
||||
}
|
||||
}
|
||||
// Add dependencies between packages
|
||||
graph.entryNodes().forEach((packageName) => {
|
||||
const packageJson = graph.getNodeData(packageName);
|
||||
[
|
||||
...Object.entries<string>(packageJson.dependencies ?? {}),
|
||||
...Object.entries<string>(packageJson.devDependencies ?? {}),
|
||||
].forEach(([dep, version]) => {
|
||||
if (version !== 'workspace:*') return;
|
||||
graph.addDependency(packageName, dep);
|
||||
});
|
||||
});
|
||||
function printGraph(graph: DepGraph<any>) {
|
||||
consola.debug('Dependency Graph:');
|
||||
function printNode(node: string, level = 0) {
|
||||
consola.debug(`${''.padStart(level * 2, ' ')}- \`${node}\``);
|
||||
graph.dependenciesOf(node).forEach((dep) => printNode(dep, level + 1));
|
||||
}
|
||||
graph.entryNodes().forEach((entry) => printNode(entry));
|
||||
}
|
||||
printGraph(graph);
|
||||
if (packageToBuild) {
|
||||
// Remove nodes not associated with the package to build
|
||||
graph.entryNodes().forEach((entry) => {
|
||||
if (entry !== packageToBuild) graph.removeNode(entry);
|
||||
});
|
||||
}
|
||||
|
||||
// Get order
|
||||
const buildOrder = graph.overallOrder().filter(
|
||||
// Remove packageToBuild if provided
|
||||
(packageName) => packageName !== packageToBuild,
|
||||
);
|
||||
consola.info('Build order:', buildOrder);
|
||||
|
||||
// Build dependencies of a package
|
||||
async function hashDir(dir: string): Promise<string> {
|
||||
const files = await glob('**/*', {
|
||||
ignore: [
|
||||
'**/dist/**',
|
||||
'**/node_modules/**',
|
||||
'**/__tests__/**',
|
||||
'**/e2e/**',
|
||||
'CHANGELOG.md',
|
||||
'typedoc.json',
|
||||
'vitest.*.ts',
|
||||
],
|
||||
cwd: dir,
|
||||
});
|
||||
const hashes = await Promise.all(
|
||||
files.sort().map(async (file) => {
|
||||
const hash = await hashFile(resolve(dir, file), { algorithm: 'md5' });
|
||||
return `${hash}-${file}`;
|
||||
}),
|
||||
);
|
||||
consola.debug(hashes.join('\n'));
|
||||
return await hash(hashes.join('\n'), { algorithm: 'md5' });
|
||||
}
|
||||
async function buildPackage(packageName: string): Promise<void> {
|
||||
const packageJson = graph.getNodeData(packageName);
|
||||
const hash = await hashDir(packageJson.dir);
|
||||
consola.debug('Directory hash:', hash);
|
||||
const cacheDir = resolve('.cache', packageJson.dir, hash);
|
||||
const outputDir = resolve(packageJson.dir, 'dist');
|
||||
if (await fs.pathExists(cacheDir)) {
|
||||
await fs.ensureDir(outputDir);
|
||||
await fs.copy(cacheDir, outputDir);
|
||||
consola.success(`\`${packageName}\` cached`);
|
||||
} else {
|
||||
await execa('pnpm', ['--filter', packageName, 'build'], {
|
||||
stdio: 'inherit',
|
||||
});
|
||||
await fs.ensureDir(cacheDir);
|
||||
await fs.copy(outputDir, cacheDir);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
for (const packageName of buildOrder) {
|
||||
await buildPackage(packageName);
|
||||
}
|
||||
} catch (err) {
|
||||
consola.error(err);
|
||||
process.exit(1);
|
||||
}
|
||||
@@ -40,13 +40,14 @@ await execa('pnpm', ['version', bumpType], {
|
||||
});
|
||||
const updatedPkgJson = await fs.readJson(pkgJsonPath);
|
||||
const newVersion: string = updatedPkgJson.version;
|
||||
const newTag = getPkgTag(pkg, newVersion);
|
||||
consola.info('Bump:', { currentVersion, bumpType, newVersion });
|
||||
|
||||
// Generate changelog
|
||||
const versionChangelog = await generateMarkDown(commits, {
|
||||
...config,
|
||||
from: currentVersion,
|
||||
to: newVersion,
|
||||
from: prevTag,
|
||||
to: newTag,
|
||||
});
|
||||
const versionChangelogBody = versionChangelog
|
||||
.split('\n')
|
||||
@@ -80,5 +81,5 @@ await execa('git', [
|
||||
'-m',
|
||||
`chore(release): ${pkgName} v${newVersion}`,
|
||||
]);
|
||||
await execa('git', ['tag', getPkgTag(pkg, newVersion)]);
|
||||
await execa('git', ['tag', newTag]);
|
||||
consola.success('Committed version and changelog');
|
||||
|
||||
@@ -27,14 +27,18 @@ config.tokens.github = process.env.GITHUB_TOKEN;
|
||||
// Update releases
|
||||
for (const release of releases) {
|
||||
const tag = getPkgTag(pkg, release.version);
|
||||
const existing = await getGithubReleaseByTag(config, tag);
|
||||
if (existing.body !== release.body) {
|
||||
await updateGithubRelease(config, existing.id!, {
|
||||
tag_name: tag,
|
||||
name: `${pkgName} v${release.version}`,
|
||||
body: release.body,
|
||||
});
|
||||
try {
|
||||
const existing = await getGithubReleaseByTag(config, tag);
|
||||
if (existing.body !== release.body) {
|
||||
await updateGithubRelease(config, existing.id!, {
|
||||
tag_name: tag,
|
||||
name: `${pkgName} v${release.version}`,
|
||||
body: release.body,
|
||||
});
|
||||
}
|
||||
consola.success(`Synced \`${tag}\``);
|
||||
} catch (err) {
|
||||
consola.fail(`\`${tag}\``, err);
|
||||
}
|
||||
consola.success(`Synced \`${tag}\``);
|
||||
}
|
||||
consola.success('Done');
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
// https://github.com/antfu-collective/taze?tab=readme-ov-file#config-file
|
||||
export default {
|
||||
exclude: ['typedoc', 'typedoc-plugin-markdown', 'typedoc-vitepress-theme'],
|
||||
};
|
||||
@@ -15,14 +15,14 @@
|
||||
"postinstall": "wxt prepare"
|
||||
},
|
||||
"dependencies": {
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0"
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/react": "^18.2.46",
|
||||
"@types/react-dom": "^18.2.18",
|
||||
"@vitejs/plugin-react": "^4.2.1",
|
||||
"typescript": "^5.3.3",
|
||||
"wxt": "^0.18.0"
|
||||
"@types/react": "^18.3.3",
|
||||
"@types/react-dom": "^18.3.0",
|
||||
"@vitejs/plugin-react": "^4.3.1",
|
||||
"typescript": "^5.4.5",
|
||||
"wxt": "^0.18.6"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,11 +15,11 @@
|
||||
"postinstall": "wxt prepare"
|
||||
},
|
||||
"dependencies": {
|
||||
"solid-js": "^1.8.7"
|
||||
"solid-js": "^1.8.17"
|
||||
},
|
||||
"devDependencies": {
|
||||
"typescript": "^5.3.3",
|
||||
"vite-plugin-solid": "^2.8.0",
|
||||
"wxt": "^0.18.0"
|
||||
"typescript": "^5.4.5",
|
||||
"vite-plugin-solid": "^2.10.2",
|
||||
"wxt": "^0.18.6"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,12 +14,12 @@
|
||||
"postinstall": "wxt prepare"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@sveltejs/vite-plugin-svelte": "^3.0.1",
|
||||
"@tsconfig/svelte": "^5.0.2",
|
||||
"svelte": "^4.2.8",
|
||||
"svelte-check": "^3.6.2",
|
||||
"tslib": "^2.6.2",
|
||||
"typescript": "^5.3.3",
|
||||
"wxt": "^0.18.0"
|
||||
"@sveltejs/vite-plugin-svelte": "^3.1.1",
|
||||
"@tsconfig/svelte": "^5.0.4",
|
||||
"svelte": "^4.2.18",
|
||||
"svelte-check": "^3.8.0",
|
||||
"tslib": "^2.6.3",
|
||||
"typescript": "^5.4.5",
|
||||
"wxt": "^0.18.6"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
"postinstall": "wxt prepare"
|
||||
},
|
||||
"devDependencies": {
|
||||
"typescript": "^5.3.3",
|
||||
"wxt": "^0.18.0"
|
||||
"typescript": "^5.4.5",
|
||||
"wxt": "^0.18.6"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,12 +15,12 @@
|
||||
"postinstall": "wxt prepare"
|
||||
},
|
||||
"dependencies": {
|
||||
"vue": "^3.4.0"
|
||||
"vue": "^3.4.27"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vitejs/plugin-vue": "^5.0.1",
|
||||
"typescript": "^5.3.3",
|
||||
"vue-tsc": "^2.0.6",
|
||||
"wxt": "^0.18.0"
|
||||
"@vitejs/plugin-vue": "^5.0.5",
|
||||
"typescript": "^5.4.5",
|
||||
"vue-tsc": "^2.0.21",
|
||||
"wxt": "^0.18.6"
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user