|
| 1 | +# 开发指南 |
| 2 | + |
| 3 | +## 1. 相关技术和工具 |
| 4 | + |
| 5 | +使用到的技术栈有: |
| 6 | + |
| 7 | +- [webpack](https://github.com/webpack/webpack) + [TypeScript](https://github.com/microsoft/TypeScript) |
| 8 | +- [Vue3 (Composition API + JSX)](<https://vuejs.org/api/#:~:text=defineCustomElement()-,Composition%20API,-setup()>) |
| 9 | +- [sass](https://github.com/sass/sass) |
| 10 | +- [Element Plus](https://element-plus.gitee.io/) |
| 11 | +- [Echarts](https://github.com/apache/echarts) |
| 12 | + |
| 13 | +以及 [Chrome Extension 开发文档](https://developer.chrome.com/docs/webstore/),目前 manifest 的版本 Chrome 和 Edge 使用的使 v3, Firefox 使用的是 v2。请注意接口兼容。 |
| 14 | + |
| 15 | +还集成了一些免费的开源工具: |
| 16 | + |
| 17 | +- 单元测试工具 [jest](https://jestjs.io/docs/getting-started) |
| 18 | +- 单元测试覆盖率 [Codecov](https://app.codecov.io/gh/sheepzh/timer) |
| 19 | +- 端到端集成测试 [puppeteer](https://developer.chrome.com/docs/extensions/how-to/test/puppeteer) |
| 20 | +- 代码质量检测 [CODEBEAT](https://codebeat.co/projects/github-com-sheepzh-timer-main) |
| 21 | +- 多语言翻译管理 [Crowdin](https://crowdin.com/project/timer-chrome-edge-firefox) |
| 22 | + |
| 23 | +## 2. 开发步骤 |
| 24 | + |
| 25 | +1. fork 自己的仓库 |
| 26 | +2. 安装依赖 |
| 27 | + |
| 28 | +```shell |
| 29 | +npm install |
| 30 | +``` |
| 31 | + |
| 32 | +3. 创建对应的需求分支 |
| 33 | +4. code |
| 34 | +5. run 开发环境 |
| 35 | + 首先执行命令 |
| 36 | + |
| 37 | +```shell |
| 38 | +npm run dev |
| 39 | +# 在 Firefox 中测试 |
| 40 | +npm run dev:firefox |
| 41 | +``` |
| 42 | + |
| 43 | +项目根目录下会输出两个文件夹,dist_dev 和 dist_dev_firefox |
| 44 | + |
| 45 | +然后根据测试浏览器导入不同目标到浏览器中: |
| 46 | + |
| 47 | +- Chrome 和 Edge 导入 dist_dev 文件夹 |
| 48 | +- Firefox 导入 dist_dev_firefox 文件夹下的 manifest.json 文件 |
| 49 | + |
| 50 | +6. 运行单元测试 |
| 51 | + |
| 52 | +```shell |
| 53 | +npm run test |
| 54 | +``` |
| 55 | + |
| 56 | +7. 运行端到端的集成测试 |
| 57 | + |
| 58 | +首先需要编译两次:集成编译和生产编译 |
| 59 | + |
| 60 | +```shell |
| 61 | +npm run dev:e2e |
| 62 | +npm run build |
| 63 | +``` |
| 64 | + |
| 65 | +然后执行测试 |
| 66 | + |
| 67 | +```shell |
| 68 | +npm run test-e2e |
| 69 | +``` |
| 70 | + |
| 71 | +如果需要使用 headless 模式启动 puppeteer,可以设置以下环境变量 |
| 72 | + |
| 73 | +```bash |
| 74 | +export USE_HEADLESS_PUPPETEER=true |
| 75 | +``` |
| 76 | + |
| 77 | +7. 提交 PR |
| 78 | + |
| 79 | +请 PR 到主仓库的 milestone 分支,一般是下一次发布的次版本号(x.x.0)。如果没有,请联系作者添加 |
| 80 | + |
| 81 | +## 3. 应用架构设计 |
| 82 | + |
| 83 | +> todo |
| 84 | +
|
| 85 | +## 4. 目录结构 |
| 86 | + |
| 87 | +```plain |
| 88 | +project |
| 89 | +│ |
| 90 | +└───doc # 文档 |
| 91 | +│ |
| 92 | +└───public # 静态资源 |
| 93 | +| |
| 94 | +└───src |
| 95 | +| | manifest.ts # Chrome 和 Edge 的声明文件 |
| 96 | +| | manifest-firefox.ts # Firefox 的声明文件 |
| 97 | +| | |
| 98 | +| └───api # HTTP API 以及扩展 API 的兼容处理 |
| 99 | +| | |
| 100 | +| └───pages # 用户界面相关代码 |
| 101 | +| | | |
| 102 | +| | └───app # 后台页 |
| 103 | +| | | |
| 104 | +| | └───popup # 弹窗页 |
| 105 | +| | | | |
| 106 | +| | | └───skeleton.ts # 弹窗页骨架屏,加速打开速度 |
| 107 | +| | | | |
| 108 | +| | | └───index.ts # 弹窗页真实界面 |
| 109 | +| | | |
| 110 | +| | └───side # 侧边栏 |
| 111 | +| | | |
| 112 | +| | └───[其他目录] # 公共代码 |
| 113 | +| | |
| 114 | +| └───background # 后台服务,负责协调数据交互,Service Worker |
| 115 | +| | |
| 116 | +| └───content-script # 注入到用户页面里的脚本 |
| 117 | +| | |
| 118 | +| └───service # 服务层 |
| 119 | +| | |
| 120 | +| └───database # 数据访问层 |
| 121 | +| | |
| 122 | +| └───i18n # 多语言 |
| 123 | +| | |
| 124 | +| └───util # 工具包 |
| 125 | +| | |
| 126 | +| └───common # 公共功能 |
| 127 | +| |
| 128 | +└───test # 单测 |
| 129 | +| └───__mock__ |
| 130 | +| | |
| 131 | +| └───storage.ts # mock chrome.storage |
| 132 | +| |
| 133 | +└───test-e2e # 端到端测试 |
| 134 | +| |
| 135 | +└───types # 补充声明 |
| 136 | +| |
| 137 | +└───webpack # webpack 打包配置 |
| 138 | +
|
| 139 | +``` |
| 140 | + |
| 141 | +## 5. 代码格式 |
| 142 | + |
| 143 | +请使用 VSCode 自带的代码格式工具,请<u>**禁用 Prettier Eslint**</u> 等格式化工具 |
| 144 | + |
| 145 | +- 尽量使用单引号 |
| 146 | +- 在符合语法正确情况下,尽量保持代码简洁 |
| 147 | +- 行尾无分号 |
| 148 | +- 换行符使用 LF (\n),Windows 下需要执行以下指令关闭警告 |
| 149 | + |
| 150 | +``` |
| 151 | +git config core.autocrlf false |
| 152 | +``` |
| 153 | + |
| 154 | +## 6. 多语言处理 |
| 155 | + |
| 156 | +用户界面的文本除了特定的专业名词可以使用英语之外,其余请使用多语言框架注入文本。见代码目录 `src/i18n` |
| 157 | + |
| 158 | +### 如何新增多语言条目 |
| 159 | + |
| 160 | +1. 在定义文件 `xxx.ts` 中新增一个字段。 |
| 161 | +2. 然后在对应资源文件 `xxx-resource.json` 中 <u>新增该字段的英语 (en) 和简体中文 (zh_CN) 的对应文本</u> 即可。 |
| 162 | +3. 在代码中调用 t(文本路径) 获取文本内容。 |
| 163 | + |
| 164 | +### 如何与 Crowdin 集成 |
| 165 | + |
| 166 | +Crowdin 是一个协作翻译平台,可以让 native 用户帮助翻译多语言内容。该项目与 Crowdin 的集成主要分为两步。 |
| 167 | + |
| 168 | +1. 上传英语文本和代码中的其他语种文本 |
| 169 | + |
| 170 | +``` |
| 171 | +# 上传英语原始文本 |
| 172 | +ts-node ./script/crowdin/sync-source.ts |
| 173 | +# 上传本地代码中其他语种的文本(不包括简体中文) |
| 174 | +ts-node ./script/crowdin/sync-translation.ts |
| 175 | +``` |
| 176 | + |
| 177 | +因为上述两个脚本,依赖在环境变量中的 Crowdin access secret。所以我将它们集成到了 Github 的 [Action](https://github.com/sheepzh/timer/actions/workflows/crowdin-sync.yml) 中。 |
| 178 | + |
| 179 | +2. 导出 Crowdin 中翻译完成的内容 |
| 180 | + |
| 181 | +``` |
| 182 | +ts-node ./script/crowdin/export-translation.ts |
| 183 | +``` |
| 184 | + |
| 185 | +同样也可以直接执行 [Action](https://github.com/sheepzh/timer/actions/workflows/crowdin-export.yml)。 |
0 commit comments