@modern-js/module-tools-docs 2.59.0 → 2.60.1

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 (207) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/doc_build/404.html +17 -0
  3. package/doc_build/api/config/build-config.html +1217 -0
  4. package/doc_build/api/config/build-preset.html +211 -0
  5. package/doc_build/api/config/dev.html +63 -0
  6. package/doc_build/api/config/plugins.html +54 -0
  7. package/doc_build/api/index.html +17 -0
  8. package/doc_build/api/plugin-api/plugin-hooks.html +395 -0
  9. package/doc_build/components/faq-build-exception.html +17 -0
  10. package/doc_build/components/faq-build-other.html +17 -0
  11. package/doc_build/components/faq-build-product.html +17 -0
  12. package/doc_build/components/faq-storybook.html +17 -0
  13. package/doc_build/components/publish-emo.html +17 -0
  14. package/doc_build/components/register-esbuild-plugin.html +27 -0
  15. package/doc_build/components/release-module-doc.html +17 -0
  16. package/doc_build/en/api/config/build-config.html +1220 -0
  17. package/doc_build/en/api/config/build-preset.html +206 -0
  18. package/doc_build/en/api/config/dev.html +63 -0
  19. package/doc_build/en/api/config/plugins.html +54 -0
  20. package/doc_build/en/api/index.html +17 -0
  21. package/doc_build/en/api/plugin-api/plugin-hooks.html +399 -0
  22. package/doc_build/en/components/faq-build-exception.html +17 -0
  23. package/doc_build/en/components/faq-build-other.html +17 -0
  24. package/doc_build/en/components/faq-build-product.html +17 -0
  25. package/doc_build/en/components/faq-storybook.html +17 -0
  26. package/doc_build/en/components/publish-emo.html +17 -0
  27. package/doc_build/en/components/register-esbuild-plugin.html +27 -0
  28. package/doc_build/en/components/release-module-doc.html +17 -0
  29. package/doc_build/en/guide/advance/asset.html +58 -0
  30. package/doc_build/en/guide/advance/build-umd.html +166 -0
  31. package/doc_build/en/guide/advance/copy.html +208 -0
  32. package/doc_build/en/guide/advance/external-dependency.html +62 -0
  33. package/doc_build/en/guide/advance/in-depth-about-build.html +302 -0
  34. package/doc_build/en/guide/advance/in-depth-about-dev-command.html +68 -0
  35. package/doc_build/en/guide/basic/before-getting-started.html +139 -0
  36. package/doc_build/en/guide/basic/command-preview.html +131 -0
  37. package/doc_build/en/guide/basic/modify-output-product.html +133 -0
  38. package/doc_build/en/guide/basic/publish-your-project.html +100 -0
  39. package/doc_build/en/guide/basic/use-micro-generator.html +54 -0
  40. package/doc_build/en/guide/basic/use-module-doc.html +397 -0
  41. package/doc_build/en/guide/basic/using-storybook.html +168 -0
  42. package/doc_build/en/guide/best-practices/components.html +198 -0
  43. package/doc_build/en/guide/best-practices/use-tailwindcss.html +243 -0
  44. package/doc_build/en/guide/faq/basic.html +23 -0
  45. package/doc_build/en/guide/faq/build.html +237 -0
  46. package/doc_build/en/guide/faq/index.html +23 -0
  47. package/doc_build/en/guide/faq/storybook.html +85 -0
  48. package/doc_build/en/guide/intro/getting-started.html +92 -0
  49. package/doc_build/en/guide/intro/welcome.html +27 -0
  50. package/doc_build/en/guide/intro/why-module-engineering-solution.html +25 -0
  51. package/doc_build/en/index.html +17 -0
  52. package/doc_build/en/plugins/guide/getting-started.html +70 -0
  53. package/doc_build/en/plugins/guide/plugin-object.html +74 -0
  54. package/doc_build/en/plugins/guide/setup-function.html +96 -0
  55. package/doc_build/en/plugins/official-list/overview.html +26 -0
  56. package/doc_build/en/plugins/official-list/plugin-babel.html +65 -0
  57. package/doc_build/en/plugins/official-list/plugin-banner.html +91 -0
  58. package/doc_build/en/plugins/official-list/plugin-import.html +111 -0
  59. package/doc_build/en/plugins/official-list/plugin-node-polyfill.html +128 -0
  60. package/doc_build/en/plugins/official-list/plugin-polyfill.html +72 -0
  61. package/doc_build/en/plugins/official-list/plugin-vue.html +66 -0
  62. package/doc_build/guide/advance/asset.html +55 -0
  63. package/doc_build/guide/advance/build-umd.html +170 -0
  64. package/doc_build/guide/advance/copy.html +208 -0
  65. package/doc_build/guide/advance/external-dependency.html +61 -0
  66. package/doc_build/guide/advance/in-depth-about-build.html +300 -0
  67. package/doc_build/guide/advance/in-depth-about-dev-command.html +68 -0
  68. package/doc_build/guide/basic/before-getting-started.html +139 -0
  69. package/doc_build/guide/basic/command-preview.html +131 -0
  70. package/doc_build/guide/basic/modify-output-product.html +134 -0
  71. package/doc_build/guide/basic/publish-your-project.html +99 -0
  72. package/doc_build/guide/basic/use-micro-generator.html +54 -0
  73. package/doc_build/guide/basic/use-module-doc.html +395 -0
  74. package/doc_build/guide/basic/using-storybook.html +177 -0
  75. package/doc_build/guide/best-practices/components.html +198 -0
  76. package/doc_build/guide/best-practices/use-tailwindcss.html +243 -0
  77. package/doc_build/guide/faq/basic.html +23 -0
  78. package/doc_build/guide/faq/build.html +234 -0
  79. package/doc_build/guide/faq/index.html +23 -0
  80. package/doc_build/guide/faq/storybook.html +85 -0
  81. package/doc_build/guide/intro/getting-started.html +89 -0
  82. package/doc_build/guide/intro/welcome.html +27 -0
  83. package/doc_build/guide/intro/why-module-engineering-solution.html +25 -0
  84. package/doc_build/index.html +17 -0
  85. package/doc_build/plugins/guide/getting-started.html +70 -0
  86. package/doc_build/plugins/guide/plugin-object.html +74 -0
  87. package/doc_build/plugins/guide/setup-function.html +95 -0
  88. package/doc_build/plugins/official-list/overview.html +26 -0
  89. package/doc_build/plugins/official-list/plugin-babel.html +64 -0
  90. package/doc_build/plugins/official-list/plugin-banner.html +94 -0
  91. package/doc_build/plugins/official-list/plugin-import.html +112 -0
  92. package/doc_build/plugins/official-list/plugin-node-polyfill.html +128 -0
  93. package/doc_build/plugins/official-list/plugin-polyfill.html +71 -0
  94. package/doc_build/plugins/official-list/plugin-vue.html +66 -0
  95. package/doc_build/static/css/styles.0b88df3a.css +1 -0
  96. package/doc_build/static/js/490.a066dbc0.js +6 -0
  97. package/doc_build/static/js/490.a066dbc0.js.LICENSE.txt +35 -0
  98. package/doc_build/static/js/async/1095.4ca5fdf0.js +1 -0
  99. package/doc_build/static/js/async/1148.ff6a84ca.js +1 -0
  100. package/doc_build/static/js/async/1306.8bc84d6b.js +1 -0
  101. package/doc_build/static/js/async/1507.fed31a58.js +1 -0
  102. package/doc_build/static/js/async/1527.4c6e53e2.js +1 -0
  103. package/doc_build/static/js/async/1657.d0d95d59.js +1 -0
  104. package/doc_build/static/js/async/1801.5d49a2fe.js +1 -0
  105. package/doc_build/static/js/async/1941.0b3cceee.js +1 -0
  106. package/doc_build/static/js/async/213.db8a0492.js +1 -0
  107. package/doc_build/static/js/async/2131.5dfdffa9.js +1 -0
  108. package/doc_build/static/js/async/2140.848412d7.js +1 -0
  109. package/doc_build/static/js/async/2206.f6b802b2.js +1 -0
  110. package/doc_build/static/js/async/2300.cba0106e.js +1 -0
  111. package/doc_build/static/js/async/2347.a480682f.js +1 -0
  112. package/doc_build/static/js/async/2365.daed0a9c.js +1 -0
  113. package/doc_build/static/js/async/2561.2e43400c.js +1 -0
  114. package/doc_build/static/js/async/2579.f7c71e6b.js +1 -0
  115. package/doc_build/static/js/async/2671.c711355f.js +1 -0
  116. package/doc_build/static/js/async/2704.561dadd9.js +1 -0
  117. package/doc_build/static/js/async/2712.5ffea5ba.js +1 -0
  118. package/doc_build/static/js/async/3023.5bef6325.js +1 -0
  119. package/doc_build/static/js/async/3039.3982622e.js +1 -0
  120. package/doc_build/static/js/async/3097.b043b3aa.js +1 -0
  121. package/doc_build/static/js/async/3213.df408a99.js +1 -0
  122. package/doc_build/static/js/async/3235.0c4d2c9b.js +1 -0
  123. package/doc_build/static/js/async/336.8387125c.js +1 -0
  124. package/doc_build/static/js/async/3493.5133deaa.js +1 -0
  125. package/doc_build/static/js/async/351.de7824af.js +1 -0
  126. package/doc_build/static/js/async/3597.cf46a69b.js +1 -0
  127. package/doc_build/static/js/async/36.eee0e8fe.js +1 -0
  128. package/doc_build/static/js/async/3628.726e3f10.js +1 -0
  129. package/doc_build/static/js/async/3724.bcc90bb4.js +1 -0
  130. package/doc_build/static/js/async/3761.949f5838.js +1 -0
  131. package/doc_build/static/js/async/4061.84ac839b.js +1 -0
  132. package/doc_build/static/js/async/4064.104b71cd.js +1 -0
  133. package/doc_build/static/js/async/4206.133ffe9e.js +1 -0
  134. package/doc_build/static/js/async/443.b519ce6b.js +1 -0
  135. package/doc_build/static/js/async/4501.c647ab73.js +1 -0
  136. package/doc_build/static/js/async/453.7358c1fd.js +1 -0
  137. package/doc_build/static/js/async/461.2d6ea16c.js +1 -0
  138. package/doc_build/static/js/async/4615.c4e5b749.js +1 -0
  139. package/doc_build/static/js/async/4655.bbe27e7b.js +1 -0
  140. package/doc_build/static/js/async/4812.ebd3f4cb.js +1 -0
  141. package/doc_build/static/js/async/4904.de72a299.js +1 -0
  142. package/doc_build/static/js/async/5105.28347c4d.js +1 -0
  143. package/doc_build/static/js/async/5453.87dcea50.js +1 -0
  144. package/doc_build/static/js/async/5455.9e038fda.js +1 -0
  145. package/doc_build/static/js/async/5493.3644c7b8.js +1 -0
  146. package/doc_build/static/js/async/5495.50aacc7e.js +1 -0
  147. package/doc_build/static/js/async/5555.40dabd12.js +1 -0
  148. package/doc_build/static/js/async/5558.073d18d0.js +1 -0
  149. package/doc_build/static/js/async/5844.b3a9d57a.js +1 -0
  150. package/doc_build/static/js/async/588.6de9811a.js +1 -0
  151. package/doc_build/static/js/async/5889.41a786b6.js +1 -0
  152. package/doc_build/static/js/async/5892.b0db6657.js +1 -0
  153. package/doc_build/static/js/async/5995.209e2925.js +1 -0
  154. package/doc_build/static/js/async/6046.963bbf59.js +1 -0
  155. package/doc_build/static/js/async/6308.6363792d.js +1 -0
  156. package/doc_build/static/js/async/6576.a753babb.js +1 -0
  157. package/doc_build/static/js/async/6615.154a2810.js +1 -0
  158. package/doc_build/static/js/async/6858.e2452605.js +1 -0
  159. package/doc_build/static/js/async/6975.be4ba201.js +1 -0
  160. package/doc_build/static/js/async/7080.1c684c7d.js +1 -0
  161. package/doc_build/static/js/async/7220.1c4ee8bb.js +1 -0
  162. package/doc_build/static/js/async/7406.b2acec42.js +1 -0
  163. package/doc_build/static/js/async/7521.ca744786.js +1 -0
  164. package/doc_build/static/js/async/7535.f50f0fd1.js +1 -0
  165. package/doc_build/static/js/async/7584.c3b673fd.js +1 -0
  166. package/doc_build/static/js/async/7600.03d9da89.js +1 -0
  167. package/doc_build/static/js/async/7663.86b79735.js +1 -0
  168. package/doc_build/static/js/async/769.2bc1c7b7.js +1 -0
  169. package/doc_build/static/js/async/7715.1bfe887f.js +1 -0
  170. package/doc_build/static/js/async/7837.5667c422.js +1 -0
  171. package/doc_build/static/js/async/8040.1cfb21ff.js +1 -0
  172. package/doc_build/static/js/async/8085.f9f71860.js +1 -0
  173. package/doc_build/static/js/async/8098.beeb77f3.js +1 -0
  174. package/doc_build/static/js/async/8134.068074a0.js +1 -0
  175. package/doc_build/static/js/async/8158.2834ced1.js +1 -0
  176. package/doc_build/static/js/async/8214.2fdfe2fe.js +1 -0
  177. package/doc_build/static/js/async/8233.24111213.js +1 -0
  178. package/doc_build/static/js/async/8451.5328c0c7.js +1 -0
  179. package/doc_build/static/js/async/8689.f8447ca1.js +1 -0
  180. package/doc_build/static/js/async/8694.077556c4.js +1 -0
  181. package/doc_build/static/js/async/8713.91395601.js +1 -0
  182. package/doc_build/static/js/async/8750.0f6872b3.js +1 -0
  183. package/doc_build/static/js/async/8802.463e3040.js +1 -0
  184. package/doc_build/static/js/async/9100.066e1017.js +1 -0
  185. package/doc_build/static/js/async/9250.8fb41a47.js +1 -0
  186. package/doc_build/static/js/async/9524.bb257861.js +1 -0
  187. package/doc_build/static/js/async/9611.b2543acb.js +1 -0
  188. package/doc_build/static/js/async/964.b00f3e9f.js +1 -0
  189. package/doc_build/static/js/async/9740.b27e6629.js +1 -0
  190. package/doc_build/static/js/index.6a5d779d.js +1 -0
  191. package/doc_build/static/js/lib-react.a93218f7.js +2 -0
  192. package/doc_build/static/js/lib-react.a93218f7.js.LICENSE.txt +39 -0
  193. package/doc_build/static/js/lib-router.f8d11890.js +2 -0
  194. package/doc_build/static/js/lib-router.f8d11890.js.LICENSE.txt +32 -0
  195. package/doc_build/static/js/styles.3f5a6140.js +1 -0
  196. package/doc_build/static/search_index.en.f19ea64b.json +1 -0
  197. package/doc_build/static/search_index.zh.e818eee4.json +1 -0
  198. package/doc_build/test-result.png +0 -0
  199. package/doc_build/why-module-solution.png +0 -0
  200. package/docs/en/api/config/dev.md +2 -2
  201. package/docs/en/guide/basic/command-preview.md +0 -16
  202. package/docs/en/guide/intro/welcome.md +0 -1
  203. package/docs/zh/api/config/dev.md +2 -2
  204. package/docs/zh/guide/basic/command-preview.md +0 -16
  205. package/docs/zh/guide/basic/using-storybook.mdx +1 -1
  206. package/docs/zh/guide/intro/welcome.md +0 -1
  207. package/package.json +4 -4
