@linyjs/plugin-docs 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (252) hide show
  1. package/README.md +97 -0
  2. package/docs/api-reference/index.md +341 -0
  3. package/docs/best-practices/error-handling.md +462 -0
  4. package/docs/best-practices/naming-conventions.md +495 -0
  5. package/docs/best-practices/performance.md +532 -0
  6. package/docs/best-practices/security.md +620 -0
  7. package/docs/faq.md +323 -0
  8. package/docs/getting-started/first-plugin.md +358 -0
  9. package/docs/getting-started/installation.md +244 -0
  10. package/docs/getting-started/quick-start.md +174 -0
  11. package/docs/guides/client-module.md +598 -0
  12. package/docs/guides/data-persistence.md +536 -0
  13. package/docs/guides/permissions.md +440 -0
  14. package/docs/guides/server-module.md +371 -0
  15. package/docs/guides/ui-slots.md +475 -0
  16. package/docs/migration/v0-to-v1.md +354 -0
  17. package/examples/analytics-plugin/README.md +416 -0
  18. package/examples/analytics-plugin/dist/client/index.d.ts +36 -0
  19. package/examples/analytics-plugin/dist/client/index.js +173 -0
  20. package/examples/analytics-plugin/dist/index.d.ts +64 -0
  21. package/examples/analytics-plugin/dist/index.js +72 -0
  22. package/examples/analytics-plugin/dist/server/index.d.ts +119 -0
  23. package/examples/analytics-plugin/dist/server/index.js +313 -0
  24. package/examples/analytics-plugin/package.json +28 -0
  25. package/examples/analytics-plugin/src/client/index.tsx +410 -0
  26. package/examples/analytics-plugin/src/index.ts +71 -0
  27. package/examples/analytics-plugin/src/server/index.ts +348 -0
  28. package/examples/analytics-plugin/tsconfig.json +21 -0
  29. package/examples/blog-plugin/README.md +316 -0
  30. package/examples/blog-plugin/dist/client/index.d.ts +22 -0
  31. package/examples/blog-plugin/dist/client/index.js +197 -0
  32. package/examples/blog-plugin/dist/server/index.d.ts +5 -0
  33. package/examples/blog-plugin/dist/server/index.js +220 -0
  34. package/examples/blog-plugin/package.json +24 -0
  35. package/examples/blog-plugin/src/client/index.tsx +405 -0
  36. package/examples/blog-plugin/src/server/index.ts +240 -0
  37. package/examples/blog-plugin/tsconfig.json +16 -0
  38. package/examples/hello-world/README.md +101 -0
  39. package/examples/hello-world/dist/client/index.d.ts +5 -0
  40. package/examples/hello-world/dist/client/index.js +80 -0
  41. package/examples/hello-world/dist/server/index.d.ts +5 -0
  42. package/examples/hello-world/dist/server/index.js +38 -0
  43. package/examples/hello-world/node_modules/.package-lock.json +61 -0
  44. package/examples/hello-world/node_modules/@linyjs/client-module-interface/HOOKS_USAGE.md +281 -0
  45. package/examples/hello-world/node_modules/@linyjs/client-module-interface/IMPLEMENTATION_SUMMARY.md +166 -0
  46. package/examples/hello-world/node_modules/@linyjs/client-module-interface/QUICK_REFERENCE.md +130 -0
  47. package/examples/hello-world/node_modules/@linyjs/client-module-interface/README.md +214 -0
  48. package/examples/hello-world/node_modules/@linyjs/client-module-interface/package.json +26 -0
  49. package/examples/hello-world/node_modules/@linyjs/client-module-interface/src/application.ts +50 -0
  50. package/examples/hello-world/node_modules/@linyjs/client-module-interface/src/comparison-example.tsx +229 -0
  51. package/examples/hello-world/node_modules/@linyjs/client-module-interface/src/di.ts +127 -0
  52. package/examples/hello-world/node_modules/@linyjs/client-module-interface/src/domain.ts +52 -0
  53. package/examples/hello-world/node_modules/@linyjs/client-module-interface/src/hooks-example.tsx +275 -0
  54. package/examples/hello-world/node_modules/@linyjs/client-module-interface/src/hooks.ts +175 -0
  55. package/examples/hello-world/node_modules/@linyjs/client-module-interface/src/index.ts +87 -0
  56. package/examples/hello-world/node_modules/@linyjs/client-module-interface/src/interfaces.ts +117 -0
  57. package/examples/hello-world/node_modules/@linyjs/client-module-interface/src/router.ts +49 -0
  58. package/examples/hello-world/node_modules/@linyjs/client-module-interface/tsconfig.json +10 -0
  59. package/examples/hello-world/node_modules/@linyjs/server-module-interface/package.json +21 -0
  60. package/examples/hello-world/node_modules/@linyjs/server-module-interface/src/application.ts +21 -0
  61. package/examples/hello-world/node_modules/@linyjs/server-module-interface/src/di.ts +127 -0
  62. package/examples/hello-world/node_modules/@linyjs/server-module-interface/src/domain.ts +75 -0
  63. package/examples/hello-world/node_modules/@linyjs/server-module-interface/src/index.ts +55 -0
  64. package/examples/hello-world/node_modules/@linyjs/server-module-interface/src/interfaces.ts +58 -0
  65. package/examples/hello-world/node_modules/@linyjs/server-module-interface/tsconfig.json +8 -0
  66. package/examples/hello-world/node_modules/@types/react/LICENSE +21 -0
  67. package/examples/hello-world/node_modules/@types/react/README.md +15 -0
  68. package/examples/hello-world/node_modules/@types/react/canary.d.ts +129 -0
  69. package/examples/hello-world/node_modules/@types/react/compiler-runtime.d.ts +4 -0
  70. package/examples/hello-world/node_modules/@types/react/experimental.d.ts +184 -0
  71. package/examples/hello-world/node_modules/@types/react/global.d.ts +166 -0
  72. package/examples/hello-world/node_modules/@types/react/index.d.ts +4369 -0
  73. package/examples/hello-world/node_modules/@types/react/jsx-dev-runtime.d.ts +33 -0
  74. package/examples/hello-world/node_modules/@types/react/jsx-runtime.d.ts +24 -0
  75. package/examples/hello-world/node_modules/@types/react/package.json +210 -0
  76. package/examples/hello-world/node_modules/@types/react/ts5.0/canary.d.ts +129 -0
  77. package/examples/hello-world/node_modules/@types/react/ts5.0/experimental.d.ts +184 -0
  78. package/examples/hello-world/node_modules/@types/react/ts5.0/global.d.ts +166 -0
  79. package/examples/hello-world/node_modules/@types/react/ts5.0/index.d.ts +4356 -0
  80. package/examples/hello-world/node_modules/@types/react/ts5.0/jsx-dev-runtime.d.ts +33 -0
  81. package/examples/hello-world/node_modules/@types/react/ts5.0/jsx-runtime.d.ts +24 -0
  82. package/examples/hello-world/node_modules/csstype/LICENSE +19 -0
  83. package/examples/hello-world/node_modules/csstype/README.md +291 -0
  84. package/examples/hello-world/node_modules/csstype/index.d.ts +22569 -0
  85. package/examples/hello-world/node_modules/csstype/index.js.flow +6863 -0
  86. package/examples/hello-world/node_modules/csstype/package.json +70 -0
  87. package/examples/hello-world/node_modules/react/LICENSE +21 -0
  88. package/examples/hello-world/node_modules/react/README.md +37 -0
  89. package/examples/hello-world/node_modules/react/cjs/react-compiler-runtime.development.js +24 -0
  90. package/examples/hello-world/node_modules/react/cjs/react-compiler-runtime.production.js +16 -0
  91. package/examples/hello-world/node_modules/react/cjs/react-compiler-runtime.profiling.js +16 -0
  92. package/examples/hello-world/node_modules/react/cjs/react-jsx-dev-runtime.development.js +338 -0
  93. package/examples/hello-world/node_modules/react/cjs/react-jsx-dev-runtime.production.js +14 -0
  94. package/examples/hello-world/node_modules/react/cjs/react-jsx-dev-runtime.profiling.js +14 -0
  95. package/examples/hello-world/node_modules/react/cjs/react-jsx-dev-runtime.react-server.development.js +370 -0
  96. package/examples/hello-world/node_modules/react/cjs/react-jsx-dev-runtime.react-server.production.js +40 -0
  97. package/examples/hello-world/node_modules/react/cjs/react-jsx-runtime.development.js +352 -0
  98. package/examples/hello-world/node_modules/react/cjs/react-jsx-runtime.production.js +34 -0
  99. package/examples/hello-world/node_modules/react/cjs/react-jsx-runtime.profiling.js +34 -0
  100. package/examples/hello-world/node_modules/react/cjs/react-jsx-runtime.react-server.development.js +370 -0
  101. package/examples/hello-world/node_modules/react/cjs/react-jsx-runtime.react-server.production.js +40 -0
  102. package/examples/hello-world/node_modules/react/cjs/react.development.js +1284 -0
  103. package/examples/hello-world/node_modules/react/cjs/react.production.js +542 -0
  104. package/examples/hello-world/node_modules/react/cjs/react.react-server.development.js +848 -0
  105. package/examples/hello-world/node_modules/react/cjs/react.react-server.production.js +423 -0
  106. package/examples/hello-world/node_modules/react/compiler-runtime.js +14 -0
  107. package/examples/hello-world/node_modules/react/index.js +7 -0
  108. package/examples/hello-world/node_modules/react/jsx-dev-runtime.js +7 -0
  109. package/examples/hello-world/node_modules/react/jsx-dev-runtime.react-server.js +7 -0
  110. package/examples/hello-world/node_modules/react/jsx-runtime.js +7 -0
  111. package/examples/hello-world/node_modules/react/jsx-runtime.react-server.js +7 -0
  112. package/examples/hello-world/node_modules/react/package.json +51 -0
  113. package/examples/hello-world/node_modules/react/react.react-server.js +7 -0
  114. package/examples/hello-world/node_modules/typescript/LICENSE.txt +55 -0
  115. package/examples/hello-world/node_modules/typescript/README.md +50 -0
  116. package/examples/hello-world/node_modules/typescript/SECURITY.md +41 -0
  117. package/examples/hello-world/node_modules/typescript/ThirdPartyNoticeText.txt +193 -0
  118. package/examples/hello-world/node_modules/typescript/bin/tsc +2 -0
  119. package/examples/hello-world/node_modules/typescript/bin/tsserver +2 -0
  120. package/examples/hello-world/node_modules/typescript/lib/_tsc.js +133818 -0
  121. package/examples/hello-world/node_modules/typescript/lib/_tsserver.js +659 -0
  122. package/examples/hello-world/node_modules/typescript/lib/_typingsInstaller.js +222 -0
  123. package/examples/hello-world/node_modules/typescript/lib/cs/diagnosticMessages.generated.json +2122 -0
  124. package/examples/hello-world/node_modules/typescript/lib/de/diagnosticMessages.generated.json +2122 -0
  125. package/examples/hello-world/node_modules/typescript/lib/es/diagnosticMessages.generated.json +2122 -0
  126. package/examples/hello-world/node_modules/typescript/lib/fr/diagnosticMessages.generated.json +2122 -0
  127. package/examples/hello-world/node_modules/typescript/lib/it/diagnosticMessages.generated.json +2122 -0
  128. package/examples/hello-world/node_modules/typescript/lib/ja/diagnosticMessages.generated.json +2122 -0
  129. package/examples/hello-world/node_modules/typescript/lib/ko/diagnosticMessages.generated.json +2122 -0
  130. package/examples/hello-world/node_modules/typescript/lib/lib.d.ts +22 -0
  131. package/examples/hello-world/node_modules/typescript/lib/lib.decorators.d.ts +384 -0
  132. package/examples/hello-world/node_modules/typescript/lib/lib.decorators.legacy.d.ts +22 -0
  133. package/examples/hello-world/node_modules/typescript/lib/lib.dom.asynciterable.d.ts +41 -0
  134. package/examples/hello-world/node_modules/typescript/lib/lib.dom.d.ts +39429 -0
  135. package/examples/hello-world/node_modules/typescript/lib/lib.dom.iterable.d.ts +571 -0
  136. package/examples/hello-world/node_modules/typescript/lib/lib.es2015.collection.d.ts +147 -0
  137. package/examples/hello-world/node_modules/typescript/lib/lib.es2015.core.d.ts +597 -0
  138. package/examples/hello-world/node_modules/typescript/lib/lib.es2015.d.ts +28 -0
  139. package/examples/hello-world/node_modules/typescript/lib/lib.es2015.generator.d.ts +77 -0
  140. package/examples/hello-world/node_modules/typescript/lib/lib.es2015.iterable.d.ts +605 -0
  141. package/examples/hello-world/node_modules/typescript/lib/lib.es2015.promise.d.ts +81 -0
  142. package/examples/hello-world/node_modules/typescript/lib/lib.es2015.proxy.d.ts +128 -0
  143. package/examples/hello-world/node_modules/typescript/lib/lib.es2015.reflect.d.ts +144 -0
  144. package/examples/hello-world/node_modules/typescript/lib/lib.es2015.symbol.d.ts +46 -0
  145. package/examples/hello-world/node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts +326 -0
  146. package/examples/hello-world/node_modules/typescript/lib/lib.es2016.array.include.d.ts +116 -0
  147. package/examples/hello-world/node_modules/typescript/lib/lib.es2016.d.ts +21 -0
  148. package/examples/hello-world/node_modules/typescript/lib/lib.es2016.full.d.ts +23 -0
  149. package/examples/hello-world/node_modules/typescript/lib/lib.es2016.intl.d.ts +31 -0
  150. package/examples/hello-world/node_modules/typescript/lib/lib.es2017.arraybuffer.d.ts +21 -0
  151. package/examples/hello-world/node_modules/typescript/lib/lib.es2017.d.ts +26 -0
  152. package/examples/hello-world/node_modules/typescript/lib/lib.es2017.date.d.ts +31 -0
  153. package/examples/hello-world/node_modules/typescript/lib/lib.es2017.full.d.ts +23 -0
  154. package/examples/hello-world/node_modules/typescript/lib/lib.es2017.intl.d.ts +44 -0
  155. package/examples/hello-world/node_modules/typescript/lib/lib.es2017.object.d.ts +49 -0
  156. package/examples/hello-world/node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts +135 -0
  157. package/examples/hello-world/node_modules/typescript/lib/lib.es2017.string.d.ts +45 -0
  158. package/examples/hello-world/node_modules/typescript/lib/lib.es2017.typedarrays.d.ts +53 -0
  159. package/examples/hello-world/node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts +77 -0
  160. package/examples/hello-world/node_modules/typescript/lib/lib.es2018.asynciterable.d.ts +53 -0
  161. package/examples/hello-world/node_modules/typescript/lib/lib.es2018.d.ts +24 -0
  162. package/examples/hello-world/node_modules/typescript/lib/lib.es2018.full.d.ts +24 -0
  163. package/examples/hello-world/node_modules/typescript/lib/lib.es2018.intl.d.ts +83 -0
  164. package/examples/hello-world/node_modules/typescript/lib/lib.es2018.promise.d.ts +30 -0
  165. package/examples/hello-world/node_modules/typescript/lib/lib.es2018.regexp.d.ts +37 -0
  166. package/examples/hello-world/node_modules/typescript/lib/lib.es2019.array.d.ts +79 -0
  167. package/examples/hello-world/node_modules/typescript/lib/lib.es2019.d.ts +24 -0
  168. package/examples/hello-world/node_modules/typescript/lib/lib.es2019.full.d.ts +24 -0
  169. package/examples/hello-world/node_modules/typescript/lib/lib.es2019.intl.d.ts +23 -0
  170. package/examples/hello-world/node_modules/typescript/lib/lib.es2019.object.d.ts +33 -0
  171. package/examples/hello-world/node_modules/typescript/lib/lib.es2019.string.d.ts +37 -0
  172. package/examples/hello-world/node_modules/typescript/lib/lib.es2019.symbol.d.ts +24 -0
  173. package/examples/hello-world/node_modules/typescript/lib/lib.es2020.bigint.d.ts +765 -0
  174. package/examples/hello-world/node_modules/typescript/lib/lib.es2020.d.ts +27 -0
  175. package/examples/hello-world/node_modules/typescript/lib/lib.es2020.date.d.ts +42 -0
  176. package/examples/hello-world/node_modules/typescript/lib/lib.es2020.full.d.ts +24 -0
  177. package/examples/hello-world/node_modules/typescript/lib/lib.es2020.intl.d.ts +474 -0
  178. package/examples/hello-world/node_modules/typescript/lib/lib.es2020.number.d.ts +28 -0
  179. package/examples/hello-world/node_modules/typescript/lib/lib.es2020.promise.d.ts +47 -0
  180. package/examples/hello-world/node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts +99 -0
  181. package/examples/hello-world/node_modules/typescript/lib/lib.es2020.string.d.ts +44 -0
  182. package/examples/hello-world/node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts +41 -0
  183. package/examples/hello-world/node_modules/typescript/lib/lib.es2021.d.ts +23 -0
  184. package/examples/hello-world/node_modules/typescript/lib/lib.es2021.full.d.ts +24 -0
  185. package/examples/hello-world/node_modules/typescript/lib/lib.es2021.intl.d.ts +166 -0
  186. package/examples/hello-world/node_modules/typescript/lib/lib.es2021.promise.d.ts +48 -0
  187. package/examples/hello-world/node_modules/typescript/lib/lib.es2021.string.d.ts +33 -0
  188. package/examples/hello-world/node_modules/typescript/lib/lib.es2021.weakref.d.ts +78 -0
  189. package/examples/hello-world/node_modules/typescript/lib/lib.es2022.array.d.ts +121 -0
  190. package/examples/hello-world/node_modules/typescript/lib/lib.es2022.d.ts +25 -0
  191. package/examples/hello-world/node_modules/typescript/lib/lib.es2022.error.d.ts +75 -0
  192. package/examples/hello-world/node_modules/typescript/lib/lib.es2022.full.d.ts +24 -0
  193. package/examples/hello-world/node_modules/typescript/lib/lib.es2022.intl.d.ts +145 -0
  194. package/examples/hello-world/node_modules/typescript/lib/lib.es2022.object.d.ts +26 -0
  195. package/examples/hello-world/node_modules/typescript/lib/lib.es2022.regexp.d.ts +39 -0
  196. package/examples/hello-world/node_modules/typescript/lib/lib.es2022.string.d.ts +25 -0
  197. package/examples/hello-world/node_modules/typescript/lib/lib.es2023.array.d.ts +924 -0
  198. package/examples/hello-world/node_modules/typescript/lib/lib.es2023.collection.d.ts +21 -0
  199. package/examples/hello-world/node_modules/typescript/lib/lib.es2023.d.ts +22 -0
  200. package/examples/hello-world/node_modules/typescript/lib/lib.es2023.full.d.ts +24 -0
  201. package/examples/hello-world/node_modules/typescript/lib/lib.es2023.intl.d.ts +56 -0
  202. package/examples/hello-world/node_modules/typescript/lib/lib.es2024.arraybuffer.d.ts +65 -0
  203. package/examples/hello-world/node_modules/typescript/lib/lib.es2024.collection.d.ts +29 -0
  204. package/examples/hello-world/node_modules/typescript/lib/lib.es2024.d.ts +26 -0
  205. package/examples/hello-world/node_modules/typescript/lib/lib.es2024.full.d.ts +24 -0
  206. package/examples/hello-world/node_modules/typescript/lib/lib.es2024.object.d.ts +29 -0
  207. package/examples/hello-world/node_modules/typescript/lib/lib.es2024.promise.d.ts +35 -0
  208. package/examples/hello-world/node_modules/typescript/lib/lib.es2024.regexp.d.ts +25 -0
  209. package/examples/hello-world/node_modules/typescript/lib/lib.es2024.sharedmemory.d.ts +68 -0
  210. package/examples/hello-world/node_modules/typescript/lib/lib.es2024.string.d.ts +29 -0
  211. package/examples/hello-world/node_modules/typescript/lib/lib.es5.d.ts +4601 -0
  212. package/examples/hello-world/node_modules/typescript/lib/lib.es6.d.ts +23 -0
  213. package/examples/hello-world/node_modules/typescript/lib/lib.esnext.array.d.ts +35 -0
  214. package/examples/hello-world/node_modules/typescript/lib/lib.esnext.collection.d.ts +96 -0
  215. package/examples/hello-world/node_modules/typescript/lib/lib.esnext.d.ts +29 -0
  216. package/examples/hello-world/node_modules/typescript/lib/lib.esnext.decorators.d.ts +28 -0
  217. package/examples/hello-world/node_modules/typescript/lib/lib.esnext.disposable.d.ts +193 -0
  218. package/examples/hello-world/node_modules/typescript/lib/lib.esnext.error.d.ts +24 -0
  219. package/examples/hello-world/node_modules/typescript/lib/lib.esnext.float16.d.ts +445 -0
  220. package/examples/hello-world/node_modules/typescript/lib/lib.esnext.full.d.ts +24 -0
  221. package/examples/hello-world/node_modules/typescript/lib/lib.esnext.intl.d.ts +21 -0
  222. package/examples/hello-world/node_modules/typescript/lib/lib.esnext.iterator.d.ts +148 -0
  223. package/examples/hello-world/node_modules/typescript/lib/lib.esnext.promise.d.ts +34 -0
  224. package/examples/hello-world/node_modules/typescript/lib/lib.esnext.sharedmemory.d.ts +25 -0
  225. package/examples/hello-world/node_modules/typescript/lib/lib.scripthost.d.ts +322 -0
  226. package/examples/hello-world/node_modules/typescript/lib/lib.webworker.asynciterable.d.ts +41 -0
  227. package/examples/hello-world/node_modules/typescript/lib/lib.webworker.d.ts +13150 -0
  228. package/examples/hello-world/node_modules/typescript/lib/lib.webworker.importscripts.d.ts +23 -0
  229. package/examples/hello-world/node_modules/typescript/lib/lib.webworker.iterable.d.ts +340 -0
  230. package/examples/hello-world/node_modules/typescript/lib/pl/diagnosticMessages.generated.json +2122 -0
  231. package/examples/hello-world/node_modules/typescript/lib/pt-br/diagnosticMessages.generated.json +2122 -0
  232. package/examples/hello-world/node_modules/typescript/lib/ru/diagnosticMessages.generated.json +2122 -0
  233. package/examples/hello-world/node_modules/typescript/lib/tr/diagnosticMessages.generated.json +2122 -0
  234. package/examples/hello-world/node_modules/typescript/lib/tsc.js +8 -0
  235. package/examples/hello-world/node_modules/typescript/lib/tsserver.js +8 -0
  236. package/examples/hello-world/node_modules/typescript/lib/tsserverlibrary.d.ts +17 -0
  237. package/examples/hello-world/node_modules/typescript/lib/tsserverlibrary.js +21 -0
  238. package/examples/hello-world/node_modules/typescript/lib/typesMap.json +497 -0
  239. package/examples/hello-world/node_modules/typescript/lib/typescript.d.ts +11437 -0
  240. package/examples/hello-world/node_modules/typescript/lib/typescript.js +200276 -0
  241. package/examples/hello-world/node_modules/typescript/lib/typingsInstaller.js +8 -0
  242. package/examples/hello-world/node_modules/typescript/lib/watchGuard.js +53 -0
  243. package/examples/hello-world/node_modules/typescript/lib/zh-cn/diagnosticMessages.generated.json +2122 -0
  244. package/examples/hello-world/node_modules/typescript/lib/zh-tw/diagnosticMessages.generated.json +2122 -0
  245. package/examples/hello-world/node_modules/typescript/package.json +120 -0
  246. package/examples/hello-world/package-lock.json +74 -0
  247. package/examples/hello-world/package.json +23 -0
  248. package/examples/hello-world/src/client/index.tsx +110 -0
  249. package/examples/hello-world/src/server/index.ts +42 -0
  250. package/examples/hello-world/tsconfig.json +16 -0
  251. package/package.json +42 -0
  252. package/src/cli.ts +321 -0
