From 2b1f4a9ef2c4e7c9863b438b9ea0c710c9838b8a Mon Sep 17 00:00:00 2001 From: OpenGG Date: Tue, 18 Mar 2025 17:17:33 +0800 Subject: [PATCH] feat(chrome-devtool): migrate to Manifest V3 with Plasmo framework - Refactor architecture to comply with Manifest V3 security requirements - Preserve devtools functionality with updated service worker lifecycle - Fix requestIdleCallback() bug in backend.ts - Replace legacy toolkit with Plasmo framework for enhanced DX - Implement automatic HMR for popup/options UI components - Update build chain and dependency tree (React 18.3.1) - Add release devtools workflow configuration BREAKING CHANGE: Requires Chrome 88+ due to Manifest V3 changes --- .eslintignore | 3 +- .github/workflows/release-devtools.yml | 62 +++++++++ devtools/chrome-extension/.gitignore | 36 +++++ devtools/chrome-extension/.npmignore | 11 -- devtools/chrome-extension/.prettierrc.mjs | 26 ++++ devtools/chrome-extension/README.md | 58 ++++++++ .../{img/logo/scalable.png => icon.png} | Bin .../chrome-extension/assets/img/loading.svg | 42 ------ .../assets/img/logo/128x128.png | Bin 6650 -> 0 bytes .../assets/img/logo/16x16.png | Bin 777 -> 0 bytes .../assets/img/logo/38x38.png | Bin 1941 -> 0 bytes .../assets/img/logo/48x48.png | Bin 2390 -> 0 bytes .../assets/img/logo/error.png | Bin 901 -> 0 bytes .../chrome-extension/assets/img/logo/gray.png | Bin 1733 -> 0 bytes .../chrome-extension/config/webpack.base.ts | 73 ---------- .../chrome-extension/config/webpack.dev.ts | 47 ------- .../chrome-extension/config/webpack.prod.ts | 44 ------ devtools/chrome-extension/package.json | 51 +++++-- .../src/app/components/Tabs.tsx | 49 ------- .../src/{extension => }/background.ts | 0 .../src/{extension => contents}/content.ts | 8 ++ .../chrome-extension/src/contents/inject.ts | 16 +++ .../formily}/app/components/FieldTree.tsx | 51 ++----- .../formily}/app/components/LeftPanel.tsx | 13 +- .../formily}/app/components/RightPanel.tsx | 16 +-- .../formily}/app/components/SearchBox.tsx | 27 +--- .../devPanels/formily/app/components/Tabs.tsx | 25 ++++ .../formily}/app/components/filter.ts | 0 .../src/{ => devPanels/formily}/app/demo.tsx | 4 +- .../src/{ => devPanels/formily}/app/index.tsx | 18 +-- .../src/devPanels/formily/index.css | 126 ++++++++++++++++++ .../src/devPanels/formily/index.html | 13 ++ .../formily/index.tsx} | 8 +- devtools/chrome-extension/src/devtools.tsx | 41 ++++++ .../src/extension/devtools.tsx | 30 ----- .../chrome-extension/src/extension/inject.ts | 26 ---- .../src/extension/manifest.json | 58 -------- .../chrome-extension/src/extension/popup.tsx | 4 - .../src/extension/views/devpanel.ejs | 32 ----- .../src/extension/views/devtools.ejs | 10 -- .../src/extension/views/popup.ejs | 10 -- devtools/chrome-extension/src/popup.tsx | 16 +++ .../{extension => webAccessible}/backend.ts | 36 +++-- devtools/chrome-extension/tsconfig.build.json | 10 -- devtools/chrome-extension/tsconfig.json | 12 +- 45 files changed, 535 insertions(+), 577 deletions(-) create mode 100644 .github/workflows/release-devtools.yml create mode 100644 devtools/chrome-extension/.gitignore delete mode 100644 devtools/chrome-extension/.npmignore create mode 100644 devtools/chrome-extension/.prettierrc.mjs create mode 100644 devtools/chrome-extension/README.md rename devtools/chrome-extension/assets/{img/logo/scalable.png => icon.png} (100%) delete mode 100644 devtools/chrome-extension/assets/img/loading.svg delete mode 100644 devtools/chrome-extension/assets/img/logo/128x128.png delete mode 100644 devtools/chrome-extension/assets/img/logo/16x16.png delete mode 100644 devtools/chrome-extension/assets/img/logo/38x38.png delete mode 100644 devtools/chrome-extension/assets/img/logo/48x48.png delete mode 100644 devtools/chrome-extension/assets/img/logo/error.png delete mode 100644 devtools/chrome-extension/assets/img/logo/gray.png delete mode 100644 devtools/chrome-extension/config/webpack.base.ts delete mode 100644 devtools/chrome-extension/config/webpack.dev.ts delete mode 100644 devtools/chrome-extension/config/webpack.prod.ts delete mode 100644 devtools/chrome-extension/src/app/components/Tabs.tsx rename devtools/chrome-extension/src/{extension => }/background.ts (100%) rename devtools/chrome-extension/src/{extension => contents}/content.ts (60%) create mode 100644 devtools/chrome-extension/src/contents/inject.ts rename devtools/chrome-extension/src/{ => devPanels/formily}/app/components/FieldTree.tsx (85%) rename devtools/chrome-extension/src/{ => devPanels/formily}/app/components/LeftPanel.tsx (77%) rename devtools/chrome-extension/src/{ => devPanels/formily}/app/components/RightPanel.tsx (56%) rename devtools/chrome-extension/src/{ => devPanels/formily}/app/components/SearchBox.tsx (75%) create mode 100644 devtools/chrome-extension/src/devPanels/formily/app/components/Tabs.tsx rename devtools/chrome-extension/src/{ => devPanels/formily}/app/components/filter.ts (100%) rename devtools/chrome-extension/src/{ => devPanels/formily}/app/demo.tsx (99%) rename devtools/chrome-extension/src/{ => devPanels/formily}/app/index.tsx (76%) create mode 100644 devtools/chrome-extension/src/devPanels/formily/index.css create mode 100644 devtools/chrome-extension/src/devPanels/formily/index.html rename devtools/chrome-extension/src/{extension/devpanel.tsx => devPanels/formily/index.tsx} (87%) create mode 100644 devtools/chrome-extension/src/devtools.tsx delete mode 100644 devtools/chrome-extension/src/extension/devtools.tsx delete mode 100644 devtools/chrome-extension/src/extension/inject.ts delete mode 100644 devtools/chrome-extension/src/extension/manifest.json delete mode 100644 devtools/chrome-extension/src/extension/popup.tsx delete mode 100644 devtools/chrome-extension/src/extension/views/devpanel.ejs delete mode 100644 devtools/chrome-extension/src/extension/views/devtools.ejs delete mode 100644 devtools/chrome-extension/src/extension/views/popup.ejs create mode 100644 devtools/chrome-extension/src/popup.tsx rename devtools/chrome-extension/src/{extension => webAccessible}/backend.ts (84%) delete mode 100644 devtools/chrome-extension/tsconfig.build.json diff --git a/.eslintignore b/.eslintignore index 92c7bb0609c..9a50fea6ae4 100644 --- a/.eslintignore +++ b/.eslintignore @@ -13,4 +13,5 @@ packages/element esm doc-site public -package \ No newline at end of file +package +assets diff --git a/.github/workflows/release-devtools.yml b/.github/workflows/release-devtools.yml new file mode 100644 index 00000000000..0f039503d10 --- /dev/null +++ b/.github/workflows/release-devtools.yml @@ -0,0 +1,62 @@ +name: Release Devtools +on: + workflow_dispatch: + inputs: + remote_debug: + description: 'Enable remote debug session?' + type: boolean + required: false + default: false + +jobs: + build: + runs-on: ubuntu-latest + + env: + DEVTOOLS_ZIP_PATH: devtools/chrome-extension/build/chrome-mv3-prod.zip + DEVTOOLS_ARTIFACT_NAME: formily-devtools + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Start debug session (when enabled) + if: ${{ inputs.remote_debug }} + uses: lhotari/action-upterm@v1 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: 16 + registry-url: https://registry.npmjs.org/ + cache: yarn + + - name: Verify environment + run: | + node --version + yarn -v + + - name: Maintain debug session (when enabled) + run: | + sleep 3600 + if: ${{ inputs.remote_debug }} + + - name: Install dependencies + run: | + yarn install --ignore-engines + + - name: Build packages + run: | + yarn build + env: + # avoid core dump, see: https://github.com/parcel-bundler/parcel/issues/10081 + PARCEL_WORKER_BACKEND: process + + - name: Validate artifact + run: test -f ${{ env.DEVTOOLS_ZIP_PATH }} + + - name: Upload Artifact + uses: actions/upload-artifact@v4 + with: + name: ${{ env.DEVTOOLS_ARTIFACT_NAME }} + path: ${{ env.DEVTOOLS_ZIP_PATH }} diff --git a/devtools/chrome-extension/.gitignore b/devtools/chrome-extension/.gitignore new file mode 100644 index 00000000000..171698d64bc --- /dev/null +++ b/devtools/chrome-extension/.gitignore @@ -0,0 +1,36 @@ + +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js + +# testing +/coverage + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* +.pnpm-debug.log* + +# local env files +.env*.local + +out/ +build/ +dist/ + +# plasmo +.plasmo + +# typescript +.tsbuildinfo + +# backend.js is generated from src/webAccessible/backend.ts +assets/backend.js diff --git a/devtools/chrome-extension/.npmignore b/devtools/chrome-extension/.npmignore deleted file mode 100644 index 1ff337420fd..00000000000 --- a/devtools/chrome-extension/.npmignore +++ /dev/null @@ -1,11 +0,0 @@ -node_modules -*.log -build -docs -doc-site -__tests__ -.eslintrc -jest.config.js -tsconfig.json -.umi -src \ No newline at end of file diff --git a/devtools/chrome-extension/.prettierrc.mjs b/devtools/chrome-extension/.prettierrc.mjs new file mode 100644 index 00000000000..27060b8cb29 --- /dev/null +++ b/devtools/chrome-extension/.prettierrc.mjs @@ -0,0 +1,26 @@ +/** + * @type {import('prettier').Options} + */ +export default { + printWidth: 80, + tabWidth: 2, + useTabs: false, + semi: false, + singleQuote: true, + trailingComma: 'all', + bracketSpacing: true, + bracketSameLine: true, + plugins: ['@ianvs/prettier-plugin-sort-imports'], + importOrder: [ + '', // Node.js built-in modules + '', // Imports not matched by other special words or groups. + '', // Empty line + '^@plasmo/(.*)$', + '', + '^@plasmohq/(.*)$', + '', + '^~(.*)$', + '', + '^[./]', + ], +} diff --git a/devtools/chrome-extension/README.md b/devtools/chrome-extension/README.md new file mode 100644 index 00000000000..14279247748 --- /dev/null +++ b/devtools/chrome-extension/README.md @@ -0,0 +1,58 @@ +# Formily DevTools + +This is a [Plasmo extension](https://docs.plasmo.com/) project bootstrapped with [`plasmo init`](https://www.npmjs.com/package/plasmo). + +## 🚀 Getting Started + +### Development Setup + +1. **Install dependencies**: + ```bash + yarn install + ``` + +2. **Start the development server**: + ```bash + yarn run dev + ``` + +3. **Load the extension in your browser**: + • For Chrome (Manifest V3): + Navigate to `build/chrome-mv3-dev` using your browser's extension developer mode + + +Open your browser and load the appropriate development build. For example, if you are developing for the chrome browser, using manifest v3, use: `build/chrome-mv3-dev`. + +You can start editing the popup by modifying `popup.tsx`. It should auto-update as you make changes. To add an options page, simply add a `options.tsx` file to the root of the project, with a react component default exported. Likewise to add a content page, add a `content.ts` file to the root of the project, importing some module and do some logic, then reload the extension on your browser. + +For further guidance, [visit our Documentation](https://docs.plasmo.com/) + +### 🔥 Hot Reload Notes + +**Special Case for webAccessibleResources/backend.ts**: +```bash +# After modifying webAccessibleResources/backend.ts +# 1. Stop the dev server (Ctrl+C) +# 2. Rerun the dev command to pick up changes: +yarn run dev +``` + +This is due to Plasmo's limitations. + +## Making production build + +Run the following: + +```bash +# Build the extension for production +yarn run build + +# Package the extension into zip file for distribution +yarn run package +``` + +This should create a production bundle for your extension, ready to be published to the stores. + +## Submit to the webstores + +The easiest way to deploy your Plasmo extension is to use the built-in [bpp](https://bpp.browser.market) GitHub action. Prior to using this action however, make sure to build your extension and upload the first version to the store to establish the basic credentials. Then, simply follow [this setup instruction](https://docs.plasmo.com/framework/workflows/submit) and you should be on your way for automated submission! diff --git a/devtools/chrome-extension/assets/img/logo/scalable.png b/devtools/chrome-extension/assets/icon.png similarity index 100% rename from devtools/chrome-extension/assets/img/logo/scalable.png rename to devtools/chrome-extension/assets/icon.png diff --git a/devtools/chrome-extension/assets/img/loading.svg b/devtools/chrome-extension/assets/img/loading.svg deleted file mode 100644 index ad9cb74d4b8..00000000000 --- a/devtools/chrome-extension/assets/img/loading.svg +++ /dev/null @@ -1,42 +0,0 @@ - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/devtools/chrome-extension/assets/img/logo/128x128.png b/devtools/chrome-extension/assets/img/logo/128x128.png deleted file mode 100644 index 08b6b14420fe44af688ac1b5ce2a47481395f4dc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6650 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 z 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 Eg65sNzW@LL diff --git a/devtools/chrome-extension/assets/img/logo/16x16.png b/devtools/chrome-extension/assets/img/logo/16x16.png deleted file mode 100644 index bdc7d05548c2086bf426d7821a8a8d40e5fe2df6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 777 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 ZGe%r@T&ACJAQY4ZJYD@<);T3K0RZWkcgz3) diff --git a/devtools/chrome-extension/assets/img/logo/gray.png b/devtools/chrome-extension/assets/img/logo/gray.png deleted file mode 100644 index 80ae7d717afe63e38d6b29c725a1494bc910d626..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1733 zcmV;$20HnPP)Px#L}ge>W=%~1DgXcg2mk?xX#fNO00031000^Q000001E2u_0{{R30RRC20H6W@ z1ONa40RR91CZGcV1ONa40RR91CIA2c0EF@&TL1tCFG)l}R9FecSW8G`R}igk8x_C7 zg`XC+MG-|^2#yL8aU)6;!NgBUdM54^vvJ`zpvHxQn^|VzB8wT~!YGOh5ycN7jt-(R zpn?$w7P+-_JHCq@erVTeoiA^Q!9Bt@~{B4=5=qDemUxrt;&*kDuCX zws=v4yMhOV8TpZ~7asq-}~#c%T?g9_9NqtBawf`fyN zhD>=bm&xH!Xss{|Bd( z-_RGYf#k`czPFl%v4VmE%F4=8#Pag;sI;_H>B|iOsi~_jC8o&T7 zU^E@)zZ?U;{$-!O_`aQx)_X&jTIKOaz8Kt3lQgCXN|}u=^0` zh$#fH+ER*;)adN&r0MBth27NDMDg)BLiKcYbw!Jdi^TbhcuiVZSfKm+dqt3~{cd-6 zx4?k|nT1~{BT{2~dz+e@n?;~&$F%+2+*}11=Ot56n1@t@7X=Lr4ETTo4+a7zJE{ck z3(H|ZCcIgDd%Fl)nP>LQ$jDHJ5)*xPy~5WvCMG6mZf;J?M&AZZND)Owqu}lD?+dHV z&d!>N2tM2v6eMDn5KC6Xi&AfIFO80lnu-CFgMErx%2ep$;)2@R+QjZdpmTL#C>s#) zka^TQQ7woymX?-ie0-b^4i3~qx;8LjKZ^oSH>zQbjEso4EG#S}#1!184sfIhko-g& z)j4uihRZ{ml_18jI5K)sQISt<$@8YBrUWp6(pD2lJ!4~I)YsQXdwYBG z6sxDl!PeTblE4@aWb8<*QU@^wlAod@{UNEAmzPsnSs4uv4^vN1kEOeTiH|w^-)D(h zo79GD8X6ibL1FhH&_QsY8DXQK4C?CYqNu1SGclaK({|kZSi*1v;OMBXu70#CKuSQK z0wJazqxAH2QEcKIHXtuB*>M@=_|c_ym&--P#l?oM(JDipk_my1n0ky*JmM^t6SFK2 zEWjiRCVtzuJn(R`N)j6z8^Yu$Y0}ctL_KA6+`v*uo-(0QK%gV0v;M5(z1q&c0;Hrl}udS_>*VH{36mI1&)SnC+L`J_VX)u-TdZ$cAh_d=#*m0@JkPLm;%Efg0Zo&F`t#Z zVr84)J%^wJx}Z}X=teqCU8xnu4O#ls`8CG{u6zE@#ivf}^fyoW)akEsADp=NadQ1n bKMwx|wy4`{dxyZC00000NkvXXu0mjfa7`^l diff --git a/devtools/chrome-extension/config/webpack.base.ts b/devtools/chrome-extension/config/webpack.base.ts deleted file mode 100644 index b0cec868578..00000000000 --- a/devtools/chrome-extension/config/webpack.base.ts +++ /dev/null @@ -1,73 +0,0 @@ -import path from 'path' -import fs from 'fs-extra' - -const getEntry = (src) => { - return [path.resolve(__dirname, '../src/extension/', src)] -} - -fs.copy( - path.resolve(__dirname, '../assets'), - path.resolve(__dirname, '../package') -) - -fs.copy( - path.resolve(__dirname, '../src/extension/manifest.json'), - path.resolve(__dirname, '../package/manifest.json') -) - -export default { - mode: 'development', - devtool: 'inline-source-map', // 嵌入到源文件中 - entry: { - popup: getEntry('./popup.tsx'), - devtools: getEntry('./devtools.tsx'), - devpanel: getEntry('./devpanel.tsx'), - content: getEntry('./content.ts'), - backend: getEntry('./backend.ts'), - demo: getEntry('../app/demo.tsx'), - inject: getEntry('./inject.ts'), - background: getEntry('./background.ts'), - }, - output: { - path: path.resolve(__dirname, '../package'), - filename: 'js/[name].bundle.js', - }, - resolve: { - modules: ['node_modules'], - extensions: ['.js', '.jsx', '.ts', '.tsx', '.json'], - }, - module: { - rules: [ - { - test: /\.tsx?$/, - use: [ - { - loader: require.resolve('ts-loader'), - options: { - transpileOnly: true, - }, - }, - ], - }, - { - test: /\.css$/, - use: [ - { - loader: require.resolve('style-loader'), - options: { - singleton: true, - }, - }, - require.resolve('css-loader'), - ], - }, - { - test: /\.html?$/, - loader: require.resolve('file-loader'), - options: { - name: '[name].[ext]', - }, - }, - ], - }, -} diff --git a/devtools/chrome-extension/config/webpack.dev.ts b/devtools/chrome-extension/config/webpack.dev.ts deleted file mode 100644 index 2377da4e6b3..00000000000 --- a/devtools/chrome-extension/config/webpack.dev.ts +++ /dev/null @@ -1,47 +0,0 @@ -import baseConfig from './webpack.base' -import HtmlWebpackPlugin from 'html-webpack-plugin' -import webpack from 'webpack' -import path from 'path' - -const PORT = 3000 - -const createPages = (pages) => { - return pages.map(({ filename, template, chunk }) => { - return new HtmlWebpackPlugin({ - filename, - template, - inject: 'body', - chunks: [chunk], - }) - }) -} - -for (let key in baseConfig.entry) { - if (Array.isArray(baseConfig.entry[key])) { - baseConfig.entry[key].push( - require.resolve('webpack/hot/dev-server'), - `${require.resolve('webpack-dev-server/client')}?http://localhost:${PORT}` - ) - } -} - -module.exports = { - ...baseConfig, - plugins: [ - ...createPages([ - { - filename: 'index.html', - template: path.resolve( - __dirname, - '../src/extension/views/devtools.ejs' - ), - chunk: 'demo', - }, - ]), - new webpack.HotModuleReplacementPlugin(), - ], - devServer: { - open: true, - port: PORT, - }, -} diff --git a/devtools/chrome-extension/config/webpack.prod.ts b/devtools/chrome-extension/config/webpack.prod.ts deleted file mode 100644 index fbe6ae51494..00000000000 --- a/devtools/chrome-extension/config/webpack.prod.ts +++ /dev/null @@ -1,44 +0,0 @@ -import baseConfig from './webpack.base' -import HtmlWebpackPlugin from 'html-webpack-plugin' -import path from 'path' - -const createPages = (pages) => { - return pages.map(({ filename, template, chunk }) => { - return new HtmlWebpackPlugin({ - filename, - template, - inject: 'body', - chunks: [chunk], - }) - }) -} - -module.exports = { - ...baseConfig, - mode: 'production', - plugins: [ - ...createPages([ - { - filename: 'popup.html', - template: path.resolve(__dirname, '../src/extension/views/popup.ejs'), - chunk: 'popup', - }, - { - filename: 'devtools.html', - template: path.resolve( - __dirname, - '../src/extension/views/devtools.ejs' - ), - chunk: 'devtools', - }, - { - filename: 'devpanel.html', - template: path.resolve( - __dirname, - '../src/extension/views/devpanel.ejs' - ), - chunk: 'devpanel', - }, - ]), - ], -} diff --git a/devtools/chrome-extension/package.json b/devtools/chrome-extension/package.json index 46b9c0ff8a9..b18ba3d7eee 100644 --- a/devtools/chrome-extension/package.json +++ b/devtools/chrome-extension/package.json @@ -1,35 +1,58 @@ { "name": "@formily/chrome-extension", - "version": "2.3.2", + "version": "3.0.0", + "displayName": "Formily DevTools", + "description": "Formily DevTools for debugging application's state changes.", "private": true, "license": "MIT", "repository": { "type": "git", "url": "git+https://github.com/alibaba/formily.git" }, - "types": "esm/index.d.ts", "bugs": { "url": "https://github.com/alibaba/formily/issues" }, "homepage": "https://github.com/alibaba/formily#readme", - "engines": { - "npm": ">=3.0.0" - }, "scripts": { - "build:devtools": "webpack-cli --config config/webpack.prod.ts", - "build:zip": "rimraf package.zip && zip -r package.zip package", - "start": "webpack-dev-server --config config/webpack.dev.ts" + "cleanup": "rm -rf .plasmo build", + "dev": "yarn run build:backend && yarn run cleanup && yarn run dev:plasmo", + "dev:plasmo": "plasmo dev", + "build": "yarn run build:backend && yarn run cleanup && yarn run build:plasmo", + "build:backend": "tsc src/webAccessible/backend.ts --outFile assets/backend.js", + "build:plasmo": "plasmo build --zip", + "package": "plasmo package" }, "dependencies": { - "@formily/core": "2.3.2", "@formily/shared": "2.3.2", - "react": "^18.0.0", - "react-dom": "^18.0.0", + "plasmo": "0.90.3", + "react": "18.3.1", + "react-dom": "18.3.1", "react-json-view": "^1.19.1", "react-treebeard": "^3.2.4" }, - "publishConfig": { - "access": "public" + "devDependencies": { + "@ianvs/prettier-plugin-sort-imports": "4.1.1", + "@types/chrome": "0.0.258", + "@types/node": "20.11.5", + "@types/react": "18.3.18", + "@types/react-dom": "18.3.5", + "prettier": "3.2.4", + "typescript": "5.3.3" }, - "gitHead": "2c44ae410a73f02735c63c6430e021a50e21f3ec" + "manifest": { + "homepage_url": "https://formilyjs.org/", + "host_permissions": [ + "" + ], + "web_accessible_resources": [ + { + "resources": [ + "~assets/backend.js" + ], + "matches": [ + "" + ] + } + ] + } } diff --git a/devtools/chrome-extension/src/app/components/Tabs.tsx b/devtools/chrome-extension/src/app/components/Tabs.tsx deleted file mode 100644 index f45da26eb2c..00000000000 --- a/devtools/chrome-extension/src/app/components/Tabs.tsx +++ /dev/null @@ -1,49 +0,0 @@ -import React from 'react' -import styled from 'styled-components' -import { toArr } from '@formily/shared' - -export const Tabs = styled(({ className, dataSource, current, onChange }) => { - current = current || 0 - return ( -
- {toArr(dataSource).map((item, index) => { - return ( -
{ - if (onChange) { - onChange(index) - } - }} - > - Form#{index + 1} -
- ) - })} -
- ) -})` - height: 36px; - border-bottom: 1px solid #3d424a; - display: flex; - line-height: 36px; - width: 100%; - overflow: scroll; - &::-webkit-scrollbar { - display: none; - } - .tab-item { - cursor: pointer; - transition: 0.15s all ease-in-out; - border-right: 1px solid #3d424a; - padding: 0 10px; - font-size: 12px; - &:hover { - background: #1d1f25; - } - &.active { - background: #1d1f25; - } - } -` diff --git a/devtools/chrome-extension/src/extension/background.ts b/devtools/chrome-extension/src/background.ts similarity index 100% rename from devtools/chrome-extension/src/extension/background.ts rename to devtools/chrome-extension/src/background.ts diff --git a/devtools/chrome-extension/src/extension/content.ts b/devtools/chrome-extension/src/contents/content.ts similarity index 60% rename from devtools/chrome-extension/src/extension/content.ts rename to devtools/chrome-extension/src/contents/content.ts index 59f8f31a822..ebc49d1b407 100644 --- a/devtools/chrome-extension/src/extension/content.ts +++ b/devtools/chrome-extension/src/contents/content.ts @@ -1,3 +1,11 @@ +import type { PlasmoCSConfig } from 'plasmo' + +export const config: PlasmoCSConfig = { + matches: [''], + run_at: 'document_start', + all_frames: true, +} + window.addEventListener( 'message', (event) => { diff --git a/devtools/chrome-extension/src/contents/inject.ts b/devtools/chrome-extension/src/contents/inject.ts new file mode 100644 index 00000000000..ed3410336b2 --- /dev/null +++ b/devtools/chrome-extension/src/contents/inject.ts @@ -0,0 +1,16 @@ +import type { PlasmoCSConfig } from 'plasmo' + +export const config: PlasmoCSConfig = { + matches: [''], + run_at: 'document_start', + all_frames: true, +} + +const injectScript = (url) => { + const script = document.createElement('script') + script.src = url + document.documentElement?.appendChild(script) + script.parentNode?.removeChild(script) +} + +injectScript(chrome.runtime.getURL('assets/backend.js')) diff --git a/devtools/chrome-extension/src/app/components/FieldTree.tsx b/devtools/chrome-extension/src/devPanels/formily/app/components/FieldTree.tsx similarity index 85% rename from devtools/chrome-extension/src/app/components/FieldTree.tsx rename to devtools/chrome-extension/src/devPanels/formily/app/components/FieldTree.tsx index be2fb049840..0aa4621402f 100644 --- a/devtools/chrome-extension/src/app/components/FieldTree.tsx +++ b/devtools/chrome-extension/src/devPanels/formily/app/components/FieldTree.tsx @@ -1,7 +1,7 @@ -import React, { useState, useEffect, useRef } from 'react' -import styled from 'styled-components' import { FormPath, isObj } from '@formily/shared' -import { Treebeard, decorators } from 'react-treebeard' +import React, { useEffect, useRef, useState } from 'react' +import { decorators, Treebeard } from 'react-treebeard' + import * as filters from './filter' import SearchBox from './SearchBox' @@ -159,7 +159,7 @@ const Header = (props) => { const title = node.data?.title ? node.data.title : '' return (
{ node.toggled = false @@ -182,10 +182,10 @@ const Header = (props) => { {node.name} - {isObj(title) ? ((title as any).title ?? '') : title} + {isObj(title) ? (title as any).title ?? '' : title}
@@ -193,19 +193,11 @@ const Header = (props) => { ) } -const ToolBar = styled.div` - border-bottom: 1px solid #3d424a; - height: 20px; - padding: 10px 10px; - padding: 5px; - overflow: auto; - position: sticky; - top: 0; - background: #282c34; - z-index: 100; -` +const ToolBar = ({ children }) => { + return
{children}
+} -export const FieldTree = styled(({ className, dataSource, onSelect }) => { +export const FieldTree = ({ dataSource, onSelect }) => { const allDataRef = useRef(createTree(dataSource)) const cursor = useRef(allDataRef.current) const [keyword, setKeyword] = useState('') @@ -244,7 +236,7 @@ export const FieldTree = styled(({ className, dataSource, onSelect }) => { }, [dataSource]) return ( -
+
@@ -260,23 +252,4 @@ export const FieldTree = styled(({ className, dataSource, onSelect }) => { />
) -})` - position: relative; - overflow: auto; - height: calc(100% - 40px); - user-select: none; - .highlight { - position: absolute; - top: 0; - right: 0; - left: -100%; - height: 100%; - z-index: 0; - &.active { - background: #3d424a; - } - } - .node-header:hover .highlight { - background: #3d424a; - } -` +} diff --git a/devtools/chrome-extension/src/app/components/LeftPanel.tsx b/devtools/chrome-extension/src/devPanels/formily/app/components/LeftPanel.tsx similarity index 77% rename from devtools/chrome-extension/src/app/components/LeftPanel.tsx rename to devtools/chrome-extension/src/devPanels/formily/app/components/LeftPanel.tsx index 2e6f1e16dfa..3f88cab4f83 100644 --- a/devtools/chrome-extension/src/app/components/LeftPanel.tsx +++ b/devtools/chrome-extension/src/devPanels/formily/app/components/LeftPanel.tsx @@ -1,12 +1,12 @@ import React, { useState } from 'react' -import { Tabs } from './Tabs' + import { FieldTree } from './FieldTree' -import styled from 'styled-components' +import { Tabs } from './Tabs' -export const LeftPanel = styled(({ className, dataSource, onSelect }) => { +export const LeftPanel = ({ dataSource, onSelect }) => { const [current, setCurrent] = useState(0) return ( -
+
{ />
) -})` - width: 50%; - min-width: 50%; -` +} diff --git a/devtools/chrome-extension/src/app/components/RightPanel.tsx b/devtools/chrome-extension/src/devPanels/formily/app/components/RightPanel.tsx similarity index 56% rename from devtools/chrome-extension/src/app/components/RightPanel.tsx rename to devtools/chrome-extension/src/devPanels/formily/app/components/RightPanel.tsx index 60d1bb1c587..07196d7d5b2 100644 --- a/devtools/chrome-extension/src/app/components/RightPanel.tsx +++ b/devtools/chrome-extension/src/devPanels/formily/app/components/RightPanel.tsx @@ -1,10 +1,9 @@ import React from 'react' -import styled from 'styled-components' import ReactJson from 'react-json-view' -export const RightPanel = styled(({ className, dataSource }) => { +export const RightPanel = ({ dataSource }) => { return ( -
+
{ />
) -})` - border-left: 1px solid #3d424a; - flex-grow: 2; - overflow: auto; - padding: 10px; - .react-json-view { - background: none !important; - font-size: 12px !important; - } -` +} diff --git a/devtools/chrome-extension/src/app/components/SearchBox.tsx b/devtools/chrome-extension/src/devPanels/formily/app/components/SearchBox.tsx similarity index 75% rename from devtools/chrome-extension/src/app/components/SearchBox.tsx rename to devtools/chrome-extension/src/devPanels/formily/app/components/SearchBox.tsx index 721b3fe55ba..23d620dcb6f 100644 --- a/devtools/chrome-extension/src/app/components/SearchBox.tsx +++ b/devtools/chrome-extension/src/devPanels/formily/app/components/SearchBox.tsx @@ -1,26 +1,11 @@ import React from 'react' -import styled from 'styled-components' -const SerachBox = styled.div` - display: flex; - align-items: center; - height: 100%; - .input-addon { - padding: 0 5px; - } - .form-control { - width: 50%; - border: none; - background: transparent; - color: white; - outline: none; - } -` +const SearchBox = ({ children }) =>
{children}
const SearchIcon = () => { return ( { export default ({ onSearch }) => { return ( - -
+ +
- +
) } diff --git a/devtools/chrome-extension/src/devPanels/formily/app/components/Tabs.tsx b/devtools/chrome-extension/src/devPanels/formily/app/components/Tabs.tsx new file mode 100644 index 00000000000..859c8db9993 --- /dev/null +++ b/devtools/chrome-extension/src/devPanels/formily/app/components/Tabs.tsx @@ -0,0 +1,25 @@ +import { toArr } from '@formily/shared' +import React from 'react' + +export const Tabs = ({ dataSource, current, onChange }) => { + current = current || 0 + return ( +
+ {toArr(dataSource).map((item, index) => { + return ( +
{ + if (onChange) { + onChange(index) + } + }} + > + Form#{index + 1} +
+ ) + })} +
+ ) +} diff --git a/devtools/chrome-extension/src/app/components/filter.ts b/devtools/chrome-extension/src/devPanels/formily/app/components/filter.ts similarity index 100% rename from devtools/chrome-extension/src/app/components/filter.ts rename to devtools/chrome-extension/src/devPanels/formily/app/components/filter.ts diff --git a/devtools/chrome-extension/src/app/demo.tsx b/devtools/chrome-extension/src/devPanels/formily/app/demo.tsx similarity index 99% rename from devtools/chrome-extension/src/app/demo.tsx rename to devtools/chrome-extension/src/devPanels/formily/app/demo.tsx index b401e9aecc6..51b7d8ed612 100644 --- a/devtools/chrome-extension/src/app/demo.tsx +++ b/devtools/chrome-extension/src/devPanels/formily/app/demo.tsx @@ -1,6 +1,8 @@ import React from 'react' import ReactDOM from 'react-dom' -import App from './index' + +import { App } from './index' + const dataSource = [ { '': { diff --git a/devtools/chrome-extension/src/app/index.tsx b/devtools/chrome-extension/src/devPanels/formily/app/index.tsx similarity index 76% rename from devtools/chrome-extension/src/app/index.tsx rename to devtools/chrome-extension/src/devPanels/formily/app/index.tsx index c2f9cee8255..1621b90a900 100644 --- a/devtools/chrome-extension/src/app/index.tsx +++ b/devtools/chrome-extension/src/devPanels/formily/app/index.tsx @@ -1,15 +1,15 @@ import React, { useState } from 'react' + import { LeftPanel } from './components/LeftPanel' import { RightPanel } from './components/RightPanel' -import styled from 'styled-components' -export default styled(({ className, dataSource }) => { +export const App = ({ dataSource }) => { const [selected, select] = useState({ current: 0, key: '', }) return ( -
+
{ @@ -35,14 +35,4 @@ export default styled(({ className, dataSource }) => { />
) -})` - display: flex; - position: absolute; - top: 0; - bottom: 0; - left: 0; - right: 0; - overflow: hidden; - color: #36d4c7; - background: #282c34; -` +} diff --git a/devtools/chrome-extension/src/devPanels/formily/index.css b/devtools/chrome-extension/src/devPanels/formily/index.css new file mode 100644 index 00000000000..2968f1b32c3 --- /dev/null +++ b/devtools/chrome-extension/src/devPanels/formily/index.css @@ -0,0 +1,126 @@ +::-webkit-scrollbar { + width: 5px; + height: 5px; +} + +::-webkit-scrollbar-thumb { + background: #101114; + border-radius: 10px; +} + +::-webkit-scrollbar-thumb:hover { + background: #494e5f; +} + +::-webkit-scrollbar-track { + background: transparent; + border-radius: 10px; +} + +.app { + display: flex; + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + overflow: hidden; + color: #36d4c7; + background: #282c34; +} + +.fieldTree { + position: relative; + overflow: auto; + height: calc(100% - 40px); + user-select: none; +} + +.fieldTreeHighlight { + position: absolute; + top: 0; + right: 0; + left: -100%; + height: 100%; + z-index: 0; + &.active { + background: #3d424a; + } +} +.fieldTreeNodeHeader:hover .fieldTreeHighlight { + background: #3d424a; +} + +.filedTreeToolBar { + border-bottom: 1px solid #3d424a; + height: 20px; + padding: 10px 10px; + padding: 5px; + overflow: auto; + position: sticky; + top: 0; + background: #282c34; + z-index: 100; +} + +.leftPanel { + width: 50%; + min-width: 50%; +} + +.rightPanel { + border-left: 1px solid #3d424a; + flex-grow: 2; + overflow: auto; + padding: 10px; +} + +.rightPanel .react-json-view { + background: none !important; + font-size: 12px !important; +} + +.searchBox { + display: flex; + align-items: center; + height: 100%; +} + +.searchBoxInputAddon { + padding: 0 5px; +} +.searchBoxFormControl { + width: 50%; + border: none; + background: transparent; + color: white; + outline: none; +} + +.tabs { + height: 36px; + border-bottom: 1px solid #3d424a; + display: flex; + line-height: 36px; + width: 100%; + overflow: scroll; +} + +.tabs::-webkit-scrollbar { + display: none; +} +.tabs .tabItem { + cursor: pointer; + transition: 0.15s all ease-in-out; + border-right: 1px solid #3d424a; + padding: 0 10px; + font-size: 12px; +} + +.tabs .tabItem:hover { + background: #1d1f25; +} + +.tabs .tabItem.active { + background: #1d1f25; +} diff --git a/devtools/chrome-extension/src/devPanels/formily/index.html b/devtools/chrome-extension/src/devPanels/formily/index.html new file mode 100644 index 00000000000..bc270f2adec --- /dev/null +++ b/devtools/chrome-extension/src/devPanels/formily/index.html @@ -0,0 +1,13 @@ + + + + Formily devtools panel + + + + + +
+ + + diff --git a/devtools/chrome-extension/src/extension/devpanel.tsx b/devtools/chrome-extension/src/devPanels/formily/index.tsx similarity index 87% rename from devtools/chrome-extension/src/extension/devpanel.tsx rename to devtools/chrome-extension/src/devPanels/formily/index.tsx index be2a23bf88e..74957725f16 100644 --- a/devtools/chrome-extension/src/extension/devpanel.tsx +++ b/devtools/chrome-extension/src/devPanels/formily/index.tsx @@ -1,6 +1,7 @@ import React, { useEffect, useState } from 'react' -import ReactDOM from 'react-dom' -import App from '../app' +import { createRoot } from 'react-dom/client' + +import { App } from './app' const backgroundPageConnection = chrome.runtime.connect({ name: '@formily-devtools-panel-script', @@ -46,4 +47,5 @@ const Devtools = () => { return } -ReactDOM.render(, document.getElementById('root')) +const root = createRoot(document.getElementById('root')) +root.render() diff --git a/devtools/chrome-extension/src/devtools.tsx b/devtools/chrome-extension/src/devtools.tsx new file mode 100644 index 00000000000..9391d8eb165 --- /dev/null +++ b/devtools/chrome-extension/src/devtools.tsx @@ -0,0 +1,41 @@ +import React from 'react' +import formilyDevPanel from 'url:./devPanels/formily/index.html' + +const createPanel = () => { + chrome.devtools.panels.create( + '🍀Formily', + null, + formilyDevPanel.split('/').pop() + ) +} + +let created = false + +const checkForFormilyPresence = () => { + if (created) { + return + } + + chrome.devtools.inspectedWindow.eval( + 'window.__FORMILY_DEV_TOOLS_HOOK__ && window.__FORMILY_DEV_TOOLS_HOOK__.hasFormilyInstance', + (hasFormily: boolean, error) => { + if (created || !hasFormily || error) { + return + } + + created = true + + clearInterval(loadCheckInterval) + + createPanel() + } + ) +} + +const loadCheckInterval = setInterval(checkForFormilyPresence, 1000) + +checkForFormilyPresence() + +const IndexDevtools = () =>

Formily devtools is running

+ +export default IndexDevtools diff --git a/devtools/chrome-extension/src/extension/devtools.tsx b/devtools/chrome-extension/src/extension/devtools.tsx deleted file mode 100644 index dad7a08d5a7..00000000000 --- a/devtools/chrome-extension/src/extension/devtools.tsx +++ /dev/null @@ -1,30 +0,0 @@ -declare let chrome: any - -let created = false - -const createPanel = () => { - if (created) { - return - } - - chrome.devtools.inspectedWindow.eval( - 'window.__FORMILY_DEV_TOOLS_HOOK__ && window.__FORMILY_DEV_TOOLS_HOOK__.hasFormilyInstance', - (hasFormily: boolean) => { - if (!hasFormily) return - created = true - clearInterval(loadCheckInterval) - chrome.devtools.panels.create( - 'Formily', - 'img/logo/scalable.png', - './devpanel.html', - function () {} - ) - } - ) -} - -const loadCheckInterval = setInterval(function () { - createPanel() -}, 1000) - -createPanel() diff --git a/devtools/chrome-extension/src/extension/inject.ts b/devtools/chrome-extension/src/extension/inject.ts deleted file mode 100644 index e9d05e1e235..00000000000 --- a/devtools/chrome-extension/src/extension/inject.ts +++ /dev/null @@ -1,26 +0,0 @@ -import backend from 'raw-loader!./backend' -function nullthrows(x: any, message?: string) { - if (x != null) { - return x - } - const error: any = new Error( - message !== undefined ? message : 'Got unexpected ' + x - ) - error.framesToPop = 1 // Skip nullthrows's own stack frame. - throw error -} - -function injectCode(code) { - const script = document.createElement('script') - script.textContent = code - - // This script runs before the element is created, - // so we add the script to instead. - nullthrows(document.documentElement).appendChild(script) - nullthrows(script.parentNode).removeChild(script) -} - -injectCode(`;(function(){ - var exports = {}; - ${backend} -})()`) diff --git a/devtools/chrome-extension/src/extension/manifest.json b/devtools/chrome-extension/src/extension/manifest.json deleted file mode 100644 index 0e6776176b7..00000000000 --- a/devtools/chrome-extension/src/extension/manifest.json +++ /dev/null @@ -1,58 +0,0 @@ -{ - "version": "0.1.13", - "name": "Formily DevTools", - "short_name": "Formily DevTools", - "description": "Formily DevTools for debugging application's state changes.", - "homepage_url": "https://github.com/alibaba/formily", - "manifest_version": 2, - "page_action": { - "default_icon": "img/logo/scalable.png", - "default_title": "Formily DevTools", - "default_popup": "popup.html" - }, - "commands": { - "devtools-left": { - "description": "DevTools window to left" - }, - "devtools-right": { - "description": "DevTools window to right" - }, - "devtools-bottom": { - "description": "DevTools window to bottom" - }, - "devtools-remote": { - "description": "Remote DevTools" - }, - "_execute_page_action": { - "suggested_key": { - "default": "Ctrl+Shift+E" - } - } - }, - "icons": { - "16": "img/logo/16x16.png", - "48": "img/logo/48x48.png", - "128": "img/logo/128x128.png" - }, - "background": { - "scripts": ["js/background.bundle.js"], - "persistent": false - }, - "content_scripts": [ - { - "matches": [""], - "exclude_globs": ["https://www.google*"], - "js": ["js/content.bundle.js", "js/inject.bundle.js"], - "run_at": "document_start", - "all_frames": true - } - ], - "devtools_page": "devtools.html", - "web_accessible_resources": ["js/backend.bundle.js"], - "externally_connectable": { - "ids": ["*"] - }, - "permissions": ["file:///*", "http://*/*", "https://*/*"], - "content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'; style-src * 'unsafe-inline'; img-src 'self' data:;", - "update_url": "https://clients2.google.com/service/update2/crx" -} diff --git a/devtools/chrome-extension/src/extension/popup.tsx b/devtools/chrome-extension/src/extension/popup.tsx deleted file mode 100644 index 39e49f32f59..00000000000 --- a/devtools/chrome-extension/src/extension/popup.tsx +++ /dev/null @@ -1,4 +0,0 @@ -import React from 'react' -import ReactDOM from 'react-dom' - -ReactDOM.render(
hello world
, document.getElementById('root')) diff --git a/devtools/chrome-extension/src/extension/views/devpanel.ejs b/devtools/chrome-extension/src/extension/views/devpanel.ejs deleted file mode 100644 index 5cd2f708d06..00000000000 --- a/devtools/chrome-extension/src/extension/views/devpanel.ejs +++ /dev/null @@ -1,32 +0,0 @@ - - - - - Formily Devtools - - - - - -
-
- \ No newline at end of file diff --git a/devtools/chrome-extension/src/extension/views/devtools.ejs b/devtools/chrome-extension/src/extension/views/devtools.ejs deleted file mode 100644 index 237c58c53ee..00000000000 --- a/devtools/chrome-extension/src/extension/views/devtools.ejs +++ /dev/null @@ -1,10 +0,0 @@ - - - - Formily Devtools - - - -
-
- \ No newline at end of file diff --git a/devtools/chrome-extension/src/extension/views/popup.ejs b/devtools/chrome-extension/src/extension/views/popup.ejs deleted file mode 100644 index 237c58c53ee..00000000000 --- a/devtools/chrome-extension/src/extension/views/popup.ejs +++ /dev/null @@ -1,10 +0,0 @@ - - - - Formily Devtools - - - -
-
- \ No newline at end of file diff --git a/devtools/chrome-extension/src/popup.tsx b/devtools/chrome-extension/src/popup.tsx new file mode 100644 index 00000000000..389c55fdde0 --- /dev/null +++ b/devtools/chrome-extension/src/popup.tsx @@ -0,0 +1,16 @@ +import React from 'react' + +const IndexPopup = () => ( +
+

Formily devtools is running!

+

+ Find out more about formily at{' '} + + formilyjs.org + + . +

+
+) + +export default IndexPopup diff --git a/devtools/chrome-extension/src/extension/backend.ts b/devtools/chrome-extension/src/webAccessible/backend.ts similarity index 84% rename from devtools/chrome-extension/src/extension/backend.ts rename to devtools/chrome-extension/src/webAccessible/backend.ts index aa52254d0db..01e39531717 100644 --- a/devtools/chrome-extension/src/extension/backend.ts +++ b/devtools/chrome-extension/src/webAccessible/backend.ts @@ -97,25 +97,33 @@ const HOOK = { form, }) let timer = null - const task = () => { - globalThis.requestIdleCallback((deadline: IIdleDeadline) => { - if (this.store[id]) { - if (deadline.timeRemaining() < 16) { - task() - } else { - send({ - type: 'update', - id, - form, - }) - } - } + const idleCallback = (deadline: IIdleDeadline) => { + const busy = deadline.timeRemaining() === 0 + if (busy) { + globalThis.requestIdleCallback(idleCallback) + return + } + + const registered = this.store[id] + + if (!registered) { + return + } + + send({ + type: 'update', + id, + form, }) } + const emit = () => { + globalThis.requestIdleCallback(idleCallback) + } + form.subscribe(() => { if (!this.hasOpenDevtools) return clearTimeout(timer) - timer = setTimeout(task, 300) + timer = setTimeout(emit, 300) }) }, update() { diff --git a/devtools/chrome-extension/tsconfig.build.json b/devtools/chrome-extension/tsconfig.build.json deleted file mode 100644 index 184756042d2..00000000000 --- a/devtools/chrome-extension/tsconfig.build.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "./lib", - "paths": { - "@formily/*": ["packages/*", "devtools/*"] - }, - "declaration": true - } -} diff --git a/devtools/chrome-extension/tsconfig.json b/devtools/chrome-extension/tsconfig.json index c6865c25a75..435bb86c1c1 100644 --- a/devtools/chrome-extension/tsconfig.json +++ b/devtools/chrome-extension/tsconfig.json @@ -1,5 +1,11 @@ { - "extends": "../../tsconfig.json", - "include": ["./src/**/*.ts", "./src/**/*.tsx"], - "exclude": ["./src/__tests__/*", "./esm/*", "./lib/*"] + "extends": "plasmo/templates/tsconfig.base", + "exclude": ["node_modules"], + "include": [".plasmo/index.d.ts", "./**/*.ts", "./**/*.tsx"], + "compilerOptions": { + "paths": { + "~*": ["./src/*"] + }, + "baseUrl": "." + } }