chore: build framework moved to wxt
This commit is contained in:
parent
fff39d745a
commit
064bbd3dec
26 changed files with 2745 additions and 3431 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -1,5 +1,9 @@
|
|||
dist
|
||||
node_modules
|
||||
.output
|
||||
stats.html
|
||||
.wxt
|
||||
web-ext.config.ts
|
||||
|
||||
*.DS_Store
|
||||
*.eslintcache
|
||||
|
|
3
.npmrc
3
.npmrc
|
@ -1,2 +1,3 @@
|
|||
engine-strict=true
|
||||
auto-install-peers=true
|
||||
auto-install-peers=true
|
||||
shamefully-hoist=true
|
||||
|
|
14
.vscode/launch.json
vendored
14
.vscode/launch.json
vendored
|
@ -1,14 +0,0 @@
|
|||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "debug vite",
|
||||
"request": "launch",
|
||||
"runtimeArgs": ["run-script", "dev"],
|
||||
"runtimeExecutable": "npm",
|
||||
"skipFiles": ["<node_internals>/**"],
|
||||
"type": "node",
|
||||
"sourceMaps": true
|
||||
}
|
||||
]
|
||||
}
|
|
@ -5,7 +5,7 @@
|
|||
"tsx": true,
|
||||
"tailwind": {
|
||||
"config": "tailwind.config.ts",
|
||||
"css": "@/index.css",
|
||||
"css": "@/assets/style.css",
|
||||
"baseColor": "slate",
|
||||
"cssVariables": true
|
||||
},
|
||||
|
|
15
index.html
15
index.html
|
@ -1,15 +0,0 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta name="description" content="Chatting Anonymously with People on the Same Website." />
|
||||
<link rel="shortcut icon" href="https://github.com/shadcn.png" type="image/x-icon" />
|
||||
<title>WebChat</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<h1>WebChat Dev</h1>
|
||||
<script type="module" src="/src/main.tsx"></script>
|
||||
</body>
|
||||
</html>
|
16
manifest.ts
16
manifest.ts
|
@ -1,16 +0,0 @@
|
|||
import { defineManifest } from '@crxjs/vite-plugin'
|
||||
import packageJson from './package.json'
|
||||
|
||||
const isDev = process.env.NODE_ENV === 'development'
|
||||
|
||||
export default defineManifest({
|
||||
manifest_version: 3,
|
||||
name: packageJson.displayName,
|
||||
version: packageJson.version,
|
||||
content_scripts: [
|
||||
{
|
||||
js: ['src/main.tsx'],
|
||||
matches: isDev ? ['*://localhost/*', 'https://www.example.com/*'] : ['https://*/*']
|
||||
}
|
||||
]
|
||||
})
|
124
package.json
124
package.json
|
@ -5,17 +5,18 @@
|
|||
"description": "Chatting Anonymously with People on the Same Website.",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite --force",
|
||||
"dev:web": "vite -c vite.config.web.ts --force",
|
||||
"build": "vite build",
|
||||
"dev": "wxt",
|
||||
"dev:firefox": "wxt -b firefox",
|
||||
"build": "wxt build",
|
||||
"build:firefox": "wxt build -b firefox",
|
||||
"pack": "cross-env NODE_ENV=production run-p pack:*",
|
||||
"pack:zip": "rimraf dist.zip && jszip-cli add dist/* -o ./dist.zip",
|
||||
"pack:crx": "crx pack dist -o ./dist.crx",
|
||||
"pack:xpi": "cross-env WEB_EXT_ARTIFACTS_DIR=./ web-ext build --source-dir ./dist --filename dist.xpi --overwrite-dest",
|
||||
"pack:zip": "wxt zip",
|
||||
"pack:firefox": "wxt zip -b firefox",
|
||||
"lint": "eslint . --ext .js,.jsx,.ts,.tsx --cache --fix",
|
||||
"clear": "rimraf dist dist.*",
|
||||
"clear": "rimraf .output",
|
||||
"tsc:check": "tsc --noEmit",
|
||||
"prepare": "husky install"
|
||||
"prepare": "husky install",
|
||||
"postinstall": "wxt prepare"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
@ -41,76 +42,69 @@
|
|||
"url": "https://github.com/molvqingtai/WebChat/issues"
|
||||
},
|
||||
"homepage": "https://github.com/molvqingtai/WebChat#readme",
|
||||
"devDependencies": {
|
||||
"@commitlint/cli": "^17.6.6",
|
||||
"@commitlint/config-conventional": "^17.6.6",
|
||||
"@crxjs/vite-plugin": "2.0.0-beta.18",
|
||||
"@ffflorian/jszip-cli": "^3.4.1",
|
||||
"@types/node": "^20.4.2",
|
||||
"@types/react": "^18.2.14",
|
||||
"@types/react-dom": "^18.2.7",
|
||||
"@types/webextension-polyfill": "^0.10.1",
|
||||
"@vitejs/plugin-react": "^4.0.3",
|
||||
"autoprefixer": "^10.4.14",
|
||||
"cross-env": "^7.0.3",
|
||||
"crx": "^5.0.1",
|
||||
"eslint": "^8.44.0",
|
||||
"eslint-config-prettier": "^8.8.0",
|
||||
"eslint-config-standard-with-typescript": "^36.0.0",
|
||||
"eslint-plugin-import": "^2.27.5",
|
||||
"eslint-plugin-n": "^16.0.1",
|
||||
"eslint-plugin-prettier": "^5.0.0",
|
||||
"eslint-plugin-promise": "^6.1.1",
|
||||
"eslint-plugin-react": "^7.32.2",
|
||||
"eslint-plugin-react-hooks": "^4.6.0",
|
||||
"eslint-plugin-tailwindcss": "^3.13.0",
|
||||
"husky": "^8.0.3",
|
||||
"lint-staged": "^13.2.3",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"postcss": "^8.4.25",
|
||||
"prettier": "^3.0.0",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"rimraf": "^5.0.1",
|
||||
"tailwindcss": "^3.3.2",
|
||||
"tailwindcss-animate": "^1.0.7",
|
||||
"typescript": "^5.1.6",
|
||||
"unplugin-icons": "^0.16.5",
|
||||
"vite": "^4.4.3",
|
||||
"web-ext": "^7.6.2",
|
||||
"webext-bridge": "^6.0.1",
|
||||
"webextension-polyfill": "^0.10.0"
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.{js,jsx,ts,tsx}": "eslint --fix"
|
||||
},
|
||||
"dependencies": {
|
||||
"@perfsee/jsonr": "^1.8.2",
|
||||
"@radix-ui/react-avatar": "^1.0.3",
|
||||
"@radix-ui/react-hover-card": "^1.0.6",
|
||||
"@perfsee/jsonr": "^1.8.4",
|
||||
"@radix-ui/react-avatar": "^1.0.4",
|
||||
"@radix-ui/react-hover-card": "^1.0.7",
|
||||
"@radix-ui/react-icons": "^1.3.0",
|
||||
"@radix-ui/react-popover": "^1.0.7",
|
||||
"@radix-ui/react-scroll-area": "^1.0.4",
|
||||
"@radix-ui/react-scroll-area": "^1.0.5",
|
||||
"@radix-ui/react-slot": "^1.0.2",
|
||||
"@tailwindcss/typography": "^0.5.9",
|
||||
"class-variance-authority": "^0.6.1",
|
||||
"clsx": "^1.2.1",
|
||||
"@tailwindcss/typography": "^0.5.10",
|
||||
"class-variance-authority": "^0.7.0",
|
||||
"clsx": "^2.0.0",
|
||||
"date-fns": "^2.30.0",
|
||||
"idb-keyval": "^6.2.1",
|
||||
"lucide-react": "^0.263.0",
|
||||
"nanoid": "^4.0.2",
|
||||
"peerjs": "^1.4.7",
|
||||
"react-markdown": "^8.0.7",
|
||||
"lucide-react": "^0.292.0",
|
||||
"nanoid": "^5.0.2",
|
||||
"peerjs": "^1.5.1",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-markdown": "^9.0.0",
|
||||
"react-nice-avatar": "^1.4.1",
|
||||
"react-use": "^17.4.0",
|
||||
"remark-breaks": "^4.0.0",
|
||||
"remark-gfm": "^3.0.1",
|
||||
"remark-gfm": "^4.0.0",
|
||||
"remesh": "^4.2.0",
|
||||
"remesh-logger": "^4.1.0",
|
||||
"remesh-react": "^4.1.0",
|
||||
"rxjs": "^7.8.1",
|
||||
"tailwind-merge": "^1.13.2",
|
||||
"type-fest": "^3.13.0"
|
||||
"tailwind-merge": "^2.0.0",
|
||||
"type-fest": "^4.6.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@commitlint/cli": "^18.2.0",
|
||||
"@commitlint/config-conventional": "^18.1.0",
|
||||
"@types/node": "^20.8.10",
|
||||
"@types/react": "^18.2.34",
|
||||
"@types/react-dom": "^18.2.14",
|
||||
"@vitejs/plugin-react": "^4.1.1",
|
||||
"autoprefixer": "^10.4.16",
|
||||
"cross-env": "^7.0.3",
|
||||
"eslint": "^8.53.0",
|
||||
"eslint-config-prettier": "^9.0.0",
|
||||
"eslint-config-standard-with-typescript": "^39.1.1",
|
||||
"eslint-plugin-import": "^2.29.0",
|
||||
"eslint-plugin-n": "^16.2.0",
|
||||
"eslint-plugin-prettier": "^5.0.1",
|
||||
"eslint-plugin-promise": "^6.1.1",
|
||||
"eslint-plugin-react": "^7.33.2",
|
||||
"eslint-plugin-react-hooks": "^4.6.0",
|
||||
"eslint-plugin-tailwindcss": "^3.13.0",
|
||||
"husky": "^8.0.3",
|
||||
"lint-staged": "^15.0.2",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"postcss": "^8.4.31",
|
||||
"prettier": "^3.0.3",
|
||||
"rimraf": "^5.0.5",
|
||||
"tailwindcss": "^3.3.5",
|
||||
"tailwindcss-animate": "^1.0.7",
|
||||
"typescript": "^5.2.2",
|
||||
"webext-bridge": "^6.0.1",
|
||||
"wxt": "^0.9.0"
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.{js,jsx,ts,tsx}": "eslint --fix"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.0.0"
|
||||
|
|
5752
pnpm-lock.yaml
5752
pnpm-lock.yaml
File diff suppressed because it is too large
Load diff
0
src/types/index.d.ts → src/@types/index.d.ts
vendored
0
src/types/index.d.ts → src/@types/index.d.ts
vendored
18
src/App.tsx
18
src/App.tsx
|
@ -1,18 +0,0 @@
|
|||
import Header from '@/views/Header'
|
||||
import Footer from '@/views/Footer'
|
||||
import Main from '@/views/Main'
|
||||
import AppButton from '@/views/AppButton'
|
||||
import AppContainer from '@/views/AppContainer'
|
||||
|
||||
export default function App() {
|
||||
return (
|
||||
<>
|
||||
<AppContainer>
|
||||
<Header />
|
||||
<Main />
|
||||
<Footer />
|
||||
</AppContainer>
|
||||
<AppButton></AppButton>
|
||||
</>
|
||||
)
|
||||
}
|
|
@ -4,7 +4,7 @@ import { FrownIcon, ThumbsUpIcon } from 'lucide-react'
|
|||
import { Avatar, AvatarImage, AvatarFallback } from '@/components/ui/Avatar'
|
||||
|
||||
import LikeButton from '@/components/LikeButton'
|
||||
import { type Message } from '@/types'
|
||||
import { type Message } from '@/@types'
|
||||
import { Markdown } from '@/components/ui/Markdown'
|
||||
|
||||
export interface MessageItemProps {
|
||||
|
|
|
@ -1,41 +0,0 @@
|
|||
import { type ReactNode } from 'react'
|
||||
import { createRoot, type Root } from 'react-dom/client'
|
||||
import { createElement } from '@/utils'
|
||||
|
||||
export interface RootOptions {
|
||||
mode?: ShadowRootMode
|
||||
style?: string
|
||||
script?: string
|
||||
element?: Element
|
||||
}
|
||||
|
||||
const createShadowRoot = (
|
||||
name: string,
|
||||
options: RootOptions
|
||||
): Root & { shadowHost: Element; shadowRoot: ShadowRoot; appRoot: Element } => {
|
||||
const { mode = 'open', style = '', script = '', element = '' } = options ?? {}
|
||||
const shadowHost = createElement(`<${name}></${name}>`)
|
||||
const shadowRoot = shadowHost.attachShadow({ mode })
|
||||
const appRoot = createElement(`<div id="app"></div>`)
|
||||
const appStyle = style && createElement(`<style type="text/css">${style}</style>`)
|
||||
const appScript = script && createElement(`<script type="application/javascript">${script}</script>`)
|
||||
const reactRoot = createRoot(appRoot)
|
||||
|
||||
shadowRoot.append(appStyle, appRoot, appScript, element)
|
||||
|
||||
return {
|
||||
shadowHost,
|
||||
shadowRoot,
|
||||
appRoot,
|
||||
render: (children: ReactNode) => {
|
||||
document.body.appendChild(shadowHost)
|
||||
return reactRoot.render(children)
|
||||
},
|
||||
unmount: () => {
|
||||
reactRoot.unmount()
|
||||
shadowHost.remove()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default createShadowRoot
|
|
@ -3,7 +3,7 @@ import { ListModule } from 'remesh/modules/list'
|
|||
import { nanoid } from 'nanoid'
|
||||
import { from, map, tap, merge } from 'rxjs'
|
||||
import Storage from './externs/Storage'
|
||||
import { type Message } from '@/types'
|
||||
import { type Message } from '@/@types'
|
||||
|
||||
const MessageListDomain = Remesh.domain({
|
||||
name: 'MessageListDomain',
|
||||
|
|
18
src/entrypoints/content/App.tsx
Normal file
18
src/entrypoints/content/App.tsx
Normal file
|
@ -0,0 +1,18 @@
|
|||
import Header from '@/entrypoints/content/views/Header'
|
||||
import Footer from '@/entrypoints/content/views/Footer'
|
||||
import Main from '@/entrypoints/content/views/Main'
|
||||
import AppButton from '@/entrypoints/content/views/AppButton'
|
||||
import AppContainer from '@/entrypoints/content/views/AppContainer'
|
||||
|
||||
export default function App() {
|
||||
return (
|
||||
<>
|
||||
<AppContainer>
|
||||
<Header />
|
||||
<Main />
|
||||
<Footer />
|
||||
</AppContainer>
|
||||
<AppButton></AppButton>
|
||||
</>
|
||||
)
|
||||
}
|
40
src/entrypoints/content/index.tsx
Normal file
40
src/entrypoints/content/index.tsx
Normal file
|
@ -0,0 +1,40 @@
|
|||
import ReactDOM from 'react-dom/client'
|
||||
import React from 'react'
|
||||
import { Remesh } from 'remesh'
|
||||
import { RemeshRoot } from 'remesh-react'
|
||||
import { RemeshLogger } from 'remesh-logger'
|
||||
import App from './App'
|
||||
import StorageImpl from '@/impl/Storage'
|
||||
|
||||
import './style.css'
|
||||
|
||||
export default defineContentScript({
|
||||
cssInjectionMode: 'ui',
|
||||
matches: ['*://*.example.com/*'],
|
||||
async main(ctx) {
|
||||
const store = Remesh.store({
|
||||
externs: [StorageImpl],
|
||||
inspectors: [RemeshLogger()]
|
||||
})
|
||||
|
||||
const ui = await createContentScriptUi(ctx, {
|
||||
name: __NAME__,
|
||||
type: 'overlay',
|
||||
mount(container) {
|
||||
const root = ReactDOM.createRoot(container)
|
||||
root.render(
|
||||
<React.StrictMode>
|
||||
<RemeshRoot store={store}>
|
||||
<App />
|
||||
</RemeshRoot>
|
||||
</React.StrictMode>
|
||||
)
|
||||
return root
|
||||
},
|
||||
onRemove(root) {
|
||||
root.unmount()
|
||||
}
|
||||
})
|
||||
ui.mount()
|
||||
}
|
||||
})
|
|
@ -6,7 +6,7 @@ export interface AppContainerProps {
|
|||
|
||||
const AppContainer: FC<AppContainerProps> = ({ children }) => {
|
||||
return (
|
||||
<div className="fixed inset-y-10 right-10 z-top box-border grid w-1/4 min-w-[375px] grid-flow-col grid-rows-[auto_1fr_auto] overflow-hidden rounded-xl bg-slate-50 font-sans shadow-2xl transition-transform">
|
||||
<div className="fixed bottom-10 right-10 top-5 z-top box-border grid w-1/4 min-w-[375px] grid-flow-col grid-rows-[auto_1fr_auto] overflow-hidden rounded-xl bg-slate-50 font-sans shadow-2xl transition-transform">
|
||||
{children}
|
||||
</div>
|
||||
)
|
34
src/main.tsx
34
src/main.tsx
|
@ -1,34 +0,0 @@
|
|||
import React from 'react'
|
||||
import { RemeshRoot } from 'remesh-react'
|
||||
import { RemeshLogger } from 'remesh-logger'
|
||||
import { Remesh } from 'remesh'
|
||||
import App from './App'
|
||||
import createShadowRoot from './createShadowRoot'
|
||||
import StorageImpl from './impl/Storage'
|
||||
import style from './index.css?inline'
|
||||
|
||||
const store = Remesh.store({
|
||||
externs: [StorageImpl],
|
||||
inspectors: [RemeshLogger()]
|
||||
})
|
||||
|
||||
const root = createShadowRoot(__NAME__, {
|
||||
style: __DEV__ ? '' : style,
|
||||
mode: __DEV__ ? 'open' : 'closed'
|
||||
})
|
||||
root.render(
|
||||
<React.StrictMode>
|
||||
<RemeshRoot store={store}>
|
||||
<App />
|
||||
</RemeshRoot>
|
||||
</React.StrictMode>
|
||||
)
|
||||
|
||||
// HMR Hack
|
||||
// https://github.com/crxjs/chrome-extension-tools/issues/600
|
||||
if (__DEV__) {
|
||||
await import('./index.css')
|
||||
const styleElement = document.querySelector('[data-vite-dev-id]')!
|
||||
|
||||
root.shadowRoot.insertBefore(styleElement, root.shadowRoot.firstChild)
|
||||
}
|
|
@ -1,22 +1,7 @@
|
|||
{
|
||||
"extends": "./.wxt/tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"module": "ESNext",
|
||||
"target": "ESNext",
|
||||
"lib": ["ESNext", "DOM", "DOM.Iterable"],
|
||||
"strict": true,
|
||||
"esModuleInterop": true,
|
||||
"incremental": false,
|
||||
"skipLibCheck": true,
|
||||
"jsx": "react-jsx",
|
||||
"moduleResolution": "Node",
|
||||
"resolveJsonModule": true,
|
||||
"noUnusedLocals": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"types": ["vite/client"],
|
||||
"paths": {
|
||||
"@/*": ["src/*"]
|
||||
}
|
||||
},
|
||||
"exclude": ["dist", "node_modules"]
|
||||
"allowImportingTsExtensions": true,
|
||||
"jsx": "react-jsx"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
import path from 'node:path'
|
||||
import { defineConfig } from 'vite'
|
||||
import react from '@vitejs/plugin-react'
|
||||
import { crx } from '@crxjs/vite-plugin'
|
||||
import manifest from './manifest'
|
||||
import packageJson from './package.json'
|
||||
|
||||
const isDev = process.env.NODE_ENV === 'development'
|
||||
|
||||
export default defineConfig({
|
||||
resolve: {
|
||||
alias: {
|
||||
'@': path.resolve(__dirname, './src')
|
||||
}
|
||||
},
|
||||
define: {
|
||||
__DEV__: isDev,
|
||||
__NAME__: JSON.stringify(packageJson.name)
|
||||
},
|
||||
plugins: [
|
||||
react(),
|
||||
// @ts-expect-error use local package
|
||||
crx({
|
||||
manifest
|
||||
})
|
||||
]
|
||||
})
|
|
@ -1,20 +0,0 @@
|
|||
import path from 'node:path'
|
||||
import { defineConfig } from 'vite'
|
||||
import react from '@vitejs/plugin-react'
|
||||
|
||||
import packageJson from './package.json'
|
||||
|
||||
const isDev = process.env.NODE_ENV === 'development'
|
||||
|
||||
export default defineConfig({
|
||||
resolve: {
|
||||
alias: {
|
||||
'@': path.resolve(__dirname, './src')
|
||||
}
|
||||
},
|
||||
define: {
|
||||
__DEV__: isDev,
|
||||
__NAME__: JSON.stringify(packageJson.name)
|
||||
},
|
||||
plugins: [react()]
|
||||
})
|
19
wxt.config.ts
Normal file
19
wxt.config.ts
Normal file
|
@ -0,0 +1,19 @@
|
|||
import { defineConfig } from 'wxt'
|
||||
import react from '@vitejs/plugin-react'
|
||||
import { name } from './package.json'
|
||||
|
||||
const isDev = process.env.NODE_ENV === 'development'
|
||||
|
||||
export default defineConfig({
|
||||
srcDir: 'src',
|
||||
runner: {
|
||||
startUrls: ['https://www.example.com/']
|
||||
},
|
||||
vite: () => ({
|
||||
define: {
|
||||
__DEV__: isDev,
|
||||
__NAME__: JSON.stringify(name)
|
||||
},
|
||||
plugins: [react()]
|
||||
})
|
||||
})
|
Loading…
Reference in a new issue