package/docs/faq.md ADDED
@@ -0,0 +1,323 @@
1
+ # 常见问题 (FAQ)
2
+
3
+ ## 入门相关
4
+
5
+ ### Q1: linyjs 是什么?
6
+
7
+ **A:** linyjs 是一个插件式的前后端应用平台,允许开发者通过创建 `.mpk` 格式的插件来扩展平台功能。它提供了完整的前后端开发框架,包括依赖注入、权限控制、UI扩展等特性。
8
+
9
+ ### Q2: 我需要哪些前置知识?
10
+
11
+ **A:**
12
+ - TypeScript (必需)
13
+ - React (客户端开发)
14
+ - Node.js (服务端开发)
15
+ - 基本的 HTTP/API 概念
16
+
17
+ ### Q3: 如何开始第一个插件?
18
+
19
+ **A:** 阅读 [快速开始](./getting-started/quick-start.md) 教程,5分钟即可创建你的第一个插件!
20
+
21
+ ---
22
+
23
+ ## 安装和配置
24
+
25
+ ### Q4: 如何安装 linyjs CLI 工具?
26
+
27
+ **A:**
28
+ ```bash
29
+ # 全局安装(推荐)
30
+ npm install -g @linyjs/cli
31
+
32
+ # 或使用 npx
33
+ npx @linyjs/cli <command>
34
+ ```
35
+
36
+ ### Q5: TypeScript 编译错误怎么办?
37
+
38
+ **A:** 确保:
39
+ 1. 安装了正确版本的 TypeScript (`^5.7.0`)
40
+ 2. `tsconfig.json` 配置正确
41
+ 3. 所有类型定义包已安装 (`@types/react` 等)
42
+
43
+ ### Q6: 如何更新到最新版本?
44
+
45
+ **A:**
46
+ ```bash
47
+ npm update @linyjs/server-module-interface
48
+ npm update @linyjs/client-module-interface
49
+ npm update @linyjs/cli
50
+ ```
51
+
52
+ ---
53
+
54
+ ## 开发相关
55
+
56
+ ### Q7: 如何调试插件?
57
+
58
+ **A:**
59
+
60
+ **方法 1: 使用 tsx 运行**
61
+ ```bash
62
+ npx tsx src/server/index.ts
63
+ ```
64
+
65
+ **方法 2: 添加日志**
66
+ ```typescript
67
+ console.log('[MyPlugin]', 'Debug info:', data);
68
+ ```
69
+
70
+ **方法 3: 浏览器 DevTools**
71
+ 客户端代码可以在浏览器中调试。
72
+
73
+ ### Q8: 插件之间如何通信?
74
+
75
+ **A:**
76
+
77
+ **方式 1: 通过共享服务**
78
+ ```typescript
79
+ // 插件 A 提供服务
80
+ export const serviceA = {
81
+ serviceTag: 'sharedService',
82
+ serviceImpl: SharedService
83
+ };
84
+
85
+ // 插件 B 使用服务
86
+ export const serviceB = {
87
+ serviceTag: 'consumer',
88
+ serviceImpl: ConsumerService,
89
+ dependencies: ['pluginA.sharedService']
90
+ };
91
+ ```
92
+
93
+ **方式 2: 通过全局状态**
94
+ 使用 jotai atoms 共享状态。
95
+
96
+ ### Q9: 如何处理插件版本兼容性?
97
+
98
+ **A:** 在 `manifest.json` 中指定依赖版本:
99
+ ```json
100
+ {
101
+ "dependencies": {
102
+ "core-auth": "^1.0.0",
103
+ "core-mongodb": ">=1.2.0"
104
+ }
105
+ }
106
+ ```
107
+
108
+ ### Q10: 插件可以修改其他插件的行为吗?
109
+
110
+ **A:** 可以通过以下方式:
111
+ 1. **覆盖路由**: 注册相同路径的路由(后加载的优先)
112
+ 2. **扩展 Slot**: 向现有 Slot 添加新组件
113
+ 3. **装饰器模式**: 包装其他插件的服务
114
+
115
+ ---
116
+
117
+ ## 打包和发布
118
+
119
+ ### Q11: 如何打包插件?
120
+
121
+ **A:** 使用 CLI 工具:
122
+ ```bash
123
+ cd my-plugin
124
+ npx @linyjs/cli pack
125
+ ```
126
+
127
+ 这将自动完成:构建、生成 manifest、验证结构、打包压缩。
128
+
129
+ ### Q12: .mpk 文件是什么格式?
130
+
131
+ **A:** `.mpk` 是 ZIP 压缩格式,包含:
132
+ ```
133
+ my-plugin.mpk (ZIP)
134
+ ├── manifest.json # 插件清单
135
+ ├── server/ # 服务端模块
136
+ │ └── index.js # 编译后的 JS
137
+ ├── client/ # 客户端模块
138
+ │ └── index.js # 编译后的 JS
139
+ └── assets/ # 静态资源
140
+ ```
141
+
142
+ ### Q13: 如何测试插件?
143
+
144
+ **A:**
145
+ ```bash
146
+ # 将插件复制到 extensions 目录
147
+ cp my-plugin.mpk /path/to/linyjs/packages/ssr/extensions/
148
+
149
+ # 启动 SSR 服务器
150
+ cd /path/to/linyjs/packages/ssr
151
+ npx tsx src/demo/dev-server-with-pkg.tsx
152
+ ```
153
+
154
+ ---
155
+
156
+ ## 高级主题
157
+
158
+ ### Q14: 为什么我的插件无法访问 React Context?
159
+
160
+ **A:** 这通常是因为 React 实例不共享导致的。确保:
161
+ 1. CLI 已 external React(默认行为)
162
+ 2. 宿主应用提供了 React(通过 Import Map)
163
+ 3. 所有插件使用同一个 React 版本
164
+
165
+ ```html
166
+ <!-- 宿主应用的 HTML -->
167
+ <script type="importmap">
168
+ {
169
+ "imports": {
170
+ "react": "/vendor/react.production.min.js",
171
+ "react-dom": "/vendor/react-dom.production.min.js"
172
+ }
173
+ }
174
+ </script>
175
+ ```
176
+
177
+ ### Q15: CLI 打包的 Bundle 体积太大怎么办?
178
+
179
+ **A:** CLI 默认启用了优化:
180
+ - ✅ esbuild - 极速构建和小体积
181
+ - ✅ Minification - 代码压缩
182
+ - ✅ Tree Shaking - 移除未使用代码
183
+ - ✅ External Dependencies - React 等由宿主提供
184
+
185
+ 进一步优化:
186
+ ```typescript
187
+ // 使用懒加载
188
+ const HeavyComponent = React.lazy(() => import('./HeavyComponent'))
189
+
190
+ // 代码分割
191
+ import('./module').then(module => {
192
+ // 动态导入
193
+ })
194
+ ```
195
+
196
+ ### Q16: 如何处理插件卸载?
197
+
198
+ **A:** 建议在插件中提供清理逻辑:
199
+ ```typescript
200
+ export function onUninstall() {
201
+ // 清理数据
202
+ db.collection('my_data').deleteMany({ plugin: 'my-plugin' });
203
+ }
204
+ ```
205
+
206
+ ### Q17: 插件可以访问环境变量吗?
207
+
208
+ **A:** 可以,通过 `process.env`:
209
+ ```typescript
210
+ const apiKey = process.env.MY_PLUGIN_API_KEY;
211
+ ```
212
+
213
+ 确保在 `.env` 文件中配置:
214
+ ```bash
215
+ MY_PLUGIN_API_KEY=your-api-key
216
+ ```
217
+
218
+ ---
219
+
220
+ ## 性能和优化
221
+
222
+ ### Q18: 如何优化插件性能?
223
+
224
+ **A:**
225
+ 1. **懒加载组件**
226
+ ```typescript
227
+ const HeavyComponent = React.lazy(() => import('./HeavyComponent'));
228
+ ```
229
+
230
+ 2. **避免不必要的重渲染**
231
+ ```typescript
232
+ import { memo } from 'react';
233
+ const ExpensiveComponent = memo(({ data }) => {
234
+ return <div>{/* ... */}</div>;
235
+ });
236
+ ```
237
+
238
+ 3. **使用缓存**
239
+ ```typescript
240
+ const cachedData = useMemo(() => expensiveCalculation(data), [data]);
241
+ ```
242
+
243
+ ### Q19: 如何减少 Bundle 大小?
244
+
245
+ **A:**
246
+ - 使用 tree shaking(确保使用 ES modules)
247
+ - External 大型依赖(如 lodash)
248
+ - 代码分割和懒加载
249
+ - 压缩图片等资源
250
+
251
+ ---
252
+
253
+ ## 安全性
254
+
255
+ ### Q20: 如何防止 XSS 攻击?
256
+
257
+ **A:**
258
+ ```typescript
259
+ function SafeDisplay({ content }: { content: string }) {
260
+ // 转义 HTML
261
+ const escaped = escapeHtml(content);
262
+ return <div dangerouslySetInnerHTML={{ __html: escaped }} />;
263
+ }
264
+ ```
265
+
266
+ ### Q21: 如何防止 SQL 注入?
267
+
268
+ **A:** 使用参数化查询:
269
+ ```typescript
270
+ // ❌ 不安全
271
+ const user = await db.collection('users').findOne({
272
+ email: userInput // 可能被注入
273
+ });
274
+
275
+ // ✅ 安全(使用 MongoDB 的参数化查询)
276
+ const user = await db.collection('users').findOne({
277
+ email: userInput // MongoDB 会自动处理
278
+ });
279
+ ```
280
+
281
+ ### Q22: 如何验证用户输入?
282
+
283
+ **A:**
284
+ ```typescript
285
+ handler: async (params) => {
286
+ const { email } = params.body;
287
+
288
+ // 验证邮箱格式
289
+ if (!isValidEmail(email)) {
290
+ return {
291
+ status: 400,
292
+ data: { error: 'Invalid email format' }
293
+ };
294
+ }
295
+ }
296
+ ```
297
+
298
+ ---
299
+
300
+ ## 获取帮助
301
+
302
+ ### Q23: 遇到问题怎么办?
303
+
304
+ **A:**
305
+ 1. 📖 查阅本文档和相关指南
306
+ 2. 💡 查看[示例项目](../examples/)
307
+ 3. 🔍 搜索 GitHub Issues
308
+ 4. 💬 在社区论坛提问
309
+ 5. 🐛 报告 Bug: [GitHub Issues](https://github.com/linyjs/linyjs/issues)
310
+
311
+ ### Q24: 如何贡献文档?
312
+
313
+ **A:**
314
+ 1. Fork 仓库
315
+ 2. 修改或添加文档
316
+ 3. 提交 Pull Request
317
+ 4. 等待审查和合并
318
+
319
+ 详见 [CONTRIBUTING.md](../CONTRIBUTING.md)
320
+
321
+ ---
322
+
323
+ **返回**: [文档首页](../README.md)
@@ -0,0 +1,358 @@
1
+ # 第一个插件教程
2
+
3
+ 在本教程中,我们将创建一个完整的博客插件,包含文章的增删改查(CRUD)功能。
4
+
5
+ ## 学习目标
6
+
7
+ 完成本教程后,你将能够:
8
+
9
+ - ✅ 创建服务端 API 控制器
10
+ - ✅ 创建客户端 React 页面
11
+ - ✅ 实现数据持久化(使用内存存储模拟)
12
+ - ✅ 理解插件的完整工作流程
13
+
14
+ ## 项目结构
15
+
16
+ 最终的项目结构如下:
17
+
18
+ ```
19
+ my-blog-plugin/
20
+ ├── package.json
21
+ ├── tsconfig.json
22
+ └── src/
23
+ ├── server/
24
+ │ └── index.ts # 服务端模块
25
+ └── client/
26
+ ├── index.tsx # 客户端模块
27
+ ├── pages/
28
+ │ ├── ArticleList.tsx
29
+ │ └── ArticleDetail.tsx
30
+ └── components/
31
+ └── ArticleCard.tsx
32
+ ```
33
+
34
+ ## 步骤 1: 初始化项目
35
+
36
+ ```bash
37
+ mkdir my-blog-plugin && cd my-blog-plugin
38
+ npm init -y
39
+ npm install @linyjs/server-module-interface @linyjs/client-module-interface react
40
+ npm install -D typescript @types/react
41
+ ```
42
+
43
+ 创建 `tsconfig.json`(参考[安装指南](./installation.md))。
44
+
45
+ ## 步骤 2: 定义数据类型
46
+
47
+ 创建 `src/shared/types.ts`:
48
+
49
+ ```typescript
50
+ export interface Article {
51
+ id: number;
52
+ title: string;
53
+ content: string;
54
+ author: string;
55
+ createdAt: string;
56
+ updatedAt: string;
57
+ }
58
+
59
+ export interface ArticleListResponse {
60
+ data: Article[];
61
+ total: number;
62
+ page: number;
63
+ limit: number;
64
+ totalPages: number;
65
+ }
66
+ ```
67
+
68
+ ## 步骤 3: 创建服务端代码
69
+
70
+ ### 3.1 文章服务
71
+
72
+ 创建 `src/server/services/ArticleService.ts`:
73
+
74
+ ```typescript
75
+ import type { Article } from '../../shared/types';
76
+
77
+ export class ArticleService {
78
+ private articles: Article[] = [];
79
+ private nextId = 1;
80
+
81
+ async getArticles(page = 1, limit = 10) {
82
+ const skip = (page - 1) * limit;
83
+ const total = this.articles.length;
84
+ const items = this.articles.slice(skip, skip + limit);
85
+
86
+ return {
87
+ data: items,
88
+ total,
89
+ page,
90
+ limit,
91
+ totalPages: Math.ceil(total / limit)
92
+ };
93
+ }
94
+
95
+ async getArticleById(id: number): Promise<Article> {
96
+ const article = this.articles.find(a => a.id === id);
97
+ if (!article) {
98
+ throw new Error('Article not found');
99
+ }
100
+ return article;
101
+ }
102
+
103
+ async createArticle(data: Partial<Article>): Promise<Article> {
104
+ const article: Article = {
105
+ id: this.nextId++,
106
+ title: data.title || 'Untitled',
107
+ content: data.content || '',
108
+ author: data.author || 'Anonymous',
109
+ createdAt: new Date().toISOString(),
110
+ updatedAt: new Date().toISOString()
111
+ };
112
+
113
+ this.articles.push(article);
114
+ return article;
115
+ }
116
+
117
+ async updateArticle(id: number, data: Partial<Article>): Promise<Article> {
118
+ const index = this.articles.findIndex(a => a.id === id);
119
+ if (index === -1) {
120
+ throw new Error('Article not found');
121
+ }
122
+
123
+ this.articles[index] = {
124
+ ...this.articles[index],
125
+ ...data,
126
+ updatedAt: new Date().toISOString()
127
+ };
128
+
129
+ return this.articles[index];
130
+ }
131
+
132
+ async deleteArticle(id: number): Promise<void> {
133
+ const index = this.articles.findIndex(a => a.id === id);
134
+ if (index === -1) {
135
+ throw new Error('Article not found');
136
+ }
137
+ this.articles.splice(index, 1);
138
+ }
139
+ }
140
+ ```
141
+
142
+ ### 3.2 文章控制器
143
+
144
+ 创建 `src/server/controllers/ArticleController.ts`:
145
+
146
+ ```typescript
147
+ import type { IControllerService } from '@linyjs/server-module-interface';
148
+ import { ArticleService } from '../services/ArticleService';
149
+
150
+ export class ArticleController implements IControllerService {
151
+ private articleService: ArticleService;
152
+
153
+ constructor() {
154
+ this.articleService = new ArticleService();
155
+ }
156
+
157
+ getRoutes() {
158
+ return [
159
+ {
160
+ method: 'GET' as const,
161
+ path: '/api/articles',
162
+ middlewares: [],
163
+ responseType: 'json' as const,
164
+ handler: async (params: any) => {
165
+ const page = parseInt(params.query?.page || '1');
166
+ const limit = parseInt(params.query?.limit || '10');
167
+ return await this.articleService.getArticles(page, limit);
168
+ }
169
+ },
170
+ {
171
+ method: 'POST' as const,
172
+ path: '/api/articles',
173
+ middlewares: [],
174
+ responseType: 'json' as const,
175
+ handler: async (params: any) => {
176
+ const article = await this.articleService.createArticle(params.body);
177
+ return { success: true, data: article };
178
+ }
179
+ }
180
+ // 添加更多路由...
181
+ ];
182
+ }
183
+ }
184
+ ```
185
+
186
+ ### 3.3 服务端模块入口
187
+
188
+ 创建 `src/server/index.ts`:
189
+
190
+ ```typescript
191
+ import type { IModule } from '@linyjs/server-module-interface';
192
+ import { ArticleController } from './controllers/ArticleController';
193
+
194
+ export const blogServerModule: IModule = {
195
+ name: 'blogServer',
196
+ serviceDefs: [
197
+ {
198
+ serviceTag: 'articleController',
199
+ serviceImpl: ArticleController,
200
+ meta: { usageType: 'controller' }
201
+ }
202
+ ]
203
+ };
204
+ ```
205
+
206
+ ## 步骤 4: 创建客户端代码
207
+
208
+ ### 4.1 文章列表组件
209
+
210
+ 创建 `src/client/components/ArticleCard.tsx`:
211
+
212
+ ```typescript
213
+ import React from 'react';
214
+ import type { Article } from '../../shared/types';
215
+
216
+ interface ArticleCardProps {
217
+ article: Article;
218
+ onClick?: () => void;
219
+ }
220
+
221
+ export function ArticleCard({ article, onClick }: ArticleCardProps) {
222
+ return (
223
+ <div
224
+ style={{
225
+ border: '1px solid #ddd',
226
+ borderRadius: '8px',
227
+ padding: '16px',
228
+ marginBottom: '16px',
229
+ cursor: onClick ? 'pointer' : 'default'
230
+ }}
231
+ onClick={onClick}
232
+ >
233
+ <h3 style={{ margin: '0 0 8px 0' }}>{article.title}</h3>
234
+ <p style={{ color: '#666', margin: '0 0 8px 0' }}>
235
+ By {article.author} • {new Date(article.createdAt).toLocaleDateString()}
236
+ </p>
237
+ <p style={{ margin: 0 }}>{article.content.substring(0, 100)}...</p>
238
+ </div>
239
+ );
240
+ }
241
+ ```
242
+
243
+ ### 4.2 文章列表页面
244
+
245
+ 创建 `src/client/pages/ArticleList.tsx`:
246
+
247
+ ```typescript
248
+ import React, { useState, useEffect } from 'react';
249
+ import type { Article, ArticleListResponse } from '../../shared/types';
250
+ import { ArticleCard } from '../components/ArticleCard';
251
+
252
+ export function ArticleList() {
253
+ const [articles, setArticles] = useState<Article[]>([]);
254
+ const [loading, setLoading] = useState(true);
255
+
256
+ useEffect(() => {
257
+ fetch('/api/articles')
258
+ .then(res => res.json())
259
+ .then((data: ArticleListResponse) => {
260
+ setArticles(data.data);
261
+ setLoading(false);
262
+ })
263
+ .catch(err => {
264
+ console.error('Failed to fetch articles:', err);
265
+ setLoading(false);
266
+ });
267
+ }, []);
268
+
269
+ if (loading) {
270
+ return <div>Loading...</div>;
271
+ }
272
+
273
+ return (
274
+ <div style={{ padding: '20px' }}>
275
+ <h1>Blog Articles</h1>
276
+ {articles.length === 0 ? (
277
+ <p>No articles yet.</p>
278
+ ) : (
279
+ articles.map(article => (
280
+ <ArticleCard key={article.id} article={article} />
281
+ ))
282
+ )}
283
+ </div>
284
+ );
285
+ }
286
+ ```
287
+
288
+ ### 4.3 客户端模块入口
289
+
290
+ 创建 `src/client/index.tsx`:
291
+
292
+ ```typescript
293
+ import type { IModule } from '@linyjs/client-module-interface';
294
+ import { ArticleList } from './pages/ArticleList';
295
+
296
+ class BlogRouteService {
297
+ basePath = '/blog';
298
+
299
+ getRoutes() {
300
+ return [
301
+ {
302
+ path: '/',
303
+ component: ArticleList,
304
+ key: 'article-list',
305
+ meta: { title: 'Blog' }
306
+ }
307
+ ];
308
+ }
309
+ }
310
+
311
+ export const blogClientModule: IModule = {
312
+ name: 'blogClient',
313
+ serviceDefs: [
314
+ {
315
+ serviceTag: 'blogRoute',
316
+ serviceImpl: BlogRouteService,
317
+ meta: { usageType: 'route' }
318
+ }
319
+ ]
320
+ };
321
+ ```
322
+
323
+ ## 步骤 5: 构建和测试
324
+
325
+ ```bash
326
+ # 编译 TypeScript
327
+ npx tsc
328
+
329
+ # 打包为 .mpk
330
+ npx @linyjs/cli pack
331
+
332
+ # 测试插件
333
+ cp my-blog-plugin.mpk /path/to/linyjs/packages/ssr/extensions/
334
+ cd /path/to/linyjs/packages/ssr
335
+ npx tsx src/demo/dev-server-with-pkg.tsx
336
+ ```
337
+
338
+ 访问 `http://localhost:3000/blog` 查看你的博客插件!
339
+
340
+ ## 扩展功能
341
+
342
+ 现在你已经有了基础框架,可以尝试添加:
343
+
344
+ - 📝 文章详情页面
345
+ - ✏️ 文章编辑功能
346
+ - 🗑️ 文章删除功能
347
+ - 🔍 文章搜索功能
348
+ - 👤 用户认证和权限控制
349
+
350
+ ## 下一步
351
+
352
+ - 📖 阅读 [服务端模块开发](../guides/server-module.md) 深入学习后端开发
353
+ - 💻 阅读 [客户端模块开发](../guides/client-module.md) 学习前端开发
354
+ - 💾 阅读 [数据持久化](../guides/data-persistence.md) 学习如何使用 MongoDB
355
+
356
+ ---
357
+
358
+ **上一篇**: [安装指南](./installation.md) | **下一篇**: [服务端模块开发](../guides/server-module.md)