diff --git a/libs/extension/babel.config.js b/libs/extension/babel.config.js new file mode 100644 index 00000000..c358bb46 --- /dev/null +++ b/libs/extension/babel.config.js @@ -0,0 +1,15 @@ +module.exports = api => { + const isTest = api.env('test'); + console.log('isTest', isTest); + return { + presets: [ + '@babel/preset-env', + '@babel/preset-typescript', + ['@babel/preset-react', { + runtime: 'classic', + 'pragma': 'Horizon.createElement', + 'pragmaFrag': 'Horizon.Fragment', + }]], + plugins: ['@babel/plugin-proposal-class-properties'], + }; +}; \ No newline at end of file diff --git a/libs/extension/package.json b/libs/extension/package.json new file mode 100644 index 00000000..ade577c7 --- /dev/null +++ b/libs/extension/package.json @@ -0,0 +1,35 @@ +{ + "name": "extension", + "version": "1.0.0", + "description": "", + "main": "", + "scripts": { + "build": "webpack --config ./webpack.config.js", + "watch": "webpack --config ./webpack.config.js --watch", + "build-dev": "webpack --config ./webpack.dev.js", + "start": "webpack serve --config ./webpack.dev.js ", + "test": "jest" + }, + "keywords": [], + "author": "", + "license": "ISC", + "devDependencies": { + "@babel/core": "7.12.3", + "@babel/plugin-proposal-class-properties": "^7.16.7", + "@babel/preset-env": "7.12.1", + "@babel/preset-react": "7.12.1", + "@babel/preset-typescript": "^7.16.7", + "@types/jest": "^27.4.1", + "babel-loader": "8.1.0", + "css-loader": "^6.7.1", + "html-webpack-plugin": "^5.5.0", + "jest": "^27.5.1", + "less": "^4.1.2", + "less-loader": "^10.2.0", + "style-loader": "^3.3.1", + "ts-jest": "^27.1.4", + "webpack": "^5.70.0", + "webpack-cli": "^4.9.2", + "webpack-dev-server": "^4.7.4" + } +} diff --git a/libs/extension/readme.md b/libs/extension/readme.md index d7e98884..ee9ec4cd 100644 --- a/libs/extension/readme.md +++ b/libs/extension/readme.md @@ -2,7 +2,6 @@ devtools_page: devtool主页面 default_popup: 拓展图标点击时弹窗页面 content_scripts: 内容脚本,在项目中负责在页面初始化时调用注入全局变量代码和消息传递 -web_accessible_resources: 注入全局变量代码 ## 打开 panel 页面调试面板的方式 @@ -53,5 +52,12 @@ sequenceDiagram - 每个vNode有唯一的 path 属性,可以作为标识使用 - 通过解析 path 值可以分析出组件树的结构 +## 组件props/state/hook等数据的传输和解析 +将数据格式进行转换后进行传递。对于 props 和 类组件的 state,他们都是对象,可以将对象进行解析然后以 k-v 的形式,树的结构显示。函数组件的 Hooks 是以数组的形式存储在 vNode 的属性中的,每个 hook 的唯一标识符是 hIndex 属性值,在对象展示的时候不能展示该属性值,需要根据 hook 类型展示一个 state/ref/effect 等值。hook 中存储的值也可能不是对象,只是一个简单的字符串,他们的解析和 props/state 的解析同样存在差异。 + + ## 滚动动态渲染 Tree 考虑到组件树可能很大,所以并不适合一次性全部渲染出来,可以通过滚动渲染的方式减少页面 dom 的数量。我们可以把树看成有不同缩进长度的列表,动态渲染滚动列表的实现可以参考谷歌的这篇文章:https://developers.google.com/web/updates/2016/07/infinite-scroller 这样,我们需要的组件树数据可以由树结构转变为数组,可以减少动态渲染时对树结构进行解析时的计算工作。 + +## 测试框架 +jest测试框架不提供浏览器插件的相关 api,我们在封装好相关 api 后需要模拟这些 api 的行为从而展开测试工作。 diff --git a/libs/extension/tsconfig.json b/libs/extension/tsconfig.json new file mode 100644 index 00000000..e2effe5e --- /dev/null +++ b/libs/extension/tsconfig.json @@ -0,0 +1,19 @@ +{ + "compilerOptions": { + "outDir": "./dist/", + "noImplicitAny": false, + "module": "es6", + "target": "es5", + "jsx": "preserve", + "allowJs": true, + "allowSyntheticDefaultImports": true, + "moduleResolution": "Node", + "baseUrl": "./", + "paths": { + "*": ["types/*"] + } + }, + "includes": [ + "./src/index.d.ts", "./src/*/*.ts", "./src/*/*.tsx" + ] +} \ No newline at end of file diff --git a/libs/extension/webpack.config.js b/libs/extension/webpack.config.js new file mode 100644 index 00000000..3910117e --- /dev/null +++ b/libs/extension/webpack.config.js @@ -0,0 +1,51 @@ +const path = require('path'); + +const config = { + entry: { + background: './src/background/index.ts', + main: './src/main/index.ts', + injector: './src/injector/index.ts', + contentScript: './src/contentScript/index.ts', + panel: './src/panel/index.tsx', + popup: './src/popup/index.ts', + }, + output: { + path: path.resolve(__dirname, './build'), + filename: '[name].js', + }, + mode: 'development', + devtool: 'inline-source-map', + module: { + rules: [ + { + test: /\.tsx?$/, + exclude: /node_modules/, + use: [ + { + loader: 'babel-loader', + } + ] + }, + { + test: /\.less/i, + use: [ + 'style-loader', + { + loader: 'css-loader', + options: { + modules: true, + + } + }, + 'less-loader'], + }] + }, + resolve: { + extensions: ['.js', '.ts', '.tsx'], + }, + externals: { + 'horizon': 'Horizon', + }, +}; + +module.exports = config; diff --git a/libs/extension/webpack.dev.js b/libs/extension/webpack.dev.js index 1c468b0c..b3332077 100644 --- a/libs/extension/webpack.dev.js +++ b/libs/extension/webpack.dev.js @@ -1,5 +1,4 @@ const path = require('path'); -const HtmlWebpackPlugin = require('html-webpack-plugin'); const webpack = require('webpack'); // 用于 panel 页面开发 @@ -8,6 +7,7 @@ module.exports = { mode: 'development', entry: { panel: path.join(__dirname, './src/panel/index.tsx'), + mockPage: path.join(__dirname, './src/devtools/mockPage/index.tsx'), }, output: { path: path.join(__dirname, 'dist'), @@ -15,7 +15,7 @@ module.exports = { }, devtool: 'source-map', resolve: { - extensions: ['.ts', '.tsx', '.js'] + extensions: ['.ts', '.tsx', '.js'], }, module: { rules: [ @@ -25,16 +25,6 @@ module.exports = { use: [ { loader: 'babel-loader', - options: { - presets: ['@babel/preset-env', - '@babel/preset-typescript', - ['@babel/preset-react', { - runtime: 'classic', - 'pragma': 'Horizon.createElement', - 'pragmaFrag': 'Horizon.Fragment', - }]], - plugins: ['@babel/plugin-proposal-class-properties'], - } } ] }, @@ -64,10 +54,6 @@ module.exports = { magicHtml: true, }, plugins: [ - new HtmlWebpackPlugin({ - filename: 'panel.html', - template: './src/panel/panel.html' - }), new webpack.DefinePlugin({ 'process.env.NODE_ENV': '"development"', isDev: 'true',