diff --git a/packages/module-react/build.config.ts b/packages/module-react/build.config.ts new file mode 100644 index 00000000..e4a0fd75 --- /dev/null +++ b/packages/module-react/build.config.ts @@ -0,0 +1,12 @@ +import { defineBuildConfig } from 'unbuild'; +import { resolve } from 'node:path'; + +export default defineBuildConfig({ + rootDir: 'modules', + outDir: resolve(__dirname, 'dist'), + entries: [{ input: 'react.ts', name: 'index' }], + rollup: { + emitCJS: true, + }, + declaration: true, +}); diff --git a/packages/module-react/components/App.tsx b/packages/module-react/components/App.tsx new file mode 100644 index 00000000..2124b612 --- /dev/null +++ b/packages/module-react/components/App.tsx @@ -0,0 +1,5 @@ +export default function () { + const [count, setCount] = useState(0); + const increment = () => setCount((count) => count + 1); + return ; +} diff --git a/packages/module-react/entrypoints/content/index.tsx b/packages/module-react/entrypoints/content/index.tsx new file mode 100644 index 00000000..34f4ae19 --- /dev/null +++ b/packages/module-react/entrypoints/content/index.tsx @@ -0,0 +1,33 @@ +import { defineContentScript } from 'wxt/sandbox'; +import { ContentScriptContext, createShadowRootUi } from 'wxt/client'; +import React from 'react'; +import ReactDOM from 'react-dom/client'; + +export default defineContentScript({ + matches: ['*://*/*'], + + async main(ctx) { + const ui = await createUi(ctx); + ui.mount(); + }, +}); + +function createUi(ctx: ContentScriptContext) { + return createShadowRootUi(ctx, { + name: 'react-ui', + position: 'inline', + append: 'first', + onMount(container) { + const root = ReactDOM.createRoot(container); + root.render( + + + , + ); + return root; + }, + onRemove(root) { + root?.unmount(); + }, + }); +} diff --git a/packages/module-react/entrypoints/popup/index.html b/packages/module-react/entrypoints/popup/index.html new file mode 100644 index 00000000..cc7ec196 --- /dev/null +++ b/packages/module-react/entrypoints/popup/index.html @@ -0,0 +1,12 @@ + + + + + + Document + + +
+ + + diff --git a/packages/module-react/entrypoints/popup/main.tsx b/packages/module-react/entrypoints/popup/main.tsx new file mode 100644 index 00000000..227f35e4 --- /dev/null +++ b/packages/module-react/entrypoints/popup/main.tsx @@ -0,0 +1,10 @@ +import React from 'react'; +import ReactDOM from 'react-dom/client'; + +const root = document.getElementById('app')!; + +ReactDOM.createRoot(root).render( + + + , +); diff --git a/packages/module-react/src/index.ts b/packages/module-react/modules/react.ts similarity index 64% rename from packages/module-react/src/index.ts rename to packages/module-react/modules/react.ts index 5ed81587..111db775 100644 --- a/packages/module-react/src/index.ts +++ b/packages/module-react/modules/react.ts @@ -13,6 +13,17 @@ export default defineWxtModule({ })); addImportPreset(wxt, 'react'); + + // Enable auto-imports for JSX files + wxt.hooks.hook('ready', (wxt) => { + if (wxt.config.imports === false) return; + + wxt.config.imports.dirsScanOptions ??= {}; + wxt.config.imports.dirsScanOptions.filePatterns = [ + // Default plus JSX/TSX + '*.{ts,js,mjs,cjs,mts,cts,jsx,tsx}', + ]; + }); }, }); diff --git a/packages/module-react/package.json b/packages/module-react/package.json index bdf716a7..81160ef5 100644 --- a/packages/module-react/package.json +++ b/packages/module-react/package.json @@ -21,8 +21,10 @@ "dist" ], "scripts": { + "dev": "wxt", + "check": "buildc --deps-only -- check", "build": "buildc -- unbuild", - "check": "buildc --deps-only -- check" + "postinstall": "buildc --deps-only -- wxt prepare" }, "peerDependencies": { "wxt": ">=0.18.6" @@ -32,7 +34,11 @@ }, "devDependencies": { "@aklinker1/check": "^1.3.1", + "@types/react": "^18.3.0", + "@types/react-dom": "^18.3.0", "publint": "^0.2.8", + "react": "^18.3.0", + "react-dom": "^18.3.0", "typescript": "^5.4.5", "unbuild": "^2.0.0", "wxt": "workspace:*" diff --git a/packages/module-react/public/.keep b/packages/module-react/public/.keep new file mode 100644 index 00000000..e69de29b diff --git a/packages/module-react/tsconfig.json b/packages/module-react/tsconfig.json index 9b2dc061..a3ad2c35 100644 --- a/packages/module-react/tsconfig.json +++ b/packages/module-react/tsconfig.json @@ -1,4 +1,8 @@ { - "extends": "../../tsconfig.base.json", + "extends": ["../../tsconfig.base.json", "./.wxt/tsconfig.json"], + "compilerOptions": { + "allowImportingTsExtensions": true, + "jsx": "react-jsx" + }, "exclude": ["node_modules/**", "dist/**"] } diff --git a/packages/module-solid/build.config.ts b/packages/module-solid/build.config.ts new file mode 100644 index 00000000..72314998 --- /dev/null +++ b/packages/module-solid/build.config.ts @@ -0,0 +1,12 @@ +import { defineBuildConfig } from 'unbuild'; +import { resolve } from 'node:path'; + +export default defineBuildConfig({ + rootDir: 'modules', + outDir: resolve(__dirname, 'dist'), + entries: [{ input: 'solid.ts', name: 'index' }], + rollup: { + emitCJS: true, + }, + declaration: true, +}); diff --git a/packages/module-solid/components/App.tsx b/packages/module-solid/components/App.tsx new file mode 100644 index 00000000..c7c50c6c --- /dev/null +++ b/packages/module-solid/components/App.tsx @@ -0,0 +1,7 @@ +import { Component } from 'solid-js'; + +export const App: Component = () => { + const [count, setCount] = createSignal(0); + const increment = () => setCount((count) => count + 1); + return ; +}; diff --git a/packages/module-solid/entrypoints/content/index.tsx b/packages/module-solid/entrypoints/content/index.tsx new file mode 100644 index 00000000..7c2f0e7c --- /dev/null +++ b/packages/module-solid/entrypoints/content/index.tsx @@ -0,0 +1,26 @@ +import { defineContentScript } from 'wxt/sandbox'; +import { ContentScriptContext, createShadowRootUi } from 'wxt/client'; +import { render } from 'solid-js/web'; + +export default defineContentScript({ + matches: ['*://*/*'], + + async main(ctx) { + const ui = await createUi(ctx); + ui.mount(); + }, +}); + +function createUi(ctx: ContentScriptContext) { + return createShadowRootUi(ctx, { + name: 'solid-ui', + position: 'inline', + append: 'first', + onMount(container) { + return render(() => , container); + }, + onRemove(unmount) { + unmount?.(); + }, + }); +} diff --git a/packages/module-solid/entrypoints/popup/index.html b/packages/module-solid/entrypoints/popup/index.html new file mode 100644 index 00000000..cc7ec196 --- /dev/null +++ b/packages/module-solid/entrypoints/popup/index.html @@ -0,0 +1,12 @@ + + + + + + Document + + +
+ + + diff --git a/packages/module-solid/entrypoints/popup/main.tsx b/packages/module-solid/entrypoints/popup/main.tsx new file mode 100644 index 00000000..b01fabf5 --- /dev/null +++ b/packages/module-solid/entrypoints/popup/main.tsx @@ -0,0 +1,5 @@ +import { render } from 'solid-js/web'; + +const root = document.getElementById('app')!; + +render(() => , root); diff --git a/packages/module-solid/src/index.ts b/packages/module-solid/modules/solid.ts similarity index 66% rename from packages/module-solid/src/index.ts rename to packages/module-solid/modules/solid.ts index 0a60e295..0309054c 100644 --- a/packages/module-solid/src/index.ts +++ b/packages/module-solid/modules/solid.ts @@ -16,6 +16,17 @@ export default defineWxtModule({ })); addImportPreset(wxt, 'solid-js'); + + // Enable auto-imports for JSX files + wxt.hooks.hook('ready', (wxt) => { + if (wxt.config.imports === false) return; + + wxt.config.imports.dirsScanOptions ??= {}; + wxt.config.imports.dirsScanOptions.filePatterns = [ + // Default plus JSX/TSX + '*.{ts,js,mjs,cjs,mts,cts,jsx,tsx}', + ]; + }); }, }); diff --git a/packages/module-solid/package.json b/packages/module-solid/package.json index edf4a06d..b1b11f31 100644 --- a/packages/module-solid/package.json +++ b/packages/module-solid/package.json @@ -21,8 +21,10 @@ "dist" ], "scripts": { + "dev": "wxt", + "check": "buildc --deps-only -- check", "build": "buildc -- unbuild", - "check": "buildc --deps-only -- check" + "postinstall": "buildc --deps-only -- wxt prepare" }, "peerDependencies": { "wxt": ">=0.18.6" @@ -33,6 +35,7 @@ "devDependencies": { "@aklinker1/check": "^1.3.1", "publint": "^0.2.8", + "solid-js": "^1.8.17", "typescript": "^5.4.5", "unbuild": "^2.0.0", "wxt": "workspace:*" diff --git a/packages/module-solid/public/.keep b/packages/module-solid/public/.keep new file mode 100644 index 00000000..e69de29b diff --git a/packages/module-solid/tsconfig.json b/packages/module-solid/tsconfig.json index 9b2dc061..add4a7d4 100644 --- a/packages/module-solid/tsconfig.json +++ b/packages/module-solid/tsconfig.json @@ -1,4 +1,8 @@ { - "extends": "../../tsconfig.base.json", + "extends": ["../../tsconfig.base.json", "./.wxt/tsconfig.json"], + "compilerOptions": { + "jsx": "preserve", + "jsxImportSource": "solid-js" + }, "exclude": ["node_modules/**", "dist/**"] } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f239151a..51ab3da0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -99,9 +99,21 @@ importers: '@aklinker1/check': specifier: ^1.3.1 version: 1.3.1(typescript@5.4.5) + '@types/react': + specifier: ^18.3.0 + version: 18.3.3 + '@types/react-dom': + specifier: ^18.3.0 + version: 18.3.0 publint: specifier: ^0.2.8 version: 0.2.8 + react: + specifier: ^18.3.0 + version: 18.3.1 + react-dom: + specifier: ^18.3.0 + version: 18.3.1(react@18.3.1) typescript: specifier: ^5.4.5 version: 5.4.5 @@ -124,6 +136,9 @@ importers: publint: specifier: ^0.2.8 version: 0.2.8 + solid-js: + specifier: ^1.8.17 + version: 1.8.17 typescript: specifier: ^5.4.5 version: 5.4.5 @@ -4700,7 +4715,6 @@ packages: hasBin: true dependencies: js-tokens: 4.0.0 - dev: false /loupe@2.3.7: resolution: {integrity: sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==} @@ -5887,7 +5901,6 @@ packages: loose-envify: 1.4.0 react: 18.3.1 scheduler: 0.23.2 - dev: false /react-is@18.2.0: resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==} @@ -5903,7 +5916,6 @@ packages: engines: {node: '>=0.10.0'} dependencies: loose-envify: 1.4.0 - dev: false /read-pkg@3.0.0: resolution: {integrity: sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==} @@ -6136,7 +6148,6 @@ packages: resolution: {integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==} dependencies: loose-envify: 1.4.0 - dev: false /scule@1.3.0: resolution: {integrity: sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==} @@ -6176,12 +6187,10 @@ packages: seroval: ^1.0 dependencies: seroval: 1.0.7 - dev: false /seroval@1.0.7: resolution: {integrity: sha512-n6ZMQX5q0Vn19Zq7CIKNIo7E75gPkGCFUEqDpa8jgwpYr/vScjqnQ6H09t1uIiZ0ZSK0ypEGvrYK2bhBGWsGdw==} engines: {node: '>=10'} - dev: false /set-value@4.1.0: resolution: {integrity: sha512-zTEg4HL0RwVrqcWs3ztF+x1vkxfm0lP+MQQFPiMJTKVceBwEV0A569Ou8l9IYQG8jOZdMVI1hGsc0tmeD2o/Lw==} @@ -6308,7 +6317,6 @@ packages: csstype: 3.1.3 seroval: 1.0.7 seroval-plugins: 1.0.7(seroval@1.0.7) - dev: false /solid-refresh@0.6.3(solid-js@1.8.17): resolution: {integrity: sha512-F3aPsX6hVw9ttm5LYlth8Q15x6MlI/J3Dn+o3EQyRTtTxidepSTwAYdozt01/YA+7ObcciagGEyXIopGZzQtbA==}