@@ -0,0 +1 @@
1
+ "use strict";(self.webpackChunk_modern_js_module_tools_docs=self.webpackChunk_modern_js_module_tools_docs||[]).push([["336"],{3865:function(e,n,d){d.r(n),d.d(n,{default:function(){return t}});var i=d(8093),c=d(5878);function s(e){let n=Object.assign({h1:"h1",a:"a",p:"p",code:"code",pre:"pre",h2:"h2",strong:"strong",h3:"h3",ul:"ul",li:"li",blockquote:"blockquote"},(0,c.ah)(),e.components);return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsxs)(n.h1,{id:"handle-third-party-dependencies",children:["Handle third-party dependencies",(0,i.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#handle-third-party-dependencies",children:"#"})]}),"\n",(0,i.jsxs)(n.p,{children:["Generally, third-party dependencies required by a project can be installed via the ",(0,i.jsx)(n.code,{children:"install"})," command in the package manager. After the third-party dependencies are successfully installed, they will generally appear under ",(0,i.jsx)(n.code,{children:"dependencies"})," and ",(0,i.jsx)(n.code,{children:"devDependencies"})," in the project ",(0,i.jsx)(n.code,{children:"package.json"}),"."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-json",meta:'title="pacakge.json"',children:'{\n "dependencies": {},\n "devDependencies": {}\n}\n'})}),"\n",(0,i.jsxs)(n.p,{children:["Dependencies under ",(0,i.jsx)(n.code,{children:'"dependencies"'})," are generally related to project code and builds, and if these third-party dependencies are declared under ",(0,i.jsx)(n.code,{children:'"devDependencies"'}),", then there will be missing dependencies in production environments."]}),"\n",(0,i.jsxs)(n.p,{children:["In addition to ",(0,i.jsx)(n.code,{children:'"dependencies"'}),", ",(0,i.jsx)(n.a,{href:"/en/guide/basic/before-getting-started#peerdependencies",children:(0,i.jsx)(n.code,{children:'"peerDependencies"'})})," can also declare dependencies that are needed in the production environment, but it puts more emphasis on the existence of these dependencies declared by ",(0,i.jsx)(n.code,{children:'"peerDependencies"'})," in the project's runtime environment, similar to the plugin mechanism."]}),"\n",(0,i.jsxs)(n.h2,{id:"default-handling-of-third-party-dependencies",children:["Default handling of third-party dependencies",(0,i.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#default-handling-of-third-party-dependencies",children:"#"})]}),"\n",(0,i.jsxs)(n.p,{children:["By default, ",(0,i.jsxs)(n.strong,{children:["third-party dependencies under ",(0,i.jsx)(n.code,{children:'"dependencies"'})," and ",(0,i.jsx)(n.code,{children:'"peerDependencies"'})," are not bundled by Modern.js Module"]}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["This is because when the npm package is installed, its ",(0,i.jsx)(n.code,{children:'"dependencies"'})," will also be installed. By not packaging ",(0,i.jsx)(n.code,{children:'"dependencies"'}),", you can reduce the size of the package product."]}),"\n",(0,i.jsxs)(n.p,{children:["If you need to package some dependencies, it is recommended to move them from ",(0,i.jsx)(n.code,{children:'"dependencies"'})," to ",(0,i.jsx)(n.code,{children:'"devDependencies"'}),", which is equivalent to ",(0,i.jsx)(n.strong,{children:"prebundle"})," the dependencies and reduces the size of the dependency installation."]}),"\n",(0,i.jsxs)(n.h3,{id:"example",children:["Example",(0,i.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#example",children:"#"})]}),"\n",(0,i.jsxs)(n.p,{children:["If the project has a dependency on ",(0,i.jsx)(n.code,{children:"react"}),"."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-json",meta:'title="package.json"',children:'{\n "dependencies": {\n "react": "^17"\n },\n // or\n "peerDependencies": {\n "react": "^17"\n }\n}\n'})}),"\n",(0,i.jsxs)(n.p,{children:["When a ",(0,i.jsx)(n.code,{children:"react"})," dependency is used in the source code:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-tsx",meta:'title="src/index.ts"',children:"import React from 'react';\nconsole.info(React);\n"})}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"react"})," code is not bundled into the artifact:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-js",meta:'title="dist/index.js"',children:"import React from 'react';\nconsole.info(React);\n"})}),"\n",(0,i.jsx)(n.p,{children:"If you want to modify the default processing, you can use the following API."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"/api/config/build-config#autoexternal",children:(0,i.jsx)(n.code,{children:"buildConfig.autoExternal"})})}),"\n"]}),"\n",(0,i.jsxs)(n.h2,{id:"exclude-specified-third-party-dependencies",children:["Exclude specified third-party dependencies",(0,i.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#exclude-specified-third-party-dependencies",children:"#"})]}),"\n",(0,i.jsxs)(n.p,{children:["We mentioned above the use of the ",(0,i.jsx)(n.code,{children:"buildConfig.autoExternal"})," API, and ",(0,i.jsx)(n.a,{href:"/en/api/config/build-config#externals",children:(0,i.jsx)(n.code,{children:"buildConfig.externals"})})," can control which third-party dependencies to handle\nthe project's dependencies in a more granular way."]}),"\n",(0,i.jsx)(n.p,{children:"For example, when we need to leave only certain dependencies unpacked, we can configure it as follows."}),"\n",(0,i.jsxs)(n.blockquote,{children:["\n",(0,i.jsx)(n.p,{children:"In this case, it is likely that some dependencies are not suitable for packaging. If this is the case, then you can handle it as follows."}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-ts",children:"epxort default defineConfig({\n buildConfig: {\n autoExternal: false,\n externals: ['pkg-1', /pkg-2/],\n }\n});\n"})})]})}function r(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},{wrapper:n}=Object.assign({},(0,c.ah)(),e.components);return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(s,{...e})}):s(e)}let t=r;r.__RSPRESS_PAGE_META={},r.__RSPRESS_PAGE_META["en%2Fguide%2Fadvance%2Fexternal-dependency.mdx"]={toc:[{text:"Default handling of third-party dependencies",id:"default-handling-of-third-party-dependencies",depth:2},{text:"Example",id:"example",depth:3},{text:"Exclude specified third-party dependencies",id:"exclude-specified-third-party-dependencies",depth:2}],title:"Handle third-party dependencies",frontmatter:{sidebar_position:4}}}}]);
@@ -0,0 +1 @@
1
+ "use strict";(self.webpackChunk_modern_js_module_tools_docs=self.webpackChunk_modern_js_module_tools_docs||[]).push([["3493"],{2489:function(e,n,r){r.r(n),r.d(n,{default:function(){return l}});var s=r(8093),d=r(5878);function i(e){let n=Object.assign({h1:"h1",a:"a",p:"p",h2:"h2",h3:"h3",ol:"ol",li:"li",pre:"pre",code:"code",table:"table",thead:"thead",tr:"tr",th:"th",tbody:"tbody",td:"td",img:"img",div:"div",ul:"ul",h4:"h4",strong:"strong"},(0,d.ah)(),e.components);return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsxs)(n.h1,{id:"开发模块文档",children:["开发模块文档",(0,s.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#开发模块文档",children:"#"})]}),"\n",(0,s.jsx)(n.p,{children:"本章介绍如何为模块项目快速搭建一个静态文档站点。"}),"\n",(0,s.jsxs)(n.h2,{id:"开始之前",children:["开始之前",(0,s.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#开始之前",children:"#"})]}),"\n",(0,s.jsxs)(n.h3,{id:"为什么我们需要为模块搭建一个文档站点",children:["为什么我们需要为模块搭建一个文档站点",(0,s.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#为什么我们需要为模块搭建一个文档站点",children:"#"})]}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsx)(n.li,{children:"文档站点可以帮助我们更好地组织文档的结构。"}),"\n",(0,s.jsx)(n.li,{children:"文档站点具有更好的表现形式,例如可以在页面中执行函数,渲染组件等。"}),"\n",(0,s.jsx)(n.li,{children:"可以更好地利用 AI 搜索的能力。"}),"\n"]}),"\n",(0,s.jsxs)(n.h3,{id:"前置准备",children:["前置准备",(0,s.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#前置准备",children:"#"})]}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["通过",(0,s.jsx)(n.a,{href:"/guide/basic/use-micro-generator",children:"微生成器"}),"开启文档功能。"]}),"\n",(0,s.jsxs)(n.li,{children:["阅读",(0,s.jsx)(n.a,{href:"https://rspress.dev/zh/guide/start/introduction.html",target:"_blank",rel:"noopener noreferrer",children:"Rspress 介绍"}),"。"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"完成准备工作之后,接下来我们会基于 Rspress 为模块项目搭建一个文档站点。"}),"\n",(0,s.jsxs)(n.h2,{id:"站点基本结构",children:["站点基本结构",(0,s.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#站点基本结构",children:"#"})]}),"\n",(0,s.jsx)(n.p,{children:"站点整体布局由三部分组成:导航栏、侧边栏以及正文部分,其中正文还包括了 TOC(Table of contents found at the beginning of a book or document)。"}),"\n",(0,s.jsxs)(n.p,{children:["Rspress 使用的是",(0,s.jsx)(n.a,{href:"https://rspress.dev/zh/guide/basic/conventional-route.html",target:"_blank",rel:"noopener noreferrer",children:"文件系统路由"}),",模块文档基于此实现了侧边栏的自动生成。\n例如,如果你有以下的文件结构:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"docs\n├── foo\n│ └── bar.md\n│ └── index.md\n└── foo.md\n└── index.md\n"})}),"\n",(0,s.jsxs)(n.p,{children:["那么 ",(0,s.jsx)(n.code,{children:"foo/bar.md"})," 的路由路径会是 ",(0,s.jsx)(n.code,{children:"/foo/bar"}),",",(0,s.jsx)(n.code,{children:"foo.md"})," 的路由路径会是 ",(0,s.jsx)(n.code,{children:"/foo"}),",",(0,s.jsx)(n.code,{children:"index.md"})," 的路由路径会是 ",(0,s.jsx)(n.code,{children:"/"}),"。"]}),"\n",(0,s.jsx)(n.p,{children:"具体映射规则如下:"}),"\n",(0,s.jsxs)(n.table,{children:["\n",(0,s.jsxs)(n.thead,{children:["\n",(0,s.jsxs)(n.tr,{children:["\n",(0,s.jsx)(n.th,{children:"文件路径"}),"\n",(0,s.jsx)(n.th,{children:"路由路径"}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.tbody,{children:["\n",(0,s.jsxs)(n.tr,{children:["\n",(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"index.md"})}),"\n",(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"/"})}),"\n"]}),"\n",(0,s.jsxs)(n.tr,{children:["\n",(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"/foo.md"})}),"\n",(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"/foo"})}),"\n"]}),"\n",(0,s.jsxs)(n.tr,{children:["\n",(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"/foo/index.md"})}),"\n",(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"/foo/"})}),"\n"]}),"\n",(0,s.jsxs)(n.tr,{children:["\n",(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"/foo/bar.md"})}),"\n",(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"/foo/bar"})}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"与上述文件路径和路由路径依次对应的侧边栏如下所示:"}),"\n",(0,s.jsx)("img",{src:"https://lf3-static.bytednsdoc.com/obj/eden-cn/rpauheh7nulwbm/edenx-module/docs-blog/autosidebar.png"}),"\n",(0,s.jsxs)(n.h3,{id:"配置侧边栏",children:["配置侧边栏",(0,s.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#配置侧边栏",children:"#"})]}),"\n",(0,s.jsxs)(n.p,{children:["如上图所示,模块文档已经为文件系统路由自动生成了侧边栏,其中侧边栏每一栏的文本是由文件的一级标题或者目录名决定。\n如果你需要自定义侧边栏,请使用 ",(0,s.jsx)(n.a,{href:"https://rspress.dev/zh/guide/basic/auto-nav-sidebar.html",target:"_blank",rel:"noopener noreferrer",children:"_meta.json"})," 或者直接配置 ",(0,s.jsx)(n.a,{href:"https://rspress.dev/zh/api/config/config-theme.html#sidebar",target:"_blank",rel:"noopener noreferrer",children:"sidebar"}),"。"]}),"\n",(0,s.jsxs)(n.div,{className:"rspress-directive info",children:[(0,s.jsx)(n.div,{className:"rspress-directive-title",children:"INFO"}),(0,s.jsxs)(n.div,{className:"rspress-directive-content",children:[(0,s.jsx)(n.p,{children:"如果你的文档目录结构是符合国际化的,例如:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"docs\n├── en\n│ ├── button.mdx\n│ ├── index.mdx\n└── zh\n ├── button.mdx\n ├── index.mdx\n"})}),"\n",(0,s.jsxs)(n.p,{children:["你需要按照",(0,s.jsx)(n.a,{href:"https://rspress.dev/zh/guide/default-theme/i18n.html",target:"_blank",rel:"noopener noreferrer",children:"国际化"}),"章节,同时配置 ",(0,s.jsx)(n.code,{children:"lang"})," 和 ",(0,s.jsx)(n.code,{children:"locales"}),",否则模块自动生成的侧边栏不会处理 ",(0,s.jsx)(n.code,{children:"zh"})," 和 ",(0,s.jsx)(n.code,{children:"en"})," 这两个目录。\n"]})]})]}),"\n",(0,s.jsxs)(n.h2,{id:"编写文档",children:["编写文档",(0,s.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#编写文档",children:"#"})]}),"\n",(0,s.jsx)(n.p,{children:"接下来我们可以专注于文档内容的编写了。除了最基本的编写 markdown 以外,你可能还需要了解以下进阶内容:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://rspress.dev/zh/guide/basic/use-mdx.html",target:"_blank",rel:"noopener noreferrer",children:"使用 MDX"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://rspress.dev/zh/guide/basic/static-assets.html",target:"_blank",rel:"noopener noreferrer",children:"使用静态资源"})}),"\n"]}),"\n",(0,s.jsxs)(n.h2,{id:"组件预览",children:["组件预览",(0,s.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#组件预览",children:"#"})]}),"\n",(0,s.jsxs)(n.p,{children:["模块文档为组件库提供了预览能力,",(0,s.jsx)(n.code,{children:"jsx"}),"和",(0,s.jsx)(n.code,{children:"tsx"}),"的代码块里的内容将会被解析为 React 组件。"]}),"\n",(0,s.jsxs)(n.h3,{id:"示例",children:["示例",(0,s.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#示例",children:"#"})]}),"\n",(0,s.jsxs)(n.p,{children:["假设我们的项目名是",(0,s.jsx)(n.code,{children:"demo"}),",并导出了一个 Button 组件。"]}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["首先新增 ",(0,s.jsx)(n.code,{children:"docs/Button.mdx"})," 文件:"]}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-mdx",meta:'title="Button.mdx"',children:"# Button\n\n## 基本用法\n\n按钮分为: 小、中、大四种尺寸\n\n```tsx\nimport React from 'react';\nimport { Button } from 'demo';\n\nexport default () => {\n return <Button size=\"large\">点我</Button>;\n};\n```\n"})}),"\n",(0,s.jsxs)(n.ol,{start:"2",children:["\n",(0,s.jsxs)(n.li,{children:["在",(0,s.jsx)(n.code,{children:"tsconfig.json"}),"里配置别名,将包名指向当前项目目录,使得文档开发者和用户使用组件方式一致:"]}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",meta:'title="tsconfig.json"',children:'{\n "compilerOptions": {\n "paths": {\n "demo": ["."]\n }\n }\n}\n'})}),"\n",(0,s.jsxs)(n.ol,{start:"3",children:["\n",(0,s.jsxs)(n.li,{children:["在 ",(0,s.jsx)(n.code,{children:".gitignore"})," 文件下添加 ",(0,s.jsx)(n.code,{children:"doc_build/"}),",文档产物将会生成在此目录下:"]}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",meta:'title=".gitignore"',children:"doc_build/\n"})}),"\n",(0,s.jsxs)(n.p,{children:["恭喜你,已经完成了一个组件文档的编写,执行",(0,s.jsx)(n.code,{children:"pnpm run dev"}),"看看效果吧,记得先构建一下组件库,确保组件产物存在。"]}),"\n",(0,s.jsxs)(n.h3,{id:"移动端预览",children:["移动端预览",(0,s.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#移动端预览",children:"#"})]}),"\n",(0,s.jsxs)(n.p,{children:["同时,我们也支持了移动端预览的方式,即使用 iframe 渲染移动端组件,并可以通过 ",(0,s.jsx)(n.code,{children:"iframePosition"})," 设置 iframe 的位置,支持扫码预览以及新页面打开。"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ts",meta:'title="modern.config.ts"',children:"import { moduleTools, defineConfig } from '@modern-js/module-tools';\nimport { modulePluginDoc } from '@modern-js/plugin-rspress';\n\nexport default defineConfig({\n plugins: [\n moduleTools(),\n modulePluginDoc({\n /**\n * 选择预览方式\n * @default internal\n */\n previewMode: 'iframe',\n /**\n * 设置 iframe 的位置\n * @default 'follow'\n */\n iframePosition: 'fixed',\n }),\n ],\n});\n"})}),"\n",(0,s.jsxs)(n.div,{className:"rspress-directive tip",children:[(0,s.jsx)(n.div,{className:"rspress-directive-title",children:"TIP"}),(0,s.jsxs)(n.div,{className:"rspress-directive-content",children:[(0,s.jsxs)(n.p,{children:["如果只想要改变某一个 ",(0,s.jsx)(n.code,{children:"jsx"})," 和 ",(0,s.jsx)(n.code,{children:"tsx"})," 代码块的预览方式,可以使用不同的修饰符进行标识:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-mdx",children:"```jsx pure\n// 这里的内容不会被渲染\n```\n\n```jsx internal\n// 内置在文档内容里渲染\n```\n\n```jsx iframe\n// 使用 iframe 渲染\n```\n"})}),"\n"]})]}),"\n",(0,s.jsxs)(n.h3,{id:"使用外部-demo",children:["使用外部 demo",(0,s.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#使用外部-demo",children:"#"})]}),"\n",(0,s.jsxs)(n.p,{children:["如果我们的 demo 非常复杂,那么建议单独编写 demo,然后在 MDX 中使用 ",(0,s.jsx)(n.code,{children:"code"})," 标签:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-mdx",children:'<code src="/path/demo.tsx"></code>\n'})}),"\n",(0,s.jsx)(n.p,{children:"这同样支持单独设置代码块的预览方式,例如:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-mdx",children:'<code src="/path/demo.tsx" previewMode="iframe"></code>\n'})}),"\n",(0,s.jsxs)(n.h2,{id:"使用内置组件",children:["使用内置组件",(0,s.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#使用内置组件",children:"#"})]}),"\n",(0,s.jsx)(n.p,{children:"插件内部实现了一部分内置组件,以便于你可以更轻松地开发模块文档。"}),"\n",(0,s.jsxs)(n.h3,{id:"api",children:["API",(0,s.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#api",children:"#"})]}),"\n",(0,s.jsx)(n.p,{children:"展示模块的 API 内容"}),"\n",(0,s.jsxs)(n.h4,{id:"解析文件",children:["解析文件",(0,s.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#解析文件",children:"#"})]}),"\n",(0,s.jsx)(n.p,{children:"在使用 API 组件之前,首先我们需要指定解析的文件:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ts",meta:'title="modern.config.ts"',children:"import { moduleTools, defineConfig } from '@modern-js/module-tools';\nimport { modulePluginDoc } from '@modern-js/plugin-rspress';\n\nexport default defineConfig({\n plugins: [\n moduleTools(),\n modulePluginDoc({\n entries: {\n Button: './src/button.tsx',\n },\n apiParseTool: 'react-docgen-typescript',\n }),\n ],\n});\n"})}),"\n",(0,s.jsxs)(n.h4,{id:"内容生成",children:["内容生成",(0,s.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#内容生成",children:"#"})]}),"\n",(0,s.jsx)(n.p,{children:"接下来我们了解一下根据解析的文件会生成什么样的 markdown 内容。"}),"\n",(0,s.jsxs)(n.p,{children:["内容可以通过 ",(0,s.jsx)(n.a,{href:"https://github.com/styleguidist/react-docgen-typescript",target:"_blank",rel:"noopener noreferrer",children:"react-docgen-typescript"})," 或者 ",(0,s.jsx)(n.a,{href:"https://github.com/documentationjs/documentation",target:"_blank",rel:"noopener noreferrer",children:"documentation"})," 两个不同的工具生成:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"react-docgen-typescript"}),"针对于组件库场景,仅会解析 props 生成表格。"]}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-tsx",children:"export type ButtonProps = {\n /**\n * Whether to disable the button\n */\n disabled?: boolean;\n /**\n * Type of Button\n * @default 'default'\n */\n size?: 'mini' | 'small' | 'default' | 'large';\n};\nexport const Button = (props?: ButtonProps) => {};\n"})}),"\n",(0,s.jsxs)(n.p,{children:["上面是一个标准写法,其中 ",(0,s.jsx)(n.code,{children:"ButtonProps"})," 将被提取至表格中, ",(0,s.jsx)(n.code,{children:"Button"})," 作为表格的标题。如果使用默认导出,文件名将作为表格标题。"]}),"\n",(0,s.jsx)(n.p,{children:"需要注意的是,export 导出事先定义的特性将不会被解析。"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-tsx",children:"const A = () => {};\n\nexport { A }; // wrong\nexport default A; // wrong\nexport const B = () => {}; // right\nexport default () => {}; // right\n"})}),"\n",(0,s.jsx)(n.p,{children:"生成的内容如下:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-mdx",children:'### ButtonTest\n\n| 属性 | 说明 | 类型 | 默认值 |\n| :------: | :---------------------------: | :-----------------------------------------: | :---------: |\n| disabled | Whether to disable the button | `boolean` | `-` |\n| size | Type of Button | `"mini" \\| "small" \\| "default" \\| "large"` | `\'default\'` |\n'})}),"\n",(0,s.jsxs)(n.div,{className:"rspress-directive warning",children:[(0,s.jsx)(n.div,{className:"rspress-directive-title",children:"WARNING"}),(0,s.jsxs)(n.div,{className:"rspress-directive-content",children:[(0,s.jsx)(n.p,{children:"如果 Props 里使用了 React 的类型,你需要在 tsconfig.json 里添加 types ,否则会解析不到 React 命名空间下的类型。"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'{\n "compilerOptions": {\n "types": ["react"]\n }\n}\n'})}),"\n",(0,s.jsx)(n.p,{children:"更好的方式是直接引用类型,例如"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-tsx",children:"import { FC } from 'react';\n"})}),"\n"]})]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"documentation"}),"适用于工具库场景,用来解析 JSDoc 注释。"]}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ts",children:"/**\n * Greet function that returns a greeting message.\n * @param {string} name - The name of the person to greet.\n * @param {string} [greeting='Hello'] - The greeting to use.\n * @returns {string} The greeting message.\n */\nfunction greet(name: string, greeting = 'Hello') {\n return `${greeting}, ${name}!`;\n}\n"})}),"\n",(0,s.jsx)(n.p,{children:"上面是一个带有 JSDoc 注释的 greet 函数。生成的内容如下:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-md",children:"\x3c!-- Generated by documentation.js. Update this documentation by updating the source code. --\x3e\n\n## greet\n\nGreet function that returns a greeting message.\n\n### Parameters\n\n- `name` **[string][1]** The name of the person to greet.\n- `greeting` **[string][1]** The greeting to use. (optional, default `'Hello'`)\n\nReturns **[string][1]** The greeting message.\n\n[1]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String\n"})}),"\n",(0,s.jsxs)(n.h4,{id:"组件使用",children:["组件使用",(0,s.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#组件使用",children:"#"})]}),"\n",(0,s.jsxs)(n.p,{children:["接下来,你便可以在文档里使用我们的内置 API 组件了,将",(0,s.jsx)(n.code,{children:"key"}),"值传入",(0,s.jsx)(n.code,{children:"moduleName"}),"属性里"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-mdx",meta:'title="Button.mdx"',children:'# Button\n\n## API\n\n<API moduleName="Button" />\n'})}),"\n",(0,s.jsxs)(n.h3,{id:"overview",children:["Overview",(0,s.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#overview",children:"#"})]}),"\n",(0,s.jsx)(n.p,{children:"展示模块列表,可以放在首页用来展示所有模块。"}),"\n",(0,s.jsx)(n.p,{children:"Overview 组件只有一个 list 属性,接收一个对象数组,下面是对象的属性"}),"\n",(0,s.jsxs)(n.table,{children:["\n",(0,s.jsxs)(n.thead,{children:["\n",(0,s.jsxs)(n.tr,{children:["\n",(0,s.jsx)(n.th,{align:"center",children:"属性"}),"\n",(0,s.jsx)(n.th,{align:"center",children:"说明"}),"\n",(0,s.jsx)(n.th,{align:"center",children:"类型"}),"\n",(0,s.jsx)(n.th,{align:"center",children:"默认值"}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.tbody,{children:["\n",(0,s.jsxs)(n.tr,{children:["\n",(0,s.jsx)(n.td,{align:"center",children:"icon"}),"\n",(0,s.jsx)(n.td,{align:"center",children:"图标"}),"\n",(0,s.jsx)(n.td,{align:"center",children:"React.ReactNode"}),"\n",(0,s.jsx)(n.td,{align:"center"}),"\n"]}),"\n",(0,s.jsxs)(n.tr,{children:["\n",(0,s.jsx)(n.td,{align:"center",children:"text"}),"\n",(0,s.jsxs)(n.td,{align:"center",children:["文本(",(0,s.jsx)(n.strong,{children:"必填"}),")"]}),"\n",(0,s.jsx)(n.td,{align:"center",children:"string"}),"\n",(0,s.jsx)(n.td,{align:"center"}),"\n"]}),"\n",(0,s.jsxs)(n.tr,{children:["\n",(0,s.jsx)(n.td,{align:"center",children:"link"}),"\n",(0,s.jsxs)(n.td,{align:"center",children:["链接(",(0,s.jsx)(n.strong,{children:"必填"}),")"]}),"\n",(0,s.jsx)(n.td,{align:"center",children:"string"}),"\n",(0,s.jsx)(n.td,{align:"center"}),"\n"]}),"\n",(0,s.jsxs)(n.tr,{children:["\n",(0,s.jsx)(n.td,{align:"center",children:"arrow"}),"\n",(0,s.jsx)(n.td,{align:"center",children:"是否展示箭头"}),"\n",(0,s.jsx)(n.td,{align:"center",children:"boolean"}),"\n",(0,s.jsx)(n.td,{align:"center",children:(0,s.jsx)(n.code,{children:"false"})}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.h2,{id:"插件配置",children:["插件配置",(0,s.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#插件配置",children:"#"})]}),"\n",(0,s.jsxs)(n.h3,{id:"apiparsetool",children:["apiParseTool",(0,s.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#apiparsetool",children:"#"})]}),"\n",(0,s.jsx)(n.p,{children:"API 解析工具"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["类型:",(0,s.jsx)(n.code,{children:"'react-docgen-typescript' | 'documentation'"})]}),"\n",(0,s.jsxs)(n.li,{children:["默认值:",(0,s.jsx)(n.code,{children:"'react-docgen-typescript'"})]}),"\n"]}),"\n",(0,s.jsxs)(n.h3,{id:"doc",children:["doc",(0,s.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#doc",children:"#"})]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"https://rspress.dev/zh/api/index.html",target:"_blank",rel:"noopener noreferrer",children:"文档框架配置"})}),"\n",(0,s.jsxs)(n.h3,{id:"entries",children:["entries",(0,s.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#entries",children:"#"})]}),"\n",(0,s.jsx)(n.p,{children:"自动生成文档的模块名称及相对路径"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["类型:",(0,s.jsx)(n.code,{children:"Entries | ToolEntries"})]}),"\n",(0,s.jsxs)(n.li,{children:["默认值:",(0,s.jsx)(n.code,{children:"{}"})]}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ts",children:"type Entries = Record<string, string>;\ntype ToolEntries = {\n documentation: Entries;\n 'react-docgen-typescript': Entries;\n};\n"})}),"\n",(0,s.jsx)(n.p,{children:"Entries 同时支持针对不同的文件使用不同的解析工具:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ts",meta:'title="modern.config.ts"',children:"import { moduleTools, defineConfig } from '@modern-js/module-tools';\nimport { modulePluginDoc } from '@modern-js/plugin-rspress';\n\nexport default defineConfig({\n plugins: [\n moduleTools(),\n modulePluginDoc({\n entries: {\n documentation: {\n Add: './src/utils/add.ts',\n },\n 'react-docgen-typescript': {\n Button: './src/components/button.tsx',\n },\n },\n }),\n ],\n});\n"})}),"\n",(0,s.jsxs)(n.h3,{id:"iframeposition",children:["iframePosition",(0,s.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#iframeposition",children:"#"})]}),"\n",(0,s.jsx)(n.p,{children:"iframe 所处页面位置"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["类型:",(0,s.jsx)(n.code,{children:"'follow' | 'fixed'"})]}),"\n",(0,s.jsxs)(n.li,{children:["默认值: ",(0,s.jsx)(n.code,{children:"'follow'"})]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"follow"}),"时,每一个代码块都会有一个 iframe 展示其渲染视图。\n",(0,s.jsx)(n.code,{children:"fixed"}),"时,iframe 将会固定在页面右侧,展示当前页面所有代码块的视图。"]}),"\n",(0,s.jsxs)(n.h3,{id:"parsetooloptions",children:["parseToolOptions",(0,s.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#parsetooloptions",children:"#"})]}),"\n",(0,s.jsx)(n.p,{children:"API 解析工具的参数"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["类型:",(0,s.jsx)(n.code,{children:"ParseToolOptions"})]}),"\n",(0,s.jsxs)(n.li,{children:["默认值:",(0,s.jsx)(n.code,{children:"{}"})]}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ts",children:"type ParseToolOptions = {\n // https://github.com/styleguidist/react-docgen-typescript#options\n 'react-docgen-typescript'?: ParserOptions;\n // https://github.com/documentationjs/documentation/blob/master/docs/NODE_API.md#parameters-1\n documentation?: DocumentationArgs;\n};\n"})}),"\n",(0,s.jsxs)(n.h3,{id:"previewmode",children:["previewMode",(0,s.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#previewmode",children:"#"})]}),"\n",(0,s.jsx)(n.p,{children:"代码块预览方式。"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["类型:",(0,s.jsx)(n.code,{children:"'internal' | 'iframe'"})]}),"\n",(0,s.jsxs)(n.li,{children:["默认值: ",(0,s.jsx)(n.code,{children:"'internal'"})]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"internal"}),"时,代码块内容将会直接渲染在页面中,反之将会通过 iframe 加载。"]}),"\n",(0,s.jsxs)(n.h3,{id:"deprecated-languages",children:["deprecated: languages",(0,s.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#deprecated-languages",children:"#"})]}),"\n",(0,s.jsxs)(n.div,{className:"rspress-directive warning",children:[(0,s.jsx)(n.div,{className:"rspress-directive-title",children:"WARNING"}),(0,s.jsx)(n.div,{className:"rspress-directive-content",children:(0,s.jsxs)(n.p,{children:["从 2.44.0 版本开始,请参考 ",(0,s.jsx)(n.a,{href:"https://rspress.dev/zh/guide/default-theme/i18n.html",target:"_blank",rel:"noopener noreferrer",children:"国际化"})," 章节来实现多语言。\n"]})})]}),"\n",(0,s.jsxs)(n.h3,{id:"deprecated-usemodulesidebar",children:["deprecated: useModuleSidebar",(0,s.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#deprecated-usemodulesidebar",children:"#"})]}),"\n",(0,s.jsxs)(n.div,{className:"rspress-directive warning",children:[(0,s.jsx)(n.div,{className:"rspress-directive-title",children:"WARNING"}),(0,s.jsx)(n.div,{className:"rspress-directive-content",children:(0,s.jsxs)(n.p,{children:["从 2.44.0 版本开始,内部实现了嗅探机制,请直接使用 ",(0,s.jsx)(n.a,{href:"https://rspress.dev/zh/guide/basic/auto-nav-sidebar.html",target:"_blank",rel:"noopener noreferrer",children:"_meta.json"}),"\n或者直接配置 ",(0,s.jsx)(n.a,{href:"https://rspress.dev/zh/api/config/config-theme.html#sidebar",target:"_blank",rel:"noopener noreferrer",children:"sidebar"})," 来实现自定义侧边栏。\n"]})})]}),"\n",(0,s.jsxs)(n.h2,{id:"命令行",children:["命令行",(0,s.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#命令行",children:"#"})]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"modern dev"}),": 启动文档站本地开发。"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"modern build --platform"}),": 构建生产环境产物。"]}),"\n"]}),"\n",(0,s.jsxs)(n.h2,{id:"进阶指南",children:["进阶指南",(0,s.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#进阶指南",children:"#"})]}),"\n",(0,s.jsxs)(n.p,{children:["以上已经介绍完了开发模块文档的基本内容,但是这对于开发一个完整的文档站是不够的。查看",(0,s.jsx)(n.a,{href:"https://rspress.dev",target:"_blank",rel:"noopener noreferrer",children:"Rspress"}),"以深入了解我们的文档框架。\n你可以通过 ",(0,s.jsx)(n.code,{children:"doc"})," 配置来修改文档框架配置。"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ts",meta:'title="modern.config.ts"',children:"import { moduleTools, defineConfig } from '@modern-js/module-tools';\nimport { modulePluginDoc } from '@modern-js/plugin-rspress';\n\nexport default defineConfig({\n plugins: [\n moduleTools(),\n modulePluginDoc({\n doc: {\n // 自定义文档站点配置\n },\n }),\n ],\n});\n"})})]})}function t(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},{wrapper:n}=Object.assign({},(0,d.ah)(),e.components);return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(i,{...e})}):i(e)}let l=t;t.__RSPRESS_PAGE_META={},t.__RSPRESS_PAGE_META["zh%2Fguide%2Fbasic%2Fuse-module-doc.mdx"]={toc:[{text:"开始之前",id:"开始之前",depth:2},{text:"为什么我们需要为模块搭建一个文档站点",id:"为什么我们需要为模块搭建一个文档站点",depth:3},{text:"前置准备",id:"前置准备",depth:3},{text:"站点基本结构",id:"站点基本结构",depth:2},{text:"配置侧边栏",id:"配置侧边栏",depth:3},{text:"编写文档",id:"编写文档",depth:2},{text:"组件预览",id:"组件预览",depth:2},{text:"示例",id:"示例",depth:3},{text:"移动端预览",id:"移动端预览",depth:3},{text:"使用外部 demo",id:"使用外部-demo",depth:3},{text:"使用内置组件",id:"使用内置组件",depth:2},{text:"API",id:"api",depth:3},{text:"解析文件",id:"解析文件",depth:4},{text:"内容生成",id:"内容生成",depth:4},{text:"组件使用",id:"组件使用",depth:4},{text:"Overview",id:"overview",depth:3},{text:"插件配置",id:"插件配置",depth:2},{text:"apiParseTool",id:"apiparsetool",depth:3},{text:"doc",id:"doc",depth:3},{text:"entries",id:"entries",depth:3},{text:"iframePosition",id:"iframeposition",depth:3},{text:"parseToolOptions",id:"parsetooloptions",depth:3},{text:"previewMode",id:"previewmode",depth:3},{text:"deprecated: languages",id:"deprecated-languages",depth:3},{text:"deprecated: useModuleSidebar",id:"deprecated-usemodulesidebar",depth:3},{text:"命令行",id:"命令行",depth:2},{text:"进阶指南",id:"进阶指南",depth:2}],title:"开发模块文档",frontmatter:{sidebar_position:5}}}}]);
@@ -0,0 +1 @@
1
+ "use strict";(self.webpackChunk_modern_js_module_tools_docs=self.webpackChunk_modern_js_module_tools_docs||[]).push([["351"],{7612:function(e,n,r){r.r(n),r.d(n,{default:function(){return c}});var o=r(8093),s=r(5878);function a(e){let n=Object.assign({h1:"h1",a:"a",p:"p",h2:"h2",div:"div",strong:"strong",h3:"h3",ul:"ul",li:"li",code:"code",pre:"pre",img:"img",h4:"h4"},(0,s.ah)(),e.components);return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsxs)(n.h1,{id:"dev",children:["dev",(0,o.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#dev",children:"#"})]}),"\n",(0,o.jsx)(n.p,{children:"本章节描述了 Modern.js Module 关于调试工具相关的所有配置。"}),"\n",(0,o.jsxs)(n.h2,{id:"storybook",children:["storybook",(0,o.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#storybook",children:"#"})]}),"\n",(0,o.jsxs)(n.div,{className:"rspress-directive warning",children:[(0,o.jsx)(n.div,{className:"rspress-directive-title",children:"WARNING"}),(0,o.jsx)(n.div,{className:"rspress-directive-content",children:(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.strong,{children:"Deprecated"}),":该配置已过时,只适用于 StorybookV6,详情请看",(0,o.jsx)(n.a,{href:"/guide/basic/using-storybook",children:"使用Storybook"}),"。\n"]})})]}),"\n",(0,o.jsxs)(n.h3,{id:"storybookwebpack",children:["storybook.webpack",(0,o.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#storybookwebpack",children:"#"})]}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["类型:",(0,o.jsx)(n.code,{children:"object | Function | undefined"})]}),"\n",(0,o.jsxs)(n.li,{children:["默认值:",(0,o.jsx)(n.code,{children:"undefined"})]}),"\n"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-ts",children:"export default {\n dev: {\n storybook: {\n webpack(config) {\n return config;\n },\n },\n },\n};\n"})}),"\n",(0,o.jsxs)(n.p,{children:["你可以通过 ",(0,o.jsx)(n.code,{children:"dev.storybook.webpack"})," 来修改 Storybook Preview-iframe 的 webpack 配置。使用方式可以参考 Modern.js 的 ",(0,o.jsx)(n.a,{href:"https://modernjs.dev/builder/api/config-tools.html#toolswebpack",target:"_blank",rel:"noopener noreferrer",children:(0,o.jsx)(n.code,{children:"tools.webpack"})})," 配置。"]}),"\n",(0,o.jsx)(n.p,{children:(0,o.jsx)(n.img,{src:"https://storybook.js.org/71522ac365feaf3338d7c242e53378f6/manager-preview.png",alt:"Storybook"})}),"\n",(0,o.jsxs)(n.h4,{id:"配置-manager-app",children:["配置 Manager App",(0,o.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#配置-manager-app",children:"#"})]}),"\n",(0,o.jsxs)(n.p,{children:["对于 Storybook Manager App 部分的 webpack 配置,可以通过增加 ",(0,o.jsx)(n.code,{children:"./config/storybook/main.js"})," 文件进行配置。"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-js",children:"// ./config/storybook/main.js\n\nmodule.exports = {\n // it controls the Storybook manager app\n managerWebpack: async (config, options) => {\n // update config here\n return config;\n },\n};\n"})}),"\n",(0,o.jsxs)(n.h3,{id:"storybookwebpackchain",children:["storybook.webpackChain",(0,o.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#storybookwebpackchain",children:"#"})]}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["类型:",(0,o.jsx)(n.code,{children:"Function | undefined"})]}),"\n",(0,o.jsxs)(n.li,{children:["默认值:",(0,o.jsx)(n.code,{children:"undefined"})]}),"\n"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-ts",children:"export default {\n dev: {\n storybook: {\n webpackChain(chain) {\n return chain;\n },\n },\n },\n};\n"})}),"\n",(0,o.jsxs)(n.p,{children:["你可以通过 ",(0,o.jsx)(n.code,{children:"dev.storybook.webpackChain"})," 来修改 Storybook Preview-iframe 的 webpack 配置。使用方式可以参考 Modern.js 的 ",(0,o.jsx)(n.a,{href:"https://modernjs.dev/builder/api/config-tools.html#toolswebpackchain",target:"_blank",rel:"noopener noreferrer",children:(0,o.jsx)(n.code,{children:"tools.webpackChain"})})," 配置。"]})]})}function i(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},{wrapper:n}=Object.assign({},(0,s.ah)(),e.components);return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(a,{...e})}):a(e)}let c=i;i.__RSPRESS_PAGE_META={},i.__RSPRESS_PAGE_META["zh%2Fapi%2Fconfig%2Fdev.md"]={toc:[{text:"storybook",id:"storybook",depth:2},{text:"storybook.webpack",id:"storybookwebpack",depth:3},{text:"配置 Manager App",id:"配置-manager-app",depth:4},{text:"storybook.webpackChain",id:"storybookwebpackchain",depth:3}],title:"dev",frontmatter:{sidebar_position:3}}}}]);
@@ -0,0 +1 @@
1
+ "use strict";(self.webpackChunk_modern_js_module_tools_docs=self.webpackChunk_modern_js_module_tools_docs||[]).push([["3597"],{5114:function(e,o,t){t.r(o),t.d(o,{default:function(){return s}});var n=t(8093),r=t(5878);function i(e){let o=Object.assign({h1:"h1",a:"a",p:"p",img:"img",strong:"strong"},(0,r.ah)(),e.components);return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsxs)(o.h1,{id:"why-you-need-modernjs-module",children:["Why you need Modern.js Module",(0,n.jsx)(o.a,{className:"header-anchor","aria-hidden":"true",href:"#why-you-need-modernjs-module",children:"#"})]}),"\n",(0,n.jsx)(o.p,{children:"You've probably all experienced it: when developing a component library or tool library from scratch, we have to consider not only how to write the code logic of the project itself, but also how to build, debug, test, format the code, and other things that have nothing to do with the code logic."}),"\n",(0,n.jsxs)(o.p,{children:["For example, when we consider which builder is used to build the code for a module project, we might previously consider ",(0,n.jsx)(o.a,{href:"https://webpack.js.org/",target:"_blank",rel:"noopener noreferrer",children:"webpack"})," or ",(0,n.jsx)(o.a,{href:"https://rollupjs.org/guide/en/",target:"_blank",rel:"noopener noreferrer",children:"Rollup"}),", but now we might also consider ",(0,n.jsx)(o.a,{href:"https://esbuild.github.io/",target:"_blank",rel:"noopener noreferrer",children:"esbuild"})," or ",(0,n.jsx)(o.a,{href:"https://swc.rs/",target:"_blank",rel:"noopener noreferrer",children:"SWC"}),"."]}),"\n",(0,n.jsx)(o.p,{children:"Regardless of which builder is chosen, this is going to be a costly learning curve for developers who are not skilled in the use of these build tools. Even if you want to use them quickly, it will take a lot of time and effort."}),"\n",(0,n.jsx)(o.p,{children:"In addition to the build, things like providing debugging tools for projects, supporting testing capabilities, adding code format validation, etc. can take a long time and effort for a novice to understand or master them and actually serve the current project."}),"\n",(0,n.jsx)(o.p,{children:"To ensure the quality of the code and the integrity of the project, we often need to do these things that are not related to the logical implementation of the code. However, these things are likely to affect the overall project development progress, reduce the developer's development experience, and make the developer feel that the development threshold of the module project is very high."}),"\n",(0,n.jsx)(o.p,{children:"If you have to go through all this work every time you develop a module type project, you will spend most of your development time in the beginning on these things that are not related to code implementation. If we could provide a module engineering solution that would help developers to solve the project engineering issues and allow them to focus more on code implementation, it would greatly improve the module type project development experience."}),"\n",(0,n.jsx)(o.p,{children:(0,n.jsx)(o.img,{src:"https://lf3-static.bytednsdoc.com/obj/eden-cn/uhbfnupenuhf/module-tools/why-module-solution.png",alt:"Not using engineering solution vs. using engineering solution"})}),"\n",(0,n.jsxs)(o.p,{children:["Modern.js, in order to make developing module type projects easier, provides a module engineering solution in order to solve the above mentioned problems and provides the main features using Modern.js Module. ",(0,n.jsx)(o.strong,{children:"Modern.js Module can be understood as a tool dedicated to the development of module type projects"}),"."]})]})}function l(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},{wrapper:o}=Object.assign({},(0,r.ah)(),e.components);return o?(0,n.jsx)(o,{...e,children:(0,n.jsx)(i,{...e})}):i(e)}let s=l;l.__RSPRESS_PAGE_META={},l.__RSPRESS_PAGE_META["en%2Fguide%2Fintro%2Fwhy-module-engineering-solution.md"]={toc:[],title:"Why you need Modern.js Module",frontmatter:{sidebar_position:2}}}}]);
@@ -0,0 +1 @@
1
+ "use strict";(self.webpackChunk_modern_js_module_tools_docs=self.webpackChunk_modern_js_module_tools_docs||[]).push([["36"],{4008:function(e,n,l){l.r(n),l.d(n,{default:function(){return d}});var i=l(8093),o=l(5878),s=l(8078);function r(e){let n=Object.assign({h1:"h1",a:"a",div:"div",p:"p",code:"code",h2:"h2",h3:"h3",pre:"pre",ul:"ul",li:"li",strong:"strong"},(0,o.ah)(),e.components);return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsxs)(n.h1,{id:"polyfill-plugin",children:["Polyfill Plugin",(0,i.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#polyfill-plugin",children:"#"})]}),"\n",(0,i.jsxs)(n.div,{className:"rspress-directive tip",children:[(0,i.jsx)(n.div,{className:"rspress-directive-title",children:"TIP"}),(0,i.jsxs)(n.div,{className:"rspress-directive-content",children:[(0,i.jsx)(n.p,{children:"Normally, we don't need to inject polyfill for npm packages, this step should be done on the web application framework side, but in some scenarios we need to inject polyfill in order to make our library run directly in low version browsers."}),"\n",(0,i.jsxs)(n.p,{children:["Note that this plugin does not transform your code syntax, it only injects polyfill for unsupported functions used in your code, importing them as normal functions instead of polluting the global. You need to install the ",(0,i.jsx)(n.code,{children:"core-js-pure"})," dependency."]}),"\n"]})]}),"\n",(0,i.jsxs)(n.h2,{id:"quick-start",children:["Quick start",(0,i.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#quick-start",children:"#"})]}),"\n",(0,i.jsxs)(n.h3,{id:"install",children:["Install",(0,i.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#install",children:"#"})]}),"\n","\n",(0,i.jsx)(s.SU,{command:"add @modern-js/plugin-module-polyfill -D"}),"\n",(0,i.jsxs)(n.h3,{id:"register",children:["Register",(0,i.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#register",children:"#"})]}),"\n",(0,i.jsx)(n.p,{children:"In Modern.js Module, you can register plugins in the following way:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-ts",children:"import { moduleTools, defineConfig } from '@modern-js/module-tools';\nimport { modulePluginPolyfill } from '@modern-js/plugin-module-polyfill';\n\nexport default defineConfig({\n plugins: [moduleTools(), modulePluginPolyfill()],\n});\n"})}),"\n",(0,i.jsx)(n.p,{children:"You can also configure registration via hooks, for example,\nif you have multiple build configurations at the same time and only need to inject the polyfill when bundle:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-ts",children:"import { moduleTools, defineConfig } from '@modern-js/module-tools';\nimport { getPolyfillHook } from '@modern-js/plugin-module-polyfill';\n\nconst polyfillHook = getPolyfillHook();\n\nexport default defineConfig({\n plugins: [moduleTools()],\n buildConfig: [\n {\n buildType: 'bundle',\n hooks: [polyfillHook],\n },\n {\n buildType: 'bundleless',\n },\n ],\n});\n"})}),"\n",(0,i.jsxs)(n.h2,{id:"config",children:["Config",(0,i.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#config",children:"#"})]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.strong,{children:"Type"})}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-ts",children:"type options = {\n targets?: Record<string, string> | string;\n};\n"})}),"\n",(0,i.jsxs)(n.h3,{id:"targets",children:["targets",(0,i.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#targets",children:"#"})]}),"\n",(0,i.jsxs)(n.p,{children:["See ",(0,i.jsx)(n.a,{href:"https://babeljs.io/docs/options#targets",target:"_blank",rel:"noopener noreferrer",children:"Babel target"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"This is a example."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-ts",children:"import { moduleTools, defineConfig } from '@modern-js/module-tools';\nimport { modulePluginPolyfill } from '@modern-js/plugin-module-polyfill';\n\nexport default defineConfig({\n plugins: [\n moduleTools(),\n modulePluginPolyfill({\n targets: '> 0.25%, not dead',\n }),\n ],\n});\n"})})]})}function t(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},{wrapper:n}=Object.assign({},(0,o.ah)(),e.components);return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(r,{...e})}):r(e)}let d=t;t.__RSPRESS_PAGE_META={},t.__RSPRESS_PAGE_META["en%2Fplugins%2Fofficial-list%2Fplugin-polyfill.mdx"]={toc:[{text:"Quick start",id:"quick-start",depth:2},{text:"Install",id:"install",depth:3},{text:"Register",id:"register",depth:3},{text:"Config",id:"config",depth:2},{text:"targets",id:"targets",depth:3}],title:"Polyfill Plugin",frontmatter:{}}}}]);
@@ -0,0 +1 @@
1
+ "use strict";(self.webpackChunk_modern_js_module_tools_docs=self.webpackChunk_modern_js_module_tools_docs||[]).push([["3628"],{3099:function(n,e,l){l.r(e),l.d(e,{default:function(){return c}});var s=l(8093),i=l(5878);function r(n){let e=Object.assign({h1:"h1",a:"a",p:"p",ol:"ol",li:"li",code:"code",pre:"pre",ul:"ul"},(0,i.ah)(),n.components);return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsxs)(e.h1,{id:"快速开始",children:["快速开始",(0,s.jsx)(e.a,{className:"header-anchor","aria-hidden":"true",href:"#快速开始",children:"#"})]}),"\n",(0,s.jsx)(e.p,{children:"Modern.js Module 不仅提供了丰富的功能,同时也支持通过插件的方式为当前项目扩展能力。"}),"\n",(0,s.jsx)(e.p,{children:"我们可以通过下面的例子来快速了解如何编写一个 Modern.js Module 插件:"}),"\n",(0,s.jsxs)(e.ol,{children:["\n",(0,s.jsxs)(e.li,{children:["首先我们在初始化的项目下创建 ",(0,s.jsx)(e.code,{children:"./plugins/example.ts"})," 文件。"]}),"\n"]}),"\n",(0,s.jsx)(e.pre,{children:(0,s.jsx)(e.code,{className:"language-md",meta:'title="./project"',children:"./\n├── plugins\n│ └── example.ts\n├── src/\n└── modern.config.ts\n"})}),"\n",(0,s.jsxs)(e.ol,{start:"2",children:["\n",(0,s.jsxs)(e.li,{children:["接着在 ",(0,s.jsx)(e.code,{children:"example.ts"})," 文件中增加插件的代码。"]}),"\n"]}),"\n",(0,s.jsx)(e.pre,{children:(0,s.jsx)(e.code,{className:"language-ts",children:"import type { CliPlugin, ModuleTools } from '@modern-js/module-tools';\n\nexport const ExamplePlugin = (): CliPlugin<ModuleTools> => {\n return {\n name: 'example',\n setup() {\n console.info('this is example plugin');\n return {\n // use hooks\n afterBuild() {\n console.info('build over');\n },\n };\n },\n };\n};\n"})}),"\n",(0,s.jsxs)(e.ol,{start:"3",children:["\n",(0,s.jsxs)(e.li,{children:["然后我们通过 ",(0,s.jsx)(e.a,{href:"/api/config/plugins",children:(0,s.jsx)(e.code,{children:"plugins"})})," API,将刚刚写好的插件进行注册。"]}),"\n"]}),"\n",(0,s.jsx)(e.pre,{children:(0,s.jsx)(e.code,{className:"language-ts",meta:'title="modern.config.ts"',children:"import { examplePlugin } from './plugins/example';\nexport default defineConfig({\n plugins: [examplePlugin()],\n});\n"})}),"\n",(0,s.jsxs)(e.ol,{start:"4",children:["\n",(0,s.jsxs)(e.li,{children:["最后运行 ",(0,s.jsx)(e.code,{children:"modern build"}),",就可以看到:"]}),"\n"]}),"\n",(0,s.jsx)(e.pre,{children:(0,s.jsx)(e.code,{className:"language-bash",meta:'title="terminal"',children:"this is example plugin\nBuild succeed: 510.684ms\nbuild over\n"})}),"\n",(0,s.jsx)(e.p,{children:"通过上面这个例子,我们了解到了下面几件事:"}),"\n",(0,s.jsxs)(e.ul,{children:["\n",(0,s.jsx)(e.li,{children:"推荐的插件目录结构"}),"\n",(0,s.jsx)(e.li,{children:"插件的初始化代码"}),"\n",(0,s.jsx)(e.li,{children:"插件的注册"}),"\n"]}),"\n",(0,s.jsx)(e.p,{children:"除了以上内容以外,我们还需要了解:"}),"\n",(0,s.jsxs)(e.ul,{children:["\n",(0,s.jsx)(e.li,{children:(0,s.jsx)(e.a,{href:"/plugins/guide/plugin-object",children:"插件对象、类型定义与推荐配置项"})}),"\n",(0,s.jsx)(e.li,{children:(0,s.jsxs)(e.a,{href:"/plugins/guide/setup-function",children:["setup 函数、",(0,s.jsx)(e.code,{children:"api"})," 对象参数、生命周期钩子"]})}),"\n"]})]})}function d(){let n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},{wrapper:e}=Object.assign({},(0,i.ah)(),n.components);return e?(0,s.jsx)(e,{...n,children:(0,s.jsx)(r,{...n})}):r(n)}let c=d;d.__RSPRESS_PAGE_META={},d.__RSPRESS_PAGE_META["zh%2Fplugins%2Fguide%2Fgetting-started.mdx"]={toc:[],title:"快速开始",frontmatter:{sidebar_position:1}}}}]);
@@ -0,0 +1 @@
1
+ "use strict";(self.webpackChunk_modern_js_module_tools_docs=self.webpackChunk_modern_js_module_tools_docs||[]).push([["3724"],{3259:function(l,i,e){e.r(i),e.d(i,{default:function(){return o}});var n=e(8093),s=e(5878);function r(l){let i=Object.assign({h1:"h1",a:"a",h2:"h2",ul:"ul",li:"li",code:"code"},(0,s.ah)(),l.components);return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsxs)(i.h1,{id:"总览",children:["总览",(0,n.jsx)(i.a,{className:"header-anchor","aria-hidden":"true",href:"#总览",children:"#"})]}),"\n",(0,n.jsxs)(i.h2,{id:"官方插件",children:["官方插件",(0,n.jsx)(i.a,{className:"header-anchor","aria-hidden":"true",href:"#官方插件",children:"#"})]}),"\n",(0,n.jsxs)(i.ul,{children:["\n",(0,n.jsxs)(i.li,{children:[(0,n.jsx)(i.a,{href:"/zh/plugins/official-list/plugin-import",children:"@modern-js/plugin-module-import"}),":使用 SWC 提供与 ",(0,n.jsx)(i.code,{children:"babel-plugin-import"})," 一样的能力。"]}),"\n",(0,n.jsxs)(i.li,{children:[(0,n.jsx)(i.a,{href:"/zh/plugins/official-list/plugin-banner",children:"@modern-js/plugin-module-banner"}),":为每个 JS 和 CSS 文件的顶部和底部添加自定义内容,例如版权信息。"]}),"\n",(0,n.jsxs)(i.li,{children:[(0,n.jsx)(i.a,{href:"/zh/plugins/official-list/plugin-node-polyfill",children:"@modern-js/plugin-module-node-polyfill"}),":会自动注入 Node 核心模块在浏览器端的 polyfills。"]}),"\n",(0,n.jsxs)(i.li,{children:[(0,n.jsx)(i.a,{href:"/zh/plugins/official-list/plugin-polyfill",children:"@modern-js/plugin-module-polyfill"}),":为你的代码中使用到的不支持的功能注入 polyfill。"]}),"\n",(0,n.jsxs)(i.li,{children:[(0,n.jsx)(i.a,{href:"/zh/plugins/official-list/plugin-babel",children:"@modern-js/plugin-module-babel"}),":使用 Babel 转换你的代码。"]}),"\n",(0,n.jsxs)(i.li,{children:[(0,n.jsx)(i.a,{href:"/zh/plugins/official-list/plugin-vue",children:"@modern-js/plugin-module-vue"}),":提供对 Vue 3 组件构建的支持。"]}),"\n"]})]})}function d(){let l=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},{wrapper:i}=Object.assign({},(0,s.ah)(),l.components);return i?(0,n.jsx)(i,{...l,children:(0,n.jsx)(r,{...l})}):r(l)}let o=d;d.__RSPRESS_PAGE_META={},d.__RSPRESS_PAGE_META["zh%2Fplugins%2Fofficial-list%2Foverview.md"]={toc:[{text:"官方插件",id:"官方插件",depth:2}],title:"总览",frontmatter:{}}}}]);
@@ -0,0 +1 @@
1
+ "use strict";(self.webpackChunk_modern_js_module_tools_docs=self.webpackChunk_modern_js_module_tools_docs||[]).push([["3761"],{5695:function(e,n,r){r.r(n),r.d(n,{default:function(){return d}});var t=r(8093),i=r(5878);function s(e){let n=Object.assign({h1:"h1",a:"a",p:"p",h2:"h2",h3:"h3",ol:"ol",li:"li",pre:"pre",code:"code",table:"table",thead:"thead",tr:"tr",th:"th",tbody:"tbody",td:"td",img:"img",div:"div",ul:"ul",h4:"h4",strong:"strong"},(0,i.ah)(),e.components);return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsxs)(n.h1,{id:"developing-module-documentation",children:["Developing Module documentation",(0,t.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#developing-module-documentation",children:"#"})]}),"\n",(0,t.jsx)(n.p,{children:"This chapter describes how to quickly build a static documentation site for a module project."}),"\n",(0,t.jsxs)(n.h2,{id:"before-we-start",children:["Before we start",(0,t.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#before-we-start",children:"#"})]}),"\n",(0,t.jsxs)(n.h3,{id:"why-we-need-to-build-a-documentation-site-for-a-module",children:["Why we need to build a documentation site for a module",(0,t.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#why-we-need-to-build-a-documentation-site-for-a-module",children:"#"})]}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsx)(n.li,{children:"a documentation site can help us to better organize the structure of the documentation."}),"\n",(0,t.jsx)(n.li,{children:"the documentation site has better presentation, such as the ability to execute functions in the page, render components."}),"\n",(0,t.jsx)(n.li,{children:"to make better use of AI search capabilities."}),"\n"]}),"\n",(0,t.jsxs)(n.h3,{id:"preliminary-preparation",children:["Preliminary preparation",(0,t.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#preliminary-preparation",children:"#"})]}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["Enable the documentation feature via ",(0,t.jsx)(n.a,{href:"/guide/basic/use-micro-generator",children:"micro-generator"}),"."]}),"\n",(0,t.jsxs)(n.li,{children:["Read ",(0,t.jsx)(n.a,{href:"https://rspress.dev/guide/start/introduction.html",target:"_blank",rel:"noopener noreferrer",children:"Introduction to Rspress"}),"."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"After finishing the preparation work, we will build a documentation site for the module project based on Rspress."}),"\n",(0,t.jsxs)(n.h2,{id:"basic-site-structure",children:["Basic site structure",(0,t.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#basic-site-structure",children:"#"})]}),"\n",(0,t.jsx)(n.p,{children:"The overall layout of the site consists of three parts: the navigation bar, the sidebar and the body part, which also includes the TOC (Table of contents found at the beginning of a book or document)."}),"\n",(0,t.jsxs)(n.p,{children:["The Rspress uses ",(0,t.jsx)(n.a,{href:"https://rspress.dev/guide/basic/conventional-route.html",target:"_blank",rel:"noopener noreferrer",children:"File System Routing"}),", on which the module documentation is based, to automate the generation of the sidebar.\nFor example, if you have the following file structure:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"docs\n├── foo\n│ └── bar.md\n│ └── index.md\n└── foo.md\n└── index.md\n\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Then the routing path for ",(0,t.jsx)(n.code,{children:"foo/bar.md"})," will be ",(0,t.jsx)(n.code,{children:"/foo/bar"}),", the routing path for ",(0,t.jsx)(n.code,{children:"foo.md"})," will be ",(0,t.jsx)(n.code,{children:"/foo"}),", and the routing path for ",(0,t.jsx)(n.code,{children:"index.md"})," will be ",(0,t.jsx)(n.code,{children:"/"}),"."]}),"\n",(0,t.jsx)(n.p,{children:"The specific mapping rules are as follows:"}),"\n",(0,t.jsxs)(n.table,{children:["\n",(0,t.jsxs)(n.thead,{children:["\n",(0,t.jsxs)(n.tr,{children:["\n",(0,t.jsx)(n.th,{children:"file-path"}),"\n",(0,t.jsx)(n.th,{children:"routing-path"}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.tbody,{children:["\n",(0,t.jsxs)(n.tr,{children:["\n",(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"index.md"})}),"\n",(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"/"})}),"\n"]}),"\n",(0,t.jsxs)(n.tr,{children:["\n",(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"/foo.md"})}),"\n",(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"/foo"})}),"\n"]}),"\n",(0,t.jsxs)(n.tr,{children:["\n",(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"/foo/index.md"})}),"\n",(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"/foo/"})}),"\n"]}),"\n",(0,t.jsxs)(n.tr,{children:["\n",(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"/foo/bar.md"})}),"\n",(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"/foo/bar"})}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"The sidebars corresponding in turn to the above file paths and routing paths are shown below:"}),"\n",(0,t.jsx)("img",{src:"https://lf3-static.bytednsdoc.com/obj/eden-cn/rpauheh7nulwbm/edenx-module/docs-blog/autosidebar.png"}),"\n",(0,t.jsxs)(n.h3,{id:"configure-sidebar",children:["Configure sidebar",(0,t.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#configure-sidebar",children:"#"})]}),"\n",(0,t.jsxs)(n.p,{children:["As shown in the figure above, the module documentation has automatically generated sidebars for file system routing, where the text of each column of the sidebar is determined by the file's first level title or directory name.\nIf you need to customize the sidebar, please use ",(0,t.jsx)(n.a,{href:"https://rspress.dev/guide/basic/auto-nav-sidebar.html",target:"_blank",rel:"noopener noreferrer",children:"_meta.json"})," or configure ",(0,t.jsx)(n.a,{href:"https://rspress.dev/api/config/config-theme.html#sidebar",target:"_blank",rel:"noopener noreferrer",children:"sidebar"})," directly."]}),"\n",(0,t.jsxs)(n.div,{className:"rspress-directive info",children:[(0,t.jsx)(n.div,{className:"rspress-directive-title",children:"INFO"}),(0,t.jsxs)(n.div,{className:"rspress-directive-content",children:[(0,t.jsx)(n.p,{children:"If your document directory structure complies with internationalization, for example:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"docs\n├── en\n│ ├── button.mdx\n│ ├── index.mdx\n└── zh\n ├── button.mdx\n ├── index.mdx\n"})}),"\n",(0,t.jsxs)(n.p,{children:["You need to follow ",(0,t.jsx)(n.a,{href:"https://rspress.dev/guide/default-theme/i18n.html",target:"_blank",rel:"noopener noreferrer",children:"internationalization"})," guide and configure ",(0,t.jsx)(n.code,{children:"lang"})," 和 ",(0,t.jsx)(n.code,{children:"locales"}),",\notherwise, the automatically generated sidebar of the module will not handle the ",(0,t.jsx)(n.code,{children:"zh"})," and ",(0,t.jsx)(n.code,{children:"en"})," directories.\n"]})]})]}),"\n",(0,t.jsxs)(n.h2,{id:"writing-documentation",children:["Writing Documentation",(0,t.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#writing-documentation",children:"#"})]}),"\n",(0,t.jsx)(n.p,{children:"Next, we can focus on writing the content of the document. In addition to the basic Markdown syntax, you may also need to understand the following advanced topics:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://rspress.dev/guide/basic/use-mdx.html",target:"_blank",rel:"noopener noreferrer",children:"Using MDX"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://rspress.dev/guide/basic/static-assets.html",target:"_blank",rel:"noopener noreferrer",children:"Using Assets"})}),"\n"]}),"\n",(0,t.jsxs)(n.h2,{id:"component-preview",children:["Component preview",(0,t.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#component-preview",children:"#"})]}),"\n",(0,t.jsx)(n.p,{children:"Module documentation provides preview capabilities for component libraries. The contents in code blocks written in jsx and tsx will be parsed as React components."}),"\n",(0,t.jsxs)(n.h3,{id:"example",children:["Example",(0,t.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#example",children:"#"})]}),"\n",(0,t.jsx)(n.p,{children:"Here is a complete example using the component preview feature:"}),"\n",(0,t.jsxs)(n.p,{children:["Assuming our project name is ",(0,t.jsx)(n.code,{children:"demo"})," and we export a Button component."]}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["Add a new ",(0,t.jsx)(n.code,{children:"docs/Button.mdx"})," file:"]}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-mdx",meta:'title="Button.mdx"',children:"# Button\n\n## Basic Usage\n\nButtons come in four sizes: small, medium, large\n\n```tsx\nimport React from 'react';\nimport { Button } from 'demo';\n\nexport default () => {\n return <Button size=\"large\">Click Me</Button>;\n};\n```\n"})}),"\n",(0,t.jsxs)(n.ol,{start:"2",children:["\n",(0,t.jsxs)(n.li,{children:["In the ",(0,t.jsx)(n.code,{children:"tsconfig.json"}),", configure aliases and point the package name to the current project directory, make the way document developers and users use components consistent:"]}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",meta:'title="tsconfig.json"',children:'{\n "compilerOptions": {\n "paths": {\n "demo": ["."]\n }\n }\n}\n'})}),"\n",(0,t.jsxs)(n.ol,{start:"3",children:["\n",(0,t.jsxs)(n.li,{children:["In the ",(0,t.jsx)(n.code,{children:".gitignore"}),", add ",(0,t.jsx)(n.code,{children:"doc_build/"}),":"]}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",meta:'title=".gitignore"',children:"doc_build/\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Congratulations, you have finished writing a component document, execute ",(0,t.jsx)(n.code,{children:"pnpm run dev"})," to see the result, remember to build the component library first to make sure the component product exists."]}),"\n",(0,t.jsxs)(n.h3,{id:"mobile-preview",children:["Mobile Preview",(0,t.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#mobile-preview",children:"#"})]}),"\n",(0,t.jsxs)(n.p,{children:["Also, we support mobile preview mode, i.e. rendering mobile components using iframe, and set iframe position by ",(0,t.jsx)(n.code,{children:"iframePosition"}),",\nsupport swipe preview and new page opening."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-ts",meta:'title="modern.config.ts"',children:"import { moduleTools, defineConfig } from '@modern-js/module-tools'.\nimport { modulePluginDoc } from '@modern-js/plugin-rspress'.\n\nexport default defineConfig({\n plugins: [\n moduleTools(),\n modulePluginDoc({\n /**\n * Select the preview method\n * @default internal\n */\n previewMode: 'iframe',\n /**\n * Select iframe position\n * @default 'follow'\n */\n iframePosition: 'fixed',\n }),\n ],\n});\n"})}),"\n",(0,t.jsxs)(n.div,{className:"rspress-directive tip",children:[(0,t.jsx)(n.div,{className:"rspress-directive-title",children:"TIP"}),(0,t.jsxs)(n.div,{className:"rspress-directive-content",children:[(0,t.jsxs)(n.p,{children:["If you only want to change the way a particular ",(0,t.jsx)(n.code,{children:"jsx"})," and ",(0,t.jsx)(n.code,{children:"tsx"})," block is previewed, you can use a different modifier to identify it:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-mdx",children:"```jsx pure\n// The content here will not be rendered\n```\n\n```jsx internal\n// Used to render components in documentation\n```\n\n```jsx iframe\n// Used to render components in iframe\n```\n"})}),"\n"]})]}),"\n",(0,t.jsxs)(n.h3,{id:"using-external-demos",children:["Using external demos",(0,t.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#using-external-demos",children:"#"})]}),"\n",(0,t.jsxs)(n.p,{children:["If our demo is very complex, then it is recommended to write the demo separately and then use the ",(0,t.jsx)(n.code,{children:"code"})," tag in the mdx:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-mdx",children:'<code src="/path/demo.tsx"></code>\n'})}),"\n",(0,t.jsx)(n.p,{children:"This also supports setting the preview method for each individual code block, for example:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-mdx",children:'<code src="/path/demo.tsx" previewMode="iframe"></code>\n'})}),"\n",(0,t.jsxs)(n.h2,{id:"using-built-in-components",children:["Using built-in components",(0,t.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#using-built-in-components",children:"#"})]}),"\n",(0,t.jsx)(n.p,{children:"The plugin implements some built-in components internally so that you can develop module documentation more easily."}),"\n",(0,t.jsxs)(n.h3,{id:"api",children:["API",(0,t.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#api",children:"#"})]}),"\n",(0,t.jsx)(n.p,{children:"Display the API content of the module."}),"\n",(0,t.jsxs)(n.h4,{id:"parse-file",children:["Parse file",(0,t.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#parse-file",children:"#"})]}),"\n",(0,t.jsx)(n.p,{children:"Before we can use the API component, we first need to specify the files to parse:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-ts",meta:'title="modern.config.ts"',children:"import { moduleTools, defineConfig } from '@modern-js/module-tools';\nimport { modulePluginDoc } from '@modern-js/plugin-rspress';\n\nexport default defineConfig({\n plugins: [\n moduleTools(),\n modulePluginDoc({\n entries: {\n Button: './src/button.tsx',\n },\n apiParseTool: 'react-docgen-typescript',\n }),\n ],\n});\n"})}),"\n",(0,t.jsxs)(n.h4,{id:"content-generation",children:["Content generation",(0,t.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#content-generation",children:"#"})]}),"\n",(0,t.jsx)(n.p,{children:"Next, we'll see what kind of markdown content is generated based on the parsed file."}),"\n",(0,t.jsxs)(n.p,{children:["Content can be generated with two different tools, ",(0,t.jsx)(n.a,{href:"https://github.com/styleguidist/react-docgen-typescript",target:"_blank",rel:"noopener noreferrer",children:"react-docgen-typescript"})," or ",(0,t.jsx)(n.a,{href:"https://github.com/documentationjs/documentation",target:"_blank",rel:"noopener noreferrer",children:"documentation"}),":"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"react-docgen-typescript"})," is targeted at component library scenarios and will only parse props to generate tables."]}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"export type ButtonProps = {\n /**\n * Whether to disable the button\n */\n disabled?: boolean;\n /* * Whether to disable the button */ disabled?\n * Type of Button\n * @default 'default'\n */\n size?: 'mini' | 'small' | 'default' | 'large';\n}.\nexport const Button = (props?: ButtonProps) => {};\n"})}),"\n",(0,t.jsxs)(n.p,{children:["The above is a standard writeup where ",(0,t.jsx)(n.code,{children:"ButtonProps"})," will be extracted into the table and ",(0,t.jsx)(n.code,{children:"Button"})," will be the title of the table.\nIf you use the default export, the filename will be used as the form title."]}),"\n",(0,t.jsx)(n.p,{children:"Notice that export features declared elsewhere are not available."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"const A = () => {};\n\nexport { A }; // wrong\nexport default A; // wrong\nexport const B = () => {}; // right\nexport default () => {}; // right\n"})}),"\n",(0,t.jsx)(n.p,{children:"The generated content is as follows:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-mdx",children:'### ButtonTest\n\n| property | description | type | default |\n| :------: | :---------------------------: | :--------------------------------------: | :---------: |\n| disabled | Whether to disable the button | `boolean` | `-` |\n| size | Type of Button | `"mini" \\|"small" \\|"default" \\|"large"` | `\'default\'` |\n'})}),"\n",(0,t.jsxs)(n.div,{className:"rspress-directive warning",children:[(0,t.jsx)(n.div,{className:"rspress-directive-title",children:"WARNING"}),(0,t.jsxs)(n.div,{className:"rspress-directive-content",children:[(0,t.jsx)(n.p,{children:"If React types are used in Props, you need to add the types in tsconfig.json, otherwise the types will not be resolved under the React namespace."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "compilerOptions": {\n "types": ["react"]\n }\n}\n'})}),"\n",(0,t.jsx)(n.p,{children:"The best way is that you import the type directly:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"import { FC } from 'react';\n"})}),"\n"]})]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"documentation"})," is used in tool library scenarios to parse JSDoc annotations."]}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-ts",children:"/**\n * Greet function that returns a greeting message.\n * @param {string} name - The name of the person to greet.\n * @param {string} [greeting='Hello'] - The greeting to use.\n * @returns {string} The greeting message.\n */\nfunction greet(name: string, greeting = 'Hello') {\n return `${greeting}, ${name}! `;\n}\n"})}),"\n",(0,t.jsx)(n.p,{children:"The above is a greet function with a JSDoc annotation. The generated content is as follows:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-md",children:"<! -- Generated by documentation.js. Update this documentation by updating the source code. --\x3e\n\n## greet\n\nGreet function that returns a greeting message.\n\n### Parameters\n\n- `name` **[string][1]** The name of the person to greet.\n- `greeting` **[string][1]** The greeting to use. (optional, default `'Hello'`)\n\nReturns **[string][1]** The greeting message.\n\n[1]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String\n"})}),"\n",(0,t.jsxs)(n.h4,{id:"using-the-component",children:["Using the component",(0,t.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#using-the-component",children:"#"})]}),"\n",(0,t.jsxs)(n.p,{children:["Next, you can use our built-in API components in your documentation by passing the ",(0,t.jsx)(n.code,{children:"key"})," value into the ",(0,t.jsx)(n.code,{children:"moduleName"})," property。"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-mdx",meta:'title="Button.mdx"',children:'# Button\n\n## API\n\n<API moduleName="Button" />\n'})}),"\n",(0,t.jsxs)(n.h3,{id:"overview",children:["Overview",(0,t.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#overview",children:"#"})]}),"\n",(0,t.jsx)(n.p,{children:"Displays a list of modules that can be placed on the front page to display all modules."}),"\n",(0,t.jsx)(n.p,{children:"The Overview component has only one list property, which receives an array of objects, and the following properties of the objects"}),"\n",(0,t.jsxs)(n.table,{children:["\n",(0,t.jsxs)(n.thead,{children:["\n",(0,t.jsxs)(n.tr,{children:["\n",(0,t.jsx)(n.th,{align:"center",children:"property"}),"\n",(0,t.jsx)(n.th,{align:"center",children:"description"}),"\n",(0,t.jsx)(n.th,{align:"center",children:"type"}),"\n",(0,t.jsx)(n.th,{align:"center",children:"default"}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.tbody,{children:["\n",(0,t.jsxs)(n.tr,{children:["\n",(0,t.jsx)(n.td,{align:"center",children:"icon"}),"\n",(0,t.jsx)(n.td,{align:"center",children:"icon"}),"\n",(0,t.jsx)(n.td,{align:"center",children:"React.ReactNode"}),"\n",(0,t.jsx)(n.td,{align:"center"}),"\n"]}),"\n",(0,t.jsxs)(n.tr,{children:["\n",(0,t.jsx)(n.td,{align:"center",children:"text"}),"\n",(0,t.jsxs)(n.td,{align:"center",children:["text(",(0,t.jsx)(n.strong,{children:"required"}),")"]}),"\n",(0,t.jsx)(n.td,{align:"center",children:"string"}),"\n",(0,t.jsx)(n.td,{align:"center"}),"\n"]}),"\n",(0,t.jsxs)(n.tr,{children:["\n",(0,t.jsx)(n.td,{align:"center",children:"link"}),"\n",(0,t.jsxs)(n.td,{align:"center",children:["link(",(0,t.jsx)(n.strong,{children:"required"}),")"]}),"\n",(0,t.jsx)(n.td,{align:"center",children:"string"}),"\n",(0,t.jsx)(n.td,{align:"center"}),"\n"]}),"\n",(0,t.jsxs)(n.tr,{children:["\n",(0,t.jsx)(n.td,{align:"center",children:"arrow"}),"\n",(0,t.jsx)(n.td,{align:"center",children:"whether to show arrows"}),"\n",(0,t.jsx)(n.td,{align:"center",children:"boolean"}),"\n",(0,t.jsx)(n.td,{align:"center",children:(0,t.jsx)(n.code,{children:"false"})}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.h2,{id:"plugin-options",children:["Plugin options",(0,t.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#plugin-options",children:"#"})]}),"\n",(0,t.jsxs)(n.h3,{id:"apiparsetool",children:["apiParseTool",(0,t.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#apiparsetool",children:"#"})]}),"\n",(0,t.jsx)(n.p,{children:"API parse tool."}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Type:",(0,t.jsx)(n.code,{children:"'react-docgen-typescript' | 'documentation'"})]}),"\n",(0,t.jsxs)(n.li,{children:["Default: ",(0,t.jsx)(n.code,{children:"'react-docgen-typescript'"})]}),"\n"]}),"\n",(0,t.jsxs)(n.h3,{id:"doc",children:["doc",(0,t.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#doc",children:"#"})]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.a,{href:"https://rspress.dev/api/index.html",target:"_blank",rel:"noopener noreferrer",children:"Config"}),"."]}),"\n",(0,t.jsxs)(n.h3,{id:"entries",children:["entries",(0,t.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#entries",children:"#"})]}),"\n",(0,t.jsx)(n.p,{children:"Module names and relative paths for automatically generated documents."}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Type:",(0,t.jsx)(n.code,{children:"Entries | ToolEntries"})]}),"\n",(0,t.jsxs)(n.li,{children:["Default: ",(0,t.jsx)(n.code,{children:"{}"})]}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-ts",children:"type Entries = Record<string, string>;\ntype ToolEntries = {\n documentation: Entries;\n 'react-docgen-typescript': Entries;\n};\n"})}),"\n",(0,t.jsx)(n.p,{children:"It also supports the use of different parsing tools for different files:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-ts",meta:'title="modern.config.ts"',children:"import { moduleTools, defineConfig } from '@modern-js/module-tools';\nimport { modulePluginDoc } from '@modern-js/plugin-rspress';\n\nexport default defineConfig({\n plugins: [\n moduleTools(),\n modulePluginDoc({\n entries: {\n documentation: {\n Add: './src/utils/add.ts',\n },\n 'react-docgen-typescript': {\n Button: './src/components/button.tsx',\n },\n },\n }),\n ],\n});\n"})}),"\n",(0,t.jsxs)(n.h3,{id:"iframeposition",children:["iframePosition",(0,t.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#iframeposition",children:"#"})]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["类型:",(0,t.jsx)(n.code,{children:"'follow' | 'fixed'"})]}),"\n",(0,t.jsxs)(n.li,{children:["默认值: ",(0,t.jsx)(n.code,{children:"'follow'"})]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["When the value is ",(0,t.jsx)(n.code,{children:"follow"}),", each code block will have an iframe showing its rendered view.\nWhen ",(0,t.jsx)(n.code,{children:"fixed"}),", the iframe will be fixed to the right side of the page, showing the view of all the code blocks on the current page."]}),"\n",(0,t.jsxs)(n.h3,{id:"parsetooloptions",children:["parseToolOptions",(0,t.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#parsetooloptions",children:"#"})]}),"\n",(0,t.jsx)(n.p,{children:"API parse tool options."}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Type:",(0,t.jsx)(n.code,{children:"ParseToolOptions"})]}),"\n",(0,t.jsxs)(n.li,{children:["Default: ",(0,t.jsx)(n.code,{children:"{}"})]}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-ts",children:"type ParseToolOptions = {\n // https://github.com/styleguidist/react-docgen-typescript#options\n 'react-docgen-typescript'?: ParserOptions;\n // https://github.com/documentationjs/documentation/blob/master/docs/NODE_API.md#parameters-1\n documentation?: DocumentationArgs;\n};\n"})}),"\n",(0,t.jsxs)(n.h3,{id:"previewmode",children:["previewMode",(0,t.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#previewmode",children:"#"})]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Type:",(0,t.jsx)(n.code,{children:"'iframe' | 'internal'"})]}),"\n",(0,t.jsxs)(n.li,{children:["Default: ",(0,t.jsx)(n.code,{children:"'internal'"})]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["In case of ",(0,t.jsx)(n.code,{children:"internal"}),", the component will be rendered directly in the page, otherwise it will be loaded through an iframe."]}),"\n",(0,t.jsxs)(n.h3,{id:"deprecated-languages",children:["deprecated: languages",(0,t.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#deprecated-languages",children:"#"})]}),"\n",(0,t.jsxs)(n.div,{className:"rspress-directive warning",children:[(0,t.jsx)(n.div,{className:"rspress-directive-title",children:"WARNING"}),(0,t.jsx)(n.div,{className:"rspress-directive-content",children:(0,t.jsxs)(n.p,{children:["Starting from version 2.44.0, please refer to the ",(0,t.jsx)(n.a,{href:"https://rspress.dev/guide/default-theme/i18n.html",target:"_blank",rel:"noopener noreferrer",children:"Internationalization"})," section to implement multiple languages.\n"]})})]}),"\n",(0,t.jsxs)(n.h3,{id:"deprecated-usemodulesidebar",children:["deprecated: useModuleSidebar",(0,t.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#deprecated-usemodulesidebar",children:"#"})]}),"\n",(0,t.jsxs)(n.div,{className:"rspress-directive warning",children:[(0,t.jsx)(n.div,{className:"rspress-directive-title",children:"WARNING"}),(0,t.jsx)(n.div,{className:"rspress-directive-content",children:(0,t.jsxs)(n.p,{children:["Starting from version 2.44.0, a sniffing mechanism has been implemented internally, so please directly use ",(0,t.jsx)(n.a,{href:"https://rspress.dev/guide/basic/auto-nav-sidebar.html",target:"_blank",rel:"noopener noreferrer",children:"_meta.json"}),"\nor directly configure ",(0,t.jsx)(n.a,{href:"https://rspress.dev/api/config/config-theme.html#sidebar",target:"_blank",rel:"noopener noreferrer",children:"sidebar"})," to implement a custom sidebar.\n"]})})]}),"\n",(0,t.jsxs)(n.h2,{id:"scripts",children:["Scripts",(0,t.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#scripts",children:"#"})]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"modern dev"}),": Start dev server for doc site."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"modern build --platform"}),": Build doc site in production, by default output directories is ",(0,t.jsx)(n.code,{children:"doc_build"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.h2,{id:"advanced-guide",children:["Advanced guide",(0,t.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#advanced-guide",children:"#"})]}),"\n",(0,t.jsxs)(n.p,{children:["The above has covered the basics of developing module documentation, but this is not enough for developing a complete documentation station. Check out the ",(0,t.jsx)(n.a,{href:"https://rspress.dev",target:"_blank",rel:"noopener noreferrer",children:"Rspress"})," for an in-depth look at our documentation framework.\nYou can modify the documentation framework configuration via the ",(0,t.jsx)(n.code,{children:"doc"})," configuration."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-ts",meta:'title="modern.config.ts"',children:"import { moduleTools, defineConfig } from '@modern-js/module-tools'.\nimport { modulePluginDoc } from '@modern-js/plugin-rspress'.\n\nexport default defineConfig({\n plugins: [\n moduleTools(),\n modulePluginDoc({\n doc: {\n // Customize the documentation site configuration\n }\n }),\n ],\n});\n"})})]})}function o(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},{wrapper:n}=Object.assign({},(0,i.ah)(),e.components);return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(s,{...e})}):s(e)}let d=o;o.__RSPRESS_PAGE_META={},o.__RSPRESS_PAGE_META["en%2Fguide%2Fbasic%2Fuse-module-doc.mdx"]={toc:[{text:"Before we start",id:"before-we-start",depth:2},{text:"Why we need to build a documentation site for a module",id:"why-we-need-to-build-a-documentation-site-for-a-module",depth:3},{text:"Preliminary preparation",id:"preliminary-preparation",depth:3},{text:"Basic site structure",id:"basic-site-structure",depth:2},{text:"Configure sidebar",id:"configure-sidebar",depth:3},{text:"Writing Documentation",id:"writing-documentation",depth:2},{text:"Component preview",id:"component-preview",depth:2},{text:"Example",id:"example",depth:3},{text:"Mobile Preview",id:"mobile-preview",depth:3},{text:"Using external demos",id:"using-external-demos",depth:3},{text:"Using built-in components",id:"using-built-in-components",depth:2},{text:"API",id:"api",depth:3},{text:"Parse file",id:"parse-file",depth:4},{text:"Content generation",id:"content-generation",depth:4},{text:"Using the component",id:"using-the-component",depth:4},{text:"Overview",id:"overview",depth:3},{text:"Plugin options",id:"plugin-options",depth:2},{text:"apiParseTool",id:"apiparsetool",depth:3},{text:"doc",id:"doc",depth:3},{text:"entries",id:"entries",depth:3},{text:"iframePosition",id:"iframeposition",depth:3},{text:"parseToolOptions",id:"parsetooloptions",depth:3},{text:"previewMode",id:"previewmode",depth:3},{text:"deprecated: languages",id:"deprecated-languages",depth:3},{text:"deprecated: useModuleSidebar",id:"deprecated-usemodulesidebar",depth:3},{text:"Scripts",id:"scripts",depth:2},{text:"Advanced guide",id:"advanced-guide",depth:2}],title:"Developing Module documentation",frontmatter:{sidebar_position:5}}}}]);
@@ -0,0 +1 @@
1
+ "use strict";(self.webpackChunk_modern_js_module_tools_docs=self.webpackChunk_modern_js_module_tools_docs||[]).push([["4061"],{992:function(e,n,r){r.r(n),r.d(n,{default:function(){return o}});var l=r(8093),s=r(5878);function i(e){let n=Object.assign({h1:"h1",a:"a",p:"p",ul:"ul",li:"li",code:"code",h2:"h2",h3:"h3",pre:"pre",blockquote:"blockquote"},(0,s.ah)(),e.components);return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsxs)(n.h1,{id:"plugin-hooks",children:["Plugin Hooks",(0,l.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#plugin-hooks",children:"#"})]}),"\n",(0,l.jsx)(n.p,{children:"本章介绍关于 Modern.js Module 支持的生命周期钩子。"}),"\n",(0,l.jsx)(n.p,{children:"目前主要包含以下几类生命周期钩子:"}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:"配置钩子:用于处理用户配置。"}),"\n",(0,l.jsxs)(n.li,{children:["构建钩子:仅在执行 ",(0,l.jsx)(n.code,{children:"build"})," 命令构建源码产物时触发。"]}),"\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.code,{children:"buildPlatform"})," 钩子:仅在执行 ",(0,l.jsx)(n.code,{children:"build --platform"})," 命令生成其他构建产物时触发。"]}),"\n",(0,l.jsxs)(n.li,{children:["调试钩子:运行 ",(0,l.jsx)(n.code,{children:"dev"})," 命令时会触发的钩子。"]}),"\n"]}),"\n",(0,l.jsxs)(n.p,{children:["这里详细解释了 ",(0,l.jsx)(n.a,{href:"https://modernjs.dev/guides/topic-detail/framework-plugin/hook.html",target:"_blank",rel:"noopener noreferrer",children:"Hook 模型"})]}),"\n",(0,l.jsxs)(n.h2,{id:"配置钩子",children:["配置钩子",(0,l.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#配置钩子",children:"#"})]}),"\n",(0,l.jsxs)(n.h3,{id:"resolvemoduleuserconfig",children:[(0,l.jsx)(n.code,{children:"resolveModuleUserConfig"}),(0,l.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#resolvemoduleuserconfig",children:"#"})]}),"\n",(0,l.jsx)(n.p,{children:"用于修改用户配置。"}),"\n",(0,l.jsxs)(n.p,{children:["类型:",(0,l.jsx)(n.code,{children:"AsyncWaterfall"})]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-ts",children:"export const myPlugin = (): CliPlugin<ModuleTools> => ({\n name: 'my-plugin',\n\n setup() {\n return {\n resolveModuleUserConfig(config: ModuleUserConfig): ModuleUserConfig {},\n };\n },\n});\n"})}),"\n",(0,l.jsxs)(n.h2,{id:"构建钩子",children:["构建钩子",(0,l.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#构建钩子",children:"#"})]}),"\n",(0,l.jsxs)(n.p,{children:["在执行 ",(0,l.jsx)(n.code,{children:"build"})," 命令的时候,会按照顺序触发以下 Hooks:"]}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"beforeBuild"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"beforeBuildTask"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"afterBuildTask"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"afterBuild"})}),"\n"]}),"\n",(0,l.jsxs)(n.h3,{id:"beforebuild",children:[(0,l.jsx)(n.code,{children:"beforeBuild"}),(0,l.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#beforebuild",children:"#"})]}),"\n",(0,l.jsx)(n.p,{children:"执行整体构建流程之前触发。"}),"\n",(0,l.jsxs)(n.p,{children:["类型:",(0,l.jsx)(n.code,{children:"ParallelWorkflow"})]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-ts",children:"export const myPlugin = (): CliPlugin<ModuleTools> => ({\n name: 'my-plugin',\n\n setup() {\n return {\n beforeBuild(options: Options): void {},\n };\n },\n});\n"})}),"\n",(0,l.jsx)(n.p,{children:"参数类型:"}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-ts",children:"type Options = {\n options: { config: BaseBuildConfig[]; cliOptions: BuildCommandOptions };\n};\n\nexport interface BuildCommandOptions {\n config: string;\n clear?: boolean;\n dts?: boolean;\n platform?: boolean | string[];\n tsconfig: string;\n watch?: boolean;\n}\n"})}),"\n",(0,l.jsxs)(n.blockquote,{children:["\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.code,{children:"BuildConfig"})," 类型参考 ",(0,l.jsx)(n.a,{href:"/api/",children:"API 配置"})]}),"\n"]}),"\n",(0,l.jsxs)(n.h3,{id:"beforebuildtask",children:[(0,l.jsx)(n.code,{children:"beforeBuildTask"}),(0,l.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#beforebuildtask",children:"#"})]}),"\n",(0,l.jsx)(n.p,{children:"根据构建配置,Modern.js Module 会将整体构建分成多个子构建任务。该 Hook 将会在每一个构建子任务之前触发。"}),"\n",(0,l.jsxs)(n.p,{children:["类型:",(0,l.jsx)(n.code,{children:"AsyncWaterfall"})]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-ts",children:"export const myPlugin = (): CliPlugin<ModuleTools> => ({\n name: 'my-plugin',\n\n setup() {\n return {\n beforeBuildTask(config: BaseBuildConfig): BaseBuildConfig {\n return config;\n },\n };\n },\n});\n"})}),"\n",(0,l.jsxs)(n.h3,{id:"afterbuildtask",children:[(0,l.jsx)(n.code,{children:"afterBuildTask"}),(0,l.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#afterbuildtask",children:"#"})]}),"\n",(0,l.jsxs)(n.p,{children:["类型:",(0,l.jsx)(n.code,{children:"ParallelWorkflow"}),",每一个构建子任务结束之后触发。"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-ts",children:"export const myPlugin = (): CliPlugin<ModuleTools> => ({\n name: 'my-plugin',\n\n setup() {\n return {\n afterBuildTask(options: BuildTaskResult): void {\n // ...\n },\n };\n },\n});\n"})}),"\n",(0,l.jsx)(n.p,{children:"参数和返回值类型:"}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-ts",children:"export interface BuildTaskResult {\n status: 'success' | 'fail';\n message?: string;\n config: BaseBuildConfig;\n}\n"})}),"\n",(0,l.jsxs)(n.h3,{id:"afterbuild",children:[(0,l.jsx)(n.code,{children:"afterBuild"}),(0,l.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#afterbuild",children:"#"})]}),"\n",(0,l.jsxs)(n.p,{children:["类型:",(0,l.jsx)(n.code,{children:"ParallelWorkflow"}),",整体构建流程结束之后触发。"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-ts",children:"export const myPlugin = (): CliPlugin<ModuleTools> => ({\n name: 'my-plugin',\n\n setup() {\n return {\n afterBuild(options: BuildResult): void {\n // ...\n },\n };\n },\n});\n"})}),"\n",(0,l.jsx)(n.p,{children:"参数和返回值类型:"}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-ts",children:"export interface BuildResult {\n status: 'success' | 'fail';\n message?: string;\n config: BuildConfig;\n commandOptions: BuildCommandOptions;\n totalDuration: number;\n}\n"})}),"\n",(0,l.jsxs)(n.h2,{id:"buildplatform-钩子",children:["buildPlatform 钩子",(0,l.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#buildplatform-钩子",children:"#"})]}),"\n",(0,l.jsxs)(n.p,{children:["module-tools 还提供了 ",(0,l.jsx)(n.code,{children:"build --platform"})," 命令来执行特定的构建任务。"]}),"\n",(0,l.jsxs)(n.p,{children:["例如在安装了 Doc 插件后,就可以执行 ",(0,l.jsx)(n.code,{children:"build --platform"})," 或者 ",(0,l.jsx)(n.code,{children:"build --platform doc"})," 来执行 doc 的构建任务。因为 doc 插件基于 buildPlatform Hooks 实现了该功能。"]}),"\n",(0,l.jsxs)(n.p,{children:["在执行 ",(0,l.jsx)(n.code,{children:"build --platform"})," 后会按照以下顺序触发 Hooks:"]}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"registerBuildPlatform"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"beforeBuildPlatform"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"buildPlatform"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"afterBuildPlatform"})}),"\n"]}),"\n",(0,l.jsxs)(n.h3,{id:"registerbuildplatform",children:[(0,l.jsx)(n.code,{children:"registerBuildPlatform"}),(0,l.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#registerbuildplatform",children:"#"})]}),"\n",(0,l.jsxs)(n.p,{children:["获取在执行 ",(0,l.jsx)(n.code,{children:"build --platform"})," 命令时候需要运行的任务信息。"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-ts",children:"export const myPlugin = (): CliPlugin<ModuleTools> => ({\n name: 'my-plugin',\n\n setup() {\n return {\n registerBuildPlatform(): RegisterBuildPlatformResult {\n // ...\n return {\n platform: 'doc',\n build() {\n // logic\n },\n };\n },\n };\n },\n});\n"})}),"\n",(0,l.jsx)(n.p,{children:"入参和返回的参数类型:"}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-ts",children:"export interface RegisterBuildPlatformResult {\n platform: string | string[];\n build: (\n currentPlatform: string, // 当前运行的 platform 构建任务\n context: { isTsProject: boolean },\n ) => void | Promise<void>;\n}\n"})}),"\n",(0,l.jsxs)(n.h3,{id:"beforebuildplatform",children:[(0,l.jsx)(n.code,{children:"beforeBuildPlatform"}),(0,l.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#beforebuildplatform",children:"#"})]}),"\n",(0,l.jsxs)(n.p,{children:["当执行 ",(0,l.jsx)(n.code,{children:"build --platform"})," 命令的时候,会触发所有已注册的构建任务。",(0,l.jsx)(n.code,{children:"beforeBuildPlatform"})," 会在执行整体的构建任务之前触发。"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-ts",children:"export const myPlugin = (): CliPlugin<ModuleTools> => ({\n name: 'my-plugin',\n\n setup() {\n return {\n beforeBuildPlatform(platforms: RegisterBuildPlatformResult[]): void {\n console.info(`have ${platforms.length} platform tasks`);\n },\n };\n },\n});\n"})}),"\n",(0,l.jsx)(n.p,{children:"入参和返回的参数类型:"}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-ts",children:"export interface RegisterBuildPlatformResult {\n platform: string | string[];\n build: (\n currentPlatform: string, // 当前运行的 platform 构建任务\n context: { isTsProject: boolean },\n ) => void | Promise<void>;\n}\n"})}),"\n",(0,l.jsxs)(n.h3,{id:"buildplatform",children:[(0,l.jsx)(n.code,{children:"buildPlatform"}),(0,l.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#buildplatform",children:"#"})]}),"\n",(0,l.jsxs)(n.p,{children:["当执行 ",(0,l.jsx)(n.code,{children:"build --platform"})," 命令的时候,会触发所有已注册的构建任务。",(0,l.jsx)(n.code,{children:"buildPlatform"})," 会在每个构建任务执行之前触发。"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-ts",children:"export const myPlugin = (): CliPlugin<ModuleTools> => ({\n name: 'my-plugin',\n\n setup() {\n return {\n buildPlatform({ platform }: Options): void {\n console.info(`current task is ${platform}`);\n },\n };\n },\n});\n"})}),"\n",(0,l.jsx)(n.p,{children:"入参和返回的参数类型:"}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-ts",children:"export interface Options {\n platform: string;\n}\n"})}),"\n",(0,l.jsxs)(n.h3,{id:"afterbuildplatform",children:[(0,l.jsx)(n.code,{children:"afterBuildPlatform"}),(0,l.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#afterbuildplatform",children:"#"})]}),"\n",(0,l.jsxs)(n.p,{children:["当执行 ",(0,l.jsx)(n.code,{children:"build --platform"})," 命令的时候,会触发所有已注册的构建任务。",(0,l.jsx)(n.code,{children:"afterBuildPlatform"})," 会在整体 platform 构建任务结束后触发。"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-ts",children:"export const myPlugin = (): CliPlugin<ModuleTools> => ({\n name: 'my-plugin',\n\n setup() {\n return {\n afterBuildPlatform(result: BuildPlatformResult): void {\n if (result.status === 'success') {\n console.info(`all platform build task success`);\n } else {\n console.error(result.message);\n }\n },\n };\n },\n});\n"})}),"\n",(0,l.jsx)(n.p,{children:"入参和返回的参数类型:"}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-ts",children:"export interface BuildPlatformResult {\n status: 'success' | 'fail';\n message: string | Error | null;\n}\n"})}),"\n",(0,l.jsxs)(n.h2,{id:"调试钩子",children:["调试钩子",(0,l.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#调试钩子",children:"#"})]}),"\n",(0,l.jsxs)(n.p,{children:["在执行 ",(0,l.jsx)(n.code,{children:"dev"})," 命令的时候,会按照顺序触发以下 Hooks:"]}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.code,{children:"registerDev"}),": 在获取调试功能信息的时候触发。"]}),"\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.code,{children:"beforeDev"}),": 开始执行调试整体流程之前触发。"]}),"\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.code,{children:"beforeDevMenu"}),": 出现调试列表/菜单之前触发。"]}),"\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.code,{children:"afterDevMenu"}),": 选择调试列表/菜单选项后触发。"]}),"\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.code,{children:"beforeDevTask"}),": 执行调试任务之前触发。"]}),"\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.code,{children:"afterDev"}),": 执行 dev 整体流程最后触发。"]}),"\n"]}),"\n",(0,l.jsxs)(n.h3,{id:"registerdev",children:[(0,l.jsx)(n.code,{children:"registerDev"}),(0,l.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#registerdev",children:"#"})]}),"\n",(0,l.jsx)(n.p,{children:"注册调试工具相关的数据。主要包含:"}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:"调试工具的名称"}),"\n",(0,l.jsx)(n.li,{children:"显示在菜单列表中的项目名称以及对应的值。"}),"\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.code,{children:"dev"})," 子命令的定义。"]}),"\n",(0,l.jsx)(n.li,{children:"是否在运行调试任务之前执行源码构建"}),"\n",(0,l.jsx)(n.li,{children:"执行调试任务的函数。"}),"\n"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-ts",children:"export const myPlugin = (): CliPlugin<ModuleTools> => ({\n name: 'my-plugin',\n\n setup() {\n return {\n registerDev() {\n return {\n // 调试工具名称\n name: 'storybook',\n // 菜单显示内容\n menuItem: {\n name: 'Storybook',\n value: 'storybook',\n },\n // 定义的 dev 子命令\n subCommands: ['storybook', 'story'],\n async action() {\n // dev logic\n },\n };\n },\n };\n },\n});\n"})}),"\n",(0,l.jsx)(n.p,{children:"入参和返回的参数类型:"}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-ts",children:"export interface DevToolData {\n name: string;\n subCommands?: string[];\n menuItem?: {\n name: string;\n value: string;\n };\n action: (\n options: { port?: string },\n context: { isTsProject?: boolean },\n ) => void | Promise<void>;\n}\n"})}),"\n",(0,l.jsxs)(n.h3,{id:"beforedev",children:[(0,l.jsx)(n.code,{children:"beforeDev"}),(0,l.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#beforedev",children:"#"})]}),"\n",(0,l.jsx)(n.p,{children:"在收集完所有调试工具元数据后,执行 dev 任务之前触发。"}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-ts",children:"export const myPlugin = (): CliPlugin<ModuleTools> => ({\n name: 'my-plugin',\n\n setup() {\n return {\n beforeDev(metas: DevToolData[]) {\n console.info(`have ${metas.length} dev tools`);\n },\n };\n },\n});\n"})}),"\n",(0,l.jsx)(n.p,{children:"入参和返回的参数类型:"}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-ts",children:"export interface DevToolData {\n name: string;\n subCommands?: string[];\n menuItem?: {\n name: string;\n value: string;\n };\n action: (\n options: { port?: string },\n context: { isTsProject?: boolean },\n ) => void | Promise<void>;\n}\n"})}),"\n",(0,l.jsxs)(n.h3,{id:"beforeafterdevmenu",children:[(0,l.jsx)(n.code,{children:"(before|after)DevMenu"}),(0,l.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#beforeafterdevmenu",children:"#"})]}),"\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.code,{children:"beforeDevMenu"})," 在出现调试列表/菜单之前触发。接收 ",(0,l.jsx)(n.a,{href:"https://github.com/SBoudrias/Inquirer.js#question",target:"_blank",rel:"noopener noreferrer",children:"inquirer question"})," 作为参数。默认值为:"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-ts",children:"const question = [\n {\n name: 'choiceDevTool',\n message: '选择调试工具',\n type: 'list',\n // 注册的调试信息\n choices,\n },\n];\n"})}),"\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.code,{children:"afterDevMenu"})," 选择调试列表/菜单选项后触发。"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-ts",children:"export const myPlugin = (): CliPlugin<ModuleTools> => ({\n name: 'my-plugin',\n\n setup() {\n return {\n beforeDevMenu(questions) {\n questions[0].message += '!';\n return questions; // required\n },\n afterDevMenu(options: Options) {\n console.info(`choise ${options.result.choiceDevTool} dev tools`);\n },\n };\n },\n});\n"})}),"\n",(0,l.jsx)(n.p,{children:"入参和返回的参数类型:"}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-ts",children:"export type { QuestionCollection } from 'inquirer';\n\nexport interface Options {\n result: PromptResult;\n devTools: DevToolData[];\n}\n\nexport type PromptResult = { choiceDevTool: string };\nexport interface DevToolData {\n name: string;\n subCommands?: string[];\n menuItem?: {\n name: string;\n value: string;\n };\n action: (\n options: { port?: string },\n context: { isTsProject?: boolean },\n ) => void | Promise<void>;\n}\n"})}),"\n",(0,l.jsxs)(n.h3,{id:"beforedevtask",children:[(0,l.jsx)(n.code,{children:"beforeDevTask"}),(0,l.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#beforedevtask",children:"#"})]}),"\n",(0,l.jsx)(n.p,{children:"执行调试任务之前触发。"}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-ts",children:"export const myPlugin = (): CliPlugin<ModuleTools> => ({\n name: 'my-plugin',\n\n setup() {\n return {\n beforeDevTask(currentDevData: DevToolData) {\n console.info(`${currentDevData.name} running`);\n },\n };\n },\n});\n"})}),"\n",(0,l.jsx)(n.p,{children:"入参和返回的参数类型:"}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-ts",children:"export interface DevToolData {\n name: string;\n subCommands?: string[];\n menuItem?: {\n name: string;\n value: string;\n };\n action: (\n options: { port?: string },\n context: { isTsProject?: boolean },\n ) => void | Promise<void>;\n}\n"})}),"\n",(0,l.jsxs)(n.h3,{id:"afterdev",children:[(0,l.jsx)(n.code,{children:"afterDev"}),(0,l.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#afterdev",children:"#"})]}),"\n",(0,l.jsx)(n.p,{children:"在中断调试任务进程时触发。"}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-ts",children:"export const myPlugin = (): CliPlugin<ModuleTools> => ({\n name: 'my-plugin',\n\n setup() {\n return {\n afterDev() {\n console.info(`exit!`);\n },\n };\n },\n});\n"})})]})}function d(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},{wrapper:n}=Object.assign({},(0,s.ah)(),e.components);return n?(0,l.jsx)(n,{...e,children:(0,l.jsx)(i,{...e})}):i(e)}let o=d;d.__RSPRESS_PAGE_META={},d.__RSPRESS_PAGE_META["zh%2Fapi%2Fplugin-api%2Fplugin-hooks.md"]={toc:[{text:"配置钩子",id:"配置钩子",depth:2},{text:"`resolveModuleUserConfig`",id:"resolvemoduleuserconfig",depth:3},{text:"构建钩子",id:"构建钩子",depth:2},{text:"`beforeBuild`",id:"beforebuild",depth:3},{text:"`beforeBuildTask`",id:"beforebuildtask",depth:3},{text:"`afterBuildTask`",id:"afterbuildtask",depth:3},{text:"`afterBuild`",id:"afterbuild",depth:3},{text:"buildPlatform 钩子",id:"buildplatform-钩子",depth:2},{text:"`registerBuildPlatform`",id:"registerbuildplatform",depth:3},{text:"`beforeBuildPlatform`",id:"beforebuildplatform",depth:3},{text:"`buildPlatform`",id:"buildplatform",depth:3},{text:"`afterBuildPlatform`",id:"afterbuildplatform",depth:3},{text:"调试钩子",id:"调试钩子",depth:2},{text:"`registerDev`",id:"registerdev",depth:3},{text:"`beforeDev`",id:"beforedev",depth:3},{text:"`(before|after)DevMenu`",id:"beforeafterdevmenu",depth:3},{text:"`beforeDevTask`",id:"beforedevtask",depth:3},{text:"`afterDev`",id:"afterdev",depth:3}],title:"Plugin Hooks",frontmatter:{}}}}]);
@@ -0,0 +1 @@
1
+ "use strict";(self.webpackChunk_modern_js_module_tools_docs=self.webpackChunk_modern_js_module_tools_docs||[]).push([["4064"],{8481:function(e,n,s){s.r(n),s.d(n,{default:function(){return a}});var i=s(8093),d=s(5878);function l(e){let n=Object.assign({h1:"h1",a:"a",p:"p",h2:"h2",ol:"ol",li:"li",code:"code",pre:"pre",div:"div",h3:"h3",ul:"ul",strong:"strong",h4:"h4"},(0,d.ah)(),e.components);return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsxs)(n.h1,{id:"using-tailwind-css",children:["Using Tailwind CSS",(0,i.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#using-tailwind-css",children:"#"})]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"https://tailwindcss.com/",target:"_blank",rel:"noopener noreferrer",children:"Tailwind CSS"})," is a CSS framework and design system based on Utility Class, which can quickly add common styles to components, and support flexible extension of theme styles."]}),"\n",(0,i.jsx)(n.p,{children:"Modern.js Module supports developing component styles using Tailwind CSS."}),"\n",(0,i.jsxs)(n.h2,{id:"enabling-tailwind-css",children:["Enabling Tailwind CSS",(0,i.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#enabling-tailwind-css",children:"#"})]}),"\n",(0,i.jsxs)(n.p,{children:["To use ",(0,i.jsx)(n.a,{href:"https://tailwindcss.com/",target:"_blank",rel:"noopener noreferrer",children:"Tailwind CSS"})," in Modern.js Module, you can follow the steps below:"]}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["Run ",(0,i.jsx)(n.code,{children:"pnpm run new"})," in the root directory of your project and make the following selections:"]}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-text",children:"? Please select the operation you want: Enable features\n? Please select the feature name: Enable Tailwind CSS\n"})}),"\n",(0,i.jsxs)(n.p,{children:["After successful initialization, you will see that the ",(0,i.jsx)(n.code,{children:"package.json"})," has added dependencies for ",(0,i.jsx)(n.code,{children:"tailwindcss"})," and ",(0,i.jsx)(n.code,{children:"@modern-js/plugin-tailwindcss"}),"."]}),"\n",(0,i.jsxs)(n.ol,{start:"2",children:["\n",(0,i.jsxs)(n.li,{children:["Register the Tailwind plugin in ",(0,i.jsx)(n.code,{children:"modern.config.ts"}),":"]}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-ts",meta:'title="modern.config.ts"',children:"import { tailwindcssPlugin } from '@modern-js/plugin-tailwindcss';\n\nexport default defineConfig({\n plugins: [..., tailwindcssPlugin()],\n});\n"})}),"\n",(0,i.jsxs)(n.ol,{start:"3",children:["\n",(0,i.jsxs)(n.li,{children:["Create a ",(0,i.jsx)(n.code,{children:"index.css"})," file and add the following code:"]}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-css",meta:'title="index.css"',children:"/* base and components are optional, please add as appropriate */\n@tailwind base;\n@tailwind components;\n@tailwind utilities;\n"})}),"\n",(0,i.jsxs)(n.div,{className:"rspress-directive info",children:[(0,i.jsx)(n.div,{className:"rspress-directive-title",children:"INFO"}),(0,i.jsx)(n.div,{className:"rspress-directive-content",children:(0,i.jsxs)(n.p,{children:["Depending on your needs, you can selectively import the CSS styles provided by Tailwind CSS. Please refer to the ",(0,i.jsxs)(n.a,{href:"https://tailwindcss.com/docs/functions-and-directives#tailwind",target:"_blank",rel:"noopener noreferrer",children:[(0,i.jsx)(n.code,{children:"@tailwind"})," documentation"]})," for detailed usage of the ",(0,i.jsx)(n.code,{children:"@tailwind"})," directive.\n"]})})]}),"\n",(0,i.jsxs)(n.ol,{start:"4",children:["\n",(0,i.jsxs)(n.li,{children:["Import the ",(0,i.jsx)(n.code,{children:"index.css"})," file, for example, add the following code in the root component ",(0,i.jsx)(n.code,{children:"src/index.jsx"}),":"]}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-js",children:"import './index.css';\n"})}),"\n",(0,i.jsxs)(n.ol,{start:"5",children:["\n",(0,i.jsx)(n.li,{children:"Now you can use the Utility Classes provided by Tailwind CSS in your components:"}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-tsx",children:'const Hello = () => (\n <div className="h-12 w-48">\n <p className="text-xl font-medium text-black">hello world</p>\n </div>\n);\n'})}),"\n",(0,i.jsxs)(n.h2,{id:"configuring-tailwind-css",children:["Configuring Tailwind CSS",(0,i.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#configuring-tailwind-css",children:"#"})]}),"\n",(0,i.jsx)(n.p,{children:"In Modern.js Module, you have two ways to configure Tailwind CSS:"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["Using the ",(0,i.jsx)(n.code,{children:"tailwind.config.{ts,js}"})," file, which follows the official usage of Tailwind CSS. Please refer to ",(0,i.jsx)(n.a,{href:"https://tailwindcss.com/docs/configuration",target:"_blank",rel:"noopener noreferrer",children:'"Tailwind CSS - Configuration"'})," for more details."]}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-ts",meta:'title="tailwind.config.ts"',children:"import type { Config } from 'tailwindcss';\n\nexport default {\n content: ['./src/**/*.{js,jsx,ts,tsx}'],\n} as Config;\n"})}),"\n",(0,i.jsxs)(n.div,{className:"rspress-directive tip",children:[(0,i.jsx)(n.div,{className:"rspress-directive-title",children:"TIP"}),(0,i.jsx)(n.div,{className:"rspress-directive-content",children:(0,i.jsxs)(n.p,{children:["Please upgrade Modern.js to version >= 2.33.0 to support automatic reading of ",(0,i.jsx)(n.code,{children:"tailwind.config.{ts,js}"})," files.\n"]})})]}),"\n",(0,i.jsxs)(n.ol,{start:"2",children:["\n",(0,i.jsxs)(n.li,{children:["Using the ",(0,i.jsx)(n.a,{href:"/api/config/build-config.html#styletailwindcss",children:"style.tailwindcss"})," configuration option. This is the old way of configuring Tailwind CSS, and we recommend using the ",(0,i.jsx)(n.code,{children:"tailwind.config.{ts,js}"})," file for configuration."]}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-ts",meta:'title="modern.config.ts"',children:"export default {\n tools: {\n tailwindcss: {\n content: ['./src/**/*.{js,jsx,ts,tsx}'],\n },\n },\n};\n"})}),"\n",(0,i.jsxs)(n.p,{children:["If you are using both the ",(0,i.jsx)(n.code,{children:"tailwind.config.{ts,js}"})," file and ",(0,i.jsx)(n.code,{children:"style.tailwindcss"})," option, the configuration defined in ",(0,i.jsx)(n.code,{children:"style.tailwindcss"})," will take precedence and override the content defined in ",(0,i.jsx)(n.code,{children:"tailwind.config.{ts,js}"}),"."]}),"\n",(0,i.jsxs)(n.h3,{id:"tailwind-css-autocomplete",children:["Tailwind CSS Autocomplete",(0,i.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#tailwind-css-autocomplete",children:"#"})]}),"\n",(0,i.jsxs)(n.p,{children:["Tailwind CSS provides an official extension called ",(0,i.jsx)(n.a,{href:"https://github.com/tailwindlabs/tailwindcss-intellisense",target:"_blank",rel:"noopener noreferrer",children:"Tailwind CSS IntelliSense"})," for autocompletion of Tailwind CSS class names, CSS functions, and directives in VS Code."]}),"\n",(0,i.jsx)(n.p,{children:"You can follow the steps below to enable the autocomplete feature:"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["Install the ",(0,i.jsx)(n.a,{href:"https://github.com/tailwindlabs/tailwindcss-intellisense",target:"_blank",rel:"noopener noreferrer",children:"Tailwind CSS IntelliSense"})," extension in VS Code."]}),"\n",(0,i.jsxs)(n.li,{children:["If the root directory of your project does not have a ",(0,i.jsx)(n.code,{children:"tailwind.config.{ts,js}"})," file, you need to create one and write the Tailwind CSS configuration for your current project. Otherwise, the IDE plugin will not work correctly."]}),"\n"]}),"\n",(0,i.jsxs)(n.h2,{id:"build-modes",children:["Build Modes",(0,i.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#build-modes",children:"#"})]}),"\n",(0,i.jsx)(n.p,{children:"When using Tailwind CSS, please note that there are significant differences between the bundle and bundleless modes in terms of the build artifacts."}),"\n",(0,i.jsxs)(n.div,{className:"rspress-directive tip",children:[(0,i.jsx)(n.div,{className:"rspress-directive-title",children:"TIP"}),(0,i.jsx)(n.div,{className:"rspress-directive-content",children:(0,i.jsxs)(n.p,{children:["For definitions of bundle and bundleless, please refer to the ",(0,i.jsx)(n.a,{href:"/guide/advance/in-depth-about-build",children:'"In-depth understanding of build"'}),".\n"]})})]}),"\n",(0,i.jsxs)(n.h3,{id:"bundle-mode",children:["Bundle Mode",(0,i.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#bundle-mode",children:"#"})]}),"\n",(0,i.jsx)(n.p,{children:"In Bundle mode, a separate CSS file is generated, and the JS output does not automatically reference the CSS output file."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Source code:"}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-tsx",meta:'title="./src/index.tsx"',children:"import './index.css';\n\nexport default () => {\n return <div className=\"bg-black\">hello world</div>;\n};\n"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Output code:"}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-js",meta:'title="./dist/es/index.js"',children:"// src/index.tsx\nimport { jsx } from 'react/jsx-runtime';\nvar src_default = () => {\n return /* @__PURE__ */ jsx('div', {\n className: 'bg-black',\n children: 'hello world',\n });\n};\nexport { src_default as default };\n"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-css",meta:'title="./dist/es/index.css"',children:".bg-black {\n --tw-bg-opacity: 1;\n background-color: rgb(0 0 0 / var(--tw-bg-opacity));\n}\n/** some more... */\n"})}),"\n",(0,i.jsxs)(n.p,{children:["If you need to inject styles into the JS artifact, you can enable the ",(0,i.jsx)(n.a,{href:"/api/config/build-config#styleinject",children:"style.inject"})," option."]}),"\n",(0,i.jsxs)(n.p,{children:["If you haven't enabled ",(0,i.jsx)(n.code,{children:"style.inject"}),", you can also let users manually import the CSS file:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-js",children:"import 'your-package/dist/es/index.css';\n"})}),"\n",(0,i.jsxs)(n.h3,{id:"bundleless-mode",children:["Bundleless Mode",(0,i.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#bundleless-mode",children:"#"})]}),"\n",(0,i.jsx)(n.p,{children:"In bundleless mode, the CSS file is automatically imported in the artifact code without the need for additional processing."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Output code:"}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-js",meta:'title="./dist/es/index.js"',children:"import { jsx as _jsx } from 'react/jsx-runtime';\nimport './index.css';\nexport default () =>\n /* @__PURE__ */ _jsx('div', {\n className: 'bg-black',\n children: 'hello world',\n });\n"})}),"\n",(0,i.jsxs)(n.h2,{id:"class-name-prefix",children:["Class Name Prefix",(0,i.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#class-name-prefix",children:"#"})]}),"\n",(0,i.jsxs)(n.p,{children:["You can add a class name prefix using the ",(0,i.jsx)(n.a,{href:"https://tailwindcss.com/docs/configuration#prefix",target:"_blank",rel:"noopener noreferrer",children:"prefix"})," option provided by Tailwind CSS. This helps avoid potential class name conflicts, such as when different versions of Tailwind CSS are used in different parts of an application or module."]}),"\n",(0,i.jsxs)(n.p,{children:["For example, you can add the ",(0,i.jsx)(n.code,{children:"foo-"})," prefix using the ",(0,i.jsx)(n.code,{children:"prefix"})," option in ",(0,i.jsx)(n.code,{children:"tailwind.config.js"}),":"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-js",meta:'title="tailwind.config.js"',children:"module.exports = {\n prefix: 'foo-',\n};\n"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Source Code:"}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-tsx",meta:'title="./src/index.tsx"',children:"import './index.css';\n\nexport default () => {\n return <div className=\"foo-bg-black\">hello world</div>;\n};\n"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Output Code:"}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-css",meta:'title="./dist/es/index.css"',children:".foo-bg-black {\n --tw-bg-opacity: 1;\n background-color: rgb(0 0 0 / var(--tw-bg-opacity));\n}\n/** some more... */\n"})}),"\n",(0,i.jsxs)(n.h2,{id:"usage-guide",children:["Usage Guide",(0,i.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#usage-guide",children:"#"})]}),"\n",(0,i.jsx)(n.p,{children:"Here are some usage examples of Tailwind CSS."}),"\n",(0,i.jsxs)(n.h3,{id:"html-class-names",children:["HTML Class Names",(0,i.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#html-class-names",children:"#"})]}),"\n",(0,i.jsxs)(n.p,{children:["Tailwind CSS supports adding styles to HTML tags through class names. ",(0,i.jsx)(n.strong,{children:"When using HTML class names, please note that the corresponding CSS styles of Tailwind CSS must be imported in advance."})]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-tsx",meta:'title="./src/index.tsx"',children:"import './index.css';\n\nexport default () => {\n return <div className=\"bg-black\">hello world</div>;\n};\n"})}),"\n",(0,i.jsx)(n.p,{children:"Generated styles (after bundling):"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-css",meta:'title="./dist/es/index.css"',children:".bg-black {\n --tw-bg-opacity: 1;\n background-color: rgba(0, 0, 0, var(--tw-bg-opacity));\n}\n/** some more... */\n"})}),"\n",(0,i.jsxs)(n.h3,{id:"apply",children:[(0,i.jsx)(n.code,{children:"@apply"}),(0,i.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#apply",children:"#"})]}),"\n",(0,i.jsxs)(n.p,{children:["Tailwind CSS provides the ",(0,i.jsx)(n.a,{href:"https://v2.tailwindcss.com/docs/functions-and-directives#apply",target:"_blank",rel:"noopener noreferrer",children:(0,i.jsx)(n.code,{children:"@apply"})})," directive, which allows us to inline the styles provided by Tailwind CSS into our own styles."]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"@apply"})," can be used in CSS, Less, and Sass."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-css",children:".btn {\n @apply font-bold py-2 px-4 rounded;\n}\n"})}),"\n",(0,i.jsx)(n.p,{children:"However, there are some considerations when using it with Less and Sass:"}),"\n",(0,i.jsxs)(n.h4,{id:"sass",children:["Sass",(0,i.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#sass",children:"#"})]}),"\n",(0,i.jsxs)(n.p,{children:["When using Tailwind with Sass and there is an ",(0,i.jsx)(n.code,{children:"!important"})," after ",(0,i.jsx)(n.code,{children:"@apply"}),", interpolation should be used to ensure Sass compiles correctly."]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Won't work as expected:"}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-sass",children:".alert {\n @apply bg-red-500 !important;\n}\n"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Will work as expected:"}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-sass",children:".alert {\n @apply bg-red-500 #{!important};\n}\n"})}),"\n",(0,i.jsxs)(n.h4,{id:"less",children:["Less",(0,i.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#less",children:"#"})]}),"\n",(0,i.jsxs)(n.p,{children:["When using Tailwind with Less, you cannot nest Tailwind's ",(0,i.jsx)(n.code,{children:"@screen"})," directive."]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Won't work as expected:"}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-less",children:".card {\n @apply rounded-none;\n\n @screen sm {\n @apply rounded-lg;\n }\n}\n"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["Instead, use regular media queries and the ",(0,i.jsx)(n.code,{children:"theme()"})," function to reference your screen sizes or simply avoid nesting your ",(0,i.jsx)(n.code,{children:"@screen"})," directive."]}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-less",meta:'title="Method 1"',children:"// Use a regular media query and theme()\n.card {\n @apply rounded-none;\n\n @media (min-width: theme('screens.sm')) {\n @apply rounded-lg;\n }\n}\n"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-less",meta:'title="Method 2"',children:"// Use the @screen directive at the top-level\n.card {\n @apply rounded-none;\n\n @media (min-width: theme('screens.sm')) {\n @apply rounded-lg;\n }\n}\n"})}),"\n",(0,i.jsxs)(n.h2,{id:"about-designsystem-config",children:["About ",(0,i.jsx)(n.code,{children:"designSystem"})," config",(0,i.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#about-designsystem-config",children:"#"})]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"designSystem"})," is a deprecated configuration option in Modern.js Module."]}),"\n",(0,i.jsxs)(n.p,{children:["Starting from Modern.js Module version 2.33.0, you can use the ",(0,i.jsx)(n.code,{children:"theme"})," configuration option of Tailwind CSS as a replacement for ",(0,i.jsx)(n.code,{children:"designSystem"}),". It is no longer necessary to split the ",(0,i.jsx)(n.code,{children:"theme"})," configuration and set it on ",(0,i.jsx)(n.code,{children:"designSystem"}),"."]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Previous usage:"}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-ts",meta:'title="modern.config.ts"',children:"const { theme, ...rest } = tailwindConfig;\n\nexport default {\n style: {\n tailwindcss: rest,\n },\n designSystem: theme,\n};\n"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Current usage:"}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-ts",meta:'title="modern.config.ts"',children:"export default {\n style: {\n tailwindcss: tailwindConfig,\n },\n};\n"})})]})}function r(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},{wrapper:n}=Object.assign({},(0,d.ah)(),e.components);return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}let a=r;r.__RSPRESS_PAGE_META={},r.__RSPRESS_PAGE_META["en%2Fguide%2Fbest-practices%2Fuse-tailwindcss.mdx"]={toc:[{text:"Enabling Tailwind CSS",id:"enabling-tailwind-css",depth:2},{text:"Configuring Tailwind CSS",id:"configuring-tailwind-css",depth:2},{text:"Tailwind CSS Autocomplete",id:"tailwind-css-autocomplete",depth:3},{text:"Build Modes",id:"build-modes",depth:2},{text:"Bundle Mode",id:"bundle-mode",depth:3},{text:"Bundleless Mode",id:"bundleless-mode",depth:3},{text:"Class Name Prefix",id:"class-name-prefix",depth:2},{text:"Usage Guide",id:"usage-guide",depth:2},{text:"HTML Class Names",id:"html-class-names",depth:3},{text:"`@apply`",id:"apply",depth:3},{text:"Sass",id:"sass",depth:4},{text:"Less",id:"less",depth:4},{text:"About `designSystem` config",id:"about-designsystem-config",depth:2}],title:"Using Tailwind CSS",frontmatter:{sidebar_position:2}}}}]);
@@ -0,0 +1 @@
1
+ "use strict";(self.webpackChunk_modern_js_module_tools_docs=self.webpackChunk_modern_js_module_tools_docs||[]).push([["4206"],{3137:function(e,t,n){n.r(t),n.d(t,{default:function(){return u}});var o=n(8093),r=n(5878);function s(e){return(0,o.jsx)(o.Fragment,{})}function _(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},{wrapper:t}=Object.assign({},(0,r.ah)(),e.components);return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(s,{...e})}):s(e)}let u=_;_.__RSPRESS_PAGE_META={},_.__RSPRESS_PAGE_META["en%2Fcomponents%2Ffaq-build-other.mdx"]={toc:[],title:"",frontmatter:{}}}}]);
@@ -0,0 +1 @@
1
+ "use strict";(self.webpackChunk_modern_js_module_tools_docs=self.webpackChunk_modern_js_module_tools_docs||[]).push([["443"],{2444:function(e,n,r){r.r(n),r.d(n,{default:function(){return a}});var i=r(8093),o=r(5878),s=r(8078);function t(e){let n=Object.assign({h1:"h1",a:"a",p:"p",code:"code",div:"div",h2:"h2",h3:"h3",pre:"pre",ul:"ul",li:"li",strong:"strong"},(0,o.ah)(),e.components);return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsxs)(n.h1,{id:"import-plugin",children:["Import Plugin",(0,i.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#import-plugin",children:"#"})]}),"\n",(0,i.jsxs)(n.p,{children:["Using ",(0,i.jsx)(n.a,{href:"https://swc.rs/",target:"_blank",rel:"noopener noreferrer",children:"SWC"})," provides the same ability and configuration as ",(0,i.jsx)(n.a,{href:"https://github.com/umijs/babel-plugin-import",target:"_blank",rel:"noopener noreferrer",children:(0,i.jsx)(n.code,{children:"babel-plugin-import"})}),"."]}),"\n",(0,i.jsxs)(n.div,{className:"rspress-directive tip",children:[(0,i.jsx)(n.div,{className:"rspress-directive-title",children:"TIP"}),(0,i.jsx)(n.div,{className:"rspress-directive-content",children:(0,i.jsxs)(n.p,{children:["Since ",(0,i.jsx)(n.code,{children:"@modern-js/module-tools"})," version >= 2.16.0, this plugin functionality is built into Modern.js Module and is provided by ",(0,i.jsx)(n.a,{href:"/api/config/build-config.html#transformimport",children:(0,i.jsx)(n.code,{children:"transformImport"})}),".\n"]})})]}),"\n",(0,i.jsxs)(n.h2,{id:"quick-start",children:["Quick Start",(0,i.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#quick-start",children:"#"})]}),"\n",(0,i.jsxs)(n.h3,{id:"install",children:["Install",(0,i.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#install",children:"#"})]}),"\n","\n",(0,i.jsx)(s.SU,{command:"add @modern-js/plugin-module-import -D"}),"\n",(0,i.jsxs)(n.h3,{id:"register",children:["Register",(0,i.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#register",children:"#"})]}),"\n",(0,i.jsx)(n.p,{children:"In Modern.js Module, you can register plugins in the following way:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-ts",children:"import { moduleTools, defineConfig } from '@modern-js/module-tools';\nimport { modulePluginImport } from '@modern-js/plugin-module-import';\n\nexport default defineConfig({\n plugins: [\n moduleTools(),\n modulePluginImport({\n pluginImport: [\n {\n libraryName: 'antd',\n style: true,\n },\n ],\n }),\n ],\n});\n"})}),"\n",(0,i.jsx)(n.p,{children:"This way we can use the ability of automatic import in Modern.js Module."}),"\n",(0,i.jsxs)(n.h2,{id:"configurations",children:["Configurations",(0,i.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#configurations",children:"#"})]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Type"}),":"]}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-ts",children:"type Options = {\n pluginImport?: ImportItem[];\n};\n"})}),"\n",(0,i.jsxs)(n.h3,{id:"pluginimport",children:["pluginImport",(0,i.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#pluginimport",children:"#"})]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Type"}),": ",(0,i.jsx)(n.code,{children:"object[]"})]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["The elements of the array are configuration objects for ",(0,i.jsx)(n.code,{children:"babel-plugin-import"}),", which can be referred to ",(0,i.jsx)(n.a,{href:"https://github.com/umijs/babel-plugin-import#options",target:"_blank",rel:"noopener noreferrer",children:"options"}),"。"]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Example:"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-ts",children:"import { modulePluginImport } from '@modern-js/plugin-module-import';\nimport { moduleTools, defineConfig } from '@modern-js/module-tools';\n\nexport default defineConfig({\n plugins: [\n moduleTools(),\n modulePluginImport({\n pluginImport: [\n // babel-plugin-import`s options config\n {\n libraryName: 'foo',\n style: true,\n },\n ],\n }),\n ],\n});\n"})}),"\n",(0,i.jsxs)(n.h2,{id:"notes",children:["Notes",(0,i.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#notes",children:"#"})]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"https://swc.rs/",target:"_blank",rel:"noopener noreferrer",children:"SWC"})," (Speedy Web Compiler) is written in Rust, and this plugin is based on SWC and ported from ",(0,i.jsx)(n.a,{href:"https://github.com/umijs/babel-plugin-import",target:"_blank",rel:"noopener noreferrer",children:"babel-plugin-import"}),". The configuration options remain consistent."]}),"\n",(0,i.jsxs)(n.p,{children:["Some configurations can be passed in as functions, such as ",(0,i.jsx)(n.code,{children:"customName"}),", ",(0,i.jsx)(n.code,{children:"customStyleName"}),", etc., but in Modern.js Module, we do not recommend using functions in these configuration items.\nBecause we will call SWC in the esbuild plugin, and then when Rust calls these configuration functions through Node-API, a deadlock will occur."]}),"\n",(0,i.jsxs)(n.p,{children:["Simple function logic can actually be replaced by template language. Below is an example of using a template with ",(0,i.jsx)(n.code,{children:"customName"}),":"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-ts",children:"import { MyButton as Btn } from 'foo';\n"})}),"\n",(0,i.jsx)(n.p,{children:"Add the following configuration on the right-hand side:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-ts",children:"modulePluginImport({\n pluginImport: [\n {\n libraryName: 'foo',\n customName: 'foo/es/{{ member }}',\n },\n ],\n});\n"})}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"{{ member }}"})," in it will be replaced with the corresponding import member. After transformation:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-ts",children:"import Btn from 'foo/es/MyButton';\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Template ",(0,i.jsx)(n.code,{children:"customName: 'foo/es/{{ member }}'"})," is the same as ",(0,i.jsx)(n.code,{children:" customName: (member) => `foo/es/${member}` "}),", but template value has no performance overhead of Node-API."]}),"\n",(0,i.jsxs)(n.p,{children:["The template used here is ",(0,i.jsx)(n.a,{href:"https://handlebarsjs.com",target:"_blank",rel:"noopener noreferrer",children:"handlebars"}),". There are some useful builtin tools, Take the above import statement as an example:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-ts",children:"import { modulePluginImport } from '@modern-js/plugin-module-import';\nimport { moduleTools, defineConfig } from '@modern-js/module-tools';\n\nexport default defineConfig({\n plugins: [\n moduleTools(),\n modulePluginImport({\n pluginImport: [\n {\n libraryName: 'foo',\n customName: 'foo/es/{{ kebabCase member }}',\n },\n ],\n }),\n ],\n});\n"})}),"\n",(0,i.jsx)(n.p,{children:"Transformed to:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-ts",children:"import Btn from 'foo/es/my-button';\n"})}),"\n",(0,i.jsx)(n.p,{children:"In addition to kebabCase, there are cameraCase, snakeCase, upperCase and lowerCase can be used as well."})]})}function l(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},{wrapper:n}=Object.assign({},(0,o.ah)(),e.components);return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(t,{...e})}):t(e)}let a=l;l.__RSPRESS_PAGE_META={},l.__RSPRESS_PAGE_META["en%2Fplugins%2Fofficial-list%2Fplugin-import.mdx"]={toc:[{text:"Quick Start",id:"quick-start",depth:2},{text:"Install",id:"install",depth:3},{text:"Register",id:"register",depth:3},{text:"Configurations",id:"configurations",depth:2},{text:"pluginImport",id:"pluginimport",depth:3},{text:"Notes",id:"notes",depth:2}],title:"Import Plugin",frontmatter:{}}}}]);
@@ -0,0 +1 @@
1
+ "use strict";(self.webpackChunk_modern_js_module_tools_docs=self.webpackChunk_modern_js_module_tools_docs||[]).push([["4501"],{6435:function(e,n,i){i.r(n),i.d(n,{default:function(){return c}});var o=i(8093),t=i(5878);function s(e){let n=Object.assign({h1:"h1",a:"a",p:"p",code:"code",h2:"h2",pre:"pre",h3:"h3",div:"div",ul:"ul",li:"li"},(0,t.ah)(),e.components);return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsxs)(n.h1,{id:"setup-function",children:["Setup function",(0,o.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#setup-function",children:"#"})]}),"\n",(0,o.jsxs)(n.p,{children:["In the ",(0,o.jsx)(n.a,{href:"/plugins/guide/plugin-object",children:'"Plugin object"'})," section we know that the plugin object contains a ",(0,o.jsx)(n.code,{children:"setup"})," function that not only contains an ",(0,o.jsx)(n.code,{children:"api"})," object parameter, but also returns a Hooks object."]}),"\n",(0,o.jsxs)(n.h2,{id:"plugin-api-objects",children:["Plugin API objects",(0,o.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#plugin-api-objects",children:"#"})]}),"\n",(0,o.jsxs)(n.p,{children:["The ",(0,o.jsx)(n.code,{children:"setup"})," function of the plugin will provide an ",(0,o.jsx)(n.code,{children:"api"})," object parameter, and you can call some of the methods provided on this object to get information about the configuration, project context, etc."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-ts",children:"export const myPlugin = (): CliPlugin<ModuleTools> => ({\n name: 'my-plugin',\n\n setup(api) {\n // Get the original configuration of the application\n const config = api.useConfigContext();\n // Get the application runtime context\n const appContext = api.useAppContext();\n // Get the final configuration after resolving\n const resolvedConfig = api.useResolvedConfigContext();\n },\n});\n"})}),"\n",(0,o.jsxs)(n.h3,{id:"apiuseappcontext",children:[(0,o.jsx)(n.code,{children:"api.useAppContext"}),(0,o.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#apiuseappcontext",children:"#"})]}),"\n",(0,o.jsx)(n.p,{children:"Used to get project context information."}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-ts",children:"const useAppContext: () => IAppContext;\n\ninterface IAppContext {\n appDirectory: string;\n configFile: string | false;\n packageName: string;\n nodeModulesDirectory: string;\n internalDirectory: string;\n plugins: {\n cli?: any;\n server?: any;\n }[];\n}\n"})}),"\n",(0,o.jsxs)(n.div,{className:"rspress-directive info",children:[(0,o.jsx)(n.div,{className:"rspress-directive-title",children:"INFO"}),(0,o.jsx)(n.div,{className:"rspress-directive-content",children:(0,o.jsxs)(n.p,{children:["Through the actual type file, we can see that there are some additional fields. However, for Modern.js Module, the fields mentioned above are the only ones that are meaningful. The same applies to other methods of the ",(0,o.jsx)(n.code,{children:"api"})," object.\n"]})})]}),"\n",(0,o.jsxs)(n.h3,{id:"apiuseresolvedconfigcontext",children:[(0,o.jsx)(n.code,{children:"api.useResolvedConfigContext"}),(0,o.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#apiuseresolvedconfigcontext",children:"#"})]}),"\n",(0,o.jsx)(n.p,{children:"Used to get the final configuration after parsing."}),"\n",(0,o.jsxs)(n.div,{className:"rspress-directive info",children:[(0,o.jsx)(n.div,{className:"rspress-directive-title",children:"INFO"}),(0,o.jsx)(n.div,{className:"rspress-directive-content",children:(0,o.jsxs)(n.p,{children:["If you need to get the build-related final configuration, you need to use the ",(0,o.jsx)(n.code,{children:"beforeBuild"})," Hook.\n"]})})]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-ts",children:"const useResolvedConfigContext: () => NormalizedConfig;\n\ninterface NormalizedConfig {\n buildConfig: PartialBuildConfig;\n buildPreset: BuildPreset;\n dev: Dev;\n plugins: PluginConfig;\n runtime: RuntimeConfig;\n runtimeByEntries?: RuntimeByEntriesConfig;\n _raw: UserConfig;\n}\n"})}),"\n",(0,o.jsxs)(n.h3,{id:"apiusehookrunners",children:[(0,o.jsx)(n.code,{children:"api.useHookRunners"}),(0,o.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#apiusehookrunners",children:"#"})]}),"\n",(0,o.jsx)(n.p,{children:"Used to get the executors of Hooks and trigger the execution of a specific Hook."}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-ts",children:"import type { CliPlugin } from '@modern-js/core';\n\nexport const myPlugin = (): CliPlugin => ({\n name: 'my-plugin',\n\n async setup(api) {\n const hookRunners = api.useHookRunners();\n // trigger the afterBuild Hook\n await hookRunners.afterBuild();\n },\n});\n"})}),"\n",(0,o.jsxs)(n.h2,{id:"asynchronous-setup",children:["Asynchronous setup",(0,o.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#asynchronous-setup",children:"#"})]}),"\n",(0,o.jsx)(n.p,{children:"The setup of a CLI plugin can be an asynchronous function that performs asynchronous logic during the initialization process."}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-ts",children:"export const myPlugin = (): CliPlugin<ModuleTools> => ({\n name: 'my-plugin',\n\n async setup(api) {\n await doSomething();\n },\n});\n"})}),"\n",(0,o.jsx)(n.p,{children:"Note that the setup function of the next plugin is not executed until the async setup function of the current plugin has finished. Therefore, you should avoid performing time-consuming asynchronous operations in the setup function to avoid slowing down the startup performance of the CLI."}),"\n",(0,o.jsxs)(n.h2,{id:"life-cycle-hooks",children:["Life cycle hooks",(0,o.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#life-cycle-hooks",children:"#"})]}),"\n",(0,o.jsxs)(n.p,{children:["We know that the ",(0,o.jsx)(n.code,{children:"setup"})," function returns a Hooks object, which can also be understood as an object with Modern.js Module lifecycle hooks."]}),"\n",(0,o.jsx)(n.p,{children:"Currently there are two main types of hooks."}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["build hooks: triggered only when the ",(0,o.jsx)(n.code,{children:"build"})," command is executed to build the source code product."]}),"\n",(0,o.jsxs)(n.li,{children:[(0,o.jsx)(n.code,{children:"buildPlatform"})," hook: triggered only when the ",(0,o.jsx)(n.code,{children:"build --platform"})," command is executed to generate other build artifacts."]}),"\n",(0,o.jsxs)(n.li,{children:["debug hooks: hooks that are triggered when running the ",(0,o.jsx)(n.code,{children:"dev"})," command."]}),"\n"]}),"\n",(0,o.jsxs)(n.p,{children:["See the ",(0,o.jsx)(n.a,{href:"/en/api/plugin-api/plugin-hooks",children:"API documentation"})," for a full list of lifecycle hooks."]})]})}function r(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},{wrapper:n}=Object.assign({},(0,t.ah)(),e.components);return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(s,{...e})}):s(e)}let c=r;r.__RSPRESS_PAGE_META={},r.__RSPRESS_PAGE_META["en%2Fplugins%2Fguide%2Fsetup-function.mdx"]={toc:[{text:"Plugin API objects",id:"plugin-api-objects",depth:2},{text:"`api.useAppContext`",id:"apiuseappcontext",depth:3},{text:"`api.useResolvedConfigContext`",id:"apiuseresolvedconfigcontext",depth:3},{text:"`api.useHookRunners`",id:"apiusehookrunners",depth:3},{text:"Asynchronous setup",id:"asynchronous-setup",depth:2},{text:"Life cycle hooks",id:"life-cycle-hooks",depth:2}],title:"Setup function",frontmatter:{sidebar_position:3}}}}]);
@@ -0,0 +1 @@
1
+ "use strict";(self.webpackChunk_modern_js_module_tools_docs=self.webpackChunk_modern_js_module_tools_docs||[]).push([["453"],{7506:function(e,n,s){s.r(n),s.d(n,{default:function(){return a}});var r=s(8093),o=s(5878);function d(e){let n=Object.assign({h1:"h1",a:"a",h2:"h2",p:"p"},(0,o.ah)(),e.components);return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsxs)(n.h1,{id:"general-questions",children:["General Questions",(0,r.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#general-questions",children:"#"})]}),"\n",(0,r.jsxs)(n.h2,{id:"what-is-the-relationship-between-modernjs-module-and-rsbuild",children:["What is the relationship between Modern.js Module and Rsbuild?",(0,r.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#what-is-the-relationship-between-modernjs-module-and-rsbuild",children:"#"})]}),"\n",(0,r.jsx)(n.p,{children:"Modern.js Module uses esbuild to build toolkits and component libraries, and Rsbuild focuses on solving web application building scenarios."}),"\n",(0,r.jsxs)(n.h2,{id:"can-modernjs-module-use-webpack-plugins-or-loaders",children:["Can Modern.js Module use webpack plugins or loaders?",(0,r.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#can-modernjs-module-use-webpack-plugins-or-loaders",children:"#"})]}),"\n",(0,r.jsxs)(n.p,{children:["Modern.js Module is based on esbuild for building and cannot use tools from the webpack-related ecosystem.\nYou can find more community plugins for esbuild ",(0,r.jsx)(n.a,{href:"https://github.com/esbuild/community-plugins",target:"_blank",rel:"noopener noreferrer",children:"here"})]}),"\n",(0,r.jsxs)(n.p,{children:["If the UMD product produced by Modern.js Module does not meet your requirements, you can use Rsbuild and add ",(0,r.jsx)(n.a,{href:"https://github.com/rspack-contrib/rsbuild-plugin-umd",target:"_blank",rel:"noopener noreferrer",children:"UMD Plugin"})," to build UMD products."]})]})}function i(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},{wrapper:n}=Object.assign({},(0,o.ah)(),e.components);return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}let a=i;i.__RSPRESS_PAGE_META={},i.__RSPRESS_PAGE_META["en%2Fguide%2Ffaq%2Fbasic.mdx"]={toc:[{text:"What is the relationship between Modern.js Module and Rsbuild?",id:"what-is-the-relationship-between-modernjs-module-and-rsbuild",depth:2},{text:"Can Modern.js Module use webpack plugins or loaders?",id:"can-modernjs-module-use-webpack-plugins-or-loaders",depth:2}],title:"General Questions",frontmatter:{}}}}]);
@@ -0,0 +1 @@
1
+ "use strict";(self.webpackChunk_modern_js_module_tools_docs=self.webpackChunk_modern_js_module_tools_docs||[]).push([["461"],{112:function(e,s,n){n.r(s),n.d(s,{default:function(){return r}});var d=n(8093),c=n(5878);function i(e){let s=Object.assign({h1:"h1",a:"a",p:"p",code:"code",h2:"h2",ul:"ul",li:"li",strong:"strong",pre:"pre"},(0,c.ah)(),e.components);return(0,d.jsxs)(d.Fragment,{children:[(0,d.jsxs)(s.h1,{id:"处理静态资源",children:["处理静态资源",(0,d.jsx)(s.a,{className:"header-anchor","aria-hidden":"true",href:"#处理静态资源",children:"#"})]}),"\n",(0,d.jsxs)(s.p,{children:["Modern.js Module 会对代码中使用的静态资源进行处理。如果需要配置,则可以使用 ",(0,d.jsx)(s.a,{href:"/api/config/build-config#asset",children:(0,d.jsx)(s.code,{children:"buildConfig.asset"})})," API。"]}),"\n",(0,d.jsxs)(s.h2,{id:"默认行为",children:["默认行为",(0,d.jsx)(s.a,{className:"header-anchor","aria-hidden":"true",href:"#默认行为",children:"#"})]}),"\n",(0,d.jsx)(s.p,{children:"默认情况下,Modern.js Module 会处理以下静态资源:"}),"\n",(0,d.jsxs)(s.ul,{children:["\n",(0,d.jsxs)(s.li,{children:[(0,d.jsx)(s.code,{children:"'.svg'"}),"、",(0,d.jsx)(s.code,{children:"'.png'"}),"、",(0,d.jsx)(s.code,{children:"'.jpg'"}),"、",(0,d.jsx)(s.code,{children:"'.jpeg'"}),"、",(0,d.jsx)(s.code,{children:"'.gif'"}),"、",(0,d.jsx)(s.code,{children:"'.webp'"})]}),"\n",(0,d.jsxs)(s.li,{children:[(0,d.jsx)(s.code,{children:"'.ttf'"}),"、",(0,d.jsx)(s.code,{children:"'.otf'"}),"、",(0,d.jsx)(s.code,{children:"'.woff'"}),"、",(0,d.jsx)(s.code,{children:"'.woff2'"}),"、",(0,d.jsx)(s.code,{children:"'.eot'"})]}),"\n",(0,d.jsxs)(s.li,{children:[(0,d.jsx)(s.code,{children:"'.mp3'"}),"、",(0,d.jsx)(s.code,{children:"'.mp4'"}),"、",(0,d.jsx)(s.code,{children:"'.webm'"}),"、",(0,d.jsx)(s.code,{children:"'.ogg'"}),"、",(0,d.jsx)(s.code,{children:"'.wav'"}),"、",(0,d.jsx)(s.code,{children:"'.flac'"}),"、",(0,d.jsx)(s.code,{children:"'.aac'"}),"、",(0,d.jsx)(s.code,{children:"'.mov'"})]}),"\n"]}),"\n",(0,d.jsx)(s.p,{children:"对于静态文件的处理,Modern.js Module 目前默认支持的功能有:"}),"\n",(0,d.jsxs)(s.ul,{children:["\n",(0,d.jsxs)(s.li,{children:["输出静态资源至 ",(0,d.jsx)(s.code,{children:"./assets"}),"。"]}),"\n",(0,d.jsxs)(s.li,{children:["对于不超过 ",(0,d.jsx)(s.strong,{children:"10kb"})," 的文件会内联到代码中。"]}),"\n"]}),"\n",(0,d.jsxs)(s.h2,{id:"示例",children:["示例",(0,d.jsx)(s.a,{className:"header-anchor","aria-hidden":"true",href:"#示例",children:"#"})]}),"\n",(0,d.jsx)(s.p,{children:"让我们看下面的例子:"}),"\n",(0,d.jsxs)(s.ul,{children:["\n",(0,d.jsx)(s.li,{children:"项目源代码:"}),"\n"]}),"\n",(0,d.jsx)(s.pre,{children:(0,d.jsx)(s.code,{className:"language-ts",meta:'title="./src/asset.ts"',children:"import img from './bg.png';\n"})}),"\n",(0,d.jsxs)(s.ul,{children:["\n",(0,d.jsxs)(s.li,{children:["如果 ",(0,d.jsx)(s.code,{children:"bg.png"})," 的大小小于 10 kb,则此时产物目录结构和产物内容为:"]}),"\n"]}),"\n",(0,d.jsx)(s.pre,{children:(0,d.jsx)(s.code,{className:"language-bash",children:"./dist\n└── asset.js\n"})}),"\n",(0,d.jsx)(s.pre,{children:(0,d.jsx)(s.code,{className:"language-js",meta:'title="./dist/asset.js"',children:"var img_default = 'data:image/png;base64,';\n"})}),"\n",(0,d.jsxs)(s.ul,{children:["\n",(0,d.jsxs)(s.li,{children:["如果 ",(0,d.jsx)(s.code,{children:"bg.png"})," 的大小大于 10 kb,则此时产物目录结构和产物内容为:"]}),"\n"]}),"\n",(0,d.jsx)(s.pre,{children:(0,d.jsx)(s.code,{className:"language-bash",children:"./dist\n├── asset.js\n└── assets\n └── bg.13e2aba2.png\n"})}),"\n",(0,d.jsx)(s.pre,{children:(0,d.jsx)(s.code,{className:"language-js",meta:'title="./dist/asset.js"',children:"import img from './assets/bg.13e2aba2.png';\n"})}),"\n",(0,d.jsx)(s.p,{children:"当你想要修改默认行为的时候,可以使用以下 API:"}),"\n",(0,d.jsxs)(s.ul,{children:["\n",(0,d.jsxs)(s.li,{children:[(0,d.jsx)(s.code,{children:"asset.path"}),":修改静态资源文件输出路径。"]}),"\n",(0,d.jsxs)(s.li,{children:[(0,d.jsx)(s.code,{children:"asset.limit"}),":修改内联静态资源文件的阈值。"]}),"\n"]})]})}function l(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},{wrapper:s}=Object.assign({},(0,c.ah)(),e.components);return s?(0,d.jsx)(s,{...e,children:(0,d.jsx)(i,{...e})}):i(e)}let r=l;l.__RSPRESS_PAGE_META={},l.__RSPRESS_PAGE_META["zh%2Fguide%2Fadvance%2Fasset.mdx"]={toc:[{text:"默认行为",id:"默认行为",depth:2},{text:"示例",id:"示例",depth:2}],title:"处理静态资源",frontmatter:{sidebar_position:7}}}}]);
@@ -0,0 +1 @@
1
+ "use strict";(self.webpackChunk_modern_js_module_tools_docs=self.webpackChunk_modern_js_module_tools_docs||[]).push([["4615"],{3456:function(e,n,o){o.r(n),o.d(n,{default:function(){return s}});var d=o(8093),i=o(5878);function t(e){let n=Object.assign({h1:"h1",a:"a",p:"p",code:"code",h2:"h2",ol:"ol",li:"li",ul:"ul",pre:"pre"},(0,i.ah)(),e.components);return(0,d.jsxs)(d.Fragment,{children:[(0,d.jsxs)(n.h1,{id:"in-depth-understanding-of-the-dev-command",children:["In-depth understanding of the dev command",(0,d.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#in-depth-understanding-of-the-dev-command",children:"#"})]}),"\n",(0,d.jsxs)(n.p,{children:["The ",(0,d.jsx)(n.code,{children:"dev"})," command provided by the Modern.js Module is mainly used for debugging the code."]}),"\n",(0,d.jsxs)(n.h2,{id:"the-overall-flow-of-the-command-run",children:["The overall flow of the command run",(0,d.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#the-overall-flow-of-the-command-run",children:"#"})]}),"\n",(0,d.jsxs)(n.ol,{children:["\n",(0,d.jsxs)(n.li,{children:["When the ",(0,d.jsx)(n.code,{children:"dev"})," command is executed, Modern.js Module starts looking for debugging tools or tasks that can be executed. A debugging tool or task is a Modern.js Module debugging tool plugin like module doc."]}),"\n",(0,d.jsx)(n.li,{children:"When a debugging tool is found, it is executed immediately."}),"\n",(0,d.jsx)(n.li,{children:"When multiple debugging tools are found, the debugging tools list menu is displayed. A debug tool can be started by selecting the name option corresponding to it."}),"\n",(0,d.jsx)(n.li,{children:"When no debug tool is found, the user is informed that no debug tool is available."}),"\n"]}),"\n",(0,d.jsxs)(n.p,{children:["In addition to the ",(0,d.jsx)(n.code,{children:"dev"})," command, you can also start a debugging tool or task directly by using the ",(0,d.jsx)(n.code,{children:"dev [debug tool name]"})," option."]}),"\n",(0,d.jsxs)(n.h2,{id:"extending-the-dev-command",children:["Extending the dev command",(0,d.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#extending-the-dev-command",children:"#"})]}),"\n",(0,d.jsx)(n.p,{children:"If you need to extend the dev command, or rather provide your own Modern.js Module debugging tool plugin, then you will need to know the following first."}),"\n",(0,d.jsxs)(n.ul,{children:["\n",(0,d.jsx)(n.li,{children:(0,d.jsx)(n.a,{href:"/plugins/guide/getting-started",children:"Development of plugins"})}),"\n",(0,d.jsx)(n.li,{children:(0,d.jsx)(n.a,{href:"/api/plugin-api/plugin-hooks#dev-hooks",children:"Debugging Tools Plugin API"})}),"\n"]}),"\n",(0,d.jsx)(n.p,{children:"In general, the code to implement a debugging tool that does nothing and the associated configuration is as follows."}),"\n",(0,d.jsx)(n.pre,{children:(0,d.jsx)(n.code,{className:"language-ts",meta:"do-nothing.ts",children:"export const myPlugin = (): CliPlugin<ModuleTools> => ({\n name: 'do-nothing',\n setup() {\n return {\n registerDev() {\n return {\n // Debugging tool name\n name: 'do-nothing',\n // Menu display content\n menuItem: {\n name: 'DoNothing',\n value: 'do-nothing',\n },\n // The defined dev subcommand\n subCommands: ['donothing', 'dn'],\n async action() {\n // dev logic\n console.info('Run build --watch, and do nothing.');\n },\n };\n },\n };\n },\n});\n"})}),"\n",(0,d.jsx)(n.p,{children:"If this debugging tool plugin is required, it needs to be added to the configuration file."}),"\n",(0,d.jsx)(n.pre,{children:(0,d.jsx)(n.code,{className:"language-ts",children:"import doNothingPlugin from './plugins/do-nothing';\n\nexport default defineConfig({\n plugins: [\n //..\n doNothingPlugin()\n ],\n});\n"})}),"\n",(0,d.jsxs)(n.p,{children:["At this point we can execute it when we execute the ",(0,d.jsx)(n.code,{children:"dev"})," or ",(0,d.jsx)(n.code,{children:"dev do-nothing"})," command. After execution, it will first execute the source build task in listening mode and print the log messages immediately afterwards."]}),"\n",(0,d.jsxs)(n.p,{children:["For currently officially supported debugging tools and third-party supported debugging tools, you can view them in ",(0,d.jsx)(n.a,{href:"/plugins/official-list/overview",children:"plugins list"}),"."]})]})}function l(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},{wrapper:n}=Object.assign({},(0,i.ah)(),e.components);return n?(0,d.jsx)(n,{...e,children:(0,d.jsx)(t,{...e})}):t(e)}let s=l;l.__RSPRESS_PAGE_META={},l.__RSPRESS_PAGE_META["en%2Fguide%2Fadvance%2Fin-depth-about-dev-command.md"]={toc:[{text:"The overall flow of the command run",id:"the-overall-flow-of-the-command-run",depth:2},{text:"Extending the dev command",id:"extending-the-dev-command",depth:2}],title:"In-depth understanding of the dev command",frontmatter:{sidebar_position:2}}}}]);
@@ -0,0 +1 @@
1
+ "use strict";(self.webpackChunk_modern_js_module_tools_docs=self.webpackChunk_modern_js_module_tools_docs||[]).push([["4655"],{5518:function(t,e,n){n.r(e),n.d(e,{default:function(){return c}});var o=n(8093),s=n(5878);function r(t){return(0,o.jsx)(o.Fragment,{})}function _(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},{wrapper:e}=Object.assign({},(0,s.ah)(),t.components);return e?(0,o.jsx)(e,{...t,children:(0,o.jsx)(r,{...t})}):r(t)}let c=_;_.__RSPRESS_PAGE_META={},_.__RSPRESS_PAGE_META["zh%2Fcomponents%2Ffaq-storybook.mdx"]={toc:[],title:"",frontmatter:{}}}}]);
@@ -0,0 +1 @@
1
+ "use strict";(self.webpackChunk_modern_js_module_tools_docs=self.webpackChunk_modern_js_module_tools_docs||[]).push([["4812"],{3374:function(t,e,n){n.r(e),n.d(e,{default:function(){return u}});var o=n(8093),r=n(5878);function s(t){return(0,o.jsx)(o.Fragment,{})}function _(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},{wrapper:e}=Object.assign({},(0,r.ah)(),t.components);return e?(0,o.jsx)(e,{...t,children:(0,o.jsx)(s,{...t})}):s(t)}let u=_;_.__RSPRESS_PAGE_META={},_.__RSPRESS_PAGE_META["en%2Fcomponents%2Ffaq-build-product.mdx"]={toc:[],title:"",frontmatter:{}}}}]);
@@ -0,0 +1 @@
1
+ "use strict";(self.webpackChunk_modern_js_module_tools_docs=self.webpackChunk_modern_js_module_tools_docs||[]).push([["4904"],{3677:function(e,n,t){t.r(n),t.d(n,{default:function(){return c}});var o=t(8093),s=t(5878);function r(e){return(0,o.jsx)(o.Fragment,{})}function _(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},{wrapper:n}=Object.assign({},(0,s.ah)(),e.components);return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(r,{...e})}):r(e)}let c=_;_.__RSPRESS_PAGE_META={},_.__RSPRESS_PAGE_META["en%2Fcomponents%2Frelease-module-doc.mdx"]={toc:[],title:"",frontmatter:{}}}}]);
@@ -0,0 +1 @@
1
+ "use strict";(self.webpackChunk_modern_js_module_tools_docs=self.webpackChunk_modern_js_module_tools_docs||[]).push([["5105"],{6394:function(e,r,n){n.r(r),n.d(r,{default:function(){return t}});var o=n(8093),s=n(5878);function d(e){let r=Object.assign({h1:"h1",a:"a",p:"p",ul:"ul",li:"li",strong:"strong",code:"code"},(0,s.ah)(),e.components);return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsxs)(r.h1,{id:"欢迎使用",children:["欢迎使用",(0,o.jsx)(r.a,{className:"header-anchor","aria-hidden":"true",href:"#欢迎使用",children:"#"})]}),"\n",(0,o.jsx)(r.p,{children:"Modern.js Module 是 Modern.js 的模块工程解决方案,同时也是核心依赖。它可以让开发者更轻松地构建、调试、发布模块类型的项目。模块类型的项目大多数情况可以认为是 npm 包类型的项目,它可能是一个组件、组件库或者工具库项目。"}),"\n",(0,o.jsx)(r.p,{children:"如果你正打算开发一个 npm 包类型的项目,那么你就来对地方了!Modern.js 提供了专业的模块工程解决方案。它带来了:"}),"\n",(0,o.jsxs)(r.ul,{children:["\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.strong,{children:"简单的项目初始化"}),":仅需执行 ",(0,o.jsx)(r.code,{children:"npx @modern-js/create project-dir"})," 命令,然后进行几个交互问题,就可以创建一个完整的模块类型项目。创建的项目还支持选择 ",(0,o.jsx)(r.a,{href:"https://pnpm.io/",target:"_blank",rel:"noopener noreferrer",children:(0,o.jsx)(r.strong,{children:"pnpm"})}),"、",(0,o.jsx)(r.a,{href:"https://classic.yarnpkg.com/",target:"_blank",rel:"noopener noreferrer",children:(0,o.jsx)(r.strong,{children:"Yarn"})})," 两种包管理器。"]}),"\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.strong,{children:"全面的构建能力和更快的构建速度"}),":Modern.js Module 基于 ",(0,o.jsx)(r.a,{href:"https://esbuild.github.io/getting-started/",target:"_blank",rel:"noopener noreferrer",children:"esbuild"})," 和 ",(0,o.jsx)(r.a,{href:"https://swc.rs/",target:"_blank",rel:"noopener noreferrer",children:"SWC"})," 提供了高性能的构建能力,并且为不同构建模块的场景提供了丰富的配置。"]}),"\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.strong,{children:"Storybook 调试工具"}),":Modern.js Module 为调试模块项目提供了 ",(0,o.jsx)(r.a,{href:"https://storybook.js.org/",target:"_blank",rel:"noopener noreferrer",children:"Storybook"})," 调试工具。在安装了 Modern.js Module 的 Storybook 插件后,你可以使用 ",(0,o.jsx)(r.code,{children:"storybook dev"})," 命令来启动它。你不仅可以使用 Storybook 对组件进行调试,也可以使用在其他类型的模块上。"]}),"\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.strong,{children:"基于 Changesets 实现的版本管理"}),":当需要对项目记录变更内容的时候,可以使用 ",(0,o.jsx)(r.code,{children:"modern change"})," 命令生成包含变更内容的 Markdown 文件;当需要对项目进行版本升级的时候,可以使用 ",(0,o.jsx)(r.code,{children:"modern bump"})," 命令通过 Markdown 文件分析并升级版本;当需要发布项目的时候,可以使用 ",(0,o.jsx)(r.code,{children:"modern release"})," 命令对项目进行发布。Modern.js Module 基于 ",(0,o.jsx)(r.a,{href:"https://github.com/changesets/changesets",target:"_blank",rel:"noopener noreferrer",children:"Changesets"})," 实现了这些命令。"]}),"\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.strong,{children:"可扩展性的插件机制"}),":想要为项目集成其他的调试工具?又或者是想要在构建过程中做一些额外处理?Modern.js Module 提供了插件机制和插件钩子,插件钩子覆盖了 ",(0,o.jsx)(r.code,{children:"dev"})," 命令和 ",(0,o.jsx)(r.code,{children:"build"})," 命令两个流程。你可以通过它们为项目进行能力的扩展。"]}),"\n",(0,o.jsxs)(r.li,{children:[(0,o.jsx)(r.strong,{children:"还有更多"}),":Modern.js Module 在未来还会不断地在构建、调试功能上进行优化。如果在模块项目构建上存在需要解决的重要问题,又或者是某个主流的模块项目调试工具、模式出现的时候,那么它们很可能成为 Modern.js Module 将要支持功能。"]}),"\n"]})]})}function l(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},{wrapper:r}=Object.assign({},(0,s.ah)(),e.components);return r?(0,o.jsx)(r,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}let t=l;l.__RSPRESS_PAGE_META={},l.__RSPRESS_PAGE_META["zh%2Fguide%2Fintro%2Fwelcome.md"]={toc:[],title:"欢迎使用",frontmatter:{sidebar_position:1}}}}]);
@@ -0,0 +1 @@
1
+ "use strict";(self.webpackChunk_modern_js_module_tools_docs=self.webpackChunk_modern_js_module_tools_docs||[]).push([["5453"],{8761:function(e,n,r){r.r(n),r.d(n,{default:function(){return l}});var d=r(8093),s=r(5878);function a(e){let n=Object.assign({h1:"h1",a:"a",p:"p",h2:"h2",code:"code",pre:"pre",ul:"ul",li:"li",em:"em",div:"div"},(0,s.ah)(),e.components);return(0,d.jsxs)(d.Fragment,{children:[(0,d.jsxs)(n.h1,{id:"cli-命令",children:["CLI 命令",(0,d.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#cli-命令",children:"#"})]}),"\n",(0,d.jsx)(n.p,{children:"Modern.js Module 项目可以使用的 CLI 命令如下:"}),"\n",(0,d.jsxs)(n.h2,{id:"modern-build",children:[(0,d.jsx)(n.code,{children:"modern build"}),(0,d.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#modern-build",children:"#"})]}),"\n",(0,d.jsx)(n.pre,{children:(0,d.jsx)(n.code,{className:"language-bash",children:'Usage: modern build [options]\n\n构建生产环境产物\n\nOptions:\n -w, --watch 使用监听模式构建代码\n --tsconfig [tsconfig] 指定 tsconfig.json 文件的路径 (default:\n "./tsconfig.json")\n --platform [platform] 构建所有或者指定平台的产物\n --no-dts 关闭 DTS 类型文件生成和类型检查\n --no-clear 关闭自动清除产物输出目录的行为\n -c, --config <config> 指定配置文件(default: "modern.config.j(t)s")\n -h, --help 展示当前命令的信息\n'})}),"\n",(0,d.jsxs)(n.p,{children:["Modern.js Module 支持 ",(0,d.jsx)(n.code,{children:"platform"})," 构建模式,可以用于执行其他工具的构建任务,目前官方支持的有 ",(0,d.jsx)(n.a,{href:"https://rspress.dev/",target:"_blank",rel:"noopener noreferrer",children:"Rspress"}),"。例如,可以通过执行 ",(0,d.jsx)(n.code,{children:"modern build --platform"})," 命令启动 doc 构建任务生成 doc 产物。"]}),"\n",(0,d.jsxs)(n.h2,{id:"modern-new",children:[(0,d.jsx)(n.code,{children:"modern new"}),(0,d.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#modern-new",children:"#"})]}),"\n",(0,d.jsx)(n.pre,{children:(0,d.jsx)(n.code,{className:"language-bash",children:"Usage: modern new [options]\n\n启用可选功能\n\nOptions:\n -d, --debug 开启 Debug 模式,打印调试日志信息 (default: false)\n -c, --config <config> 生成器运行默认配置(JSON 字符串)\n --dist-tag <tag> 生成器使用特殊的 npm Tag 版本\n --registry 生成器运行过程中定制 npm Registry\n -h, --help display help for command\n"})}),"\n",(0,d.jsxs)(n.p,{children:[(0,d.jsx)(n.code,{children:"modern new"})," 命令用于启动微生成器功能,它可以为项目启用默认没有提供的功能。"]}),"\n",(0,d.jsx)(n.p,{children:"目前可以开启的功能有:"}),"\n",(0,d.jsxs)(n.ul,{children:["\n",(0,d.jsx)(n.li,{children:"Storybook V7"}),"\n",(0,d.jsx)(n.li,{children:"Tailwind CSS 支持"}),"\n",(0,d.jsx)(n.li,{children:"Modern.js Runtime API"}),"\n"]}),"\n",(0,d.jsxs)(n.p,{children:["关于这些功能,可以通过",(0,d.jsx)(n.a,{href:"/guide/basic/use-micro-generator",children:"「使用微生成器」"})," 章节了解更多。"]}),"\n",(0,d.jsxs)(n.h2,{id:"modern-dev",children:[(0,d.jsx)(n.code,{children:"modern dev"}),(0,d.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#modern-dev",children:"#"})]}),"\n",(0,d.jsx)(n.pre,{children:(0,d.jsx)(n.code,{className:"language-bash",children:"Usage: modern dev [options]\n\n运行和调试模块\n\nOptions:\n -h, --help display help for command\n\nCommands:\n[dev-tools-subCommand]\n"})}),"\n",(0,d.jsxs)(n.p,{children:["Modern.js Module 提供了使用调试工具的能力,可以通过 ",(0,d.jsx)(n.code,{children:"modern dev"})," 命令来启动。不过要注意的是,默认情况下是没有提供调试相关的插件,因此此时执行 ",(0,d.jsx)(n.code,{children:"modern dev"})," 会提示: ",(0,d.jsx)(n.em,{children:'"No dev tools found available"'}),"。"]}),"\n",(0,d.jsxs)(n.p,{children:["目前官方支持的调试工具有 ",(0,d.jsx)(n.a,{href:"https://rspress.dev/",target:"_blank",rel:"noopener noreferrer",children:"Rspress"}),",因此在你执行 ",(0,d.jsx)(n.code,{children:"modern new"})," 命令开启它后,就可以执行 ",(0,d.jsx)(n.code,{children:"modern dev"})," 或者 ",(0,d.jsx)(n.code,{children:"modern dev doc"})," 执行它。"]}),"\n",(0,d.jsxs)(n.h2,{id:"modern-change",children:[(0,d.jsx)(n.code,{children:"modern change"}),(0,d.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#modern-change",children:"#"})]}),"\n",(0,d.jsx)(n.pre,{children:(0,d.jsx)(n.code,{className:"language-bash",children:"Usage: modern change [options]\n\n创建变更集\n\nOptions:\n --empty 创建空变更集 (default: false)\n --open 使用编辑器中打开创建的变更集 (default: false)\n -h, --help display help for command\n"})}),"\n",(0,d.jsxs)(n.p,{children:[(0,d.jsx)(n.code,{children:"modern change"})," 命令用于生成 ",(0,d.jsx)(n.a,{href:"https://github.com/changesets/changesets",target:"_blank",rel:"noopener noreferrer",children:"changesets"})," 需要的 Markdown 文件。"]}),"\n",(0,d.jsxs)(n.h2,{id:"modern-pre",children:[(0,d.jsx)(n.code,{children:"modern pre"}),(0,d.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#modern-pre",children:"#"})]}),"\n",(0,d.jsx)(n.pre,{children:(0,d.jsx)(n.code,{className:"language-bash",children:"Usage: modern pre [options] <enter|exit> [tag]\n\n进入和退出预发布模式\n\nOptions:\n -h, --help display help for command\n"})}),"\n",(0,d.jsxs)(n.p,{children:["可以使用 ",(0,d.jsx)(n.code,{children:"modern pre"})," 命令在正式发布前",(0,d.jsx)(n.a,{href:"https://github.com/atlassian/changesets/blob/main/docs/prereleases.md",target:"_blank",rel:"noopener noreferrer",children:"预发布"}),"一个版本。"]}),"\n",(0,d.jsxs)(n.h2,{id:"modern-bump",children:[(0,d.jsx)(n.code,{children:"modern bump"}),(0,d.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#modern-bump",children:"#"})]}),"\n",(0,d.jsx)(n.pre,{children:(0,d.jsx)(n.code,{className:"language-bash",children:'Usage: modern bump [options]\n\n使用变更集自动更新发布版本和变更日志\n\nOptions:\n --canary 创建一个预发布版本进行测试 (default: false)\n --preid <tag> 在对预发布版本进行版本控制时指定标识符 (default: "next")\n --snapshot 创建一个特殊版本进行测试 (default: false)\n -h, --help display help for command\n'})}),"\n",(0,d.jsxs)(n.p,{children:["按照 ",(0,d.jsx)(n.a,{href:"https://github.com/changesets/changesets",target:"_blank",rel:"noopener noreferrer",children:"changesets"})," 生成的变更记录的 Markdown 文件修改 ",(0,d.jsx)(n.code,{children:"package.json"})," 中的版本号, 同时生成 ",(0,d.jsx)(n.code,{children:"CHANGELOG.md"})," 文件。"]}),"\n",(0,d.jsxs)(n.h2,{id:"modern-release",children:[(0,d.jsx)(n.code,{children:"modern release"}),(0,d.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#modern-release",children:"#"})]}),"\n",(0,d.jsx)(n.pre,{children:(0,d.jsx)(n.code,{className:"language-bash",children:'Usage: modern release [options]\n\n发布 npm 包\n\nOptions:\n --tag <tag> 发布 npm 包使用特定的 tag (default: "")\n --ignore-scripts 发布时忽略 package.json 中的 scripts 命令,仅支持在 pnpm monorepo\n 中使用 (default: "")\n -h, --help display help for command\n'})}),"\n",(0,d.jsxs)(n.p,{children:[(0,d.jsx)(n.code,{children:"modern release"})," 命令可以将模块发布到 ",(0,d.jsx)(n.a,{href:"https://www.npmjs.com/",target:"_blank",rel:"noopener noreferrer",children:"npm Registry"})," 上。"]}),"\n",(0,d.jsxs)(n.ul,{children:["\n",(0,d.jsxs)(n.li,{children:[(0,d.jsx)(n.code,{children:"--tag"})," 参数可以指定发布时具体的 ",(0,d.jsx)(n.a,{href:"https://docs.npmjs.com/adding-dist-tags-to-packages",target:"_blank",rel:"noopener noreferrer",children:"dist tags"}),"。"]}),"\n"]}),"\n",(0,d.jsxs)(n.h2,{id:"modern-gen-release-note",children:[(0,d.jsx)(n.code,{children:"modern gen-release-note"}),(0,d.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#modern-gen-release-note",children:"#"})]}),"\n",(0,d.jsx)(n.pre,{children:(0,d.jsx)(n.code,{className:"language-bash",children:"Usage: modern gen-release-note [options]\n\n根据当前仓库 changeset 信息生成 Release Note\n\nOptions:\n --repo <repo> 仓库名称,用于生成 Pull Request 链接, 例如: web-infra-dev/modern.js\n --custom <cumtom> 自定义 Release Note 生成函数\n -h, --help display help for command\n"})}),"\n",(0,d.jsxs)(n.p,{children:["根据当前仓库的 changeset 信息自动生成 ",(0,d.jsx)(n.a,{href:"https://en.wikipedia.org/wiki/Release_notes",target:"_blank",rel:"noopener noreferrer",children:"Release Note"}),"。"]}),"\n",(0,d.jsxs)(n.div,{className:"rspress-directive tip",children:[(0,d.jsx)(n.div,{className:"rspress-directive-title",children:"TIP"}),(0,d.jsx)(n.div,{className:"rspress-directive-content",children:(0,d.jsxs)(n.p,{children:["需要在 ",(0,d.jsx)(n.code,{children:"bump"})," 命令之前执行。\n"]})})]}),"\n",(0,d.jsxs)(n.h2,{id:"modern-upgrade",children:[(0,d.jsx)(n.code,{children:"modern upgrade"}),(0,d.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#modern-upgrade",children:"#"})]}),"\n",(0,d.jsx)(n.pre,{children:(0,d.jsx)(n.code,{className:"language-bash",children:'Usage: modern upgrade [options]\n\n升级 Modern.js 到最新版本\n\nOptions:\n --registry <registry> 定制 npm registry (default: "")\n -d,--debug 开启 Debug 模式,打印调试日志信息 (default: false)\n --cwd <cwd> 项目路径 (default: "")\n -h, --help display help for command\n'})}),"\n",(0,d.jsxs)(n.p,{children:[(0,d.jsx)(n.code,{children:"modern upgrade"})," 命令,用于升级项目 Modern.js 相关依赖至最新版本。"]}),"\n",(0,d.jsxs)(n.p,{children:["在项目根目录下执行命令 ",(0,d.jsx)(n.code,{children:"npx modern upgrade"}),",会默认将当前执行命令项目的 ",(0,d.jsx)(n.code,{children:"package.json"})," 中的 Modern.js 相关依赖更新至最新版本。"]})]})}function o(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},{wrapper:n}=Object.assign({},(0,s.ah)(),e.components);return n?(0,d.jsx)(n,{...e,children:(0,d.jsx)(a,{...e})}):a(e)}let l=o;o.__RSPRESS_PAGE_META={},o.__RSPRESS_PAGE_META["zh%2Fguide%2Fbasic%2Fcommand-preview.md"]={toc:[{text:"`modern build`",id:"modern-build",depth:2},{text:"`modern new`",id:"modern-new",depth:2},{text:"`modern dev`",id:"modern-dev",depth:2},{text:"`modern change`",id:"modern-change",depth:2},{text:"`modern pre`",id:"modern-pre",depth:2},{text:"`modern bump`",id:"modern-bump",depth:2},{text:"`modern release`",id:"modern-release",depth:2},{text:"`modern gen-release-note`",id:"modern-gen-release-note",depth:2},{text:"`modern upgrade`",id:"modern-upgrade",depth:2}],title:"CLI 命令",frontmatter:{sidebar_position:2}}}}]);
@@ -0,0 +1 @@
1
+ "use strict";(self.webpackChunk_modern_js_module_tools_docs=self.webpackChunk_modern_js_module_tools_docs||[]).push([["5455"],{2330:function(e,n,r){r.r(n),r.d(n,{default:function(){return h}});var s=r(8093),i=r(5878);function l(e){let n=Object.assign({h1:"h1",a:"a",p:"p",ul:"ul",li:"li"},(0,i.ah)(),e.components);return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsxs)(n.h1,{id:"常见问题",children:["常见问题",(0,s.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#常见问题",children:"#"})]}),"\n",(0,s.jsx)(n.p,{children:"这里是 Modern.js Module 常见问题分类列表:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"/zh/guide/faq/basic",children:"通用类问题"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"/zh/guide/faq/build",children:"构建相关问题"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"/zh/guide/faq/storybook",children:"Storybook 相关问题"})}),"\n"]})]})}function d(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},{wrapper:n}=Object.assign({},(0,i.ah)(),e.components);return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}let h=d;d.__RSPRESS_PAGE_META={},d.__RSPRESS_PAGE_META["zh%2Fguide%2Ffaq%2Findex.md"]={toc:[],title:"常见问题",frontmatter:{}}}}]);