@modern-js/module-tools-docs 2.25.2-beta.0 → 2.25.2

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 (210) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/docs/en/api/config/build-config.md +9 -9
  3. package/docs/en/api/config/build-preset.mdx +4 -4
  4. package/docs/en/guide/advance/asset.mdx +2 -2
  5. package/docs/en/guide/advance/build-umd.mdx +9 -9
  6. package/docs/en/guide/advance/copy.md +1 -1
  7. package/docs/en/guide/advance/external-dependency.mdx +2 -2
  8. package/docs/en/guide/advance/in-depth-about-build.md +11 -11
  9. package/docs/en/guide/advance/in-depth-about-dev-command.md +1 -1
  10. package/docs/en/guide/basic/before-getting-started.md +1 -1
  11. package/docs/en/guide/basic/command-preview.md +5 -5
  12. package/docs/en/guide/basic/modify-output-product.md +18 -18
  13. package/docs/en/guide/basic/using-storybook.mdx +1 -1
  14. package/docs/en/guide/best-practices/components.mdx +10 -10
  15. package/docs/en/guide/faq/build.mdx +1 -1
  16. package/docs/en/guide/intro/welcome.md +2 -2
  17. package/docs/en/plugins/guide/getting-started.mdx +1 -1
  18. package/docs/en/plugins/guide/plugin-object.mdx +2 -2
  19. package/docs/en/plugins/guide/setup-function.mdx +1 -1
  20. package/docs/zh/guide/faq/build.mdx +1 -1
  21. package/package.json +3 -3
  22. package/doc_build/api/config/build-config.html +0 -522
  23. package/doc_build/api/config/build-preset.html +0 -71
  24. package/doc_build/api/config/design-system.html +0 -113
  25. package/doc_build/api/config/dev.html +0 -40
  26. package/doc_build/api/config/plugins.html +0 -31
  27. package/doc_build/api/config/testing.html +0 -31
  28. package/doc_build/api/index.html +0 -11
  29. package/doc_build/api/plugin-api/plugin-hooks.html +0 -122
  30. package/doc_build/components/faq-build-exception.html +0 -11
  31. package/doc_build/components/faq-build-other.html +0 -11
  32. package/doc_build/components/faq-build-product.html +0 -11
  33. package/doc_build/components/faq-storybook.html +0 -11
  34. package/doc_build/components/faq-test.html +0 -11
  35. package/doc_build/en/api/config/build-config.html +0 -443
  36. package/doc_build/en/api/config/build-preset.html +0 -71
  37. package/doc_build/en/api/config/design-system.html +0 -127
  38. package/doc_build/en/api/config/dev.html +0 -40
  39. package/doc_build/en/api/config/plugins.html +0 -31
  40. package/doc_build/en/api/config/testing.html +0 -31
  41. package/doc_build/en/api/index.html +0 -11
  42. package/doc_build/en/api/plugin-api/plugin-hooks.html +0 -122
  43. package/doc_build/en/components/faq-build-exception.html +0 -11
  44. package/doc_build/en/components/faq-build-other.html +0 -11
  45. package/doc_build/en/components/faq-build-product.html +0 -11
  46. package/doc_build/en/components/faq-storybook.html +0 -11
  47. package/doc_build/en/components/faq-test.html +0 -11
  48. package/doc_build/en/guide/advance/asset.html +0 -31
  49. package/doc_build/en/guide/advance/build-umd.html +0 -42
  50. package/doc_build/en/guide/advance/copy.html +0 -52
  51. package/doc_build/en/guide/advance/external-dependency.html +0 -32
  52. package/doc_build/en/guide/advance/in-depth-about-build.html +0 -123
  53. package/doc_build/en/guide/advance/in-depth-about-dev-command.html +0 -32
  54. package/doc_build/en/guide/advance/theme-config.html +0 -39
  55. package/doc_build/en/guide/basic/before-getting-started.html +0 -97
  56. package/doc_build/en/guide/basic/command-preview.html +0 -73
  57. package/doc_build/en/guide/basic/modify-output-product.html +0 -113
  58. package/doc_build/en/guide/basic/publish-your-project.html +0 -60
  59. package/doc_build/en/guide/basic/test-your-project.html +0 -41
  60. package/doc_build/en/guide/basic/use-micro-generator.html +0 -47
  61. package/doc_build/en/guide/basic/using-storybook.html +0 -76
  62. package/doc_build/en/guide/best-practices/components.html +0 -121
  63. package/doc_build/en/guide/faq/build.html +0 -91
  64. package/doc_build/en/guide/faq/index.html +0 -17
  65. package/doc_build/en/guide/faq/storybook.html +0 -53
  66. package/doc_build/en/guide/faq/test.html +0 -16
  67. package/doc_build/en/guide/intro/getting-started.html +0 -53
  68. package/doc_build/en/guide/intro/welcome.html +0 -23
  69. package/doc_build/en/guide/intro/why-module-engineering-solution.html +0 -19
  70. package/doc_build/en/index.html +0 -11
  71. package/doc_build/en/plugins/guide/getting-started.html +0 -25
  72. package/doc_build/en/plugins/guide/plugin-object.html +0 -24
  73. package/doc_build/en/plugins/guide/setup-function.html +0 -40
  74. package/doc_build/en/plugins/official-list/overview.html +0 -19
  75. package/doc_build/en/plugins/official-list/plugin-babel.html +0 -23
  76. package/doc_build/en/plugins/official-list/plugin-banner.html +0 -40
  77. package/doc_build/en/plugins/official-list/plugin-import.html +0 -44
  78. package/doc_build/en/plugins/official-list/plugin-node-polyfill.html +0 -88
  79. package/doc_build/en/plugins/official-list/plugin-polyfill.html +0 -28
  80. package/doc_build/guide/advance/asset.html +0 -31
  81. package/doc_build/guide/advance/build-umd.html +0 -42
  82. package/doc_build/guide/advance/copy.html +0 -52
  83. package/doc_build/guide/advance/external-dependency.html +0 -31
  84. package/doc_build/guide/advance/in-depth-about-build.html +0 -123
  85. package/doc_build/guide/advance/in-depth-about-dev-command.html +0 -32
  86. package/doc_build/guide/advance/theme-config.html +0 -38
  87. package/doc_build/guide/basic/before-getting-started.html +0 -97
  88. package/doc_build/guide/basic/command-preview.html +0 -73
  89. package/doc_build/guide/basic/modify-output-product.html +0 -110
  90. package/doc_build/guide/basic/publish-your-project.html +0 -62
  91. package/doc_build/guide/basic/test-your-project.html +0 -43
  92. package/doc_build/guide/basic/use-micro-generator.html +0 -45
  93. package/doc_build/guide/basic/using-storybook.html +0 -74
  94. package/doc_build/guide/best-practices/components.html +0 -121
  95. package/doc_build/guide/faq/build.html +0 -91
  96. package/doc_build/guide/faq/index.html +0 -17
  97. package/doc_build/guide/faq/storybook.html +0 -53
  98. package/doc_build/guide/faq/test.html +0 -16
  99. package/doc_build/guide/intro/getting-started.html +0 -50
  100. package/doc_build/guide/intro/welcome.html +0 -23
  101. package/doc_build/guide/intro/why-module-engineering-solution.html +0 -19
  102. package/doc_build/index.html +0 -11
  103. package/doc_build/plugins/guide/getting-started.html +0 -25
  104. package/doc_build/plugins/guide/plugin-object.html +0 -24
  105. package/doc_build/plugins/guide/setup-function.html +0 -40
  106. package/doc_build/plugins/official-list/overview.html +0 -19
  107. package/doc_build/plugins/official-list/plugin-babel.html +0 -23
  108. package/doc_build/plugins/official-list/plugin-banner.html +0 -40
  109. package/doc_build/plugins/official-list/plugin-import.html +0 -44
  110. package/doc_build/plugins/official-list/plugin-node-polyfill.html +0 -88
  111. package/doc_build/plugins/official-list/plugin-polyfill.html +0 -28
  112. package/doc_build/route.json +0 -10
  113. package/doc_build/ssr/bundles/main.js +0 -30
  114. package/doc_build/ssr/bundles/main.js.LICENSE.txt +0 -103
  115. package/doc_build/static/css/defaultVendors~docs_en_api_config_build-config_md~docs_en_api_config_build-preset_mdx~docs_en~2cd1be.71af0621.css +0 -1
  116. package/doc_build/static/css/main.1e1c5ea3.css +0 -17
  117. package/doc_build/static/js/async/default~docs_en_guide_faq_build_mdx~docs_en_guide_faq_storybook_mdx~docs_en_guide_faq_test_md~931d29.a2443c41.js +0 -1
  118. package/doc_build/static/js/async/docs_en_api_config_build-config_md.47c13184.js +0 -1
  119. package/doc_build/static/js/async/docs_en_api_config_build-preset_mdx.240d175b.js +0 -1
  120. package/doc_build/static/js/async/docs_en_api_config_design-system_md.b2ec1ff7.js +0 -1
  121. package/doc_build/static/js/async/docs_en_api_config_dev_md.6ad208aa.js +0 -1
  122. package/doc_build/static/js/async/docs_en_api_config_plugins_md.da21c1a9.js +0 -1
  123. package/doc_build/static/js/async/docs_en_api_config_testing_md.5655d56b.js +0 -1
  124. package/doc_build/static/js/async/docs_en_api_index_md.b332bf64.js +0 -1
  125. package/doc_build/static/js/async/docs_en_api_plugin-api_plugin-hooks_md.b0f73e0d.js +0 -1
  126. package/doc_build/static/js/async/docs_en_guide_advance_asset_mdx.d302e90c.js +0 -1
  127. package/doc_build/static/js/async/docs_en_guide_advance_build-umd_mdx.554fa073.js +0 -1
  128. package/doc_build/static/js/async/docs_en_guide_advance_copy_md.78b33f73.js +0 -1
  129. package/doc_build/static/js/async/docs_en_guide_advance_external-dependency_mdx.507e4091.js +0 -1
  130. package/doc_build/static/js/async/docs_en_guide_advance_in-depth-about-build_md.207e8b25.js +0 -1
  131. package/doc_build/static/js/async/docs_en_guide_advance_in-depth-about-dev-command_md.72d6b6fc.js +0 -1
  132. package/doc_build/static/js/async/docs_en_guide_advance_theme-config_mdx.168a5eec.js +0 -1
  133. package/doc_build/static/js/async/docs_en_guide_basic_before-getting-started_md.a00933ab.js +0 -1
  134. package/doc_build/static/js/async/docs_en_guide_basic_command-preview_md.5e63d7ad.js +0 -1
  135. package/doc_build/static/js/async/docs_en_guide_basic_modify-output-product_md.abd250e1.js +0 -1
  136. package/doc_build/static/js/async/docs_en_guide_basic_publish-your-project_md.3b098b03.js +0 -1
  137. package/doc_build/static/js/async/docs_en_guide_basic_test-your-project_mdx.b86e9b69.js +0 -1
  138. package/doc_build/static/js/async/docs_en_guide_basic_use-micro-generator_md.e03b16c8.js +0 -1
  139. package/doc_build/static/js/async/docs_en_guide_basic_using-storybook_mdx.32e9b389.js +0 -1
  140. package/doc_build/static/js/async/docs_en_guide_best-practices_components_mdx.a56e369b.js +0 -1
  141. package/doc_build/static/js/async/docs_en_guide_faq_build_mdx.81c243c7.js +0 -1
  142. package/doc_build/static/js/async/docs_en_guide_faq_index_md.85367f4a.js +0 -1
  143. package/doc_build/static/js/async/docs_en_guide_faq_storybook_mdx.d6b26cfd.js +0 -1
  144. package/doc_build/static/js/async/docs_en_guide_faq_test_mdx.a7a1c8b5.js +0 -1
  145. package/doc_build/static/js/async/docs_en_guide_intro_getting-started_md.7c901798.js +0 -1
  146. package/doc_build/static/js/async/docs_en_guide_intro_welcome_md.69fe3324.js +0 -1
  147. package/doc_build/static/js/async/docs_en_guide_intro_why-module-engineering-solution_md.766afaee.js +0 -1
  148. package/doc_build/static/js/async/docs_en_index_md.32415ad9.js +0 -1
  149. package/doc_build/static/js/async/docs_en_plugins_guide_getting-started_mdx.c6631fd6.js +0 -1
  150. package/doc_build/static/js/async/docs_en_plugins_guide_plugin-object_mdx.0971cbdb.js +0 -1
  151. package/doc_build/static/js/async/docs_en_plugins_guide_setup-function_mdx.388d92b1.js +0 -1
  152. package/doc_build/static/js/async/docs_en_plugins_official-list_overview_md.9390ed67.js +0 -1
  153. package/doc_build/static/js/async/docs_en_plugins_official-list_plugin-babel_md.0528b729.js +0 -1
  154. package/doc_build/static/js/async/docs_en_plugins_official-list_plugin-banner_md.c14f8599.js +0 -1
  155. package/doc_build/static/js/async/docs_en_plugins_official-list_plugin-import_mdx.67bac7e1.js +0 -1
  156. package/doc_build/static/js/async/docs_en_plugins_official-list_plugin-node-polyfill_md.19819cf5.js +0 -1
  157. package/doc_build/static/js/async/docs_en_plugins_official-list_plugin-polyfill_md.473537df.js +0 -1
  158. package/doc_build/static/js/async/docs_zh_api_config_build-config_md.e52b0287.js +0 -1
  159. package/doc_build/static/js/async/docs_zh_api_config_build-preset_mdx.8b874378.js +0 -1
  160. package/doc_build/static/js/async/docs_zh_api_config_design-system_md.ceae6914.js +0 -1
  161. package/doc_build/static/js/async/docs_zh_api_config_dev_md.033094f8.js +0 -1
  162. package/doc_build/static/js/async/docs_zh_api_config_plugins_md.ab43b516.js +0 -1
  163. package/doc_build/static/js/async/docs_zh_api_config_testing_md.2c1f171d.js +0 -1
  164. package/doc_build/static/js/async/docs_zh_api_index_md.5df1b9d0.js +0 -1
  165. package/doc_build/static/js/async/docs_zh_api_plugin-api_plugin-hooks_md.9f155180.js +0 -1
  166. package/doc_build/static/js/async/docs_zh_guide_advance_asset_mdx.0b551e5e.js +0 -1
  167. package/doc_build/static/js/async/docs_zh_guide_advance_build-umd_mdx.4c0a741d.js +0 -1
  168. package/doc_build/static/js/async/docs_zh_guide_advance_copy_md.ff70ddd3.js +0 -1
  169. package/doc_build/static/js/async/docs_zh_guide_advance_external-dependency_mdx.64bae82a.js +0 -1
  170. package/doc_build/static/js/async/docs_zh_guide_advance_in-depth-about-build_md.d16f07b4.js +0 -1
  171. package/doc_build/static/js/async/docs_zh_guide_advance_in-depth-about-dev-command_md.2eabb853.js +0 -1
  172. package/doc_build/static/js/async/docs_zh_guide_advance_theme-config_mdx.5670e00b.js +0 -1
  173. package/doc_build/static/js/async/docs_zh_guide_basic_before-getting-started_md.3e23f82e.js +0 -1
  174. package/doc_build/static/js/async/docs_zh_guide_basic_command-preview_md.718669ed.js +0 -1
  175. package/doc_build/static/js/async/docs_zh_guide_basic_modify-output-product_md.bea77add.js +0 -1
  176. package/doc_build/static/js/async/docs_zh_guide_basic_publish-your-project_md.b0c63699.js +0 -1
  177. package/doc_build/static/js/async/docs_zh_guide_basic_test-your-project_mdx.b9ee0af4.js +0 -1
  178. package/doc_build/static/js/async/docs_zh_guide_basic_use-micro-generator_md.ad32d392.js +0 -1
  179. package/doc_build/static/js/async/docs_zh_guide_basic_using-storybook_mdx.2748f6f6.js +0 -1
  180. package/doc_build/static/js/async/docs_zh_guide_best-practices_components_mdx.e4450a3c.js +0 -1
  181. package/doc_build/static/js/async/docs_zh_guide_faq_build_mdx.470ca09d.js +0 -1
  182. package/doc_build/static/js/async/docs_zh_guide_faq_index_md.9c5738a8.js +0 -1
  183. package/doc_build/static/js/async/docs_zh_guide_faq_storybook_mdx.e1fb8e18.js +0 -1
  184. package/doc_build/static/js/async/docs_zh_guide_faq_test_mdx.d332b61f.js +0 -1
  185. package/doc_build/static/js/async/docs_zh_guide_intro_getting-started_md.8af35ffc.js +0 -1
  186. package/doc_build/static/js/async/docs_zh_guide_intro_welcome_md.6169850d.js +0 -1
  187. package/doc_build/static/js/async/docs_zh_guide_intro_why-module-engineering-solution_md.ff0f5ef0.js +0 -1
  188. package/doc_build/static/js/async/docs_zh_index_md.bc7e2f02.js +0 -1
  189. package/doc_build/static/js/async/docs_zh_plugins_guide_getting-started_mdx.6a2c07ee.js +0 -1
  190. package/doc_build/static/js/async/docs_zh_plugins_guide_plugin-object_mdx.9a665baa.js +0 -1
  191. package/doc_build/static/js/async/docs_zh_plugins_guide_setup-function_mdx.a614b224.js +0 -1
  192. package/doc_build/static/js/async/docs_zh_plugins_official-list_overview_md.bf4a7405.js +0 -1
  193. package/doc_build/static/js/async/docs_zh_plugins_official-list_plugin-babel_md.7107a66b.js +0 -1
  194. package/doc_build/static/js/async/docs_zh_plugins_official-list_plugin-banner_md.4443ae99.js +0 -1
  195. package/doc_build/static/js/async/docs_zh_plugins_official-list_plugin-import_mdx.e4923a9a.js +0 -1
  196. package/doc_build/static/js/async/docs_zh_plugins_official-list_plugin-node-polyfill_md.26c9cb0d.js +0 -1
  197. package/doc_build/static/js/async/docs_zh_plugins_official-list_plugin-polyfill_md.0bda701d.js +0 -1
  198. package/doc_build/static/js/defaultVendors~docs_en_api_config_build-config_md~docs_en_api_config_build-preset_mdx~docs_en~2cd1be.7070a8dd.js +0 -1
  199. package/doc_build/static/js/defaultVendors~docs_en_api_config_build-config_md~docs_en_api_config_build-preset_mdx~docs_en~2cd1be.7070a8dd.js.LICENSE.txt +0 -20
  200. package/doc_build/static/js/lib-lodash.20527186.js +0 -1
  201. package/doc_build/static/js/lib-polyfill.a99fdfae.js +0 -1
  202. package/doc_build/static/js/lib-react.87879e53.js +0 -1
  203. package/doc_build/static/js/lib-react.87879e53.js.LICENSE.txt +0 -29
  204. package/doc_build/static/js/lib-router.65b37e4a.js +0 -1
  205. package/doc_build/static/js/lib-router.65b37e4a.js.LICENSE.txt +0 -32
  206. package/doc_build/static/js/main.42725889.js +0 -1
  207. package/doc_build/static/search_index.en.6f4165d1.json +0 -1
  208. package/doc_build/static/search_index.en.8cd54797.json +0 -1
  209. package/doc_build/static/search_index.zh.7ed3054c.json +0 -1
  210. package/doc_build/static/search_index.zh.97edcc6e.json +0 -1
@@ -1 +0,0 @@
1
- [{"id":36,"title":"buildConfig","routePath":"/module-tools/api/config/build-config","lang":"zh","toc":[{"text":"alias","id":"alias","depth":2,"charIndex":159},{"text":"asset","id":"asset","depth":2,"charIndex":876},{"text":"asset.path","id":"assetpath","depth":2,"charIndex":899},{"text":"asset.limit","id":"assetlimit","depth":2,"charIndex":970},{"text":"asset.publicPath","id":"assetpublicpath","depth":2,"charIndex":1286},{"text":"asset.svgr","id":"assetsvgr","depth":2,"charIndex":1503},{"text":"asset.svgr.include","id":"assetsvgrinclude","depth":2,"charIndex":1899},{"text":"asset.svgr.exclude","id":"assetsvgrexclude","depth":2,"charIndex":1998},{"text":"autoExternal","id":"autoexternal","depth":2,"charIndex":2099},{"text":"autoExternal.dependencies","id":"autoexternaldependencies","depth":2,"charIndex":2598},{"text":"autoExternal.peerDependencies","id":"autoexternalpeerdependencies","depth":2,"charIndex":2686},{"text":"buildType","id":"buildtype","depth":2,"charIndex":2782},{"text":"copy","id":"copy","depth":2,"charIndex":2883},{"text":"copy.patterns","id":"copypatterns","depth":2,"charIndex":3051},{"text":"copy.options","id":"copyoptions","depth":2,"charIndex":3218},{"text":"define","id":"define","depth":2,"charIndex":3451},{"text":"dts","id":"dts","depth":2,"charIndex":3784},{"text":"dts.abortOnError","id":"dtsabortonerror","depth":2,"charIndex":3940},{"text":"dts.distPath","id":"dtsdistpath","depth":2,"charIndex":4274},{"text":"dts.only","id":"dtsonly","depth":2,"charIndex":4348},{"text":"dts.respectExternal","id":"dtsrespectexternal","depth":2,"charIndex":4410},{"text":"dts.tsconfigPath","id":"dtstsconfigpath","depth":2,"charIndex":4627},{"text":"esbuildOptions","id":"esbuildoptions","depth":2,"charIndex":4707},{"text":"externalHelpers","id":"externalhelpers","depth":2,"charIndex":5310},{"text":"externals","id":"externals","depth":2,"charIndex":5939},{"text":"format","id":"format","depth":2,"charIndex":6193},{"text":"format: \\'esm\\'","id":"format:-\\'esm\\'","depth":3,"charIndex":-1},{"text":"format: \\'cjs\\'","id":"format:-\\'cjs\\'","depth":3,"charIndex":-1},{"text":"format: \\'iife\\'","id":"format:-\\'iife\\'","depth":3,"charIndex":-1},{"text":"format: \\'umd\\'","id":"format:-\\'umd\\'","depth":3,"charIndex":-1},{"text":"input","id":"input","depth":2,"charIndex":7058},{"text":"jsx","id":"jsx","depth":2,"charIndex":7565},{"text":"metafile","id":"metafile","depth":2,"charIndex":7900},{"text":"minify","id":"minify","depth":2,"charIndex":8239},{"text":"outDir","id":"outdir","depth":2,"charIndex":8491},{"text":"platform","id":"platform","depth":2,"charIndex":8540},{"text":"redirect","id":"redirect","depth":2,"charIndex":8646},{"text":"sideEffects","id":"sideeffects","depth":2,"charIndex":9013},{"text":"sourceDir","id":"sourcedir","depth":2,"charIndex":9819},{"text":"sourceMap","id":"sourcemap","depth":2,"charIndex":9915},{"text":"sourceType","id":"sourcetype","depth":2,"charIndex":10002},{"text":"splitting","id":"splitting","depth":2,"charIndex":10133},{"text":"style","id":"style","depth":2,"charIndex":10187},{"text":"style.less","id":"styleless","depth":2,"charIndex":10208},{"text":"style.less.lessOptions","id":"stylelesslessoptions","depth":2,"charIndex":10234},{"text":"style.less.additionalData","id":"stylelessadditionaldata","depth":2,"charIndex":10325},{"text":"style.less.implementation","id":"stylelessimplementation","depth":2,"charIndex":10557},{"text":"sass","id":"sass","depth":2,"charIndex":11020},{"text":"style.sass.sassOptions","id":"stylesasssassoptions","depth":2,"charIndex":11040},{"text":"style.sass.additionalData","id":"stylesassadditionaldata","depth":2,"charIndex":11110},{"text":"style.sass.implementation","id":"stylesassimplementation","depth":2,"charIndex":11402},{"text":"style.postcss","id":"stylepostcss","depth":2,"charIndex":11866},{"text":"style.inject","id":"styleinject","depth":2,"charIndex":12079},{"text":"style.autoModules","id":"styleautomodules","depth":2,"charIndex":13023},{"text":"style.modules","id":"stylemodules","depth":2,"charIndex":13257},{"text":"style.tailwindcss","id":"styletailwindcss","depth":2,"charIndex":13610},{"text":"target","id":"target","depth":2,"charIndex":14128},{"text":"transformImport","id":"transformimport","depth":2,"charIndex":14517},{"text":"注意事项","id":"注意事项","depth":3,"charIndex":14863},{"text":"umdGlobals","id":"umdglobals","depth":2,"charIndex":14892},{"text":"umdModuleName","id":"umdmodulename","depth":2,"charIndex":15186}],"domain":"","content":"#\n\nbuildConfig 是一个用来描述如何编译、生成构建产物的配置项,它包含了构建的所有配置。\n\n * 类型:object | object[]\n * 默认值: undefined\n\nTIP\n\n在开始使用 buildConfig 之前,请先阅读以下文档来了解其作用:\n\n * 修改输出产物\n * 深入理解构建\n\n\nalias#\n\n * 类型:Record | Function\n * 默认值:{'@': 'src',}\n\nTIP\n\n对于 TypeScript 项目,只需要在 tsconfig.json 中配置 compilerOptions.paths, Module Tools\n会自动识别 tsconfig.json 里的别名,因此不需要额外配置 alias 字段。\n\nexport default defineConfig({\n buildConfig: {\n alias: {\n '@common': './src/common',\n },\n },\n});\n\n\n以上配置完成后,如果在代码中引用 @common/Foo.tsx, 则会映射到 /src/common/Foo.tsx 路径上。\n\nalias 的值定义为函数时,可以接受预设的 alias 对象,并对其进行修改。\n\nexport default defineConfig({\n buildConfig: {\n alias: alias => {\n alias['@common'] = './src/common';\n },\n },\n});\n\n\n也可以在函数中返回一个新对象作为最终结果,新对象会覆盖预设的 alias 对象。\n\nexport default defineConfig({\n buildConfig: {\n alias: alias => {\n return {\n '@common': './src/common',\n };\n },\n },\n});\n\n\n\nasset#\n\n包含静态资源相关的配置。\n\n\nasset.path#\n\n静态资源输出路径,会基于 outDir 进行输出。\n\n * 类型: string\n * 默认值: assets\n\n\nasset.limit#\n\n用于设置静态资源被自动内联为 base64 的体积阈值。\n\nModule Tools 在进行打包时,默认会内联体积小于 10KB 的图片、字体、媒体等资源,将它们通过 Base64 编码,并内联到产物中,不再会发送独立的\nHTTP 请求。\n\n你可以通过修改 limit 参数来调整这个阈值。\n\n * 类型: number\n * 默认值: 10 * 1024\n\n例如,将 limit 设置为 0 来避免资源内联:\n\nexport default defineConfig({\n buildConfig: {\n asset: {\n limit: 0,\n },\n },\n});\n\n\n\nasset.publicPath#\n\n打包时给未内联资源的 CDN 前缀。\n\n * 类型: string\n * 默认值: undefined\n\nexport default defineConfig({\n buildConfig: {\n asset: {\n publicPath: 'https://xxx/',\n },\n },\n});\n\n\n此时,所有静态资源都会添加 https://xxx/ 前缀。\n\n\nasset.svgr#\n\n打包时将 SVG 作为一个 React 组件处理,options 参考 svgr,另外还支持了 include 和 exclude\n两个配置项,用于匹配需要处理的 SVG 文件。\n\n * 类型: boolean | object\n * 默认值: false\n\n开启 svgr 功能后,可以使用默认导出的方式将 SVG 当做组件使用。\n\n// true\n\n\nexport default () => ;\n\n\nWARNING\n\n目前不支持下面的用法:\n\n\n\n\n当开启功能后,可以通过在 modern-app-env.d.ts 文件中增加类型定义,修改使用 SVG 的类型:\n\ndeclare module '*.svg' {\n const src: React.FunctionComponent>;\n export default src;\n}\n\n/// \n\n\n\nasset.svgr.include#\n\n设定匹配的 SVG 文件\n\n * 类型: string | RegExp | (string | RegExp)[]\n * 默认值: /\\.svg$/\n\n\nasset.svgr.exclude#\n\n设定不匹配的 SVG 文件\n\n * 类型: string | RegExp | (string | RegExp)[]\n * 默认值: undefined\n\n\nautoExternal#\n\n自动外置项目的 \"dependencies\" 和 \"peerDependencies\",不会将其打包到最终的 bundle 产物中。\n\n * 类型: boolean | object\n * 默认值: true\n\n当我们希望关闭对于第三方依赖的默认处理行为时候,可以通过以下方式来实现:\n\nexport default defineConfig({\n buildConfig: {\n autoExternal: false,\n },\n});\n\n\n这样对于 \"dependencies\" 和 \"peerDependencies\" 下面的依赖都会进行打包处理。如果只想要关闭其中某个下面的依赖处理,则可以使用\nbuildConfig.autoExternal 的对象形式:\n\nexport default defineConfig({\n buildConfig: {\n autoExternal: {\n dependencies: false,\n peerDependencies: false,\n },\n },\n});\n\n\n\nautoExternal.dependencies#\n\n是否需要外置项目的 \"dependencies\" 依赖。\n\n * 类型: boolean\n * 默认值: true\n\n\nautoExternal.peerDependencies#\n\n是否需要外置项目的 \"peerDependencies\" 依赖。\n\n * 类型: boolean\n * 默认值: true\n\n\nbuildType#\n\n构建类型,bundle 会打包你的代码,bundleless 只做代码的转换。\n\n * 类型: 'bundle' | 'bundleless'\n * 默认值: bundle\n\n\ncopy#\n\n将文件或目录拷贝到指定位置。\n\n * 类型: object\n\nexport default defineConfig({\n buildConfig: {\n copy: {\n patterns: [{ from: './src/assets', to: '' }],\n },\n },\n});\n\n\n\ncopy.patterns#\n\n * 类型: CopyPattern[]\n * 默认值: []\n\ninterface CopyPattern {\n from: string;\n to?: string;\n context?: string;\n globOptions?: globby.GlobbyOptions;\n}\n\n\n\ncopy.options#\n\n * 类型:\n\ntype Options = {\n concurrency?: number;\n enableCopySync?: boolean;\n};\n\n\n * 默认值: { concurrency: 100, enableCopySync: false }\n\n * concurrency: 指定并行执行多少个复制任务。\n\n * enableCopySync: 使用 fs.copySync,默认情况下 fs.copy。\n\n\ndefine#\n\n定义全局变量,会被注入到代码中\n\n * 类型: Record\n * 默认值: {}\n\n由于 define 功能是由全局文本替换实现的,所以需要保证全局变量值为字符串,更为安全的做法是将每个全局变量的值转化为字符串,使用\nJSON.stringify 进行转换,如下所示:\n\nexport default defineConfig({\n buildConfig: {\n define: {\n VERSION: JSON.stringify('1.0'),\n },\n },\n});\n\n\nTIP\n\n为了防止全局替换替换过度,建议使用时遵循以下两个原则:\n\n * 全局常量使用大写\n * 自定义全局常量前缀后缀,确保独一无二\n\n\ndts#\n\n类型文件生成的相关配置,默认情况会生成。\n\n * 类型: false | object\n * 默认值:\n\n{\n abortOnError: true,\n distPath: './',\n only: false,\n tsconfigPath: './tsconfig.json',\n}\n\n\n\ndts.abortOnError#\n\n用于控制在出现类型错误的时候,是否允许构建成功。\n\n * 类型:boolean\n * 默认值:true\n\n默认情况下,在出现类型错误的时候会导致构建失败。将 abortOnError 设置为 false 后,即使代码中出现了类型问题,构建依然会成功:\n\nexport default defineConfig({\n buildConfig: {\n dts: {\n abortOnError: false,\n },\n },\n});\n\n\nWARNING\n\n当关闭该配置后,无法保证类型文件能正常生成,且不保证内容正确。在 buildType: 'bundle' 时,即打包模式下,类型文件一定不会生成。\n\n\ndts.distPath#\n\n类型文件的输出路径,基于 outDir 进行输出。\n\n * 类型: string\n * 默认值: ./types\n\n\ndts.only#\n\n只生成类型文件,不生成 js 文件。\n\n * 类型: boolean\n * 默认值: false\n\n\ndts.respectExternal#\n\n当设为 false 时,不会打包任何三方包类型,设为 true 时,会根据 externals 来决定是否需要打包三方类型。\n\n在对类型文件进行打包时,构建工具还未对 export\n进行分析,因此当你引用的任何一个三方包出现类型错误时,都可能会中断当前的构建流程,这会导致构建流程不可控,因此我们可以通过这个配置来避免该问题。\n\n * 类型: boolean\n * 默认值: true\n\n\ndts.tsconfigPath#\n\nTypeScript 配置文件的路径。\n\n * 类型: string\n * 默认值: ./tsconfig.json\n\n\nesbuildOptions#\n\n直接修改esbuild 配置\n\n * 类型: Function\n * 默认值: c => c\n\n例如我们需要修改生成文件的后缀:\n\nexport default defineConfig({\n buildConfig: {\n esbuildOptions: options => {\n options.outExtension = { '.js': '.mjs' };\n return option;\n },\n },\n});\n\n\nTIP\n\n我们在原本 esbuild 构建的基础上做了许多扩展,因此使用此配置需要注意以下几点:\n\n 1. 优先使用我们提供的配置,例如 esbuild 并不支持target: 'es5',但我们内部使用 swc\n 支持了此场景,此时通过esbuildOptions设置target: 'es5'会报错。\n 2. 目前我们内部使用enhanced-resolve替代了 esbuild 的 resolve 解析算法,所以修改 esbuild resolve\n 相关配置无效,计划在未来会切换回来。\n 3. 使用 esbuild 插件时需要将插件加在 plugins 数组的头部,因为我们内部也是通过一个 esbuild\n 插件介入到整个构建流程中去的,因此需要将自定义插件优先注册。\n\n\nexternalHelpers#\n\n默认情况下,输出的 JS 代码可能会依赖一些辅助函数来支持目标环境或者输出格式,这些辅助函数会被内联在需要它的文件中。\n\n当在使用 SWC Transform 进行代码转换的时候,可以启动 externalHelpers 配置,将内联的辅助函数转换为从外部模块\n@swc/helpers 导入这些辅助函数。\n\n * 类型:boolean\n * 默认值:false\n\n下面是使用该配置前后的产物变化比较。\n\n开启前:\n\n// 辅助函数\nfunction asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {\n // ...\n}\n// 辅助函数\nfunction _async_to_generator(fn) {\n return function () {\n // use asyncGeneratorStep\n // ...\n };\n}\n\n// 你的代码\nexport var yourCode = function () {\n // use _async_to_generator\n};\n\n\n开启后:\n\n// 从 @swc/helpers 导入的辅助函数\n\n\n// 你的代码\nexport var yourCode = function () {\n // use _async_to_generator\n};\n\n\n\nexternals#\n\n用于在打包时排除一些外部依赖,避免将这些依赖打包到最终的 bundle 中。\n\n * 类型:\n\ntype Externals = (string | RegExp)[];\n\n\n * 默认值: []\n * 构建类型:仅支持 buildType: 'bundle'\n * 示例:\n\nexport default defineConfig({\n buildConfig: {\n // 避免打包 React\n externals: ['react'],\n },\n});\n\n\n\nformat#\n\n用于设置 JavaScript 产物输出的格式,其中 iife 和 umd 只在 buildType 为 bundle 时生效。\n\n * 类型:'esm' | 'cjs' | 'iife' | 'umd'\n * 默认值:cjs\n\n\nformat: 'esm'#\n\nesm 代表 \"ECMAScript 模块\",它需要运行环境支持 import 和 export 语法。\n\n * 示例:\n\nexport default defineConfig({\n buildConfig: {\n format: 'esm',\n },\n});\n\n\n\nformat: 'cjs'#\n\ncjs 代表 \"CommonJS\",它需要运行环境支持 exports、require 和 module 语法,通常为 Node.js 环境。\n\n * 示例:\n\nexport default defineConfig({\n buildConfig: {\n format: 'cjs',\n },\n});\n\n\n\nformat: 'iife'#\n\niife 代表 \"立即调用函数表达式\",它将代码包裹在函数表达式中,确保代码中的任何变量不会意外地与全局范围中的变量冲突,通常在浏览器环境中运行。\n\n * 示例:\n\nexport default defineConfig({\n buildConfig: {\n format: 'iife',\n },\n});\n\n\n\nformat: 'umd'#\n\numd 代表 \"Universal Module Definition\",用于在不同环境(浏览器、Node.js 等)中运行。umd\n格式的模块可以在多种环境下使用,既可以作为全局变量访问,也可以通过模块加载器(如 RequireJS)进行模块化加载。\n\n * 示例:\n\nexport default defineConfig({\n buildConfig: {\n format: 'umd',\n },\n});\n\n\n\ninput#\n\n指定构建的入口文件,数组形式可以指定目录。\n\n * 类型:\n\ntype Input =\n | string[];\n | {\n [name: string]: string;\n }\n\n\n * 默认值:bundle 模式下默认为 ['src/index.ts'],bundleless 模式下默认为 ['src']\n\n数组用法:\n\nexport default defineConfig({\n buildConfig: {\n input: ['src/index.ts', 'src/index2.ts'],\n },\n});\n\n\n对象用法:\n\n当在 bundle 模式下需要修改产物的输出文件名称的时候,可以使用对象形式进行配置。\n\n对象的 Key 是产物的文件名称,Value 是源码的文件路径。\n\nexport default defineConfig({\n buildConfig: {\n format: 'esm',\n input: {\n 'index.esm': './src/index.ts',\n },\n },\n});\n\n\n\njsx#\n\n指定 JSX 的编译方式,默认支持 React 17 及更高版本,自动注入 JSX 运行时代码。\n\n * 类型: automatic | transform\n * 默认值: automatic\n\n如果你需要支持 React 16,则可以设置 jsx 为 transform:\n\nexport default defineConfig({\n buildConfig: {\n jsx: 'transform',\n },\n});\n\n\nTIP\n\n关于 JSX Transform 的更多说明,可以参考以下链接:\n\n * React Blog - Introducing the New JSX Transform.\n * esbuild - JSX.\n\n\nmetafile#\n\n这个选项用于构建分析,开启该选项后,esbuild 会以 JSON 格式生成有关构建的一些元数据。\n\n * 类型:boolean\n * 默认值:false\n * 构建类型:仅支持 buildType: 'bundle'\n\n开启 metafile 生成:\n\nexport default defineConfig({\n buildConfig: {\n buildType: 'bundle',\n metafile: true,\n },\n});\n\n\n在执行 build 构建后,产物目录下会生成 metafile-[xxx].json 文件,你可以通过 esbuild analyze 和\nbundle-buddy 等工具进行可视化分析。\n\n\nminify#\n\n使用 esbuild 或者 terser 压缩代码,也可以传入 terserOptions。\n\n * 类型: 'terser' | 'esbuild' | false | object\n * 默认值: false\n\nexport default defineConfig({\n buildConfig: {\n minify: {\n compress: {\n drop_console: true,\n },\n },\n },\n});\n\n\n\noutDir#\n\n指定构建的输出目录\n\n * 类型: string\n * 默认值: dist\n\n\nplatform#\n\n默认生成用于 Node.js 环境下的代码,你也可以指定为 browser,会生成用于浏览器环境的代码。\n\n * 类型: 'browser' | 'node'\n * 默认值: node\n\n\nredirect#\n\n在 buildType: 'bundleless' 构建模式下,会对引用路径进行重定向,确保指向了正确的产物,例如:\n\n * import './index.less' 会被改写成 import './index.css'\n * 会被改写成 (依实际情况而定)\n\n在某些场景下,你可能不需要这些功能,那么可以通过此配置关闭它,关闭后,其引用路径将不会发生改变。\n\nexport default {\n buildConfig: {\n redirect: {\n alias: false, // 关闭对别名路径的修改\n style: false, // 关闭对样式文件路径的修改\n asset: false, // 关闭对资源文件路径的修改\n },\n },\n};\n\n\n\nsideEffects#\n\n配置模块的副作用\n\n * 类型: RegExg[] | (filePath: string, isExternal: boolean) => boolean | boolean\n * 默认值: undefined\n\n通常情况下,我们通过 package.json 的 \"sideEffects\" 字段来配置模块的副作用,但是在某些情况下,三方包的 package.json\n是不可靠的。 例如我们引用了一个三方包的样式文件。\n\nimport 'other-package/dist/index.css';\n\n\n但是这个三方包的 package.json 里并没有将样式文件配置到 \"sideEffects\" 里。\n\n{\n \"sideEffects\": [\"dist/index.js\"]\n}\n\n\n同时你又设置了 style.inject 为 true,在控制台可以看到类似的警告信息:\n\n[LIBUILD:ESBUILD_WARN] Ignoring this import because \"other-package/dist/index.css\" was marked as having no side effects\n\n\n这时候就可以使用这个配置项,手动配置模块的\"sideEffects\",配置支持正则和函数形式。\n\nexport default defineConfig({\n buildConfig: {\n sideEffects: [/\\.css$/],\n // or\n // sideEffects: (filePath, isExternal) => /\\.css$/.test(filePath),\n },\n});\n\n\nTIP\n\n添加此配置后,打包时将不会再读取 package.json 里的 \"sideEffects\" 字段。\n\n\nsourceDir#\n\n指定构建的源码目录,默认为 src,用于在 bundleless 构建时基于源码目录结构生成对应的产物目录。\n\n * 类型: string\n * 默认值: src\n\n\nsourceMap#\n\n控制 sourceMap 如何生成。\n\n * 类型: boolean | 'inline' | 'external'\n * 默认值: false\n\n\nsourceType#\n\n设置源码的格式。默认情况下,会将源码作为 EsModule 进行处理。当源码使用的是 CommonJS 的时候,需要设置 commonjs。\n\n * 类型:'commonjs' | 'module'\n * 默认值:'module'\n\n\nsplitting#\n\n是否开启代码分割。\n\n * 类型: boolean\n * 默认值: false\n\n\nstyle#\n\n配置样式相关的配置。\n\n\nstyle.less#\n\nless 相关配置。\n\n\nstyle.less.lessOptions#\n\n详细配置参考 less。\n\n * 类型: object\n * 默认值: { javascriptEnabled: true }\n\n\nstyle.less.additionalData#\n\n在入口文件起始添加 Less 代码。\n\n * 类型: string\n * 默认值: undefined\n\nexport default defineConfig({\n buildConfig: {\n style: {\n less: {\n additionalData: `@base-color: #c6538c;`,\n },\n },\n },\n});\n\n\n\nstyle.less.implementation#\n\n配置 Less 使用的实现库,在不指定的情况下,使用的内置版本是 4.1.3。\n\n * 类型: string | object\n * 默认值: undefined\n\n设置 object 类型时,可以指定 Less 的实现库。\n\nexport default defineConfig({\n buildConfig: {\n style: {\n less: {\n implementation: require('less'),\n },\n },\n },\n});\n\n\nstring 类型时,指定 Less 的实现库的路径\n\nexport default defineConfig({\n buildConfig: {\n style: {\n less: {\n implementation: require.resolve('less'),\n },\n },\n },\n});\n\n\n\nsass#\n\nSass 相关配置。\n\n\nstyle.sass.sassOptions#\n\n详细配置参考 node-sass\n\n * 类型: object\n * 默认值: {}\n\n\nstyle.sass.additionalData#\n\n在入口文件起始添加 Sass 代码。\n\n * 类型: string | Function\n * 默认值: undefined\n\nexport default defineConfig({\n buildConfig: {\n style: {\n sass: {\n additionalData: `$base-color: #c6538c;\n $border-dark: rgba($base-color, 0.88);`,\n },\n },\n },\n});\n\n\n\nstyle.sass.implementation#\n\n配置 Sass 使用的实现库,在不指定的情况下,使用的内置版本是 1.5.4。\n\n * 类型: string | object\n * 默认值: undefined\n\n设置为 object 类型时,可以指定 Sass 的实现库。\n\nexport default defineConfig({\n buildConfig: {\n style: {\n sass: {\n implementation: require('sass'),\n },\n },\n },\n});\n\n\nstring 类型时,指定 Sass 的实现库的路径\n\nexport default defineConfig({\n buildConfig: {\n style: {\n sass: {\n implementation: require.resolve('sass'),\n },\n },\n },\n});\n\n\n\nstyle.postcss#\n\n * plugins\n * processOptions\n\n详细配置查看 PostCSS。\n\n基础使用:\n\nexport default defineConfig({\n buildConfig: {\n style: {\n postcss: {\n plugins: [yourPostCSSPlugin],\n },\n },\n },\n});\n\n\n\nstyle.inject#\n\n配置打包模式下是否将 CSS 样式插入到 JavaScript 代码中。\n\n * 类型: boolean\n * 默认值: false\n\n将 inject 设置为 true 来开启此功能:\n\nexport default defineConfig({\n buildConfig: {\n inject: true,\n },\n});\n\n\n开启后,你会看到源码中引用的 CSS 代码被包含在了打包后的 JS 产物中。\n\n例如,你在源码里写了 import './index.scss',那么在产物中你会看到以下代码:\n\n// node_modules/style-inject/dist/style-inject.es.js\nfunction styleInject(css, ref) {\n // ...\n}\nvar style_inject_es_default = styleInject;\n\n// src/index.scss\nvar css_248z = '.body {\\n color: black;\\n}';\nstyle_inject_es_default(css_248z);\n\n\nTIP\n\n开启 inject 后,你需要注意以下几点:\n\n * CSS 文件中的 @import 不会被处理。如果你的 CSS 文件中有 @import ,那么你需要在 JS 文件中手动引入 CSS\n 文件(less,scss 文件不需要,因为它们会有预处理)。\n * 需要考虑 sideEffects 的影响。默认情况下,我们的构建器会认为 CSS 是有副作用的,如果你的项目中或者三方包的 package.json\n 设置了 sideEffects 字段并且没有包含此 CSS 文件,那么你将会得到一个警告:\n\n[LIBUILD:ESBUILD_WARN] Ignoring this import because \"src/index.scss\" was marked as having no side effects by plugin \"libuild:adapter\"\n\n\n此时可以通过配置 sideEffects 来解决。\n\n\nstyle.autoModules#\n\n根据文件名自动启用 CSS Modules。\n\n * 类型: boolean | RegExp\n * 默认值: true\n\ntrue : 为以 .module.css .module.less .module.scss .module.sass 文件名结尾的样式文件启用 CSS\nModules。\n\nfalse : 禁用 CSS Modules.\n\nRegExp : 为匹配正则条件的所有文件启用 CSS Modules.\n\n\nstyle.modules#\n\nCSS Modules 配置。\n\n * 类型: object\n * 默认值: {}\n\n一个常用的配置是 localsConvention,它可以改变 CSS Modules 的类名生成规则。\n\nexport default defineConfig({\n buildConfig: {\n style: {\n modules: {\n localsConvention: 'camelCaseOnly',\n },\n },\n },\n});\n\n\n对于以下样式:\n\n.box-title {\n color: red;\n}\n\n\n你可以使用 styles.boxTitle 来访问。\n\n详细配置查看 postcss-modules\n\n\nstyle.tailwindcss#\n\nTailwind CSS 相关配置。\n\n * 类型: object | Function\n * 默认值: 见下方配置详情\n\nconst tailwind = {\n content: [\n './config/html/**/*.html',\n './config/html/**/*.ejs',\n './config/html/**/*.hbs',\n './src/**/*.js',\n './src/**/*.jsx',\n './src/**/*.ts',\n './src/**/*.tsx',\n './storybook/**/*',\n ],\n};\n\n\n值为 object 类型时,与默认配置通过 Object.assign 合并。\n\n值为 Function 类型时,函数返回的对象与默认配置通过 Object.assign 合并。\n\n不允许出现 theme 属性,否则会构建失败, 使用 designSystem 作为 Tailwind CSS Theme 配置。\n\n其他的使用方式和 Tailwind CSS 一致: 快速传送门。\n\n\ntarget#\n\ntarget 用于为生成的 JavaScript 代码设置目标环境。它让 Module Tools 将目标环境无法识别的 JavaScript\n语法转换为在这些环境中可用的低版本 JavaScript 语法。\n\n * 类型:\n\ntype Target =\n | 'es5'\n | 'es6'\n | 'es2015'\n | 'es2016'\n | 'es2017'\n | 'es2018'\n | 'es2019'\n | 'es2020'\n | 'es2021'\n | 'es2022'\n | 'esnext';\n\n\n * 默认值: 'es6'\n\n例如,将代码编译到 es5 语法:\n\nexport default defineConfig({\n buildConfig: {\n target: 'es5',\n },\n});\n\n\n\ntransformImport#\n\n提供与 babel-plugin-import 等价的能力和配置,基于 SWC 实现。\n\n * 类型:object[]\n * 默认值:[]\n\n数组元素为一个 babel-plugin-import 的配置对象。配置对象可以参考 options。\n\n使用示例:\n\nexport default defineConfig({\n buildConfig: {\n transformImport: [\n // babel-plugin-import 的 options 配置\n {\n libraryName: 'foo',\n style: true,\n },\n ],\n },\n});\n\n\n\n注意事项#\n\n参考「Import 插件——注意事项」\n\n\numdGlobals#\n\n指定 UMD 产物外部导入的全局变量。\n\n * 类型: Record\n * 默认值: {}\n\nexport default defineConfig({\n buildConfig: {\n umdGlobals: {\n react: 'React',\n 'react-dom': 'ReactDOM',\n },\n },\n});\n\n\n此时,react 和 react-dom 会被看做是外部导入的全局变量,不会被打包进 UMD 产物中,而是通过 global.React 和\nglobal.ReactDOM 的方式进行访问。\n\n\numdModuleName#\n\n指定 UMD 产物的模块名。\n\n * 类型: string | Function\n * 默认值: name => name\n\nexport default defineConfig({\n buildConfig: {\n format: 'umd',\n umdModuleName: 'myLib',\n },\n});\n\n\n此时 UMD 产物会去挂载到 global.myLib 上。\n\nTIP\n * 需要遵守 UMD 规范,UMD 产物的模块名不能和全局变量名冲突。\n * 模块名会被转换为驼峰命名,如 my-lib 会被转换为 myLib,可参考toIdentifier。\n\n同时函数形式可以接收一个参数,为当前打包文件的输出路径\n\nexport default defineConfig({\n buildConfig: {\n format: 'umd',\n umdModuleName: path => {\n if (path.includes('index')) {\n return 'myLib';\n } else {\n return 'myLib2';\n }\n },\n },\n});\n","frontmatter":{"sidebar_position":1},"_filepath":"/Users/bytedance/github/targeral/modern-js/packages/document/module-doc/docs/zh/api/config/build-config.md","_relativePath":"zh/api/config/build-config.md"},{"id":37,"title":"buildPreset","routePath":"/module-tools/api/config/build-preset","lang":"zh","toc":[{"text":"string","id":"string","depth":2,"charIndex":75},{"text":"\\'npm-library\\'","id":"\\'npm-library\\'","depth":3,"charIndex":-1},{"text":"\\'npm-library-with-umd\\'","id":"\\'npm-library-with-umd\\'","depth":3,"charIndex":-1},{"text":"\\'npm-component\\'","id":"\\'npm-component\\'","depth":3,"charIndex":-1},{"text":"\\'npm-component-with-umd\\'","id":"\\'npm-component-with-umd\\'","depth":3,"charIndex":-1},{"text":"关于预设值支持的 ECMAScript 版本以及 {es5...esnext}","id":"关于预设值支持的-ecmascript-版本以及-{es5esnext}","depth":3,"charIndex":2841},{"text":"Function","id":"function","depth":2,"charIndex":3152},{"text":"函数参数","id":"函数参数","depth":3,"charIndex":3520},{"text":"preset","id":"preset","depth":4,"charIndex":3598},{"text":"extendPreset","id":"extendpreset","depth":4,"charIndex":3705}],"domain":"","content":"#\n\n构建的预设字符串或者预设函数。提供开箱即用的构建配置。\n\n * 类型:string | Function\n * 默认值: undefined\n\n\nstring#\n\n字符串的形式可以让你直接使用内置的预设。\n\n\n\nexport default defineConfig({\n buildPreset: 'npm-library',\n});\n\n\n\n'npm-library'#\n\n在类 NPM 包管理器下使用的 Library 通用模式,包含 esm 和 cjs 两种 Bundle 产物,并且包含一份类型文件。\n\nINFO\n\n关于类 NPM 包管理器\n\n * npm\n * yarn\n * pnpm\n\n{\n \"main\": \"./dist/lib/index.js\",\n \"module\": \"./dist/es/index.js\",\n \"types\": \"./dist/types/index.d.ts\"\n}\n\n\n预设字符串对应的构建配置:\n\nexport const buildConfig = [\n {\n format: 'cjs',\n target: 'es6',\n buildType: 'bundle',\n outDir: './dist/lib',\n },\n {\n format: 'esm',\n target: 'es6',\n buildType: 'bundle',\n outDir: './dist/es',\n },\n {\n buildType: 'bundle',\n outDir: './dist/types',\n dts: {\n only: true,\n },\n },\n];\n\n\n\n'npm-library-with-umd'#\n\n在类 NPM 包管理器下使用,并且 Library 支持类似 unpkg 的模式。在预设 'npm-library' 的基础上,额外提供 umd 产物。\n\n{\n \"main\": \"./dist/lib/index.js\",\n \"module\": \"./dist/es/index.js\",\n \"types\": \"./dist/types/index.d.ts\",\n \"unpkg\": \"./dist/umd/index.js\",\n};\n\n\n预设字符串对应的构建配置:\n\nexport const buildConfig = [\n {\n format: 'cjs',\n target: 'es6',\n buildType: 'bundle',\n outDir: './dist/lib',\n },\n {\n format: 'esm',\n target: 'es6',\n buildType: 'bundle',\n outDir: './dist/es',\n },\n {\n format: 'umd',\n target: 'es6',\n buildType: 'bundle',\n outDir: './dist/umd',\n },\n {\n buildType: 'bundle',\n outDir: './dist/types',\n dts: {\n only: true,\n },\n },\n];\n\n\n\n'npm-component'#\n\n在类 NPM 包管理器下使用的 组件(库)通用模式。包含 esm 和 cjs 两种 Bundleless 产物(便于 Tree shaking\n优化),以及包含一份类型文件。\n\n对于源码中包含的样式文件,产物中提供样式的编译产物和样式的源文件。\n\n{\n \"main\": \"./dist/lib/index.js\", // bundleless type\n \"module\": \"./dist/es/index.js\", // bundleless type\n \"types\": \"./dist/types/index.d.ts\",\n};\n\n\n预设字符串对应的构建配置:\n\nexport const buildConfig = [\n {\n format: 'cjs',\n target: 'es6',\n buildType: 'bundleless',\n outDir: './dist/lib',\n },\n {\n format: 'esm',\n target: 'es6',\n buildType: 'bundleless',\n outDir: './dist/es',\n },\n {\n buildType: 'bundleless',\n outDir: './dist/types',\n dts: {\n only: true,\n },\n },\n];\n\n\n\n'npm-component-with-umd'#\n\n在类 NPM 包管理器下使用的组件(库),同时支持类 unpkg 的模式。 在预设 'npm-component' 的基础上,额外提供 umd 产物。\n\n{\n \"main\": \"./dist/lib/index.js\", // bundleless type\n \"module\": \"./dist/es/index.js\", // bundleless type\n \"types\": \"./dist/types/index.d.ts\",\n \"unpkg\": \"./dist/umd/index.js\",\n};\n\n\nexport const buildConfig = [\n {\n format: 'cjs',\n target: 'es6',\n buildType: 'bundleless',\n outDir: './dist/lib',\n },\n {\n format: 'esm',\n target: 'es6',\n buildType: 'bundleless',\n outDir: './dist/es',\n },\n {\n format: 'umd',\n target: 'es6',\n buildType: 'bundle',\n outDir: './dist/umd',\n },\n {\n buildType: 'bundleless',\n outDir: './dist/types',\n dts: {\n only: true,\n },\n },\n];\n\n\n\n关于预设值支持的 ECMAScript 版本以及 {es5...esnext}#\n\n当想要使用支持其他 ECMAScript 版本的 buildPreset 预设的时候,可以直接在\n'npm-library'、'npm-library-with-umd'、'npm-component'、'npm-component-with-umd'\n这些预设值后面增加想要支持的版本。\n\n例如希望 'npm-library' 预设支持 'es2017',则可以按照如下方式配置:\n\n\n\nexport default defineConfig({\n buildPreset: 'npm-library-es2017',\n});\n\n\n\nFunction#\n\n函数的配置方式,可以通过 preset 参数获取到预设值,然后对里面的构建配置进行修改来自定义你的构建配置。\n以下是一个函数的配置方式的例子,它配置了压缩构建产物的功能:\n\n\n\nexport default defineConfig({\n buildPreset({ preset }) {\n const { NPM_LIBRARY } = preset;\n return NPM_LIBRARY.map(config => {\n config.minify = {\n compress: {\n drop_console: true,\n },\n };\n return config;\n });\n },\n});\n\n\n\n函数参数#\n\nbuildPreset 的函数形式包含了一个对象形式的函数参数。该对象包含以下字段:\n\n * preset\n * extendPreset\n\npreset#\n\n类型:Object\n\n包含了所有可用的构建预设对应的构建配置。可以通过 buildPreset\n所支持的字符串来使用构建配置,也可以使用这些字符串的下划线命令的方式。下面是两种方式的使用示例:\n\nextendPreset#\n\n类型:Function\n\n用于扩展某个 buildPreset 的工具函数,可以修改 buildPreset 对应的构建配置。\n\n> 底层使用类似 {...oldBuildConfig, ...extendBuildConfig} 方式进行处理。\n\n例如在 'npm-library' 构建预设的基础上增加 define 配置:\n\n\n\nexport default defineConfig({\n buildPreset({ extendPreset }) {\n return extendPreset('npm-library', {\n define: {\n VERSION: '1.0.1',\n },\n });\n },\n});\n","frontmatter":{"sidebar_position":2},"_filepath":"/Users/bytedance/github/targeral/modern-js/packages/document/module-doc/docs/zh/api/config/build-preset.mdx","_relativePath":"zh/api/config/build-preset.mdx"},{"id":38,"title":"designSystem","routePath":"/module-tools/api/config/design-system","lang":"zh","toc":[{"text":"Screens","id":"screens","depth":2,"charIndex":12978},{"text":"Max-width 断点","id":"max-width-断点","depth":3,"charIndex":14164},{"text":"多个范围的断点","id":"多个范围的断点","depth":3,"charIndex":14808},{"text":"自定义媒体查询","id":"自定义媒体查询","depth":3,"charIndex":15295},{"text":"Print 样式","id":"print-样式","depth":3,"charIndex":15516},{"text":"Dark Mode","id":"dark-mode","depth":3,"charIndex":15802},{"text":"Colors","id":"colors","depth":2,"charIndex":16159},{"text":"Spacing","id":"spacing","depth":2,"charIndex":16491},{"text":"核心插件","id":"核心插件","depth":2,"charIndex":16987},{"text":"自定义默认配置","id":"自定义默认配置","depth":2,"charIndex":17595},{"text":"覆盖默认配置","id":"覆盖默认配置","depth":3,"charIndex":17656},{"text":"扩展默认配置","id":"扩展默认配置","depth":3,"charIndex":18052},{"text":"引用其他值","id":"引用其他值","depth":3,"charIndex":18661},{"text":"禁用整个核心插件","id":"禁用整个核心插件","depth":3,"charIndex":19390},{"text":"添加自己的 key","id":"添加自己的-key","depth":3,"charIndex":19771},{"text":"配置引用","id":"配置引用","depth":2,"charIndex":20736}],"domain":"","content":"#\n\n本章描述了有关 designSystem 相关的配置。\n\nTIP\n\n需要先通过 pnpm run new 启用 Tailwind CSS 功能。\n\n * 类型:object\n * 默认值: 见下方配置详情。\n\nconst designSystem = {\n screens: {\n sm: '640px',\n md: '768px',\n lg: '1024px',\n xl: '1280px',\n },\n colors: {\n transparent: 'transparent',\n current: 'currentColor',\n\n black: '#000',\n white: '#fff',\n\n gray: {\n 100: '#f7fafc',\n 200: '#edf2f7',\n 300: '#e2e8f0',\n 400: '#cbd5e0',\n 500: '#a0aec0',\n 600: '#718096',\n 700: '#4a5568',\n 800: '#2d3748',\n 900: '#1a202c',\n },\n red: {\n 100: '#fff5f5',\n 200: '#fed7d7',\n 300: '#feb2b2',\n 400: '#fc8181',\n 500: '#f56565',\n 600: '#e53e3e',\n 700: '#c53030',\n 800: '#9b2c2c',\n 900: '#742a2a',\n },\n orange: {\n 100: '#fffaf0',\n 200: '#feebc8',\n 300: '#fbd38d',\n 400: '#f6ad55',\n 500: '#ed8936',\n 600: '#dd6b20',\n 700: '#c05621',\n 800: '#9c4221',\n 900: '#7b341e',\n },\n yellow: {\n 100: '#fffff0',\n 200: '#fefcbf',\n 300: '#faf089',\n 400: '#f6e05e',\n 500: '#ecc94b',\n 600: '#d69e2e',\n 700: '#b7791f',\n 800: '#975a16',\n 900: '#744210',\n },\n green: {\n 100: '#f0fff4',\n 200: '#c6f6d5',\n 300: '#9ae6b4',\n 400: '#68d391',\n 500: '#48bb78',\n 600: '#38a169',\n 700: '#2f855a',\n 800: '#276749',\n 900: '#22543d',\n },\n teal: {\n 100: '#e6fffa',\n 200: '#b2f5ea',\n 300: '#81e6d9',\n 400: '#4fd1c5',\n 500: '#38b2ac',\n 600: '#319795',\n 700: '#2c7a7b',\n 800: '#285e61',\n 900: '#234e52',\n },\n blue: {\n 100: '#ebf8ff',\n 200: '#bee3f8',\n 300: '#90cdf4',\n 400: '#63b3ed',\n 500: '#4299e1',\n 600: '#3182ce',\n 700: '#2b6cb0',\n 800: '#2c5282',\n 900: '#2a4365',\n },\n indigo: {\n 100: '#ebf4ff',\n 200: '#c3dafe',\n 300: '#a3bffa',\n 400: '#7f9cf5',\n 500: '#667eea',\n 600: '#5a67d8',\n 700: '#4c51bf',\n 800: '#434190',\n 900: '#3c366b',\n },\n purple: {\n 100: '#faf5ff',\n 200: '#e9d8fd',\n 300: '#d6bcfa',\n 400: '#b794f4',\n 500: '#9f7aea',\n 600: '#805ad5',\n 700: '#6b46c1',\n 800: '#553c9a',\n 900: '#44337a',\n },\n pink: {\n 100: '#fff5f7',\n 200: '#fed7e2',\n 300: '#fbb6ce',\n 400: '#f687b3',\n 500: '#ed64a6',\n 600: '#d53f8c',\n 700: '#b83280',\n 800: '#97266d',\n 900: '#702459',\n },\n },\n spacing: {\n px: '1px',\n 0: '0',\n 1: '0.25rem',\n 2: '0.5rem',\n 3: '0.75rem',\n 4: '1rem',\n 5: '1.25rem',\n 6: '1.5rem',\n 8: '2rem',\n 10: '2.5rem',\n 12: '3rem',\n 16: '4rem',\n 20: '5rem',\n 24: '6rem',\n 32: '8rem',\n 40: '10rem',\n 48: '12rem',\n 56: '14rem',\n 64: '16rem',\n },\n backgroundColor: theme => theme('colors'),\n backgroundOpacity: theme => theme('opacity'),\n backgroundPosition: {\n bottom: 'bottom',\n center: 'center',\n left: 'left',\n 'left-bottom': 'left bottom',\n 'left-top': 'left top',\n right: 'right',\n 'right-bottom': 'right bottom',\n 'right-top': 'right top',\n top: 'top',\n },\n backgroundSize: {\n auto: 'auto',\n cover: 'cover',\n contain: 'contain',\n },\n borderColor: theme => ({\n ...theme('colors'),\n default: theme('colors.gray.300', 'currentColor'),\n }),\n borderOpacity: theme => theme('opacity'),\n borderRadius: {\n none: '0',\n sm: '0.125rem',\n default: '0.25rem',\n md: '0.375rem',\n lg: '0.5rem',\n full: '9999px',\n },\n borderWidth: {\n default: '1px',\n 0: '0',\n 2: '2px',\n 4: '4px',\n 8: '8px',\n },\n boxShadow: {\n xs: '0 0 0 1px rgba(0, 0, 0, 0.05)',\n sm: '0 1px 2px 0 rgba(0, 0, 0, 0.05)',\n default: '0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)',\n md: '0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)',\n lg: '0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)',\n xl: '0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)',\n '2xl': '0 25px 50px -12px rgba(0, 0, 0, 0.25)',\n inner: 'inset 0 2px 4px 0 rgba(0, 0, 0, 0.06)',\n outline: '0 0 0 3px rgba(66, 153, 225, 0.5)',\n none: 'none',\n },\n container: {},\n cursor: {\n auto: 'auto',\n default: 'default',\n pointer: 'pointer',\n wait: 'wait',\n text: 'text',\n move: 'move',\n 'not-allowed': 'not-allowed',\n },\n divideColor: theme => theme('borderColor'),\n divideOpacity: theme => theme('borderOpacity'),\n divideWidth: theme => theme('borderWidth'),\n fill: {\n current: 'currentColor',\n },\n flex: {\n 1: '1 1 0%',\n auto: '1 1 auto',\n initial: '0 1 auto',\n none: 'none',\n },\n flexGrow: {\n 0: '0',\n default: '1',\n },\n flexShrink: {\n 0: '0',\n default: '1',\n },\n fontFamily: {\n sans: [\n 'system-ui',\n '-apple-system',\n 'BlinkMacSystemFont',\n '\"Segoe UI\"',\n 'Roboto',\n '\"Helvetica Neue\"',\n 'Arial',\n '\"Noto Sans\"',\n 'sans-serif',\n '\"Apple Color Emoji\"',\n '\"Segoe UI Emoji\"',\n '\"Segoe UI Symbol\"',\n '\"Noto Color Emoji\"',\n ],\n serif: ['Georgia', 'Cambria', '\"Times New Roman\"', 'Times', 'serif'],\n mono: [\n 'Menlo',\n 'Monaco',\n 'Consolas',\n '\"Liberation Mono\"',\n '\"Courier New\"',\n 'monospace',\n ],\n },\n fontSize: {\n xs: '0.75rem',\n sm: '0.875rem',\n base: '1rem',\n lg: '1.125rem',\n xl: '1.25rem',\n '2xl': '1.5rem',\n '3xl': '1.875rem',\n '4xl': '2.25rem',\n '5xl': '3rem',\n '6xl': '4rem',\n },\n fontWeight: {\n hairline: '100',\n thin: '200',\n light: '300',\n normal: '400',\n medium: '500',\n semibold: '600',\n bold: '700',\n extrabold: '800',\n black: '900',\n },\n height: theme => ({\n auto: 'auto',\n ...theme('spacing'),\n full: '100%',\n screen: '100vh',\n }),\n inset: {\n 0: '0',\n auto: 'auto',\n },\n letterSpacing: {\n tighter: '-0.05em',\n tight: '-0.025em',\n normal: '0',\n wide: '0.025em',\n wider: '0.05em',\n widest: '0.1em',\n },\n lineHeight: {\n none: '1',\n tight: '1.25',\n snug: '1.375',\n normal: '1.5',\n relaxed: '1.625',\n loose: '2',\n 3: '.75rem',\n 4: '1rem',\n 5: '1.25rem',\n 6: '1.5rem',\n 7: '1.75rem',\n 8: '2rem',\n 9: '2.25rem',\n 10: '2.5rem',\n },\n listStyleType: {\n none: 'none',\n disc: 'disc',\n decimal: 'decimal',\n },\n margin: (theme, { negative }) => ({\n auto: 'auto',\n ...theme('spacing'),\n ...negative(theme('spacing')),\n }),\n maxHeight: {\n full: '100%',\n screen: '100vh',\n },\n maxWidth: (theme, { breakpoints }) => ({\n none: 'none',\n xs: '20rem',\n sm: '24rem',\n md: '28rem',\n lg: '32rem',\n xl: '36rem',\n '2xl': '42rem',\n '3xl': '48rem',\n '4xl': '56rem',\n '5xl': '64rem',\n '6xl': '72rem',\n full: '100%',\n ...breakpoints(theme('screens')),\n }),\n minHeight: {\n 0: '0',\n full: '100%',\n screen: '100vh',\n },\n minWidth: {\n 0: '0',\n full: '100%',\n },\n objectPosition: {\n bottom: 'bottom',\n center: 'center',\n left: 'left',\n 'left-bottom': 'left bottom',\n 'left-top': 'left top',\n right: 'right',\n 'right-bottom': 'right bottom',\n 'right-top': 'right top',\n top: 'top',\n },\n opacity: {\n 0: '0',\n 25: '0.25',\n 50: '0.5',\n 75: '0.75',\n 100: '1',\n },\n order: {\n first: '-9999',\n last: '9999',\n none: '0',\n 1: '1',\n 2: '2',\n 3: '3',\n 4: '4',\n 5: '5',\n 6: '6',\n 7: '7',\n 8: '8',\n 9: '9',\n 10: '10',\n 11: '11',\n 12: '12',\n },\n padding: theme => theme('spacing'),\n placeholderColor: theme => theme('colors'),\n placeholderOpacity: theme => theme('opacity'),\n space: (theme, { negative }) => ({\n ...theme('spacing'),\n ...negative(theme('spacing')),\n }),\n stroke: {\n current: 'currentColor',\n },\n strokeWidth: {\n 0: '0',\n 1: '1',\n 2: '2',\n },\n textColor: theme => theme('colors'),\n textOpacity: theme => theme('opacity'),\n width: theme => ({\n auto: 'auto',\n ...theme('spacing'),\n '1/2': '50%',\n '1/3': '33.333333%',\n '2/3': '66.666667%',\n '1/4': '25%',\n '2/4': '50%',\n '3/4': '75%',\n '1/5': '20%',\n '2/5': '40%',\n '3/5': '60%',\n '4/5': '80%',\n '1/6': '16.666667%',\n '2/6': '33.333333%',\n '3/6': '50%',\n '4/6': '66.666667%',\n '5/6': '83.333333%',\n '1/12': '8.333333%',\n '2/12': '16.666667%',\n '3/12': '25%',\n '4/12': '33.333333%',\n '5/12': '41.666667%',\n '6/12': '50%',\n '7/12': '58.333333%',\n '8/12': '66.666667%',\n '9/12': '75%',\n '10/12': '83.333333%',\n '11/12': '91.666667%',\n full: '100%',\n screen: '100vw',\n }),\n zIndex: {\n auto: 'auto',\n 0: '0',\n 10: '10',\n 20: '20',\n 30: '30',\n 40: '40',\n 50: '50',\n },\n gap: theme => theme('spacing'),\n gridTemplateColumns: {\n none: 'none',\n 1: 'repeat(1, minmax(0, 1fr))',\n 2: 'repeat(2, minmax(0, 1fr))',\n 3: 'repeat(3, minmax(0, 1fr))',\n 4: 'repeat(4, minmax(0, 1fr))',\n 5: 'repeat(5, minmax(0, 1fr))',\n 6: 'repeat(6, minmax(0, 1fr))',\n 7: 'repeat(7, minmax(0, 1fr))',\n 8: 'repeat(8, minmax(0, 1fr))',\n 9: 'repeat(9, minmax(0, 1fr))',\n 10: 'repeat(10, minmax(0, 1fr))',\n 11: 'repeat(11, minmax(0, 1fr))',\n 12: 'repeat(12, minmax(0, 1fr))',\n },\n gridColumn: {\n auto: 'auto',\n 'span-1': 'span 1 / span 1',\n 'span-2': 'span 2 / span 2',\n 'span-3': 'span 3 / span 3',\n 'span-4': 'span 4 / span 4',\n 'span-5': 'span 5 / span 5',\n 'span-6': 'span 6 / span 6',\n 'span-7': 'span 7 / span 7',\n 'span-8': 'span 8 / span 8',\n 'span-9': 'span 9 / span 9',\n 'span-10': 'span 10 / span 10',\n 'span-11': 'span 11 / span 11',\n 'span-12': 'span 12 / span 12',\n },\n gridColumnStart: {\n auto: 'auto',\n 1: '1',\n 2: '2',\n 3: '3',\n 4: '4',\n 5: '5',\n 6: '6',\n 7: '7',\n 8: '8',\n 9: '9',\n 10: '10',\n 11: '11',\n 12: '12',\n 13: '13',\n },\n gridColumnEnd: {\n auto: 'auto',\n 1: '1',\n 2: '2',\n 3: '3',\n 4: '4',\n 5: '5',\n 6: '6',\n 7: '7',\n 8: '8',\n 9: '9',\n 10: '10',\n 11: '11',\n 12: '12',\n 13: '13',\n },\n gridTemplateRows: {\n none: 'none',\n 1: 'repeat(1, minmax(0, 1fr))',\n 2: 'repeat(2, minmax(0, 1fr))',\n 3: 'repeat(3, minmax(0, 1fr))',\n 4: 'repeat(4, minmax(0, 1fr))',\n 5: 'repeat(5, minmax(0, 1fr))',\n 6: 'repeat(6, minmax(0, 1fr))',\n },\n gridRow: {\n auto: 'auto',\n 'span-1': 'span 1 / span 1',\n 'span-2': 'span 2 / span 2',\n 'span-3': 'span 3 / span 3',\n 'span-4': 'span 4 / span 4',\n 'span-5': 'span 5 / span 5',\n 'span-6': 'span 6 / span 6',\n },\n gridRowStart: {\n auto: 'auto',\n 1: '1',\n 2: '2',\n 3: '3',\n 4: '4',\n 5: '5',\n 6: '6',\n 7: '7',\n },\n gridRowEnd: {\n auto: 'auto',\n 1: '1',\n 2: '2',\n 3: '3',\n 4: '4',\n 5: '5',\n 6: '6',\n 7: '7',\n },\n transformOrigin: {\n center: 'center',\n top: 'top',\n 'top-right': 'top right',\n right: 'right',\n 'bottom-right': 'bottom right',\n bottom: 'bottom',\n 'bottom-left': 'bottom left',\n left: 'left',\n 'top-left': 'top left',\n },\n scale: {\n 0: '0',\n 50: '.5',\n 75: '.75',\n 90: '.9',\n 95: '.95',\n 100: '1',\n 105: '1.05',\n 110: '1.1',\n 125: '1.25',\n 150: '1.5',\n },\n rotate: {\n '-180': '-180deg',\n '-90': '-90deg',\n '-45': '-45deg',\n 0: '0',\n 45: '45deg',\n 90: '90deg',\n 180: '180deg',\n },\n translate: (theme, { negative }) => ({\n ...theme('spacing'),\n ...negative(theme('spacing')),\n '-full': '-100%',\n '-1/2': '-50%',\n '1/2': '50%',\n full: '100%',\n }),\n skew: {\n '-12': '-12deg',\n '-6': '-6deg',\n '-3': '-3deg',\n 0: '0',\n 3: '3deg',\n 6: '6deg',\n 12: '12deg',\n },\n transitionProperty: {\n none: 'none',\n all: 'all',\n default:\n 'background-color, border-color, color, fill, stroke, opacity, box-shadow, transform',\n colors: 'background-color, border-color, color, fill, stroke',\n opacity: 'opacity',\n shadow: 'box-shadow',\n transform: 'transform',\n },\n transitionTimingFunction: {\n linear: 'linear',\n in: 'cubic-bezier(0.4, 0, 1, 1)',\n out: 'cubic-bezier(0, 0, 0.2, 1)',\n 'in-out': 'cubic-bezier(0.4, 0, 0.2, 1)',\n },\n transitionDuration: {\n 75: '75ms',\n 100: '100ms',\n 150: '150ms',\n 200: '200ms',\n 300: '300ms',\n 500: '500ms',\n 700: '700ms',\n 1000: '1000ms',\n },\n transitionDelay: {\n 75: '75ms',\n 100: '100ms',\n 150: '150ms',\n 200: '200ms',\n 300: '300ms',\n 500: '500ms',\n 700: '700ms',\n 1000: '1000ms',\n },\n};\n\n\nTIP\n\n更多关于TailwindCSS 配置\n\ndesignSystem 用于定义项目的调色板、排版比例(Typographic Scales 或者 Type\nScale)、字体列表、断点、边框圆角值等等。因为 Modern.js 借用了 Tailwind Theme 的设计方式,并且内部也集成了 Tailwind\nCSS,所以 designSystem 使用方式与 Tailwind CSS Theme 相同\n\ndesignSystem 对象包含 screens、colors 和 spacing 的属性,以及每个可自定义核心插件。\n\n\nScreens#\n\n使用screens 可以自定义项目中的响应断点:\n\nconst designSystem = {\n screens: {\n sm: '640px',\n md: '768px',\n lg: '1024px',\n xl: '1280px',\n },\n};\n\n\n其中 screens 对象里的属性名是屏幕名称(用作 Tailwind CSS 生成的自适应实用程序变体的前缀,例如\nmd:text-center),值是该断点应在其开始的 min-width。\n\n默认断点受常见设备分辨率的启发:\n\nconst designSystem = {\n screens: {\n sm: '640px',\n // => @media (min-width: 640px) { ... }\n\n md: '768px',\n // => @media (min-width: 768px) { ... }\n\n lg: '1024px',\n // => @media (min-width: 1024px) { ... }\n\n xl: '1280px',\n // => @media (min-width: 1280px) { ... }\n },\n};\n\n\n你可以在你的项目中使用任意你喜欢的名称作为断点的属性:\n\nconst designSystem = {\n screens: {\n tablet: '640px',\n // => @media (min-width: 640px) { ... }\n\n laptop: '1024px',\n // => @media (min-width: 1024px) { ... }\n\n desktop: '1280px',\n // => @media (min-width: 1280px) { ... }\n },\n};\n\n\n这些屏幕名称反映在 utilities 中,因此 text-center 现在是这样的:\n\n.text-center {\n text-align: center;\n}\n\n@media (min-width: 640px) {\n .tablet\\:text-center {\n text-align: center;\n }\n}\n\n@media (min-width: 1024px) {\n .laptop\\:text-center {\n text-align: center;\n }\n}\n\n@media (min-width: 1280px) {\n .desktop\\:text-center {\n text-align: center;\n }\n}\n\n\n\nMax-width 断点#\n\n如果要使用 max-width 断点而不是 min-width,可以将屏幕指定为具有 max 属性的对象:\n\nconst designSystem = {\n screens: {\n xl: { max: '1279px' },\n // => @media (max-width: 1279px) { ... }\n\n lg: { max: '1023px' },\n // => @media (max-width: 1023px) { ... }\n\n md: { max: '767px' },\n // => @media (max-width: 767px) { ... }\n\n sm: { max: '639px' },\n // => @media (max-width: 639px) { ... }\n },\n};\n\n\n如有必要,以创建带有 min-width 和 max-width 定义的断点,例如:\n\nconst designSystem = {\n screens: {\n sm: { min: '640px', max: '767px' },\n md: { min: '768px', max: '1023px' },\n lg: { min: '1024px', max: '1279px' },\n xl: { min: '1280px' },\n },\n};\n\n\n\n多个范围的断点#\n\n有时,将单个断点定义应用于多个范围会很有用。\n\n例如,假设您有一个 sidebar,并且希望断点基于内容区域宽度而不是整个视口。您可以模拟这种情况,当 sidebar\n可见并缩小内容区域时,断点的样式使用较小的断点样式:\n\nconst designSystem = {\n screens: {\n sm: '500px',\n md: [\n // Sidebar appears at 768px, so revert to `sm:` styles between 768px\n // and 868px, after which the main content area is wide enough again to\n // apply the `md:` styles.\n { min: '668px', max: '767px' },\n { min: '868px' },\n ],\n lg: '1100px',\n xl: '1400px',\n },\n};\n\n\n\n自定义媒体查询#\n\n如果需要为断点提供完全自定义的媒体查询,则可以使用带有 raw 属性的对象:\n\nconst designSystem = {\n extend: {\n screens: {\n portrait: { raw: '(orientation: portrait)' },\n // => @media (orientation: portrait) { ... }\n },\n },\n};\n\n\n\nPrint 样式#\n\n如果需要为打印应用不同的样式,则 raw 选项可能特别有用。\n\n需要做的就是在 designSystem.extend.screens 下添加一个 print:\n\nconst designSystem = {\n extend: {\n screens: {\n print: { raw: 'print' },\n // => @media print { ... }\n },\n },\n};\n\n\n然后,可以使用诸如 print:text-black 之类的类来指定仅当某人尝试打印页面时才应用的样式:\n\n\n \n\n\n\n\nDark Mode#\n\nraw 选项可以用于实现 “暗模式” 屏幕:\n\nconst designSystem = {\n extend: {\n screens: {\n dark: { raw: '(prefers-color-scheme: dark)' },\n // => @media (prefers-color-scheme: dark) { ... }\n },\n },\n};\n\n\n然后,您可以使用 dark: 前缀在暗模式下为元素设置不同的样式:\n\n\n \n\n\n\n请注意,由于这些 screen variants 是在 Tailwind CSS 中实现的,因此无法使用这种方法将断点与暗模式结合使用 ,例如\nmd:dark:text-gray-300 将不起作用。\n\n\nColors#\n\ncolors 属性可让您自定义项目的全局调色板。\n\nconst designSystem = {\n colors: {\n transparent: 'transparent',\n black: '#000',\n white: '#fff',\n gray: {\n 100: '#f7fafc',\n // ...\n 900: '#1a202c',\n },\n\n // ...\n },\n};\n\n\n默认情况下,这些颜色由 backgroundColor,textColor 和 borderColor 核心插件继承。\n\n想了解更多,可以查看:Customizing Colors。\n\n\nSpacing#\n\n使用 space 属性,可以自定义项目的全局间距和缩放比例:\n\nconst designSystem = {\n spacing: {\n px: '1px',\n 0: '0',\n 1: '0.25rem',\n 2: '0.5rem',\n 3: '0.75rem',\n 4: '1rem',\n 5: '1.25rem',\n 6: '1.5rem',\n 8: '2rem',\n 10: '2.5rem',\n 12: '3rem',\n 16: '4rem',\n 20: '5rem',\n 24: '6rem',\n 32: '8rem',\n 40: '10rem',\n 48: '12rem',\n 56: '14rem',\n 64: '16rem',\n },\n};\n\n\n默认情况下,这些值由 padding,margin,negativeMargin,width 和 height 核心插件继承。\n\n想要了解更多,看 Customizing Spacing。\n\n\n核心插件#\n\n主题部分的其余部分用于配置每个核心插件可用的值。\n\n例如,borderRadius 属性可让您自定义将生成的圆角的 utilities:\n\nconst designSystem = {\n borderRadius: {\n none: '0',\n sm: '.125rem',\n default: '.25rem',\n lg: '.5rem',\n full: '9999px',\n },\n};\n\n\n属性名确定所生成类的后缀,值确定实际 CSS 声明的值。 上面的示例borderRadius配置将生成以下 CSS 类:\n\n.rounded-none {\n border-radius: 0;\n}\n.rounded-sm {\n border-radius: 0.125rem;\n}\n.rounded {\n border-radius: 0.25rem;\n}\n.rounded-lg {\n border-radius: 0.5rem;\n}\n.rounded-full {\n border-radius: 9999px;\n}\n\n\n会注意到,在主题配置中使用 default 属性创建了不带后缀的 rounded 类。这是许多(尽管不是全部)核心插件支持的 Tailwind CSS\n中的通用约定。\n\n要了解有关自定义特定核心插件的更多信息,请访问该插件的文档。\n\n\n自定义默认配置#\n\n开箱即用,您的项目将自动从默认主题配置继承值。如果想自定义默认主题,则根据目标有几种不同的选择。\n\n\n覆盖默认配置#\n\n要覆盖默认配置中的选项,请在 designSystem 中添加要覆盖的属性:\n\n\n\nconst designSystem = {\n // Replaces all of the default `opacity` values\n opacity: {\n 0: '0',\n 20: '0.2',\n 40: '0.4',\n 60: '0.6',\n 80: '0.8',\n 100: '1',\n },\n};\n\nexport default defineConfig({\n designSystem,\n});\n\n\n这将完全替换默认属性配置,因此在上面的示例中,不会生成默认的 opacity utilities。\n\n您未提供的任何属性都将从默认主题继承,因此在上面的示例中,将保留颜色,间距,边框圆角,背景位置等内容的默认主题配置。\n\n\n扩展默认配置#\n\n如果您想保留主题选项的默认值,但又要添加新值,请在 designSystem.extend 属性下添加扩展的内容。\n\n例如,如果您想添加一个额外的断点但保留现有的断点,则可以扩展 screens 属性:\n\n\n\nconst designSystem = {\n extend: {\n // Adds a new breakpoint in addition to the default breakpoints\n screens: {\n '2xl': '1440px',\n },\n },\n};\n\nexport default defineConfig({\n designSystem,\n});\n\n\n您当然可以覆盖默认主题的某些部分,并在同一配置中扩展默认主题的其他部分:\n\n\n\nconst designSystem = {\n opacity: {\n 0: '0',\n 20: '0.2',\n 40: '0.4',\n 60: '0.6',\n 80: '0.8',\n 100: '1',\n },\n extend: {\n screens: {\n '2xl': '1440px',\n },\n },\n};\n\nexport default defineConfig({\n designSystem,\n});\n\n\n\n引用其他值#\n\n如果需要在配置中引用另一个值,可以通过提供闭包函数而不是静态值来实现。函数将收到 theme() 函数作为参数,您可以使用该函数使用点表示法在配置中查找其他值。\n\n例如,您可以在 fill 配置上通过引用 theme('colors') 为调色板中的每种颜色生成 fill utilities。\n\n\n\nconst designSystem = {\n colors: {\n // ...\n },\n fill: theme => theme('colors'),\n};\n\nexport default defineConfig({\n designSystem,\n});\n\n\ntheme()函数尝试从已经完全合并的配置对象中找到您要查找的值,因此它可以引用您自己的自定义设置以及默认主题值。它也可以递归工作,因此只要链末尾有一个静态值,\n它就可以解析您要查找的值。\n\n引用默认配置\n\n如果出于任何原因想要引用默认配置中的值,则可以从 tailwindcss/defaultTheme\n导入它。一个有用的示例是,如果要将添加默认配置提供的字体中某一个字体:\n\n\n\nconst defaultTheme = require('tailwindcss/defaultTheme');\n\nconst designSystem = {\n extend: {\n fontFamily: {\n sans: ['Lato', ...defaultTheme.fontFamily.sans],\n },\n },\n};\n\nexport default defineConfig({\n designSystem,\n});\n\n\n\n禁用整个核心插件#\n\n如果您不想为某个核心插件生成任何类,则最好在 corePlugins 配置中将该插件设置为 false,而不是在配置中为该属性提供一个空对象:\n\n// Don't assign an empty object in your theme configuration\n\nconst designSystem = {\n opacity: {},\n};\n\n// Do disable the plugin in your corePlugins configuration\nconst designSyttem = {\n corePlugins: {\n opacity: false,\n },\n};\n\n\n最终结果是相同的,但是由于许多核心插件未公开任何配置,因此无论如何只能使用 corePlugins 禁用它们,最好保持一致。\n\n\n添加自己的 key#\n\n在很多情况下,将自己的属性添加到配置对象可能会很有用。\n\n其中一个示例是添加新属性为多个核心插件之间复用。例如,您可以提取一个 positions对象,backgroundPosition 和\nobjectPosition 插件都可以引用该对象:\n\nconst designSystem = {\n positions: {\n bottom: 'bottom',\n center: 'center',\n left: 'left',\n 'left-bottom': 'left bottom',\n 'left-top': 'left top',\n right: 'right',\n 'right-bottom': 'right bottom',\n 'right-top': 'right top',\n top: 'top',\n },\n backgroundPosition: theme => theme('positions'),\n objectPosition: theme => theme('positions'),\n};\n\n\n另一个示例是在自定义插件中添加新的属性以进行引用。例如,如果您为项目编写了渐变插件,则可以向该插件引用的主题对象添加渐变属性:\n\n\n\nconst designSystem = {\n gradients: theme => ({\n 'blue-green': [theme('colors.blue.500'), theme('colors.green.500')],\n 'purple-blue': [theme('colors.purple.500'), theme('colors.blue.500')],\n // ...\n }),\n};\n\nexport default defineConfig({\n designSystem,\n buildConfig: {\n style: {\n postcss: {\n plugins: [require('./plugins/gradients')],\n },\n },\n },\n});\n\n\n\n配置引用#\n\n除了 screens,colors 和 spacing 外,配置对象中的所有属性都映射到 Tailwind CSS\n的核心插件上。由于许多插件负责仅接受静态值集(例如,例如float)的 CSS 属性,因此请注意,并非每个插件在主题对象中都有对应的属性。\n\n所有这些属性也可以在 designSystem.extend 属性下使用,以扩展默认主题。\n\n关于所有属性的作用,可以查看此 链接。","frontmatter":{"sidebar_position":3},"_filepath":"/Users/bytedance/github/targeral/modern-js/packages/document/module-doc/docs/zh/api/config/design-system.md","_relativePath":"zh/api/config/design-system.md"},{"id":39,"title":"dev","routePath":"/module-tools/api/config/dev","lang":"zh","toc":[{"text":"storybook","id":"storybook","depth":2,"charIndex":128},{"text":"storybook.webpack","id":"storybookwebpack","depth":3,"charIndex":291},{"text":"配置 Manager App","id":"配置-manager-app","depth":4,"charIndex":601},{"text":"storybook.webpackChain","id":"storybookwebpackchain","depth":3,"charIndex":897}],"domain":"","content":"#\n\n本章节描述了 Module Tools 关于调试工具相关的所有配置。\n\nexport default {\n dev: {\n storybook: {\n /* Storybook Config */\n },\n },\n};\n\n\n\nstorybook#\n\n首先需要确保:\n\n * 开启 Storybook 调试功能或者安装 @modern-js/plugin-storybook 插件。\n * 注册 @modern-js/plugin-storybook 插件。\n\n> 关于如何开启 Storybook 调试功能,可以参考:「Storybook 调试」\n\n\nstorybook.webpack#\n\n * 类型:object | Function | undefined\n * 默认值:undefined\n\nexport default {\n dev: {\n storybook: {\n webpack(config) {\n return config;\n },\n },\n },\n};\n\n\n你可以通过 dev.storybook.webpack 来修改 Storybook Preview-iframe 的 webpack 配置。使用方式可以参考\nModern.js Builder 的 tools.webpack 配置。\n\n\n\n配置 Manager App#\n\n对于 Storybook Manager App 部分的 webpack 配置,可以通过增加 ./config/storybook/main.js\n文件进行配置。\n\n// ./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\n\nstorybook.webpackChain#\n\n * 类型:Function | undefined\n * 默认值:undefined\n\nexport default {\n dev: {\n storybook: {\n webpackChain(chain) {\n return chain;\n },\n },\n },\n};\n\n\n你可以通过 dev.storybook.webpackChain 来修改 Storybook Preview-iframe 的 webpack\n配置。使用方式可以参考 Modern.js Builder 的 tools.webpackChain 配置。","frontmatter":{"sidebar_position":3},"_filepath":"/Users/bytedance/github/targeral/modern-js/packages/document/module-doc/docs/zh/api/config/dev.md","_relativePath":"zh/api/config/dev.md"},{"id":40,"title":"plugins","routePath":"/module-tools/api/config/plugins","lang":"zh","toc":[{"text":"插件执行顺序","id":"插件执行顺序","depth":2,"charIndex":75},{"text":"开发插件","id":"开发插件","depth":2,"charIndex":213},{"text":"示例","id":"示例","depth":2,"charIndex":245},{"text":"使用 npm 上的插件","id":"使用-npm-上的插件","depth":3,"charIndex":251},{"text":"使用本地插件","id":"使用本地插件","depth":4,"charIndex":369},{"text":"插件配置项","id":"插件配置项","depth":3,"charIndex":478}],"domain":"","content":"#\n\n本章介绍注册 Module Tools 插件的配置。\n\n * 类型:ModuleToolsPlugin[]\n * 默认值:undefined\n\n\n插件执行顺序#\n\n默认情况下,自定义插件会按照 plugins 数组的顺序依次执行,Module Tools 内置插件的执行时机早于自定义插件。\n\n当插件内部使用了控制顺序的相关字段,比如 pre、post 时,会基于声明的字段对执行顺序进行调整,详见 插件之间的关系。\n\n\n开发插件#\n\n关于如何编写插件,可以查看「插件编写指南」。\n\n\n示例#\n\n\n使用 npm 上的插件#\n\n使用 npm 上的插件,需要通过包管理器安装插件,并通过 import 引入。\n\n\n\nexport default defineConfig({\n plugins: [myPlugin()],\n});\n\n\n使用本地插件#\n\n使用本地代码仓库中的插件,直接通过相对路径 import 引入即可。\n\n\n\nexport default defineConfig({\n plugins: [myPlugin()],\n});\n\n\n\n插件配置项#\n\n如果插件提供了一些自定义的配置项,你可以通过插件函数的参数传入配置。\n\n\n\nexport default defineConfig({\n plugins: [\n myPlugin({\n foo: 1,\n bar: 2,\n }),\n ],\n});\n","frontmatter":{"sidebar_position":4},"_filepath":"/Users/bytedance/github/targeral/modern-js/packages/document/module-doc/docs/zh/api/config/plugins.md","_relativePath":"zh/api/config/plugins.md"},{"id":41,"title":"testing","routePath":"/module-tools/api/config/testing","lang":"zh","toc":[{"text":"jest","id":"jest","depth":2,"charIndex":55},{"text":"transformer","id":"transformer","depth":2,"charIndex":457}],"domain":"","content":"#\n\n本章描述了测试相关的配置。\n\nTIP\n\n需要先通过 pnpm run new 启用 单元测试 功能。\n\n\njest#\n\n * 类型: object | Function\n * 默认值:{}\n\n对应 Jest 的配置,当为 object 类型时,可以配置 Jest 所支持的所有底层配置 。\n\n\n\nexport default defineConfig({\n testing: {\n jest: {\n testTimeout: 10000,\n },\n },\n});\n\n\n值为 Function 类型时,默认配置作为第一个参数传入,需要返回新的 Jest 配置对象。\n\n\n\nexport default defineConfig({\n testing: {\n jest: options => {\n return {\n ...options,\n testTimeout: 10000,\n };\n },\n },\n});\n\n\n\ntransformer#\n\n * 类型:'babel-jest' | 'ts-jest'\n * 默认值:'babel-jest'\n\n配置执行测试的时候对于源码的编译工具: babel-jest 或 ts-jest。默认使用 babel-jest。\n\nINFO\n\nbabel-jest 也可以编译 TS 文件,但不会类型报错,如果你需要跑测试的时候对 TS 类型进行校验,那么请使用 ts-jest。","frontmatter":{"sidebar_position":5},"_filepath":"/Users/bytedance/github/targeral/modern-js/packages/document/module-doc/docs/zh/api/config/testing.md","_relativePath":"zh/api/config/testing.md"},{"id":42,"title":"概览","routePath":"/module-tools/api/","lang":"zh","toc":[],"domain":"","content":"#","frontmatter":{"overview":true,"sidebar_label":"概览","sidebar_position":1},"_filepath":"/Users/bytedance/github/targeral/modern-js/packages/document/module-doc/docs/zh/api/index.md","_relativePath":"zh/api/index.md"},{"id":43,"title":"Plugin Hooks","routePath":"/module-tools/api/plugin-api/plugin-hooks","lang":"zh","toc":[{"text":"构建钩子","id":"构建钩子","depth":2,"charIndex":168},{"text":"beforeBuild","id":"beforebuild","depth":3,"charIndex":277},{"text":"beforeBuildTask","id":"beforebuildtask","depth":3,"charIndex":827},{"text":"afterBuildTask","id":"afterbuildtask","depth":3,"charIndex":1155},{"text":"afterBuild","id":"afterbuild","depth":3,"charIndex":1505},{"text":"buildPlatform 钩子","id":"buildplatform-钩子","depth":2,"charIndex":1897},{"text":"registerBuildPlatform","id":"registerbuildplatform","depth":3,"charIndex":2236},{"text":"beforeBuildPlatform","id":"beforebuildplatform","depth":3,"charIndex":2843},{"text":"buildPlatform","id":"buildplatform","depth":3,"charIndex":3424},{"text":"afterBuildPlatform","id":"afterbuildplatform","depth":3,"charIndex":3799},{"text":"调试钩子","id":"调试钩子","depth":2,"charIndex":4377},{"text":"registerDev","id":"registerdev","depth":3,"charIndex":4606},{"text":"beforeDev","id":"beforedev","depth":3,"charIndex":5452},{"text":"(before|after)DevMenu","id":"(before|after)devmenu","depth":3,"charIndex":5964},{"text":"beforeDevTask","id":"beforedevtask","depth":3,"charIndex":7000},{"text":"afterDev","id":"afterdev","depth":3,"charIndex":7509}],"domain":"","content":"#\n\n本章介绍关于 Module Tools 支持的生命周期钩子。\n\n目前主要包含两类生命周期钩子:\n\n * 构建钩子:仅在执行 build 命令构建源码产物时触发。\n * buildPlatform 钩子:仅在执行 build --platform 命令生成其他构建产物时触发。\n * 调试钩子:运行 dev 命令时会触发的钩子。\n\n\n构建钩子#\n\n在执行 build 命令的时候,会按照顺序触发以下 Hooks:\n\n * beforeBuild\n * beforeBuildTask\n * afterBuildTask\n * afterBuild\n\n\nbeforeBuild#\n\n执行整体构建流程之前触发。\n\nexport const myPlugin = (): CliPlugin => ({\n name: 'my-plugin',\n\n setup() {\n return {\n beforeBuild(options: Options): Return {\n return options.config;\n },\n };\n },\n});\n\n\n参数和返回值类型:\n\ntype Options = {\n options: { config: BuildConfig; 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\ntype Return = BuildConfig;\n\n\n> BuildConfig 类型参考 API 配置\n\n\nbeforeBuildTask#\n\n根据构建配置,Module Tools 会将整体构建分成多个子构建任务。该 Hook 将会在每一个构建子任务之前触发。\n\nexport const myPlugin = (): CliPlugin => ({\n name: 'my-plugin',\n\n setup() {\n return {\n beforeBuildTask(config: BaseBuildConfig): BaseBuildConfig {\n return config;\n },\n };\n },\n});\n\n\n参数和返回值类型:\n\nBaseBuildConfig 类型参考 API 配置。\n\n\nafterBuildTask#\n\n每一个构建子任务结束之后触发。\n\nexport const myPlugin = (): CliPlugin => ({\n name: 'my-plugin',\n\n setup() {\n return {\n afterBuildTask(options: BuildTaskResult): void {\n // ...\n },\n };\n },\n});\n\n\n参数和返回值类型:\n\nexport interface BuildTaskResult {\n status: 'success' | 'fail';\n message?: string;\n config: BaseBuildConfig;\n}\n\n\n\nafterBuild#\n\n整体构建流程结束之后触发。\n\nexport const myPlugin = (): CliPlugin => ({\n name: 'my-plugin',\n\n setup() {\n return {\n afterBuild(options: BuildResult): void {\n // ...\n },\n };\n },\n});\n\n\n参数和返回值类型:\n\nexport interface BuildResult {\n status: 'success' | 'fail';\n message?: string;\n config: BuildConfig;\n commandOptions: BuildCommandOptions;\n totalDuration: number;\n}\n\n\n\nbuildPlatform 钩子#\n\nmodule-tools 还提供了 build --platform 命令来执行特定的构建任务。\n\n例如在安装了 Storybook 插件后,就可以执行 build --platform 或者 build --platform storybook 来执行\nStorybook 的构建任务。因为 Storybook 插件基于 buildPlatform Hooks 实现了该功能。\n\n在执行 build --platform 后会按照以下顺序触发 Hooks:\n\n * registerBuildPlatform\n * beforeBuildPlatform\n * buildPlatform\n * afterBuildPlatform\n\n\nregisterBuildPlatform#\n\n获取在执行 build --platform 命令时候需要运行的任务信息。\n\nexport const myPlugin = (): CliPlugin => ({\n name: 'my-plugin',\n\n setup() {\n return {\n registerBuildPlatform(): RegisterBuildPlatformResult {\n // ...\n return {\n platform: 'stroybook',\n build() {\n // run storybook logic\n },\n };\n },\n };\n },\n});\n\n\n入参和返回的参数类型:\n\nexport interface RegisterBuildPlatformResult {\n platform: string | string[];\n build: (\n currentPlatform: string, // 当前运行的 platform 构建任务\n context: { isTsProject: boolean },\n ) => void | Promise;\n}\n\n\n\nbeforeBuildPlatform#\n\n当执行 build --platform 命令的时候,会触发所有已注册的构建任务。beforeBuildPlatform 会在执行整体的构建任务之前触发。\n\nexport const myPlugin = (): CliPlugin => ({\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\n入参和返回的参数类型:\n\nexport interface RegisterBuildPlatformResult {\n platform: string | string[];\n build: (\n currentPlatform: string, // 当前运行的 platform 构建任务\n context: { isTsProject: boolean },\n ) => void | Promise;\n}\n\n\n\nbuildPlatform#\n\n当执行 build --platform 命令的时候,会触发所有已注册的构建任务。buildPlatform 会在每个构建任务执行之前触发。\n\nexport const myPlugin = (): CliPlugin => ({\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\n入参和返回的参数类型:\n\nexport interface Options {\n platform: string;\n}\n\n\n\nafterBuildPlatform#\n\n当执行 build --platform 命令的时候,会触发所有已注册的构建任务。afterBuildPlatform 会在整体 platform\n构建任务结束后触发。\n\nexport const myPlugin = (): CliPlugin => ({\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\n入参和返回的参数类型:\n\nexport interface BuildPlatformResult {\n status: 'success' | 'fail';\n message: string | Error | null;\n}\n\n\n\n调试钩子#\n\n在执行 dev 命令的时候,会按照顺序触发以下 Hooks:\n\n * registerDev: 在获取调试功能信息的时候触发。\n * beforeDev: 开始执行调试整体流程之前触发。\n * beforeDevMenu: 出现调试列表/菜单之前触发。\n * afterDevMenu: 选择调试列表/菜单选项后触发。\n * beforeDevTask: 执行调试任务之前触发。\n * afterDev: 执行 dev 整体流程最后触发。\n\n\nregisterDev#\n\n注册调试工具相关的数据。主要包含:\n\n * 调试工具的名称\n * 显示在菜单列表中的项目名称以及对应的值。\n * dev 子命令的定义。\n * 是否在运行调试任务之前执行源码构建\n * 执行调试任务的函数。\n\nexport const myPlugin = (): CliPlugin => ({\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\n入参和返回的参数类型:\n\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;\n}\n\n\n\nbeforeDev#\n\n在收集完所有调试工具元数据后,执行 dev 任务之前触发。\n\nexport const myPlugin = (): CliPlugin => ({\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\n入参和返回的参数类型:\n\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;\n}\n\n\n\n(before|after)DevMenu#\n\nbeforeDevMenu 在出现调试列表/菜单之前触发。接收 inquirer question 作为参数。默认值为:\n\nconst question = [\n {\n name: 'choiceDevTool',\n message: '选择调试工具',\n type: 'list',\n // 注册的调试信息\n choices,\n },\n];\n\n\nafterDevMenu 选择调试列表/菜单选项后触发。\n\nexport const myPlugin = (): CliPlugin => ({\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\n入参和返回的参数类型:\n\nexport 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;\n}\n\n\n\nbeforeDevTask#\n\n执行调试任务之前触发。\n\nexport const myPlugin = (): CliPlugin => ({\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\n入参和返回的参数类型:\n\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;\n}\n\n\n\nafterDev#\n\n在中断调试任务进程时触发。\n\nexport const myPlugin = (): CliPlugin => ({\n name: 'my-plugin',\n\n setup() {\n return {\n afterDev() {\n console.info(`exit!`);\n },\n };\n },\n});\n","frontmatter":{},"_filepath":"/Users/bytedance/github/targeral/modern-js/packages/document/module-doc/docs/zh/api/plugin-api/plugin-hooks.md","_relativePath":"zh/api/plugin-api/plugin-hooks.md"},{"id":44,"title":"","routePath":"/module-tools/components/faq-build-exception","lang":"zh","toc":[],"domain":"","content":"","frontmatter":{},"_filepath":"/Users/bytedance/github/targeral/modern-js/packages/document/module-doc/docs/zh/components/faq-build-exception.mdx","_relativePath":"zh/components/faq-build-exception.mdx"},{"id":45,"title":"","routePath":"/module-tools/components/faq-build-other","lang":"zh","toc":[],"domain":"","content":"","frontmatter":{},"_filepath":"/Users/bytedance/github/targeral/modern-js/packages/document/module-doc/docs/zh/components/faq-build-other.mdx","_relativePath":"zh/components/faq-build-other.mdx"},{"id":46,"title":"","routePath":"/module-tools/components/faq-build-product","lang":"zh","toc":[],"domain":"","content":"","frontmatter":{},"_filepath":"/Users/bytedance/github/targeral/modern-js/packages/document/module-doc/docs/zh/components/faq-build-product.mdx","_relativePath":"zh/components/faq-build-product.mdx"},{"id":47,"title":"","routePath":"/module-tools/components/faq-storybook","lang":"zh","toc":[],"domain":"","content":"","frontmatter":{},"_filepath":"/Users/bytedance/github/targeral/modern-js/packages/document/module-doc/docs/zh/components/faq-storybook.mdx","_relativePath":"zh/components/faq-storybook.mdx"},{"id":48,"title":"","routePath":"/module-tools/components/faq-test","lang":"zh","toc":[],"domain":"","content":"","frontmatter":{},"_filepath":"/Users/bytedance/github/targeral/modern-js/packages/document/module-doc/docs/zh/components/faq-test.mdx","_relativePath":"zh/components/faq-test.mdx"},{"id":49,"title":"处理静态资源文件","routePath":"/module-tools/guide/advance/asset","lang":"zh","toc":[{"text":"默认行为","id":"默认行为","depth":2,"charIndex":61}],"domain":"","content":"#\n\n模块工程会对代码中使用的静态资源进行处理。如果需要配置,则可以使用 buildConfig.asset API。\n\n\n默认行为#\n\n默认情况下,模块工程对于以下静态资源会进行处理:\n\n * '.svg'、'.png'、'.jpg'、'.jpeg'、'.gif'、'.webp'\n * '.ttf'、'.otf'、'.woff'、'.woff2'、'.eot'\n * '.mp3'、'.mp4'、'.webm'、'.ogg'、'.wav'、'.flac'、'.aac'、'.mov'\n\n对于静态文件的处理,模块工程目前默认支持的功能有:\n\n * 设置静态资源路径为 ./assets。\n * 对于不超过 10kb 的文件会内联到代码中。\n\n让我们看下面的例子:\n\n当想要修改默认行为的时候,可以使用以下 API:\n\n * asset.path:修改静态资源文件输出路径。\n * asset.limit:修改内联静态资源文件的阈值。","frontmatter":{"sidebar_position":7},"_filepath":"/Users/bytedance/github/targeral/modern-js/packages/document/module-doc/docs/zh/guide/advance/asset.mdx","_relativePath":"zh/guide/advance/asset.mdx"},{"id":50,"title":"构建 umd 产物","routePath":"/module-tools/guide/advance/build-umd","lang":"zh","toc":[{"text":"umd 产物的第三方依赖处理","id":"umd-产物的第三方依赖处理","depth":2,"charIndex":256},{"text":"更改项目的全局变量名称","id":"更改项目的全局变量名称","depth":2,"charIndex":714}],"domain":"","content":"#\n\numd 全称为 Universal Module Definition,这种格式的 JS 文件可以运行在多个运行环境:\n\n * 浏览器环境:基于 AMD 规范进行模块加载\n * Node.js 环境:基于 CommonJS 进行模块加载\n * 其他情况:将模块挂载在全局对象上。\n\n因此我们可以通过下面的方式,将项目的构建产物指定为 umd 产物:\n\nexport default defineConfig({\n buildConfig: {\n format: 'umd',\n },\n});\n\n\n\numd 产物的第三方依赖处理#\n\n在 「如何处理第三方依赖」 章节中,我们知道可以通过 autoExternals 和 externals API 来控制项目是否对第三方依赖打包。 因此在构建\numd 产物的过程中,我们也可以这样使用:\n\n通过上面的例子我们知道,当使用 autoExternal 和 externals API 后:\n\n * 在 Node.js 环境下,可以通过 require('react') 获取 react 依赖。\n * 在 浏览器环境下,可以通过 global.react 获取 react 依赖。\n\n然而在浏览器环境下,获取第三方依赖的时候,全局变量名称不一定与依赖名称完全相同,此时就要使用 buildConfig.umdGlobals API。\n\n还是使用之前的例子,当 react 依赖以 windows.React 或者 global.React 全局变量的形式存在于浏览器环境下,那么此时:\n\n此时项目就可以运行在浏览器中,并使用存在于全局对象上的 React 变量了。\n\n\n更改项目的全局变量名称#\n\n当我们将下面的代码打包成 umd 产物并运行在浏览器的时候,我们可以通过 window.index 来使用该模块。\n\nexport default () => {\n console.info('hello world');\n};\n\n\n默认情况下,以源码文件名称作为该模块在浏览器里全局变量的名称。对于上面的例子,其产物内容如下:\n\n(function (global, factory) {\n if (typeof module === 'object' && typeof module.exports === 'object')\n factory(exports);\n else if (typeof define === 'function' && define.amd)\n define(['exports'], factory);\n else if (\n (global = typeof globalThis !== 'undefined' ? globalThis : global || self)\n )\n factory((global.index = {}));\n})(this, function (exports) {\n //...\n});\n\n\n如果需要修改它,则需要使用 buildConfig.umdModuleName API。\n\n当使用该 API 后:\n\nexport default defineConfig({\n buildConfig: {\n format: 'umd',\n umdModuleName: 'myLib',\n },\n});\n\n\n此时构建产物的内容为:\n\n(function (global, factory) {\n if (typeof module === 'object' && typeof module.exports === 'object')\n factory(exports);\n else if (typeof define === 'function' && define.amd)\n define(['exports'], factory);\n else if (\n (global = typeof globalThis !== 'undefined' ? globalThis : global || self)\n )\n factory((global.myLib = {}));\n})(this, function (exports) {\n //...\n});\n","frontmatter":{"sidebar_position":5},"_filepath":"/Users/bytedance/github/targeral/modern-js/packages/document/module-doc/docs/zh/guide/advance/build-umd.mdx","_relativePath":"zh/guide/advance/build-umd.mdx"},{"id":51,"title":"使用 Copy 工具","routePath":"/module-tools/guide/advance/copy","lang":"zh","toc":[{"text":"了解 Copy API","id":"了解-copy-api","depth":2,"charIndex":59},{"text":"API 详解","id":"api-详解","depth":2,"charIndex":174},{"text":"不同场景使用示例","id":"不同场景使用示例","depth":2,"charIndex":1501},{"text":"将文件复制文件","id":"将文件复制文件","depth":3,"charIndex":1513},{"text":"将文件复制到目录","id":"将文件复制到目录","depth":3,"charIndex":1857},{"text":"从目录复制到目录","id":"从目录复制到目录","depth":3,"charIndex":2195},{"text":"从目录到文件","id":"从目录到文件","depth":3,"charIndex":2589},{"text":"使用 Glob","id":"使用-glob","depth":3,"charIndex":2994}],"domain":"","content":"#\n\n模块工程提供了 Copy 工具用于将已经存在的单个文件或整个目录复制到产物目录中。接下来我们学习如何使用它。\n\n\n了解 Copy API#\n\n我们可以通过 buildConfig.copy API 来使用 Copy 工具,它包含以下两个主要配置:\n\n * patterns\n * options\n\n在开始学习之前可以先花一些时间了解它们。\n\n\nAPI 详解#\n\ncopy.patterns 用于寻找复制的文件以及配置输出的路径。\n\n其中 patterns.from 用于指定要复制的文件或者目录。它接收 Glob 形式字符串或具体路径。Glob 形式字符串是指 fast-glob\npattern-syntax。因此我们可以按照如下两种方式使用它:\n\nexport default defineConfig({\n buildConfig: {\n copy: {\n patterns: [\n { from: './index.html', to: '' },\n { from: './*.html', to: '' },\n ],\n },\n },\n});\n\n\npatterns.context 一般和 patterns.from 配合使用,默认情况下它的值与 buildConfig.sourceDir\n相同,因此我们可以按照如下方式指定 src/data.json 文件为要复制的文件:\n\n> 默认情况下,buildConfig.sourceDir 为 src\n\nexport default defineConfig({\n buildConfig: {\n copy: {\n patterns: [\n { from: './data.json' to: ''},\n ],\n },\n },\n});\n\n\n当指定的文件不在源码目录的时候,可以修改 context 配置。例如指定项目目录下的 temp/index.html 为要复制的文件:\n\n\n\nexport default defineConfig({\n buildConfig: {\n copy: {\n patterns: [\n {\n from: './index.html',\n context: path.join(__dirname, './temp')\n to: '',\n }\n ],\n },\n },\n});\n\n\npatterns.to 用于指定复制文件的输出路径,默认情况下它的值为 buildConfig.outDir对应的值。因此我们按照如下方式将\nsrc/index.html 复制到 dist 目录下:\n\nexport default defineConfig({\n buildConfig: {\n copy: {\n patterns: [{ from: './index.html' }],\n },\n },\n});\n\n\n当我们配置了 patterns.to 的时候:\n\n * 如果是相对路径,则该路径会相对于 buildConfig.outDir 计算出复制文件输出的绝对路径。\n * 如果是绝对路径,则会直接使用该值。\n\n最后 patterns.globOptions 用于配置寻找复制文件 globby 对象,其配置可参考:\n\n * globby.options\n\n\n不同场景使用示例#\n\n\n将文件复制文件#\n\nexport default defineConfig({\n buildConfig: [\n {\n outDir: 'dist',\n copy: {\n patterns: [\n /**\n * copy file to file\n */\n {\n from: './temp-1/a.png',\n context: __dirname,\n to: './temp-1/b.png',\n },\n ],\n },\n },\n ],\n});\n\n\n\n将文件复制到目录#\n\nexport default defineConfig({\n buildConfig: [\n {\n outDir: 'dist',\n copy: {\n patterns: [\n /**\n * copy file to dir\n */\n {\n from: './temp-2/a.png',\n context: __dirname,\n to: './temp-2',\n },\n ],\n },\n },\n ],\n});\n\n\n\n从目录复制到目录#\n\nexport default defineConfig({\n buildConfig: [\n {\n outDir: 'dist',\n copy: {\n patterns: [\n /**\n * copy dir to dir\n */\n {\n from: './temp-3/',\n to: './temp-3',\n context: __dirname,\n },\n ],\n options: {\n enableCopySync: true,\n },\n },\n },\n ],\n});\n\n\n\n从目录到文件#\n\nexport default defineConfig({\n buildConfig: [\n {\n outDir: 'dist',\n copy: {\n patterns: [\n /**\n * copy dir to file\n */\n {\n from: './temp-4/',\n context: __dirname,\n to: './temp-4/_index.html',\n },\n ],\n options: {\n enableCopySync: true,\n },\n },\n },\n ],\n});\n\n\n\n使用 Glob#\n\nexport default defineConfig({\n buildConfig: [\n {\n outDir: 'dist',\n copy: {\n patterns: [\n /**\n * copy glob to dir\n */\n {\n from: './*.html',\n to: './temp-5',\n },\n ],\n options: {\n enableCopySync: true,\n },\n },\n },\n {\n copy: {\n patterns: [\n /**\n * copy glob to file\n */\n {\n from: './*.html',\n to: './temp-6/index.html',\n },\n ],\n options: {\n enableCopySync: true,\n },\n },\n },\n ],\n});\n","frontmatter":{"sidebar_position":3},"_filepath":"/Users/bytedance/github/targeral/modern-js/packages/document/module-doc/docs/zh/guide/advance/copy.md","_relativePath":"zh/guide/advance/copy.md"},{"id":52,"title":"如何处理第三方依赖","routePath":"/module-tools/guide/advance/external-dependency","lang":"zh","toc":[{"text":"第三方依赖的默认处理","id":"第三方依赖的默认处理","depth":2,"charIndex":314},{"text":"排除指定第三方依赖","id":"排除指定第三方依赖","depth":2,"charIndex":619}],"domain":"","content":"#\n\n一般来说,项目所需要的第三方依赖可以通过包管理器的 install 命令安装,在安装第三方依赖成功后,这些第三方依赖一般会出现在项目 package.json\n的 dependencies 和 devDependencies 下。\n\n{\n \"dependencies\": {},\n \"devDependencies\": {}\n}\n\n\n\"dependencies\" 下的依赖通常来说是这个包运行所需的依赖, \"devDependencies\" 则代表着开发依赖。\n\n除了 \"dependencies\" 以外,\"peerDependencies\" 也可以声明在生产环境下运行所需要的依赖,此时会和它的宿主共享一份依赖。\n\n\n第三方依赖的默认处理#\n\n在模块工程里,默认情况下不会对 \"dependencies\" 以及 \"peerDependencies\" 下的第三方依赖进行打包处理。\n\n这是因为在安装 npm 包时,其 \"dependencies\" 也会被安装。不打包 \"dependencies\",可以减小包产物的体积。\n\n如果需要打包某些依赖,建议将它们从 \"dependencies\" 挪到 \"devDependencies\" ,这相当于对依赖进行 prebundle\n,可以减小依赖安装的体积。\n\n如果想要修改默认的处理方式,可以通过下面的 API 进行修改:\n\n * buildConfig.autoExternal\n\n\n排除指定第三方依赖#\n\n在上面我们提到了 buildConfig.autoExternal API 的用途,同时 buildConfig.externals\n可以实现对三方依赖更细微的处理。\n\n例如当我们需要仅对某些依赖不进行打包处理的时候,可以按照如下方式进行配置:\n\n> 一般这种情况,可能是某些依赖不适合进行打包处理。如果遇到这种情况,则可以按照下面的方式进行处理。\n\nepxort default defineConfig({\n buildConfig: {\n autoExternal: false,\n externals: ['pkg-1', /pkg-2/],\n }\n});\n","frontmatter":{"sidebar_position":4},"_filepath":"/Users/bytedance/github/targeral/modern-js/packages/document/module-doc/docs/zh/guide/advance/external-dependency.mdx","_relativePath":"zh/guide/advance/external-dependency.mdx"},{"id":53,"title":"深入理解构建","routePath":"/module-tools/guide/advance/in-depth-about-build","lang":"zh","toc":[{"text":"深入理解 buildConfig","id":"深入理解-buildconfig","depth":2,"charIndex":195},{"text":"Bundle 和 Bundleless","id":"bundle-和-bundleless","depth":3,"charIndex":215},{"text":"input 与 sourceDir 的关系","id":"input-与-sourcedir-的关系","depth":3,"charIndex":735},{"text":"input 的对象模式","id":"input-的对象模式","depth":4,"charIndex":1081},{"text":"sourceDir","id":"sourcedir","depth":4,"charIndex":1401},{"text":"类型文件","id":"类型文件","depth":3,"charIndex":1584},{"text":"关闭类型生成","id":"关闭类型生成","depth":4,"charIndex":1623},{"text":"打包类型文件","id":"打包类型文件","depth":4,"charIndex":1773},{"text":"别名转换","id":"别名转换","depth":4,"charIndex":2060},{"text":"一些 dts 的使用示例","id":"一些-dts-的使用示例","depth":4,"charIndex":2327},{"text":"buildConfig.define 不同场景的使用方式","id":"buildconfigdefine-不同场景的使用方式","depth":3,"charIndex":2899},{"text":"环境变量替换","id":"环境变量替换","depth":4,"charIndex":2990},{"text":"全局变量替换","id":"全局变量替换","depth":4,"charIndex":3298},{"text":"构建过程","id":"构建过程","depth":2,"charIndex":3687},{"text":"构建报错","id":"构建报错","depth":2,"charIndex":3857}],"domain":"","content":"#\n\n在 \"基础使用\" 的部分,我们已经知道可以通过 buildConfig 配置对项目的输出产物进行修改。buildConfig\n不仅描述了产物的一些特性,同时还为构建产物提供了一些功能。\n\nTIP\n\n如果你还不了解 buildConfig 的作用,请先阅读 修改输出产物。\n\n而在本章里我们将要深入理解某些构建配置的使用以及了解执行 modern build 命令的时候发生了什么。\n\n\n深入理解 buildConfig#\n\n\nBundle 和 Bundleless#\n\n那么首先我们来了解一下 Bundle 和 Bundleless。\n\n所谓 Bundle 是指对构建产物进行打包,构建产物可能是一个文件,也有可能是基于一定的代码拆分策略得到的多个文件。\n\n而 Bundleless 则是指对每个源文件单独进行编译构建,但是并不将它们打包在一起。每一个产物文件都可以找到与之相对应的源码文件。Bundleless\n构建的过程,也可以理解为仅对源文件进行代码转换的过程。\n\n它们有各自的好处:\n\n * Bundle 可以减少构建产物的体积,也可以对依赖预打包,减小安装依赖的体积。提前对库进行打包,可以加快应用项目构建的速度。\n * Bundleless 则是可以保持原有的文件结构,更有利于调试和 tree shaking。\n\nWARNING\n\nBundleless 是单文件编译模式,因此对于类型的引用和导出你需要加上 type 字段, 例如 import type { A } from\n'./types\n\n在 buildConfig 中可以通过 buildConfig.buildType 来指定当前构建任务是 Bundle 还是 Bundleless。\n\n\ninput 与 sourceDir 的关系#\n\nbuildConfig.input 用于指定读取源码的文件路径或者目录路径,其默认值在 Bundle 和 Bundleless 构建过程中有所不同:\n\n * 当 buildType: 'bundle' 的时候,input 默认值为 src/index.(j|t)sx?\n * 当 buildType: 'bundleless' 的时候,input 默认值为 ['src']\n\nWARNING\n\n建议不要在 Bundleless 构建过程中指定多个源码文件目录,这可能会导致产物里的相对路径不正确。\n\n从默认值上我们可以知道:Bundle 构建一般可以指定文件路径作为构建的入口,而 Bundleless 构建则更期望使用目录路径寻找源文件。\n\ninput 的对象模式#\n\n在 Bundle 构建过程中,除了将 input\n设置为一个数组,也可以将它设置为一个对象。通过使用对象的形式,我们可以修改构建产物输出的文件名称。那么对于下面的例子,./src/index.ts\n对应的构建产物文件路径为 ./dist/main.js。\n\n\n\nexport default defineConfig({\n buildConfig: {\n input: {\n main: ['./src/index.ts'],\n },\n outDir: './dist',\n },\n});\n\n\n而在 Bundleless 构建过程中,虽然同样支持这样的使用方式,但是并不推荐。\n\nsourceDir#\n\nsourceDir 用于指定源码目录,它主要与以下两个内容有关系:\n\n * 类型文件生成\n * 指定构建过程中的 outbase\n\n一般来说:\n\n * 在 Bundleless 构建过程中,sourceDir 与 input 的值要保持一致,它们的默认值都是 src。\n * 在 Bundle 构建过程中,无需使用 sourceDir。\n\n\n类型文件#\n\nbuildConfig.dts 配置主要用于类型文件的生成。\n\n关闭类型生成#\n\n默认情况下类型生成功能是开启的,如果需要关闭的话,可以按照如下配置:\n\n\n\nexport default defineConfig({\n buildConfig: {\n dts: false,\n },\n});\n\n\nTIP\n\n关闭类型文件后,一般来说构建速度会有所提升。\n\n打包类型文件#\n\n在 buildType: 'bundleless' 的时候,类型文件的生成是使用项目的 tsc 命令来完成生产。\n\n模块工程解决方案同时还支持对类型文件进行打包,不过使用该功能的时候需要注意:\n\n * 一些第三方依赖存在错误的语法会导致打包过程失败。因此对于这种情况,需要手动通过 buildConfig.externals 将这类第三方包排除。\n * 对于第三方依赖的类型文件指向的是一个 .ts 文件的情况,目前无法处理。比如第三方依赖的 package.json 中存在这样的内容: {\"types\":\n \"./src/index.ts\"}。\n\n别名转换#\n\n在 Bundleless 构建过程中,如果源代码中出现了别名,例如:\n\n\n\n\n正常来说,使用 tsc 生成的产物类型文件也会包含这些别名。不过 Module Tools 会对 tsc 生成的类型文件里的别名进行转换处理:\n\n * 对于类似 `` 这样形式的代码可以进行别名转换。\n * 对于类似 export { utils } from '@common/utils' 这样形式的代码可以进行别名转换。\n\n然而也存在一些情况,目前还无法处理:\n\n * 对于类似 Promise 这样形式的输出类型目前无法进行转换。\n\n一些 dts 的使用示例#\n\n一般使用方式:\n\n\n\nexport default defineConfig({\n // 此时打包的类型文件输出路径为 `./dist/types`\n buildConfig: {\n buildType: 'bundle',\n dts: {\n tsconfigPath: './other-tsconfig.json',\n distPath: './types',\n },\n outDir: './dist',\n },\n});\n\n\n使用 dts.only 的情况:\n\n\n\nexport default defineConfig({\n // 此时类型文件没有进行打包,输出路径为 `./dist/types`\n buildConfig: [\n {\n buildType: 'bundle',\n dts: false,\n outDir: './dist',\n },\n {\n buildType: 'bundleless',\n dts: {\n only: true,\n },\n outDir: './dist/types',\n },\n ],\n});\n\n\n\nbuildConfig.define 不同场景的使用方式#\n\nbuildConfig.define 功能有些类似 webpack.DefinePlugin。这里介绍几个使用场景:\n\n环境变量替换#\n\n\nexport default defineConfig({\n buildConfig: {\n define: {\n 'process.env.VERSION': JSON.stringify(process.env.VERSION || '0.0.0'),\n },\n },\n});\n\n\n通过上面的配置,我们就可以将下面这段代码:\n\n// 编译前代码\nconsole.log(process.env.VERSION);\n\n\n在执行 VERSION=1.0.0 modern build 的时候,转换为:\n\n// 编译后代码\nconsole.log('1.0.0');\n\n\n全局变量替换#\n\n\nexport default defineConfig({\n buildConfig: {\n define: {\n VERSION: JSON.stringify(require('./package.json').version || '0.0.0'),\n },\n },\n});\n\n\n通过上面的配置,我们就可以将下面这段代码:\n\n// 编译前代码\nconsole.log(VERSION);\n\n\n转换为:\n\n// 编译后代码\nconsole.log('1.0.0');\n\n\n不过要注意:如果项目是一个 TypeScript 项目,那么你可能需要在项目源代码目录下的 .d.ts 文件里增加以下内容:\n\n> 如果不存在 d.ts 文件,则可以手动创建。\n\ndeclare const YOUR_ADD_GLOBAL_VAR;\n\n\n\n构建过程#\n\n当执行 modern build 命令的时候,会发生\n\n * 根据 buildConfig.outDir 清理产物目录。\n * 编译 js/ts 源代码生成 Bundle/Bundleless 的 JS 构建产物。\n * 使用 tsc 生成 Bundle/Bundleless 的类型文件。\n * 处理 Copy 任务。\n\n\n构建报错#\n\n当发生构建报错的时候,基于以上了解到的信息,可以很容易的明白在终端出现的报错内容:\n\njs 或者 ts 构建的报错:\n\nerror ModuleBuildError:\n\n╭───────────────────────╮\n│ bundle failed: │\n│ - format is \"cjs\" │\n│ - target is \"esnext\" │\n╰───────────────────────╯\n\nDetailed Information:\n\n\n类型文件生成过程的报错:\n\nerror ModuleBuildError:\n\nbundle DTS failed:\n\n\n对于 js/ts 构建错误,我们可以从报错信息中知道:\n\n * 通过 'bundle failed:' 来判断报错的是 Bundle 构建还是 Bundleless 构建?\n * 构建过程的 format 是什么?\n * 构建过程的 target 是什么?\n * 具体的报错信息。","frontmatter":{"sidebar_position":1},"_filepath":"/Users/bytedance/github/targeral/modern-js/packages/document/module-doc/docs/zh/guide/advance/in-depth-about-build.md","_relativePath":"zh/guide/advance/in-depth-about-build.md"},{"id":54,"title":"深入理解 dev 命令","routePath":"/module-tools/guide/advance/in-depth-about-dev-command","lang":"zh","toc":[{"text":"命令运行的整体流程","id":"命令运行的整体流程","depth":2,"charIndex":29},{"text":"扩展 dev 命令","id":"扩展-dev-命令","depth":2,"charIndex":318}],"domain":"","content":"#\n\n模块工程提供的 dev 命令主要用于代码的调试。\n\n\n命令运行的整体流程#\n\n 1. 当执行 dev 命令的时候,Module Tools 开始寻找是否存在可以执行的调试工具或者任务。调试工具或者任务就是类似 Storybook 这样的\n Module Tools 调试工具插件。\n 2. 当发现存在一个调试工具的时候,则会立即执行它。\n 3. 当发现多个调试工具的时候,则显示调试工具列表菜单。可以通过选择某个调试工具对应的名称选项启动它。\n 4. 当没有发现调试工具的时候,则告诉用户没有可用的调试工具。\n\n我们除了可以执行 dev 命令以外,也可以通过 dev [调试工具名称] 的方式来直接启动调试工具或者任务。\n\n\n扩展 dev 命令#\n\n如果需要扩展 dev 命令或者说提供自己的 Module Tools 调试工具插件,那么你需要先了解以下内容:\n\n * 开发插件\n * 调试工具插件 API\n\n一般来说,实现一个什么都不做的调试工具,其实现代码以及相关配置如下:\n\nexport const myPlugin = (): CliPlugin => ({\n name: 'do-nothing',\n setup() {\n return {\n registerDev() {\n return {\n // 调试工具名称\n name: 'do-nothing',\n // 菜单显示内容\n menuItem: {\n name: 'DoNothing',\n value: 'do-nothing',\n },\n // 定义的 dev 子命令\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\n如果需要使用该调试工具插件,则需要在配置文件中增加它:\n\n\n\nexport default defineConfig({\n plugins: [\n //..\n doNothingPlugin()\n ],\n});\n\n\n此时我们执行 dev 或者 dev do-nothing 命令的时候,就可以执行它了。在执行后,它会先执行监听模式的源码构建任务,并紧接着打印日志信息。\n\n对于目前官方支持的调试工具和第三方支持的调试工具,可以在插件列表中查看。","frontmatter":{"sidebar_position":2},"_filepath":"/Users/bytedance/github/targeral/modern-js/packages/document/module-doc/docs/zh/guide/advance/in-depth-about-dev-command.md","_relativePath":"zh/guide/advance/in-depth-about-dev-command.md"},{"id":55,"title":"主题配置","routePath":"/module-tools/guide/advance/theme-config","lang":"zh","toc":[{"text":"动机和原理","id":"动机和原理","depth":2,"charIndex":40},{"text":"使用示例","id":"使用示例","depth":2,"charIndex":528},{"text":"tailwindcss","id":"tailwindcss","depth":3,"charIndex":536},{"text":"HTML 类名","id":"html-类名","depth":4,"charIndex":778},{"text":"@apply 指令","id":"@apply-指令","depth":4,"charIndex":865}],"domain":"","content":"#\n\n模块工程通过 designSystem API,提供了配置主题的能力。\n\n\n动机和原理#\n\n主题配置有些类似组件库中的定制主题功能,主要用于样式开发中使用。我们可以通过 designSystem 配置在不同的样式开发环境下使用由它生成的\ndesignToken。\n\n所谓 designToken 在不同的样式开发环境下对应不同的东西:\n\n * tailwindcss: 以 designSystem 作为 tailwindcss 的 theme 配置。因此可以使用:\n * tailwindcss 支持的 HTML 类名。\n * 在 css/less/sass 下通过 @apply 自定义指令使用与 tailwindcss 支持的 HTML 类名同名的字符串。\n * css/less/scss: 通过 designSystem 生成全局的样式变量。\n\ndesignSystem API 的数据结构借鉴了 tailwindcss 配置对象中的 theme API,因此存在默认的一套\ndesignToken。关于默认值,可以查看 designSystem API。\n\nINFO\n\n目前暂时还未支持 css/less/sass 全局变量。\n\n\n使用示例#\n\n\ntailwindcss#\n\n在使用 tailwindcss 的时候,可以通过 designSystem 来设置它的 theme 配置。\n\n例如在下面的配置中扩展了原有的颜色配置:\n\nexport default {\n designSystem: {\n extend: {\n colors: {\n primary: '#1677ff',\n },\n },\n },\n};\n\n\n我们可以在代码中有两种使用 tailwindcss 的方式。\n\nHTML 类名#\n\nimport 'tailwindcss/utilities.css';\n\nexport default () => {\n return \n;\n};\n\n\n@apply 指令#\n\n关于 @apply。","frontmatter":{"sidebar_position":6},"_filepath":"/Users/bytedance/github/targeral/modern-js/packages/document/module-doc/docs/zh/guide/advance/theme-config.mdx","_relativePath":"zh/guide/advance/theme-config.mdx"},{"id":56,"title":"开始之前","routePath":"/module-tools/guide/basic/before-getting-started","lang":"zh","toc":[{"text":"环境准备","id":"环境准备","depth":2,"charIndex":3},{"text":"初识 npm","id":"初识-npm","depth":2,"charIndex":191},{"text":"npm 包类型项目","id":"npm-包类型项目","depth":2,"charIndex":394},{"text":"使用第三方 npm 包","id":"使用第三方-npm-包","depth":2,"charIndex":1025},{"text":"还需要了解的 npm 零碎知识","id":"还需要了解的-npm-零碎知识","depth":2,"charIndex":1992},{"text":"npm 包的程序入口","id":"npm-包的程序入口","depth":3,"charIndex":2011},{"text":"\\\"scripts\\\"","id":"\\\"scripts\\\"","depth":3,"charIndex":-1},{"text":"npm install","id":"npm-install","depth":4,"charIndex":2880},{"text":"npm publish","id":"npm-publish","depth":4,"charIndex":3144},{"text":"peerDependencies","id":"peerdependencies","depth":3,"charIndex":3304},{"text":"npm 包管理器","id":"npm-包管理器","depth":2,"charIndex":3618},{"text":"Module Tools 配置文件","id":"module-tools-配置文件","depth":2,"charIndex":3746}],"domain":"","content":"#\n\n\n环境准备#\n\n为了使用 Modern.js 模块工程解决方案,首先需要 NodeJS,我们推荐最新的长期维护版本,并确保 Node 版本大于等于 14.18.0。因为非稳定的\nNodeJS 时常有一些 Bug,你可以使用 nvm-windows 和 nvm(Mac / Linux)安装,这样你就可以方便地切换到不同的 NodeJS\n版本,这些版本可能会用于不同的项目。\n\n\n初识 npm#\n\n当 NodeJS 被安装后,你不仅可以在命令行中访问 node 可执行程序,同时你也可以执行 npm 命令。\n\nnpm 是 NodeJS 的标准软件包管理器。它一开始的用途是用于下载和管理 NodeJS 包的依赖关系,但后来它逐渐变成为一个用于前端 JavaScript\n的工具。\n\n如果你已经对 npm 和 npm 包的使用方式有所了解,那么可以直接跳到「npm 包管理器」部分。\n\n\nnpm 包类型项目#\n\n那么什么是 npm 包类型的项目呢?当我们在一个空的项目目录下执行 npm init 命令的时候,它会在当前目录下面创建一个文件名为 package.json\n的 JSON 文件。在创建过程中,我们需要填写包括但不限于 npm 包的名称、版本号、描述等等内容,这些填写的内容都会在生成的 package.json\n文件中找到:\n\n{\n \"name\": \"npm-demo\",\n \"version\": \"1.0.0\",\n \"description\": \"\",\n \"main\": \"index.js\",\n \"scripts\": {\n \"test\": \"echo \\\"Error: no test specified\\\" && exit 1\"\n },\n \"author\": \"\",\n \"license\": \"ISC\"\n}\n\n\n此时这个包含了初始化后的 package.json 文件的项目就是一个 npm 包类型的项目,你可以执行 npm publish 命令将这个项目发布到 npm\nRegistry。\n\nnpm Registry 是一个 npm 包存储的地方,开发者们不仅可以将他们自己的 npm 包发布到 npm Registry,还可以通过 npm\nRegistry 使用其他开发者发布的 npm 包。\n\n优质的 npm 包会有更多的人去使用,因为它不仅节省了很多代码实现的工作,同时也不容易让项目出现问题。\n\n\n使用第三方 npm 包#\n\n当要为初始化的项目增加第三方的 npm 包的时候,我们可以把这一过程叫做“为项目安装依赖”或是“为项目增加依赖”。在增加依赖之前,首先我们要特别了解一件事情\n—— npm 依赖的软件包类型:\n\n * \"dependencies\":一种是你的应用程序在生产环境中需要的软件包。\n * \"devDependencies\":另一种是仅在本地开发和测试中需要的软件包。\n \n > 软件包可以理解为是第三方的 npm 包。\n\n你可以通过执行 npm install npm-package-name 或者 npm add npm-package-name\n的方式来安装在生产环境中需要的软件包,或者也可以在 package.json 文件中手动的将需要安装的包和对应的语义化版本写在 \"dependencies\"\n里,并执行 npm install 命令:\n\n{\n \"name\": \"your-npm-project\",\n \"dependencies\": {\n \"npm-package-name\": \"0.1.0\"\n }\n}\n\n\n同理,你也可以执行 npm install npm-package-name --save-dev 或 npm add npm-package-name\n--save-dev 的方式来安装仅在本地开发和测试中需要的软件包,或者也可以在 package.json 文件中手动的将需要安装的包和对应的语义化版本写在\n\"devDependencies\" 里,并执行 npm install 命令:\n\n{\n \"name\": \"your-npm-project\",\n \"devDependencies\": {\n \"npm-package-name\": \"0.1.0\"\n }\n}\n\n\n在安装或者使用第三方 npm 包的时候一定要确定它们的用途,以及通过区分它们的类型确定好它们应该放在 \"dependencies\" 还是\n\"devDependencies\" 中。\n\nTIP\n\n一般来说,需要在源代码中使用到的包都属于 dependencies 依赖。除非你通过打包的方式将依赖的代码输出到本地,那么这种情况可以将它作为\ndevDependencies 依赖。\n\n\n还需要了解的 npm 零碎知识#\n\n\nnpm 包的程序入口#\n\n在 package.json 中存在一个 \"main\" 属性,它对应的值是一个模块 ID,或者更直观的说是一个 NodeJS 文件路径,它是你程序的主要入口。\n\n例如你的包名为 foo,并且用户安装了它,然后执行 require(\"foo\") 代码,那么 foo 这个 npm 包的 \"main\"\n字段对应的文件将会被导出。\n\n推荐在你的 npm 包里一定要设置 \"main\" 字段。如果没有设置 \"main\",则默认入口为包的根目录下的 index.js 文件。\n\n除了需要设置 \"main\" 属性以外,一般还会设置 \"module\" 属性。它与 \"main\" 属性的用途类似,它主要是用于在 webpack\n场景下使用。webpack 在大多数情况下,会以 \"module\" -> \"main\" 这个顺序读取 npm 包的入口(文件)。\n\n> 想要了解关于 webpack 如何做这件事,可以查看这个链接。\n\n\n\"scripts\"#\n\npackage.json 文件的 \"scripts\" 属性支持一些内置的脚本和 npm 预设的生命周期事件,以及任意的脚本。\n\n这些都可以通过运行 npm run-script 或简称 npm run 来执行。\n\n名称匹配的前置命令和后置命令也会被运行(例如 premyscript、myscript、postmyscript)。\n\n{\n \"scripts\": {\n \"premyscript\": \"\",\n \"myscript\": \"\",\n \"postmyscript\": \"\"\n }\n}\n\n\n当执行 npm run myscripts 的时候,premyscripts 对应的脚本会在它之前执行,postmyscripts 对应的脚本会在它之后执行。\n\n来自依赖的脚本命令可以用 npm explore -- npm run 运行。\n\n还有一些特殊的生命周期脚本(Life Scripts),只在某些情况下发生。这里介绍几个通常需要了解的情况。\n\nnpm install#\n\n当你运行 npm install -g 时,以下脚本会运行。\n\n * preinstall\n * install\n * postinstall\n * prepublish\n * preprepare\n * prepare\n * postprepare\n\n如果你的软件包根目录有一个 binding.gyp 文件,而你没有定义 install 或 preinstall 脚本,那么 npm 将以 node-gyp\nrebuild 作为默认的 install 命令,使用 node-gyp 进行编译。\n\nnpm publish#\n\n当发布项目的时候,执行该命令会触发以下脚本:\n\n * prepublishOnly\n * prepack\n * prepare\n * postpack\n * publish\n * postpublish\n\n当以 --dry-run 模式运行的时候,prepare 对应的脚本将不会执行。\n\n\npeerDependencies#\n\n在某些情况下,你的 npm 项目与它的宿主工具或者库之间存在某种兼容关系(例如一个 webpack 插件项目和 webpack),同时你的 npm\n项目不想将宿主作为必要的依赖,这个时候通常说明你的项目可能是这个宿主工具或者库的插件。你的 npm\n项目会对宿主包的版本有一定的要求,因为只有在特定的版本下才会暴露出 npm 项目所需要的 API。\n\n关于更多 peerDependencies 的解释,可以通过下面的链接了解 npm、pnpm、Yarn 对于它的不同处理方式:\n\n * npm 对 peerDependencies 的解释\n * pnpm vs npm VS Yarn\n\n\nnpm 包管理器#\n\n除了 npm 这种标准的包管理器以外,目前主流的还有 pnpm 和 Yarn,它们都是不错的 npm cli 替代品。\n\n推荐使用 pnpm 来管理项目依赖,可以通过下面的方式安装它:\n\nnpm install -g pnpm\n\n\n\nModule Tools 配置文件#\n\n通过@modern-js/create创建的模块工程项目目录下提供了 Module Tools 的配置文件 —— modern.config.(j|t)s。但\nmodern.config 配置文件不是必须存在的。\n\n默认情况下,生成的配置文件的内容如下:\n\n\n\nexport default defineConfig({\n plugins: [moduleTools()],\n buildPreset: 'npm-library',\n});\n\n\n我们推荐使用 defineConfig 函数,不过并不强制使用它。因此你也可以在配置文件中直接返回一个对象:\n\n\n\nexport default {\n plugins: [moduleTools()],\n buildPreset: 'npm-library',\n};\n","frontmatter":{"sidebar_position":1},"_filepath":"/Users/bytedance/github/targeral/modern-js/packages/document/module-doc/docs/zh/guide/basic/before-getting-started.md","_relativePath":"zh/guide/basic/before-getting-started.md"},{"id":57,"title":"CLI 命令","routePath":"/module-tools/guide/basic/command-preview","lang":"zh","toc":[{"text":"modern build","id":"modern-build","depth":2,"charIndex":35},{"text":"modern new","id":"modern-new","depth":2,"charIndex":1071},{"text":"modern dev","id":"modern-dev","depth":2,"charIndex":1530},{"text":"modern test","id":"modern-test","depth":2,"charIndex":1897},{"text":"modern lint","id":"modern-lint","depth":2,"charIndex":2101},{"text":"modern change","id":"modern-change","depth":2,"charIndex":2394},{"text":"modern pre","id":"modern-pre","depth":2,"charIndex":2634},{"text":"modern bump","id":"modern-bump","depth":2,"charIndex":2780},{"text":"modern release","id":"modern-release","depth":2,"charIndex":3123},{"text":"modern gen-release-note","id":"modern-gen-release-note","depth":2,"charIndex":3474},{"text":"modern upgrade","id":"modern-upgrade","depth":2,"charIndex":3804}],"domain":"","content":"#\n\nModule Tools 项目可以使用的 CLI 命令如下:\n\n\nmodern build#\n\nUsage: 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 -h, --help 展示当前命令的信息\n\n\n当想要启动项目构建的时候,可以执行 modern build 命令。在使用这个命令的时候,我们可以:\n\n * 当想要以观察模式启动构建时,使用 --watch 选项。\n * 当想要指定项目编译读取的 TypeScript 配置文件的路径时,使用 build --tsconfig ./path/config.json\n 选项。使用该选项后,会覆盖所有 buildConfig 里 dts.tsconfigPath 配置。\n * 当需要关闭项目的 DTS 类型文件生成和类型检查行为时,可以使用 --no-dts\n 选项。注意:类型文件的生成依赖类型检查的结果。如果关闭了类型检查,那么类型文件也不会生成。\n * 当需要关闭自动清除产物输出目录的行为时,可以使用 --no-clear 选项。\n\n除了以上,模块工程还支持 platform 构建模式,可以用于执行其他工具的构建任务。例如,目前官方支持在安装了\n@modern-js/plugin-storybook 插件后,可以通过执行 modern build --platform 或者 modern build\n--platform storybook 命令启动 Storybook 构建任务生成 Storybook 产物。\n\nTIP\n\n在执行 Storybook 构建的时候,如果需要读取项目的构建产物。那么在执行 modern build --platform 命令启动 Storybook\n构建之前,不要忘记先执行 modern build 命令确保项目构建产物的存在。\n\n\nmodern new#\n\nUsage: modern new [options]\n\n启用可选功能\n\nOptions:\n -d, --debug 开启 Debug 模式,打印调试日志信息 (default: false)\n -c, --config 生成器运行默认配置(JSON 字符串)\n --dist-tag 生成器使用特殊的 npm Tag 版本\n --registry 生成器运行过程中定制 npm Registry\n -h, --help display help for command\n\n\nmodern new 命令用于启动微生成器功能,它可以为项目启用默认没有提供的功能。\n\n目前可以开启的功能有:\n\n * Test 测试\n * Storybook 调试\n * Tailwind CSS 支持\n * Modern.js Runtime API\n\n关于这些功能,可以通过「使用微生成器」 章节了解更多。\n\n\nmodern dev#\n\nUsage: modern dev [options]\n\n运行和调试模块\n\nOptions:\n -h, --help display help for command\n\nCommands:\n[dev-tools-subCommand]\n\n\n模块工程解决方案提供了使用调试工具的能力,可以通过 modern dev 命令来启动。不过要注意的是,默认情况下是没有提供调试相关的插件,因此此时执行\nmodern dev 会提示: \"No dev tools found available\"。\n\n目前官方支持的调试工具有 Storybook,因此在你执行 modern new 命令开启它后,就可以执行 modern dev 或者 modern dev\nstorybook 执行它。\n\n\nmodern test#\n\nUsage: modern test [options]\n\nOptions:\n -h, --help display help for command\n\n\n需要先执行 modern new 开启测试功能,然后才可以执行 modern test 命令。 modern test 命令会自动将\ntests/*.test.(js|ts|jsx|tsx) 文件当做测试用例运行。\n\n\nmodern lint#\n\nUsage: modern lint [options] [...files]\n\nlint and fix source files\n\nOptions:\n --no-fix disable auto fix source file\n -h, --help display help for command\n\n\n运行 ESLint 检查代码语法情况。通常情况下,我们只需要在 git commit 阶段通过 lint-staged 检查本次提交修改的部分代码。\n\n * --no-fix 参数设置后可以关闭自动修复 lint 错误代码的能力。\n\n\nmodern change#\n\nUsage: modern change [options]\n\n创建变更集\n\nOptions:\n --empty 创建空变更集 (default: false)\n --open 使用编辑器中打开创建的变更集 (default: false)\n -h, --help display help for command\n\n\nmodern change 命令用于生成 changesets 需要的 Markdown 文件。\n\n\nmodern pre#\n\nUsage: modern pre [options] [tag]\n\n进入和退出预发布模式\n\nOptions:\n -h, --help display help for command\n\n\n可以使用 modern pre 命令在正式发布前预发布一个版本。\n\n\nmodern bump#\n\nUsage: modern bump [options]\n\n使用变更集自动更新发布版本和变更日志\n\nOptions:\n --canary 创建一个预发布版本进行测试 (default: false)\n --preid 在对预发布版本进行版本控制时指定标识符 (default: \"next\")\n --snapshot 创建一个特殊版本进行测试 (default: false)\n -h, --help display help for command\n\n\n按照 changesets 生成的变更记录的 Markdown 文件修改 package.json 中的版本号, 同时生成 CHANGELOG.md 文件。\n\n\nmodern release#\n\nUsage: modern release [options]\n\n发布 npm 包\n\nOptions:\n --tag 发布 npm 包使用特定的 tag (default: \"\")\n --ignore-scripts 发布时忽略 package.json 中的 scripts 命令,仅支持在 pnpm monorepo\n 中使用 (default: \"\")\n -h, --help display help for command\n\n\nmodern release 命令可以将模块发布到 npm Registry 上。\n\n * --tag 参数可以指定发布时具体的 dist tags。\n\n\nmodern gen-release-note#\n\nUsage: modern gen-release-note [options]\n\n根据当前仓库 changeset 信息生成 Release Note\n\nOptions:\n --repo 仓库名称,用于生成 Pull Request 链接, 例如: web-infra-dev/modern.js\n --custom 自定义 Release Note 生成函数\n -h, --help display help for command\n\n\n根据当前仓库的 changeset 信息自动生成 Release Note。\n\nTIP\n\n需要在 bump 命令之前执行。\n\n\nmodern upgrade#\n\nUsage: modern upgrade [options]\n\n升级 Modern.js 到最新版本\n\nOptions:\n --registry 定制 npm registry (default: \"\")\n -d,--debug 开启 Debug 模式,打印调试日志信息 (default: false)\n --cwd 项目路径 (default: \"\")\n -h, --help display help for command\n\n\nmodern upgrade 命令,用于升级项目 Modern.js 相关依赖至最新版本。\n\n在项目根目录下执行命令 npx modern upgrade,会默认将当前执行命令项目的 package.json 中的 Modern.js\n相关依赖更新至最新版本。","frontmatter":{"sidebar_position":2},"_filepath":"/Users/bytedance/github/targeral/modern-js/packages/document/module-doc/docs/zh/guide/basic/command-preview.md","_relativePath":"zh/guide/basic/command-preview.md"},{"id":58,"title":"修改输出产物","routePath":"/module-tools/guide/basic/modify-output-product","lang":"zh","toc":[{"text":"默认输出产物","id":"默认输出产物","depth":2,"charIndex":3},{"text":"构建预设","id":"构建预设","depth":2,"charIndex":474},{"text":"构建预设的字符串形式","id":"构建预设的字符串形式","depth":3,"charIndex":570},{"text":"构建预设的函数形式","id":"构建预设的函数形式","depth":3,"charIndex":1218},{"text":"构建配置(对象)","id":"构建配置(对象)","depth":2,"charIndex":2006},{"text":"什么时候使用 buildConfig","id":"什么时候使用-buildconfig","depth":2,"charIndex":3333}],"domain":"","content":"#\n\n\n默认输出产物#\n\n当你在初始化的项目里使用 modern build 命令的时候,Module Tools 会根据当前配置内容,生成相应的构建产物。\n\n默认的配置内容如下:\n\n\n\nexport default defineConfig({\n // 注册 Module Tools 的 CLI 工具\n plugins: [moduleTools()],\n // 指定构建预设配置\n buildPreset: 'npm-library',\n});\n\n\n默认生成产物具有以下特点:\n\n * 会生成 CommonJS 和 ESM 两份产物。\n * 代码语法支持到 ES6 ,更高级的语法将会被转换。\n * 所有的代码经过打包变成了一个文件,即进行了 bundle 处理。\n * 产物输出根目录为项目下的 dist 目录,类型文件输出的目录为 dist/types。\n\n看到这里你可能会有以下疑问:\n\n 1. buildPreset 是什么?\n 2. 产物的这些特点是由什么决定的?\n\n接下来,我们首先来了解一下 buildPreset。\n\n\n构建预设#\n\nbuildPreset 代表着提前准备好的一组或者多组构建相关的配置,只需要使用 buildPreset\n对应的预设值,就可以省去麻烦且复杂的配置工作,得到符合预期的产物。\n\n\n构建预设的字符串形式#\n\n构建预设的值可以是字符串形式,因此这样形式的构建预设叫做预设字符串。\n\n模块工程解决方案根据 npm 包使用的通用场景,提供了通用的构建预设字符串以及相应的变体。目前支持的所有预设字符串可以通过 BuildPreset API\n查看。这里讲解一下关于通用的预设字符串与变体之间的关系。\n\n在通用的预设字符串中,\"npm-library\" 可以用于在开发库类型的 npm 包的场景下使用,它适合大多数普通的模块类型项目。当设置\n\"npm-library\" 的时候,项目的输出产物会有以下特点:\n\n * 在 dist/lib 目录下会得到代码格式为 cjs、语法支持到 es6 且经过打包处理后的产物。\n * 在 dist/es 目录下会得到代码格式为 esm、语法支持为 es6 且经过打包处理后的产物。\n * 在 dist/types 目录下会得到类型文件。如果不是 TypeScript 项目,则没有该目录。\n\n而预设字符串 \"npm-library\" 对应的变体则是在原本产物的基础上修改了代码语法支持这一特点,同时在字符串命名上也变为了\n\"npm-library-[es5 | es2016...es2020 | esnext]\" 这样的形式。\n\n例如,如果在预设字符串 \"npm-library\" 对应的输出产物基础上,让产物代码支持的语法变为 es5 的话,那么只需要将 \"npm-library\"\n改变为 \"npm-library-es5\" 就可以了。\n\n\n构建预设的函数形式#\n\n除了字符串形式以外,构建预设的值也可以是函数形式,在函数中可以打印或者修改某个预设值对应的具体配置。\n\n例如,如果使用预设函数的形式达到预设字符串 \"npm-library-es5\" 同样的效果,可以按照如下的方式:\n\n\n\nexport default defineConfig({\n plugins: [moduleTools()],\n buildPreset({ preset }) {\n return preset.NPM_LIBRARY.map(config => {\n return { ...config, target: 'es5' };\n });\n },\n});\n\n\n在上面的代码实现中,preset.NPM_LIBRARY 与预设字符串 \"npm-library\" 是相对应的,它代表与 \"npm-library\"\n等价的多个构建相关的配置。\n\n我们通过 map 方法遍历了 NPM_LIBRARY 这个数组,在这个数组中包含了多个 buildConfig 对象。我们将原本的 buildConfig\n对象进行了浅拷贝,并修改了浅拷贝后 target 的值,将它指定为 es5。\n\n如果你想了解 preset.NPM_LIBRARY 具体包含的内容,可以通过 BuildPreset API 查看。\n\n此外,在 preset 对象下,不仅包含了 NPM_LIBRARY,也包含了其他类似的常量。\n\nTIP\n\n我们不仅可以使用 preset.NPM_LIBRARY 来获取 \"npm-library\" 对应的构建配置,也可以使用\npreset['npm-library'] 这样的方式。\n\n那么这里的 buildConfig 对象是什么呢?之前提到的构建产物特点又是根据什么呢?\n\n接下来我们解释一下。\n\n\n构建配置(对象)#\n\nbuildConfig 是一个用来描述如何编译、生成构建产物的配置项。在最开始提到的关于“构建产物的特点”,其实都是 buildConfig\n所支持的属性。目前所支持的属性覆盖了大部分模块类型项目在构建产物时的需求,buildConfig\n不仅包含一些产物所具备的属性,也包含了构建产物所需要的一些特性功能。接下来从分类的角度简单罗列一下:\n\n构建产物的基本属性包括:\n\n * 产物是否被打包:对应的 API 是 buildConfig.buildType。\n * 产物对于语法的支持:对应的 API 是 buildConfig.target。\n * 产物格式:对应的 API 是 buildConfig.format。\n * 产物类型文件如何处理,对应的 API 是 buildConfig.dts。\n * 产物的 sourceMap 如何处理:对应的 API 是 buildConfig.sourceMap。\n * 产物对应的输入(或者是源文件):对应的 API 是 buildConfig.input。\n * 产物输出的目录:对应的 API 是 buildConfig.outDir。\n * 构建的源码目录:对应的 API 是 buildConfig.sourceDir。\n\n构建产物所需的常用功能包括:\n\n * 别名:对应的 API 是 buildConfig.alias。\n * 静态资源处理:对应的 API 是 buildConfig.asset。\n * 第三方依赖处理:对应的 API 有:\n * buildConfig.autoExternal。\n * buildConfig.externals。\n * 拷贝:对应的 API 是 buildConfig.copy。\n * 全局变量替换:对应的 API 是 buildConfig.define。\n * 指定 JSX 编译方式,对应的 API 是 buildConfig.jsx。\n\n一些高级属性或者使用频率不高的功能:\n\n * 产物代码压缩:对应的 API 是 buildConfig.minify。\n * 代码分割:buildConfig.spitting\n * 指定构建产物用于 NodeJS 环境还是浏览器环境:对应的 API 是 buildConfig.platform。\n * umd 产物相关:\n * 指定 umd 产物外部导入的全局变量:对应的 API 是 buildConfig.umdGlobals。\n * 指定 umd 产物的模块名:对应的 API 是 buildConfig.umdModuleName。\n\n除了以上分类以外,关于这些 API 的常见问题和最佳实践可以通过下面的链接来了解:\n\n * 什么是 bundle 和 bundleless?\n * input 与 sourceDir 的关系。\n * 产物中类型文件的多种生成方式。\n * buildConfig.define 不同场景的使用方式。\n * 如何处理第三方依赖?\n * 如何使用拷贝?\n * 如何构建 umd 产物?\n * 静态资源目前所支持的能力。\n\n\n什么时候使用 buildConfig#\n\nbuildConfig 是用于修改产物的方式之一,当与 buildPreset 配置同时存在的时候,只有 buildConfig\n才会生效。因此如果按照如下方式配置:\n\n\n\nexport default defineConfig({\n buildConfig: {\n format: 'umd',\n },\n buildPreset: 'npm-library',\n});\n\n\n那么此时就会看到如下提示:\n\n因为同时出现 'buildConfig' 和 'buildPreset' 配置,因此仅 'buildConfig' 配置生效\n\n\nbuildPreset 代表的一组或者多组构建相关的配置都是由 buildConfig 组成,当使用 buildPreset\n无法满足当前项目需求的时候,就可以使用 buildConfig 来自定义输出产物。\n\n在使用 buildConfig 的过程,就是对获得怎样的构建产物的思考过程。","frontmatter":{"sidebar_position":3},"_filepath":"/Users/bytedance/github/targeral/modern-js/packages/document/module-doc/docs/zh/guide/basic/modify-output-product.md","_relativePath":"zh/guide/basic/modify-output-product.md"},{"id":59,"title":"版本管理与发布","routePath":"/module-tools/guide/basic/publish-your-project","lang":"zh","toc":[{"text":"跟踪变更","id":"跟踪变更","depth":2,"charIndex":152},{"text":"版本更新","id":"版本更新","depth":2,"charIndex":1046},{"text":"发布","id":"发布","depth":2,"charIndex":1309},{"text":"预发布","id":"预发布","depth":2,"charIndex":1647}],"domain":"","content":"#\n\n一个 npm 类型的模块项目发布流程包含了两个阶段:\n\n * 第一阶段是在开发期间,开发者需要提供变更文件,该文件记录了在发布期间需要的变更内容;\n * 第二阶段是在发布期间,Module Tools 会收集所有的变更文件来更新版本、更新发布日志,并发布新的包到 npm Registry 上。\n\n\n跟踪变更#\n\n当项目发生变化的时候需要将变化的内容记录下来。项目发生的变化一般是指:\n\n * 新功能\n * 修复问题\n * 配置文件修改\n * ...\n\n当这些任务一旦开发完成后,需要通过以下命令来对当前的变化进行记录:\n\n * modern change\n\n执行 modern change 命令后会向开发者提出几个问题,并根据开发者的回答生成变更记录。变更记录文件包含了版本变化的类型和其描述,该文件会被提交到\ngit 仓库中。\n\n$ npx modern change\n🦋 What kind of change is this for module-example? (current version is 0.1.0) · patch\n🦋 Please enter a summary for this change (this will be in the changelogs). Submit empty line to open external editor\n🦋 Summary · publish test\n🦋 === Releasing the following packages ===\n🦋 [Patch]\n🦋 module\n🦋 Is this your desired changeset? (Y/n) · true\n🦋 Changeset added! - you can now commit it\n🦋\n🦋 If you want to modify or expand on the changeset summary, you can find it here\n🦋 info /xxxxxx/module/.changeset/brave-dryers-agree.md\n\n\n当执行成功后,生成的包含变更记录的 Markdown 文件会保存在项目的 .changeset 目录下面。其内容类似下面这样:\n\n---\n'module-example': patch\n---\n\npublish test\n\n\n\n版本更新#\n\n当需要更新项目版本的时候,执行以下命令:\n\n * modern bump\n\n执行 modern bump 将会基于 .changeset/ 目录下记录了变更的 Markdown 文件内容来修改 package.json\n中的版本号,同时生成 CHANGELOG.md 文件。而当版本更新完成后,这些记录变更的 Markdown 文件也会被删除,也可说这些 Markdown\n文件被“消耗”掉了。\n\n# module\n\n## 0.1.1\n\n### Patch Changes\n\n- publish test\n\n\n\n发布#\n\n发布项目可以执行以下命令:\n\n * modern release\n\nmodern release 命令可以将项目发布到 npm Registry。\n\n此时发布的是 latest 版本,也可以说是正式版本。如果想要修改 dist-tag,可以通过 modern release --tag 命令来指定。例如:\n\nmodern release --tag beta\n\n\n但是如果希望将当前项目的版本号也修改为预发布的版本号,则需要使用 modern pre 命令。\n\n> 所谓 dist-tag,可以理解:为当前发布的版本打标签。一般来说,默认发布的版本对应的 dist-tag 为 latest,因此可以把 latest\n> 认为是正式版本的 dist-tag。\n\n\n预发布#\n\n当需要在正式发布之前进行预发布,则需要执行以下命令:\n\n * modern pre\n\n首先 modern pre enter 进入预发布模式, 可以与发布项目的时候使用 modern release --tag 命令指定的 tag 一致。\n\n$ npx modern pre enter next\n🦋 success Entered pre mode with tag next\n🦋 info Run `changeset version` to version packages with prerelease versions\n✨ Done in 5.30s.\n\n\n接着可以使用 modern bump 命令更新具体的版本号,此时不会真正的“消耗”记录变更的 Markdown 文件:\n\n$ npx modern bump\n🦋 warn ===============================IMPORTANT!===============================\n🦋 warn You are in prerelease mode\n🦋 warn If you meant to do a normal release you should revert these changes and run `changeset pre exit`\n🦋 warn You can then run `changeset version` again to do a normal release\n🦋 warn ----------------------------------------------------------------------\n🦋 All files have been updated. Review them and commit at your leisure\n\n\n然后可以看到 package.json 中更新的版本号会类似这样:0.1.2-next.0。\n\n最后,如果不需要再进行预发布,则一定要执行 modern pre exit 命令,这样可以退出预发布状态,并且当再次执行 modern bump\n命令的时候,就可以发布正式的版本。","frontmatter":{"sidebar_position":7},"_filepath":"/Users/bytedance/github/targeral/modern-js/packages/document/module-doc/docs/zh/guide/basic/publish-your-project.md","_relativePath":"zh/guide/basic/publish-your-project.md"},{"id":60,"title":"测试项目","routePath":"/module-tools/guide/basic/test-your-project","lang":"zh","toc":[{"text":"先决条件和约定","id":"先决条件和约定","depth":2,"charIndex":21},{"text":"运行测试","id":"运行测试","depth":2,"charIndex":405},{"text":"使用配置","id":"使用配置","depth":2,"charIndex":539},{"text":"测试示例","id":"测试示例","depth":2,"charIndex":610},{"text":"普通模块","id":"普通模块","depth":3,"charIndex":618},{"text":"组件","id":"组件","depth":3,"charIndex":653}],"domain":"","content":"#\n\n本章将要介绍如何测试可复用模块。\n\n\n先决条件和约定#\n\n想要使用项目的测试功能,需要确保项目中包含依赖:\"@modern-js/plugin-testing\",以及按照类似下面的内容进行配置:\n\n\n\n\nexport default defineConfig({\n plugins: [\n moduleTools(),\n testingPlugin(),\n ],\n});\n\n\n可以通过执行 modern new 命令来开启测试功能。\n\n在模块工程方案中,对于测试用例或者说编写测试的文件有如下约定:\n\n * 项目目录下的 tests 目录为测试用例和测试文件的目录,不支持更改运行测试用例的目录。\n * 默认会自动将后缀为 .test.[tj]sx? 的文件识别为测试文件。\n * 其他的 .[tj]sx? 后缀的文件被识别为普通的文件,可以用于测试的 utils 文件或者其他用途。\n\n\n运行测试#\n\n当准备好了依赖、增加了相关配置以及了解了测试用例在哪里编写后,我们可以通过以下命令来执行测试:\n\nmodern test\n\n// 更新 snapshot\nmodern test --updateSnapshot\n\n\n执行之后,会看到测试的结果:\n\n\n\n\n使用配置#\n\n模块工程方案对测试提供了以下配置:\n\n * testing\n\n可以在 modern.config.(j|t)s 中增加它。\n\n\n测试示例#\n\n\n普通模块#\n\n对于普通的模块,我们可以按照如下方式使用测试功能:\n\n\n组件#\n\n对于组件,Modern.js 的 Runtime API 提供了用于测试 UI 组件的功能,其功能由 @modern-js/runtime/testing\n提供。\n\nTIP\n\n如果需要使用 Runtime API,那么可以通过 微生成器 开启。","frontmatter":{"sidebar_position":6},"_filepath":"/Users/bytedance/github/targeral/modern-js/packages/document/module-doc/docs/zh/guide/basic/test-your-project.mdx","_relativePath":"zh/guide/basic/test-your-project.mdx"},{"id":61,"title":"使用微生成器","routePath":"/module-tools/guide/basic/use-micro-generator","lang":"zh","toc":[{"text":"Test 测试","id":"test-测试","depth":2,"charIndex":150},{"text":"Storybook 调试","id":"storybook-调试","depth":2,"charIndex":404},{"text":"Tailwind CSS 支持","id":"tailwind-css-支持","depth":2,"charIndex":761},{"text":"启动 Modern.js Runtime API","id":"启动-modernjs-runtime-api","depth":2,"charIndex":1040}],"domain":"","content":"#\n\n模块工程解决方案提供了微生成器工具,它可以为当前项目:\n\n * 新增目录和文件\n * 修改 package.json 文件内容\n * 执行命令\n\n因此通过这些能力,微生成器可以为项目开启额外的特性功能。\n\n可以通过 modern new 启动微生成器。目前模块工程方案支持的微生成器功能有:\n\n\nTest 测试#\n\n当我们想要对一些模块进行测试的时候,可以启用测试功能。启动该功能后,会在项目目录下创建 tests 目录以及相关文件,在 package.json 中新增\n\"@modern-js/plugin-testing\" 依赖。\n\nTIP\n\n在成功开启后,会提示需要手动在配置中增加如下类似的代码。\n\n\n\n\nexport default defineConfig({\n plugins: [\n moduleTools(),\n testingPlugin(),\n ],\n});\n\n\n\nStorybook 调试#\n\n当我们想要对组件或者普通模块进行调试的时候,可以启用 Storybook 调试功能。启动该功能后,会在项目目录下创建 stories 目录以及相关文件,在\npackage.json 中新增 \"@modern-js/plugin-storybook\" 依赖。\n\nTIP\n\n在成功开启后,会提示需要手动在配置中增加如下类似的代码。\n\n\n\n\nexport default defineConfig({\n plugins: [\n moduleTools(),\n storybookPlugin(),\n ],\n});\n\n\n关于如何启动 Storybook 以及如何使用 Storybook,可以查看下面的链接:\n\n * modern dev\n * 使用 Storybook\n\n\nTailwind CSS 支持#\n\n当我们想要为项目增加 Tailwind CSS 支持的时候,可以启动这个功能。Tailwind CSS 是一个 CSS 库,提供开箱即用的样式。\n\n关于如何在模块工程里使用 Tailwind CSS,可以查看:\n\n * 使用 Tailwind CSS\n\nTIP\n\n在成功开启后,会提示需要手动在配置中增加如下类似的代码。\n\n\n\n\nexport default defineConfig({\n plugins: [\n moduleTools(),\n tailwindPlugin(),\n ],\n});\n\n\n\n启动 Modern.js Runtime API#\n\nModern.js 提供了 Runtime API 能力,这些 API 只能在 Modern.js 的应用项目环境中使用。如果你需要开发一个 Modern.js\n应用环境中使用的组件,那么你可以开启该特性,微生成器会增加 \"@modern-js/runtime\"依赖。\n\n另外,Storybook 调试工具也会通过检测项目的依赖确定项目是否需要使用 Runtime API,并且提供与 Modern.js 应用项目一样的\nRuntime API 运行环境。\n\nTIP\n\n在成功开启后,会提示需要手动在配置中增加如下类似的代码。\n\n\n\n\nexport default defineConfig({\n plugins: [\n moduleTools(),\n runtime(),\n ],\n});\n","frontmatter":{"sidebar_position":4},"_filepath":"/Users/bytedance/github/targeral/modern-js/packages/document/module-doc/docs/zh/guide/basic/use-micro-generator.md","_relativePath":"zh/guide/basic/use-micro-generator.md"},{"id":62,"title":"使用 Storybook","routePath":"/module-tools/guide/basic/using-storybook","lang":"zh","toc":[{"text":"调试代码","id":"调试代码","depth":2,"charIndex":288},{"text":"引用组件产物","id":"引用组件产物","depth":3,"charIndex":487},{"text":"引用组件源码","id":"引用组件源码","depth":3,"charIndex":1117},{"text":"配置 Storybook","id":"配置-storybook","depth":2,"charIndex":1514},{"text":"构建 Storybook 产物","id":"构建-storybook-产物","depth":2,"charIndex":1911}],"domain":"","content":"#\n\n首先如果没有看过以下内容的话,可以先花几分钟先了解一下:\n\n * 使用微生成器开启 Storybook 调试\n * modern dev\n\nStorybook 是一个专门用于组件调试的工具,它围绕着组件开发提供了:\n\n * 丰富多样的调试能力\n * 可与一些测试工具结合使用\n * 可重复使用的文档内容\n * 可分享能力\n * 工作流程自动化\n\n因此 Storybook 是一个复杂且功能强大的工具。\n\nModule Tools 集成了 Storybook,因此你几乎可以按照 Storybook\n官方文档的内容进行使用。不过依然有一些地方需要注意,接下来讲解一下。\n\n\n调试代码#\n\n在调试代码过程中需要引入项目代码,目前可以通过两种方式引入项目代码:\n\n * 引用项目产物\n * 引用项目源码\n\n我们推荐使用第一种“引用项目产物”的方式。因为它更接近真实的使用场景,不仅可以对组件功能进行调试,同时也对构建产物的正确性进行了验证。不过我们也可以在测试项目功\n能的时候引用源码,在验证项目产物的时候引用项目的包名。\n\n接下来我们分别讲一下这两种方式具体如何使用。\n\n\n引用组件产物#\n\n假如存在 TypeScript 项目 foo:\n\nINFO\n\n在开发过程中,可能会遇到无法实时获得类型定义的情况。因为只有当保存代码后,产物目录下的类型文件才会更新。此时:\n\n对于 pnpm 的项目,可以按照下面的内容对 package.json 进行修改:\n\n{\n \"name\": \"foo\",\n \"main\": \"./dist/index.js\",\n \"types\": \"./src/index.ts\",\n \"publishConfig\": {\n \"types\": \"./dist/index.d.ts\",\n }\n}\n\n\n> 关于 pnpm 的 publishConfig 的使用,可以阅读下面这个链接。\n\n而对于 npm 和 Yarn 的项目,则只能通过手动的方式在开发阶段和发布阶段对 package.json 的 types 的值进行修改。\n\n那么为什么可以直接引用产物呢?\n\n 1. 在执行 modern dev storybook 命令之前,执行 modern build --watch 命令,保证项目构建产物的存在。\n 2. 在 Storybook 内部增加了根据 tsconfig.json 文件的 compilerOptions.paths 配置或者(在 JS\n 项目中)直接以项目名称作为别名的处理逻辑,保证能够根据 package.json 解析出项目的产物路径。\n\n\n引用组件源码#\n\n引用组件的源码可以通过相对路径的方式:\n\n\n\nconst Component = () => \nthis is a Story Component {content};\n\nexport const YourStory = () => ;\n\nexport default {\n title: 'Your Stories',\n};\n\n\n为什么不推荐使用源码的方式?\n\n不仅仅是因为使用组件源码无法验证组件产物是否正确,同时模块工程对于构建产物支持的一些配置无法完全转换为 Storybook\n内部的配置。如果某些配置无法进行相互转换的话,就会在 Storybook 调试过程中出现不符合预期的结果。\n\nModule Tools 是基于 esbuild 实现的,而 Storybook 是基于 Webpack 实现的。esbuild 的配置无法与 Webpack\n完全兼容。\n\n\n配置 Storybook#\n\nStorybook 官方通过一个名为 .storybook 的文件夹来进行项目配置,其中包含各种配置文件。在模块工程方案中,可以在项目的\nconfig/storybook 目录下增加 Storybook 配置文件。\n\n关于 Storybook 各种配置文件的使用方式,可以查看下面的链接:\n\n * Configure Storybook\n\n不过在模块项目里进行 Storybook 存在一些限制:\n\n * 目前不能修改 Story 文件存放的位置,即无法在 main.js 文件里修改 stories 配置。\n * 目前不能修改 Webpack 和 Babel 相关的配置,即无法在 main.js 文件里修改 webpackFinal 和 babel 配置。\n\n在未来我们会考虑这些配置是否可以允许修改,不过目前为了减少不可预知的问题暂时限制使用这些配置。\n\n\n构建 Storybook 产物#\n\n除了可以对组件或者普通的模块进行 Storybook 调试,还可以通过下面的命令来执行 Storybook 的构建任务。\n\nmodern build --platform storybook\n\n\n关于 modern build --platform 命令可以查看:\n\n * modern build\n\n构建完成后,可以在 dist/storybook-static 目录看到构建产物文件。","frontmatter":{"sidebar_position":5},"_filepath":"/Users/bytedance/github/targeral/modern-js/packages/document/module-doc/docs/zh/guide/basic/using-storybook.mdx","_relativePath":"zh/guide/basic/using-storybook.mdx"},{"id":63,"title":"开发组件","routePath":"/module-tools/guide/best-practices/components","lang":"zh","toc":[{"text":"初始化项目","id":"初始化项目","depth":2,"charIndex":30},{"text":"使用 Storybook 调试代码","id":"使用-storybook-调试代码","depth":2,"charIndex":39},{"text":"开发样式","id":"开发样式","depth":2,"charIndex":60},{"text":"CSS/PostCSS","id":"css/postcss","depth":3,"charIndex":168},{"text":"Less","id":"less","depth":3,"charIndex":382},{"text":"Sass/Scss","id":"sass/scss","depth":3,"charIndex":436},{"text":"Tailwind CSS","id":"tailwind-css","depth":3,"charIndex":501},{"text":"HTML 类名","id":"html-类名","depth":4,"charIndex":605},{"text":"@apply","id":"@apply","depth":4,"charIndex":615},{"text":"推荐方式","id":"推荐方式","depth":4,"charIndex":944},{"text":"bundle 和 bundleless 构建产物区别","id":"bundle-和-bundleless-构建产物区别","depth":4,"charIndex":1090},{"text":"CSS Modules","id":"css-modules","depth":3,"charIndex":1682},{"text":"配置构建产物","id":"配置构建产物","depth":2,"charIndex":1904},{"text":"测试组件","id":"测试组件","depth":2,"charIndex":2385},{"text":"发布组件","id":"发布组件","depth":2,"charIndex":2419}],"domain":"","content":"#\n\n本章将要介绍如何使用模块工程解决方案开发组件项目。\n\n\n初始化项目#\n\n\n使用 Storybook 调试代码#\n\n\n开发样式#\n\n接下来我们可以给组件添加样式。\n\n目前支持开发样式的能力有:\n\n * CSS/PostCSS\n * Less\n * Scss/Sass\n * Tailwind CSS\n * CSS Modules\n\n\nCSS/PostCSS#\n\n模块工程支持 PostCSS,并且内置了以下 PostCSS 插件:\n\n * flexbugs-fixes\n * custom-properties\n * initial\n * page-break\n * font-variant\n * media-minmax\n * nesting\n\n因此我们可以在项目中创建 .css 文件,并且可以直接在 css 文件中使用这些插件提供的语法支持和能力。\n\n\nLess#\n\n模块工程支持使用 Less 开发样式。\n\n> 目前内置的 Less 版本为 v4.1.3\n\n\nSass/Scss#\n\n模块工程支持使用 Scss/Sass 开发样式。\n\n> 目前内置的 Sass 版本为 v1.54.4\n\n\nTailwind CSS#\n\n模块工程支持使用 Tailwind CSS 开发组件样式。\n\n默认情况下,模块工程没有开启该功能,需要按照下面的方式开启它。\n\nTailwind CSS 提供了两种使用方式:\n\nHTML 类名#\n\n@apply#\n\nTailwind CSS 提供了 @apply 指令,可以通过它将 Tailwind CSS 提供的样式内联到我们编写的样式中。\n\n@apply 可以用于 CSS、Less、Sass 中。\n\n.btn {\n @apply font-bold py-2 px-4 rounded;\n}\n\n\n但是使用过程中,对于 Less 和 Sass 有些情况需要注意:\n\nSass#\n\n当将 Tailwind 与 Sass 一起使用时,@apply 后面存在 !important 的时候,需要使用插值来让 Sass 正确编译。\n\nLess#\n\n在与 Less 一起使用 Tailwind 时,你不能嵌套 Tailwind 的 @screen 指令。\n\n推荐方式#\n\n推荐使用 @apply 指定的方式开发样式,这样在样式产物中仅包含通过指令内联的样式。\n\n当使用 HTML 类名的方式添加样式的时候,默认情况下 Tailwind\n不仅会将本身类名对应的样式加入产物中,同时还会有额外的样式代码存在,虽然这些代码可能不会对本身的样式产生影响。\n\nbundle 和 bundleless 构建产物区别#\n\n对于以下代码,在 bundle 和 bundleless 两种模式下,构建产物会有很大区别。\n\n> 所谓 bundle 和 bundleless 可以查看 「Bundle 和 Bundleless」\n\nimport 'tailwindcss/utilities.css';\n\nexport default () => {\n return \nhello world11;\n};\n\n\nBundle 模式下,会将第三方依赖打包进来。\n\n对于样式则会生成一份单独的产物文件,并且在 JS 产物文件中并不会存在导入样式的相关代码。\n\n如果需要将样式注入 JS 产物中,可以开启 style.inject 选项。\n\nBundleless 模式下,并不会将第三方依赖打包进来,此时不会有样式产物生成。\n\n\nimport 'tailwindcss/utilities.css';\nvar src_default = () => {\n return /* @__PURE__ */ jsx('div', {\n className: 'bg-black text-white',\n children: 'hello world11',\n });\n};\nexport { src_default as default };\n\n\n\nCSS Modules#\n\n模块工程支持使用 CSS Module 开发样式。默认情况下会将以下文件识别为 CSS Module 文件:\n\n * .module.css\n * .module.less\n * .module.scss\n * .module.sass\n\n如果需要对 CSS Modules 进行配置,可以查看以下 API:\n\n * style.autoModules\n * style.modules\n\n下面是一个代码示例:\n\n\n配置构建产物#\n\n根据组件项目使用的多数场景,推荐使用 npm-component 构建预设。该预设得到的产物目录结构为:\n\n.\n├── dist\n│ ├── es\n│ ├── lib\n│ └── types\n\n\n * ./dist/es: 包含了支持 es6 语法的 ES modules 格式的 bundleless 产物。\n * ./dist/lib: 包含了支持 es6 语法的 CommonJS 格式的 bundleless 产物。\n * ./dist/types: 包含了类型文件。\n\n如果对使用语法支持有要求,可以手动配置 buildPreset,并且支持在 npm-component 基础上增加后缀的方式修改支持的语法:\n\nexport default defineConfig({\n buildPreset: 'npm-component-es2019',\n});\n\n\n如果对构建产物目录结构有特殊需求,则可以使用 buildConfig API,可以通过以下文档来了解使用方式:\n\n * 修改输出产物\n * 深入理解构建\n\n\n测试组件#\n\n关于如何对组件进行测试,可以参考 「测试项目」。\n\n\n发布组件#\n\n推荐使用模块工程提供版本发布功能,可以参考 「版本管理与发布」。","frontmatter":{"sidebar_position":1},"_filepath":"/Users/bytedance/github/targeral/modern-js/packages/document/module-doc/docs/zh/guide/best-practices/components.mdx","_relativePath":"zh/guide/best-practices/components.mdx"},{"id":64,"title":"构建相关问题","routePath":"/module-tools/guide/faq/build","lang":"zh","toc":[{"text":"产物问题","id":"产物问题","depth":2,"charIndex":3},{"text":"Class Fields 的初始化处理","id":"class-fields-的初始化处理","depth":3,"charIndex":11},{"text":"babel-plugin-lodash 将引入的 lodash 处理成 undefined","id":"babel-plugin-lodash-将引入的-lodash-处理成-undefined","depth":3,"charIndex":1315},{"text":"异常类问题","id":"异常类问题","depth":2,"charIndex":1721},{"text":"Dynamic require of \\\"react\\\" is not supported","id":"dynamic-require-of-\\\"react\\\"-is-not-supported","depth":3,"charIndex":-1},{"text":"问题描述","id":"问题描述","depth":4,"charIndex":1776},{"text":"解决办法","id":"解决办法","depth":4,"charIndex":1951},{"text":"参考链接","id":"参考链接","depth":4,"charIndex":2244},{"text":"编译过程中,因为某个组件库的 less 文件报错:\\'Operation on an invalid type\\'","id":"编译过程中,因为某个组件库的-less-文件报错:\\'operation-on-an-invalid-type\\'","depth":3,"charIndex":-1},{"text":"Bundle DTS failed","id":"bundle-dts-failed","depth":3,"charIndex":3434},{"text":"defineConfig 函数类型报错:如果没有引用 \\\"...\\\",则无法命名 \\\"default\\\" 的推断类型","id":"defineconfig-函数类型报错:如果没有引用-\\\"\\\",则无法命名-\\\"default\\\"-的推断类型","depth":3,"charIndex":-1},{"text":"其他","id":"其他","depth":2,"charIndex":3868},{"text":"在 环境中构建任务超时","id":"在--环境中构建任务超时","depth":3,"charIndex":-1},{"text":"增加额外的编译能力","id":"增加额外的编译能力","depth":3,"charIndex":3945},{"text":"支持生成 CSS Modules 的 TypeScript 声明文件","id":"支持生成-css-modules-的-typescript-声明文件","depth":3,"charIndex":4338}],"domain":"","content":"#\n\n\n产物问题#\n\n\nClass Fields 的初始化处理#\n\nTypeSript 提供了 useDefineForClassFields 配置用于控制对于 public class fields 的转换处理。\n\n如果有一段代码:\n\nclass C {\n foo = 100;\n bar: string;\n}\n\n\n当 useDefineForClassFields 为 false 的时候,则编译后的代码会变为:\n\nclass C {\n constructor() {\n this.foo = 100;\n }\n}\n\n\n当 useDefineForClassFields 为 true 的时候,则编译后的代码会变为:\n\nclass C {\n constructor() {\n Object.defineProperty(this, \"foo\", {\n enumerable: true,\n configurable: true,\n writable: true,\n value: 100,\n });\n Object.defineProperty(this, \"bar\", {\n enumerable: true,\n configurable: true,\n writable: true,\n value: void 0,\n });\n }\n}\n\n\n同时该配置的默认值会根据 tsconfig.json 的 target 配置而变化:当 target 是 ES2022 或者更高的时候,则\nuseDefineForClassFields 默认配置为 true,否则就是默认为 false。\n\n关于 TypeScript 这个配置的更多信息,可以参考下面的链接:\n\n * The useDefineForClassFields Flag and The declare Property Modifier\n\nModern.js Module 目前会根据下面的逻辑进行处理:\n\n 1. 首先根据当前项目的 tsconfig.json 的 useDefineForClassFields 配置确定在 Modern.js Module\n 内部如何处理。目前只会读取当前项目路径下的 tsconfig.json 文件的内容,暂时不支持根据 extends 配置来获取最终的 tsconfig\n 配置。\n 2. 如果没有检测 tsconfig.json 的 useDefineForClassFields 配置,则会根据 tsconfig.json 的\n target 配置来确定默认值。如果 target 大于 ES2022(包含 EsNext),则useDefineForClassFields默认为\n true,否则为 false。\n 3. 如果没有检测到 tsconfig.json 的 target,则按照 useDefineForClassFields的值 为 true 进行处理。\n\n\nbabel-plugin-lodash 将引入的 lodash 处理成 undefined#\n\n当使用类似下面的方式的时候,会出现这个问题:\n\n\n\nexport const libs = {\n _: Lodash,\n}\n\n\n目前在 babel-plugin-lodash Github 上的相关 Issue:\n\n * #235\n\n这个问题的解决办法是移除 babel-plugin-lodash,因为此时不需要该插件进行按需引用,使用该插件会产生副作用。\n\n类似的情况在 babel-plugin-import 上也可能会出现。比如有类似如下的代码:\n\n\n\nexport const libs = {\n comps: Comps,\n};\n\n\n此时 babel-plugin-import 也可能会导致 Comps 变为 undefined。因此也需要移除对应的 babel-plugin-import。\n\n\n异常类问题#\n\n\nDynamic require of \"react\" is not supported#\n\n问题描述#\n\n当构建的产物配置中产物格式为 ES modules 的时候:\n\nexport default defineConfig({\n buildConfig: {\n format: 'esm',\n },\n});\n\n\n如果导入了的第三方 npm 包的 cjs 产物,那么生成的产物可能会在 webpack 下有可能无法正常运行。\n\n\n\n解决办法#\n\n 1. 首先需要找到是哪个第三方包引起的问题。例如报错信息中指向了 react 这个包,那么就要寻找在哪个第三方包里存在 require('react')\n 这样的代码。比如 react-draggable ,这个包仅包含 cjs 产物,那么问题定位到 react-draggable 这个包。\n 2. 然后我们需要将这个包通过下面的配置进行排除,即不打包存在问题的第三方包。\n\nexport default defineConfig({\n buildConfig: {\n externals: ['react-draggable'],\n }\n});\n\n\n参考链接#\n\n * When using esbuild with external react I get Dynamic require of \"react\" is\n not supported\n\n\n编译过程中,因为某个组件库的 less 文件报错:'Operation on an invalid type'#\n\n可能是因为该组件库依赖的 Less 版本是 v3,而 Modern.js Module 默认是 v4。v3 与 v4 在 math 配置上存在有 Break\nChange,可以查看这个链接 了解详情。\n\n因此,如果是在源码中使用了类似这样的组件库:\n\n在构建配置中使用了 buildPreset 的情况下,按照下面进行修改:\n\nmodule.exports = {\n buildPreset({ extendPreset }) {\n return extendPreset('your-build-preset', {\n style: {\n less: {\n lessOptions: {\n math: 'always',\n },\n },\n },\n });\n },\n}\n\n\n或者使用了自定义的 buildConfig 的情况下,按照下面进行修改:\n\nmodule.exports = {\n buildConfig: {\n style: {\n less: {\n lessOptions: {\n math: 'always',\n },\n },\n },\n }\n};\n\n\n如果是在 Storybook 中使用了类似这样的组件,则需要修改 Storybook 的调试配置:\n\nmodule.exports = {\n dev: {\n storybook: {\n webpackChain(chain, { CHAIN_ID }) {\n chain.module\n .rule(CHAIN_ID.RULE.LESS)\n .use(CHAIN_ID.USE.LESS)\n .tap(options => {\n options.lessOptions = {\n ...options.lessOptions,\n math: 'always',\n };\n return options;\n });\n },\n },\n },\n}\n\n\n\nBundle DTS failed#\n\n正常情况下,使用 tsc Modern.js Module\n不仅支持输出松散的类型文件产物,同时也支持打包类型文件,可以将这些松散的类型文件以及第三方依赖的类型文件打包成一个文件。\n\n不过,打包第三方依赖的类型文件是存在风险的,因为存在第三方依赖的类型文件无法打包的情况。\n\n因此当遇到 Modern.js Module 构建过程中出现 Bundle DTS failed\n的错误信息标题的时候,可以观察报错信息是来自某个第三方依赖。尝试设置 dts.respectExternal 为 false\n来关闭打包第三方依赖的类型文件的行为。\n\n\ndefineConfig 函数类型报错:如果没有引用 \"...\",则无法命名 \"default\" 的推断类型#\n\n检查项目的 tsconfig.json 文件中是否存在 include 配置,如果没有,则尝试增加下面的内容:\n\n{\n \"include\": [\"src\"]\n}\n\n\n\n其他#\n\n\n在 Cloud IDE 环境中构建任务超时#\n\n该问题在 1.13.4 版本中修复,执行 npx edenx upgrade 进行升级。\n\n\n增加额外的编译能力#\n\nModern.js Module 基于 esbuild 实现,因此如果有特殊需求或者想要增加额外的编译能力,可以通过实现 esbuild 插件来解决。\n\nModern.js Module 提供了 esbuildOptions 配置允许修改 EdenX 内部的 esbuild 配置,因此可以通过该配置来增加自定义的\nesbuild 插件:\n\nexport default defineConfig({\n buildConfig: {\n esbuildOptions: options => {\n options.plugins = [\n ...options.plugins,\n yourEsbuildPlugin,\n ];\n return option;\n },\n },\n});\n\n\n\n支持生成 CSS Modules 的 TypeScript 声明文件#\n\n * 方案一:https://github.com/Quramy/typed-css-modules\n * 方案二:https://www.npmjs.com/package/@guanghechen/postcss-modules-dts","frontmatter":{},"_filepath":"/Users/bytedance/github/targeral/modern-js/packages/document/module-doc/docs/zh/guide/faq/build.mdx","_relativePath":"zh/guide/faq/build.mdx"},{"id":65,"title":"常见问题","routePath":"/module-tools/guide/faq/","lang":"zh","toc":[],"domain":"","content":"#\n\n这里是 EdenX Module 常见问题分类列表:\n\n * 代码构建相关的问题\n * 测试相关的问题\n * Storybook 相关的问题","frontmatter":{},"_filepath":"/Users/bytedance/github/targeral/modern-js/packages/document/module-doc/docs/zh/guide/faq/index.md","_relativePath":"zh/guide/faq/index.md"},{"id":66,"title":"Storybook 相关问题","routePath":"/module-tools/guide/faq/storybook","lang":"zh","toc":[{"text":"支持 Storybook v7","id":"支持-storybook-v7","depth":2,"charIndex":3},{"text":"使用 Storybook Addon 或者其他配置不生效","id":"使用-storybook-addon-或者其他配置不生效","depth":2,"charIndex":102},{"text":"Cannot find module \\'react-dom/package.json","id":"cannot-find-module-\\'react-dom/packagejson","depth":2,"charIndex":-1},{"text":"报错后,看不到具体报错信息","id":"报错后,看不到具体报错信息","depth":2,"charIndex":471},{"text":"Can`t find any stories is your Storybook","id":"can`t-find-any-stories-is-your-storybook","depth":2,"charIndex":1190},{"text":"Storybook 怎么发布","id":"storybook-怎么发布","depth":2,"charIndex":1321},{"text":"Storybook 添加 Proxy 功能","id":"storybook-添加-proxy-功能","depth":2,"charIndex":1407},{"text":"修改存在 Story 文件的目录","id":"修改存在-story-文件的目录","depth":2,"charIndex":2126}],"domain":"","content":"#\n\n\n支持 Storybook v7#\n\nStorybook v7 目前还没支持,目前计划在 Storybook v7 中支持 Rspack 构建,因此进度会慢一些。 相关 Issue:#3376。\n\n\n使用 Storybook Addon 或者其他配置不生效#\n\nEdenX Module 目前使用的 Storybook 版本是 v6,如果使用了 v7 版本的 Addon 可能会出现插件不生效的情况。\n\n除了 Addon 以外,其他配置也可能会有区别。比如修改 preview.js 配置文件的话,Storybook v6 与 v7 的写法也不相同:\n\n * v6:文档链接\n * v7:文档链接\n\n\nCannot find module 'react-dom/package.json#\n\n在执行 Storybook 调试的时候,出现以下问题:\n\n\n\n解决办法:在项目中安装 react-dom 依赖。\n\n{\n \"devDependencies\": {\n \"react-dom\": \"^17\"\n }\n}\n\n\n\n报错后,看不到具体报错信息#\n\n解决办法:\n\n 1. 找到 @storybook/core-server/dist/cjs/dev-server.js\n 2. 找到 var _await$Promise$all = await Promise.all([preview, manager 这附近的代码。\n 3. 修改成:\n\nvar _await$Promise$all = await Promise.all([\n preview.catch(e => console.info(e)),\n manager // TODO #13083 Restore this when compiling the preview is fast enough\n // .then((result) => {\n // if (!options.ci && !options.smokeTest) openInBrowser(address);\n // return result;\n // })\n .catch(previewBuilder.bail)]),\n _await$Promise$all2 = _slicedToArray(_await$Promise$all, 2),\n previewResult = _await$Promise$all2[0],\n managerResult = _await$Promise$all2[1]; // TODO #13083 Remove this when compiling the preview is fast enough\n\n\n\nCan`t find any stories is your Storybook#\n\n\n\n当遇到这样的问题的时候,首先可以打开一下浏览器的控制台,应该会有些报错信息。可以先根据报错信息来推断是不是编写代码里出现的问题导致 Storybook\n无法正常运行。\n\n\nStorybook 怎么发布#\n\n目前没有专门用于 Storybook 部署/发布的平台。可以参考下面的方案:\n\n * Storybook 发布到 Deploy 平台\n\n\nStorybook 添加 Proxy 功能#\n\nStorybook 没有提供相关方案,不过 Storybook Issue 中有找到相关的解决办法。在 EdenX Module 中,你可以:\n\n 1. 添加 config/storybook/middleware.js 文件,并初始化下面的内容:\n\n/* eslint-disable filenames/match-exported */\nmodule.exports = function expressMiddleware(router) {\n // router is express router\n // \n // router = new Router();\n};\n\n\n 2. 添加 http-proxy-middleware 依赖\n 3. 添加代理路由相关配置\n\n/* eslint-disable filenames/match-exported */\nconst { createProxyMiddleware } = require(\"http-proxy-middleware\");\n\nmodule.exports = function expressMiddleware (router) {\n router.use('/api', createProxyMiddleware({\n target: \"http://localhost:8000\",\n changeOrigin: true\n }))\n}\n\n\n相关链接:https://github.com/storybookjs/storybook/issues/11551\n\n\n修改存在 Story 文件的目录#\n\n目前暂时无法修改存放 Story 文件的目录,仅对 your-project/stories 目录下的\n*.stories.(t|j)s(x)、*.stories.md(x) 文件识别为 Story 文件。","frontmatter":{},"_filepath":"/Users/bytedance/github/targeral/modern-js/packages/document/module-doc/docs/zh/guide/faq/storybook.mdx","_relativePath":"zh/guide/faq/storybook.mdx"},{"id":67,"title":"测试相关问题","routePath":"/module-tools/guide/faq/test","lang":"zh","toc":[{"text":"执行 test 命令报错 TypeError: Cannot read property \\'testEnvironmentOptions\\' of undefined","id":"执行-test-命令报错-typeerror:-cannot-read-property-\\'testenvironmentoptions\\'-of-undefined","depth":2,"charIndex":-1}],"domain":"","content":"#\n\n\n执行 test 命令报错 TypeError: Cannot read property 'testEnvironmentOptions' of\nundefined#\n\n\n\n问题原因多是存在多个版本的 jest-environment-jsdom 依赖,可以检查 Monorepo 中其他项目是否有\njest-environment-jsdom 依赖,并通过 Monorepo 提供的 overrides 能力统一依赖版本。","frontmatter":{},"_filepath":"/Users/bytedance/github/targeral/modern-js/packages/document/module-doc/docs/zh/guide/faq/test.mdx","_relativePath":"zh/guide/faq/test.mdx"},{"id":68,"title":"快速开始","routePath":"/module-tools/guide/intro/getting-started","lang":"zh","toc":[{"text":"三分钟快速上手","id":"三分钟快速上手","depth":2,"charIndex":3},{"text":"创建新项目","id":"创建新项目","depth":3,"charIndex":106},{"text":"接入已有项目","id":"接入已有项目","depth":3,"charIndex":483},{"text":"查看官方示例","id":"查看官方示例","depth":3,"charIndex":1027},{"text":"让我们开始吧","id":"让我们开始吧","depth":2,"charIndex":1273}],"domain":"","content":"#\n\n\n三分钟快速上手#\n\n想要实际体验 Module Tools?首先需要安装 Node.js LTS,并确保 Node 版本大于等于 14.18.0。我们推荐使用 Node.js 16\n的 LTS 版本。\n\n\n创建新项目#\n\n如果你想要创建一个完整的模块工程项目,可以执行以下命令:\n\nnpx @modern-js/create your-project-dir-name\n\n\nINFO\n\n执行 npx @modern-js/create -h 查看更多命令行参数\n\n接着在问题交互中,按照如下选择:\n\n? 请选择你想创建的工程类型:Npm 模块\n? 请填写项目名称:library\n? 请选择开发语言:TS\n? 请选择包管理工具:pnpm\n\n\n> 项目名称为 package.json 中的 \"name\" 字段值。\n\n接着就会开始初始化项目的流程。在项目目录和文件生成以及依赖安装完毕后,此时就创建了一个完整的模块工程项目。\n\n我们可以直接执行 pnpm build 命令启动项目的构建,执行 pnpm build --watch 命令开启构建的观察模式。\n\n\n接入已有项目#\n\n在你的项目里安装以下依赖:\n\n * \"@modern-js/module-tools\"\n * \"typescript\"(如果不是 TypeScript 项目,则省略)\n\nnpm install -D @modern-js/module-tools typescript\n\n\n> 对于使用 pnpm 或者 Yarn 包管理器的项目,只需要替换 npm 就可以了。推荐使用 pnpm。\n\n接着在项目的根目录下创建 modern.config.(t|j)s 文件:\n\n\n\nexport default defineConfig({\n plugins: [moduleTools()],\n});\n\n\n最后在项目的 package.json 文件里增加命令 \"build\": \"modern build\":\n\n{\n \"scripts\": {\n \"build\": \"modern build\"\n }\n}\n\n\n如果你的项目存在 src/index.(js|jsx) 文件或者同时存在 src/index.(ts|tsx) 和 tsconfig.json\n文件,那么恭喜你可以运行直接运行 npm run build 来使用 Module Tools 构建你的项目了。\n\n\n查看官方示例#\n\n如果你想要看看使用了模块工程方案的完整项目,可以执行以下命令:\n\ngit clone https://github.com/web-infra-dev/module-tools-examples\ncd module-tools-example/base\n\n## 执行构建:\npnpm build\n\n## 监听模式执行构建:\npnpm build --watch\n\n## 启动 Storybook\npnpm dev storybook\n\n## 测试\npnpm test\n\n\n\n让我们开始吧#\n\n选择适合你的教程:\n\n * 我是初学者,需要学习 Module Tools 的基础使用。\n * 我已经初步掌握了 Module Tools 的使用,可以学习 Module Tools 的进阶指南。\n * 我需要扩展项目能力,需要学习如何开发 Module Tools 的插件。","frontmatter":{"sidebar_position":3},"_filepath":"/Users/bytedance/github/targeral/modern-js/packages/document/module-doc/docs/zh/guide/intro/getting-started.md","_relativePath":"zh/guide/intro/getting-started.md"},{"id":69,"title":"欢迎使用","routePath":"/module-tools/guide/intro/welcome","lang":"zh","toc":[],"domain":"","content":"#\n\nModule Tools 是 Modern.js\n的模块工程解决方案,同时也是核心依赖。它可以让开发者更轻松地构建、调试、发布模块类型的项目。模块类型的项目大多数情况可以认为是 npm\n包类型的项目,它可能是一个组件、组件库或者工具库项目。\n\n如果你正打算开发一个 npm 包类型的项目,那么你就来对地方了!Modern.js 提供了专业的模块工程解决方案。它带来了:\n\n * 简单的项目初始化:仅需执行 npx @modern-js/create project-dir\n 命令,然后进行几个交互问题,就可以创建一个完整的模块类型项目。创建的项目还支持选择 pnpm、Yarn 两种包管理器。\n * 代码格式化:在模块工程项目中,你可以执行 modern lint 来对代码进行格式化。同时初始化的模块工程项目里包含了 Modern.js 的\n ESLint 规则集,可以满足大部分场景下的需求。\n * 全面的构建能力和更快的构建速度:Module Tools 基于 esbuild 和 SWC\n 提供了高性能的构建能力,并且为不同构建模块的场景提供了丰富的配置。\n * Storybook 调试工具:Module Tools 为调试模块项目提供了 Storybook 调试工具。在安装了 Module Tools 的\n Storybook 插件后,你可以使用 modern dev storybook 命令来启动它。你不仅可以使用 Storybook\n 对组件进行调试,也可以使用在其他类型的模块上。\n * 集成 Jest 的测试能力:在需要对模块测试的时候,可以使用 Module Tools 的 modern test 命令。Module Tools\n 不仅集成了 Jest,同时也提供了配置 Jest 的 API。\n * 基于 Changesets 实现的版本管理:当需要对项目记录变更内容的时候,可以使用 modern change 命令生成包含变更内容的 Markdown\n 文件;当需要对项目进行版本升级的时候,可以使用 modern bump 命令通过 Markdown 文件分析并升级版本;当需要发布项目的时候,可以使用\n modern release 命令对项目进行发布。Module Tools 基于 Changesets 实现了这些命令。\n * 可扩展性的插件机制:想要为项目集成其他的调试工具?又或者是想要在构建过程中做一些额外处理?Module Tools\n 提供了插件机制和插件钩子,插件钩子覆盖了 dev 命令和 build 命令两个流程。你可以通过它们为项目进行能力的扩展。\n * 还有更多:Module Tools\n 在未来还会不断地在构建、调试功能上进行优化。如果在模块项目构建上存在需要解决的重要问题,又或者是某个主流的模块项目调试工具、模式出现的时候,那么它们很可能\n 成为 Module Tools 将要支持功能。","frontmatter":{"sidebar_position":1},"_filepath":"/Users/bytedance/github/targeral/modern-js/packages/document/module-doc/docs/zh/guide/intro/welcome.md","_relativePath":"zh/guide/intro/welcome.md"},{"id":70,"title":"为什么需要模块工程解决方案","routePath":"/module-tools/guide/intro/why-module-engineering-solution","lang":"zh","toc":[],"domain":"","content":"#\n\n大家可能都经历过:从零开始开发一个组件库或者工具库的过程中,我们不仅要考虑项目本身的代码逻辑如何编写,还要考虑项目的构建、调试、测试、代码格式化等等和代码逻辑无\n关的事情。\n\n比如说,当我们考虑构建模块项目的代码是使用什么构建工具的时候,在之前我们可能会考虑使用 webpack 还是 Rollup,然而现在的话,也许还会考虑是使用\nesbuild 还是 SWC。\n\n无论选择哪个构建工具,这对于没有熟练掌握这些构建工具使用方式的开发者来说,是需要一定的成本去学习的。即使想要快速使用,也会需要花费大量的时间和精力。\n\n而除了构建这件事情以外,像为项目提供调试工具、支持测试能力、增加代码格式校验等等,对于一个新手来说都有可能需要花费很长的时间和精力了解或者掌握它们,并且真正的服\n务于当前的项目中。\n\n而为了保证代码质量以及项目的完整性,我们往往是需要做这些与代码逻辑实现无关的事情。然而这些事情很有可能会影响整体的项目开发进度,降低开发者的开发体验,会让开发者\n感觉模块项目的开发门槛很高。\n\n如果说每次开发一个模块类型的项目都需要经历一遍这些工作准备的话,那么基本上刚开始开发的时间会大部分花费在这些与代码实现无关的事情上。如果能够提供一个模块工程解决\n方案,它能够帮助开发者解决项目工程上的事情,让开发者可以更专注于代码的实现上,那么这将会大大提升模块类型项目的开发体验。\n\n\n\nModern.js 为了让开发模块类型的项目更简单,为了解决上述提到的问题提供了模块工程解决方案,并且使用 Module Tools\n提供了主要的功能。Module-tools 可以理解为是一个专门用于模块类型项目开发的工具。","frontmatter":{"sidebar_position":2},"_filepath":"/Users/bytedance/github/targeral/modern-js/packages/document/module-doc/docs/zh/guide/intro/why-module-engineering-solution.md","_relativePath":"zh/guide/intro/why-module-engineering-solution.md"},{"id":72,"title":"快速开始","routePath":"/module-tools/plugins/guide/getting-started","lang":"zh","toc":[],"domain":"","content":"#\n\n模块工程解决方案不仅提供了丰富的功能,同时也支持通过插件的方式为当前项目扩展能力。\n\n我们可以通过下面的例子来快速了解如何编写一个 Module Tools 插件:\n\n通过上面这个例子,我们了解到了下面几件事:\n\n * 推荐的插件目录结构\n * 插件的初始化代码\n * 插件的注册\n\n除了以上内容以外,我们还需要了解:\n\n * 插件对象、类型定义与推荐配置项\n * setup 函数、api 对象参数、生命周期钩子","frontmatter":{"sidebar_position":1},"_filepath":"/Users/bytedance/github/targeral/modern-js/packages/document/module-doc/docs/zh/plugins/guide/getting-started.mdx","_relativePath":"zh/plugins/guide/getting-started.mdx"},{"id":73,"title":"插件对象","routePath":"/module-tools/plugins/guide/plugin-object","lang":"zh","toc":[{"text":"插件类型定义","id":"插件类型定义","depth":2,"charIndex":232},{"text":"插件配置项","id":"插件配置项","depth":2,"charIndex":497}],"domain":"","content":"#\n\nModule-tools 插件是一个对象,对象包含以下属性:\n\n * name:插件的名称,唯一标识符。\n * setup:插件初始化函数,只会执行一次。setup 函数可以返回一个 Hooks 对象,module-tools 会在特定的时机执行 Hooks\n 对象上定义的 Hook 对应的函数。\n\n例如在下面的插件代码示例中,在项目开始执行构建任务之前会触发 beforeBuild 函数的执行,并打印 build start 的 log 内容。\n\n\n插件类型定义#\n\n使用 TypeScript 时,可以引入内置的 CliPlugin 和 ModuleTools 类型,为插件提供正确的类型推导:\n\n\n\nconst myPlugin: CliPlugin = {\n name: 'my-plugin',\n\n setup() {\n const foo = '1';\n\n return {\n // this is hook\n afterBuild: () => {\n //...\n },\n };\n },\n};\n\n\n\n插件配置项#\n\n建议将插件写成函数的形式,使插件能通过函数入参来接收配置项:\n\n\n\ntype MyPluginOptions = {\n foo: string;\n};\n\nconst myPlugin = (options: MyPluginOptions): CliPlugin => ({\n name: 'my-plugin',\n\n setup() {\n console.log(options.foo);\n },\n});\n","frontmatter":{"sidebar_position":2},"_filepath":"/Users/bytedance/github/targeral/modern-js/packages/document/module-doc/docs/zh/plugins/guide/plugin-object.mdx","_relativePath":"zh/plugins/guide/plugin-object.mdx"},{"id":74,"title":"Setup 函数","routePath":"/module-tools/plugins/guide/setup-function","lang":"zh","toc":[{"text":"插件 API 对象","id":"插件-api-对象","depth":2,"charIndex":77},{"text":"api.useAppContext","id":"apiuseappcontext","depth":3,"charIndex":441},{"text":"api.useResolvedConfigContext","id":"apiuseresolvedconfigcontext","depth":3,"charIndex":808},{"text":"api.useHookRunners","id":"apiusehookrunners","depth":3,"charIndex":1208},{"text":"异步 setup","id":"异步-setup","depth":2,"charIndex":1471},{"text":"生命周期钩子","id":"生命周期钩子","depth":2,"charIndex":1646}],"domain":"","content":"#\n\n在「插件对象」 部分我们知道插件对象包含了一个 setup 函数,该函数不仅包含了一个 api 对象参数,同时还可以返回一个 Hooks 对象。\n\n\n插件 API 对象#\n\n插件的 setup 函数会提供一个 api 对象参数,你可以调用该对象上提供的一些方法来获取到配置、项目上下文等信息。\n\nexport const myPlugin = (): CliPlugin => ({\n name: 'my-plugin',\n\n setup(api) {\n // 获取应用原始配置\n const config = api.useConfigContext();\n // 获取应用运行上下文\n const appContext = api.useAppContext();\n // 获取解析之后的最终配置\n const resolvedConfig = api.useResolvedConfigContext();\n },\n});\n\n\n\napi.useAppContext#\n\n用于获取项目上下文信息。\n\nconst 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\nINFO\n\n通过实际的类型文件我们可以看到还存在着其他的字段,不过目前对于模块工程有意义的字段只有以上内容。api 对象其他的方法也是如此。\n\n\napi.useResolvedConfigContext#\n\n用于获取解析之后的最终配置。\n\nINFO\n\n如果需要获取构建相关的最终配置,需要使用 beforeBuild Hook。\n\nconst useResolvedConfigContext: () => NormalizedConfig;\n\ninterface NormalizedConfig {\n buildConfig: PartialBuildConfig;\n buildPreset: BuildPreset;\n designSystem?: Record;\n dev: Dev;\n plugins: PluginConfig;\n runtime: RuntimeConfig;\n runtimeByEntries?: RuntimeByEntriesConfig;\n _raw: UserConfig;\n}\n\n\n\napi.useHookRunners#\n\n用于获取 Hooks 的执行器,并触发特定的 Hook 执行。\n\n\n\nexport const myPlugin = (): CliPlugin => ({\n name: 'my-plugin',\n\n async setup(api) {\n const hookRunners = api.useHookRunners();\n // 触发 afterBuild Hook\n await hookRunners.afterBuild();\n },\n});\n\n\n\n异步 setup#\n\nCLI 插件的 setup 可以是一个异步函数,在初始化过程中执行异步逻辑。\n\nexport const myPlugin = (): CliPlugin => ({\n name: 'my-plugin',\n\n async setup(api) {\n await doSomething();\n },\n});\n\n\n\n生命周期钩子#\n\n我们知道 setup 函数会返回一个 Hooks 对象,所谓 Hooks 对象也可以理解是具有 Module Tools 生命周期钩子的对象。\n\n目前主要包含两类钩子:\n\n * 构建钩子:仅在执行 build 命令构建源码产物时触发。\n * buildPlatform 钩子:仅在执行 build --platform 命令生成其他构建产物时触发。\n * 调试钩子:运行 dev 命令时会触发的钩子。\n\n关于生命周期钩子的完整列表参考 API 文档。","frontmatter":{"sidebar_position":3},"_filepath":"/Users/bytedance/github/targeral/modern-js/packages/document/module-doc/docs/zh/plugins/guide/setup-function.mdx","_relativePath":"zh/plugins/guide/setup-function.mdx"},{"id":75,"title":"总览","routePath":"/module-tools/plugins/official-list/overview","lang":"zh","toc":[{"text":"官方插件","id":"官方插件","depth":2,"charIndex":3}],"domain":"","content":"#\n\n\n官方插件#\n\n * @modern-js/plugin-module-import:使用 SWC 提供与 babel-plugin-import 一样的能力。\n * @modern-js/plugin-module-banner:为每个 JS 和 CSS 文件的顶部和底部添加自定义内容,例如版权信息。\n * @modern-js/plugin-module-node-polyfill:会自动注入 Node 核心模块在浏览器端的 polyfills。\n * @modern-js/plugin-module-polyfill:为你的代码中使用到的不支持的功能注入 polyfill。\n * @modern-js/plugin-module-babel:使用 Babel 转换你的代码。","frontmatter":{},"_filepath":"/Users/bytedance/github/targeral/modern-js/packages/document/module-doc/docs/zh/plugins/official-list/overview.md","_relativePath":"zh/plugins/official-list/overview.md"},{"id":76,"title":"Babel 插件","routePath":"/module-tools/plugins/official-list/plugin-babel","lang":"zh","toc":[{"text":"快速开始","id":"快速开始","depth":2,"charIndex":50},{"text":"安装","id":"安装","depth":3,"charIndex":58},{"text":"注册插件","id":"注册插件","depth":3,"charIndex":220},{"text":"配置","id":"配置","depth":2,"charIndex":362}],"domain":"","content":"#\n\nTIP\n\n通常情况下,我们无需使用 Babel 转换我们的代码,此插件仅作为一种降级方式。\n\n\n快速开始#\n\n\n安装#\n\n# npm\nnpm install @modern-js/plugin-module-babel -D\n\n# yarn\nyarn add @modern-js/plugin-module-babel -D\n\n# pnpm\npnpm add @modern-js/plugin-module-babel -D\n\n\n\n注册插件#\n\n在 Module Tools 中,你可以按照如下方式注册插件:\n\n\n\n\nexport default defineConfig({\n plugins: [\n moduleTools(),\n modulePluginBabel(),\n ],\n});\n\n\n\n配置#\n\nSee Babel options\n\n下面是一个配置了@babel/preset-env的例子:\n\n\n\n\nexport default defineConfig({\n plugins: [\n moduleTools(),\n modulePluginBabel({\n presets: [['@babel/preset-env']],\n }),\n ],\n});\n","frontmatter":{},"_filepath":"/Users/bytedance/github/targeral/modern-js/packages/document/module-doc/docs/zh/plugins/official-list/plugin-babel.md","_relativePath":"zh/plugins/official-list/plugin-babel.md"},{"id":77,"title":"Banner 插件","routePath":"/module-tools/plugins/official-list/plugin-banner","lang":"zh","toc":[{"text":"快速开始","id":"快速开始","depth":2,"charIndex":36},{"text":"安装","id":"安装","depth":3,"charIndex":44},{"text":"注册插件","id":"注册插件","depth":3,"charIndex":209},{"text":"示例","id":"示例","depth":2,"charIndex":484},{"text":"在 JS 文件顶部增加版权信息","id":"在-js-文件顶部增加版权信息","depth":3,"charIndex":490},{"text":"配置","id":"配置","depth":2,"charIndex":956},{"text":"banner","id":"banner","depth":3,"charIndex":1103},{"text":"footer","id":"footer","depth":3,"charIndex":1182}],"domain":"","content":"#\n\n提供为每个 JS 和 CSS 文件的顶部和底部注入内容的能力。\n\n\n快速开始#\n\n\n安装#\n\n# npm\nnpm install @modern-js/plugin-module-banner -D\n\n# yarn\nyarn add @modern-js/plugin-module-banner -D\n\n# pnpm\npnpm add @modern-js/plugin-module-banner -D\n\n\n\n注册插件#\n\n在 Module Tools 中,你可以按照如下方式注册插件:\n\n\n\n\nexport default defineConfig({\n plugins: [\n moduleTools(),\n modulePluginBanner({\n banner: {\n js: '//comment',\n css: '/*comment*/',\n },\n }),\n ],\n});\n\n\nTIP\n\n注意:CSS 的注释不支持 //comment 这样的写法。详见「CSS 注释」\n\n\n示例#\n\n\n在 JS 文件顶部增加版权信息#\n\n\n\n\nconst copyRight = `/*\n © Copyright 2020 xxx.com or one of its affiliates.\n * Some Sample Copyright Text Line\n * Some Sample Copyright Text Line\n * Some Sample Copyright Text Line\n * Some Sample Copyright Text Line\n * Some Sample Copyright Text Line\n * Some Sample Copyright Text Line\n*/`;\n\nexport default defineConfig({\n plugins: [\n moduleTools(),\n modulePluginBanner({\n banner: {\n js: copyRight,\n },\n }),\n ],\n});\n\n\n\n配置#\n\n * 类型:\n\ntype BannerOptions = {\n banner: {\n js?: string;\n css?: string;\n };\n footer?: {\n js?: string;\n css?: string;\n };\n};\n\n\n\nbanner#\n\n在顶部增加内容。\n\n * banner.js:在 JS 文件顶部增加内容。\n * banner.css:在 CSS 文件顶部增加内容。\n\n\nfooter#\n\n在底部增加内容。\n\n * footer.js:在 JS 文件底部增加内容。\n * footer.css:在 CSS 文件底部增加内容。","frontmatter":{},"_filepath":"/Users/bytedance/github/targeral/modern-js/packages/document/module-doc/docs/zh/plugins/official-list/plugin-banner.md","_relativePath":"zh/plugins/official-list/plugin-banner.md"},{"id":78,"title":"Import 插件","routePath":"/module-tools/plugins/official-list/plugin-import","lang":"zh","toc":[{"text":"快速开始","id":"快速开始","depth":2,"charIndex":141},{"text":"安装","id":"安装","depth":3,"charIndex":149},{"text":"注册插件","id":"注册插件","depth":3,"charIndex":314},{"text":"配置","id":"配置","depth":2,"charIndex":606},{"text":"pluginImport","id":"pluginimport","depth":3,"charIndex":673},{"text":"注意事项","id":"注意事项","depth":2,"charIndex":1025}],"domain":"","content":"#\n\n提供与 babel-plugin-import 等价的能力和配置,基于 SWC 实现。\n\nTIP\n\n从 @modern-js/module-tools v2.16.0 版本开始,该插件功能内置在 Module Tools 中,由 transformImport\n配置提供。\n\n\n快速开始#\n\n\n安装#\n\n# npm\nnpm install @modern-js/plugin-module-import -D\n\n# yarn\nyarn add @modern-js/plugin-module-import -D\n\n# pnpm\npnpm add @modern-js/plugin-module-import -D\n\n\n\n注册插件#\n\n在 Module Tools 中,你可以按照如下方式注册插件:\n\n\n\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\n这样我们就可以在 Module Tools 中使用自动导入的能力了。\n\n\n配置#\n\n * 类型:\n\ntype Options = {\n pluginImport?: ImportItem[];\n};\n\n\n\npluginImport#\n\n * 类型:object[]\n\n其中数组元素为一个 babel-plugin-import 的配置对象。配置对象可以参考 options。\n\n使用示例:\n\n\n\n\nexport default defineConfig({\n plugins: [\n moduleTools(),\n modulePluginImport({\n pluginImport: [\n // babel-plugin-import 的 options 配置\n {\n libraryName: 'foo',\n style: true,\n },\n ],\n }),\n ],\n});\n\n\n\n注意事项#\n\nSWC (Speedy Web Compiler) 是基于 Rust 语言编写的,而该插件是基于 SWC,移植自\nbabel-plugin-import,配置选项保持了一致。\n\n一些配置可以传入函数,例如 customName,customStyleName 等,这些 JavaScript 函数会由 Rust 通过 Node-API\n调用,这种调用会造成一些性能劣化。\n\n简单的函数逻辑其实可以通过模版语言来代替,因此 customName,customStyleName\n等这些配置除了可以传入函数,也可以传入字符串作为模版来代替函数,提高性能。\n\n可以看出配置 customName: \"foo/es/{{ member }}\" 的效果等同于配置 customName: (member) =>\n`foo/es/${member}` ,但是不会有 Node-API 的调用开销。\n\n这里使用到的模版是 handlebars,模版配置中还内置了一些有用的辅助工具,还是以上面的导入语句为例,配置成:\n\n\n\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\n会转换成下面的结果:\n\n\n\n\n除了 kebabCase 以外还有 camelCase,snakeCase,upperCase,lowerCase 可以使用。","frontmatter":{},"_filepath":"/Users/bytedance/github/targeral/modern-js/packages/document/module-doc/docs/zh/plugins/official-list/plugin-import.mdx","_relativePath":"zh/plugins/official-list/plugin-import.mdx"},{"id":79,"title":"Node Polyfill 插件","routePath":"/module-tools/plugins/official-list/plugin-node-polyfill","lang":"zh","toc":[{"text":"快速开始","id":"快速开始","depth":2,"charIndex":213},{"text":"安装","id":"安装","depth":3,"charIndex":221},{"text":"注册插件","id":"注册插件","depth":3,"charIndex":407},{"text":"配置","id":"配置","depth":2,"charIndex":556},{"text":"exclude","id":"exclude","depth":3,"charIndex":647},{"text":"overrides","id":"overrides","depth":3,"charIndex":824},{"text":"Node Polyfills","id":"node-polyfills","depth":2,"charIndex":1053},{"text":"Globals","id":"globals","depth":3,"charIndex":1071},{"text":"Modules","id":"modules","depth":3,"charIndex":1194},{"text":"Fallbacks","id":"fallbacks","depth":3,"charIndex":1632}],"domain":"","content":"#\n\nNode Polyfill 介绍\n\n通常情况下,我们不会在浏览器端使用 Node 模块。但在当前代码需要同时在 Node 端和浏览器端运行时,用到一些 Node 模块是有可能的。Node\nPolyfill 为这些 Node 模块提供了浏览器版本的 polyfills。\n\n通过使用 Node Polyfill 插件,会自动注入 Node 核心模块在浏览器端的 polyfills,让你可以在浏览器端放心使用这些模块。\n\n\n快速开始#\n\n\n安装#\n\n# npm\nnpm install @modern-js/plugin-module-node-polyfill -D\n\n# yarn\nyarn add @modern-js/plugin-module-node-polyfill -D\n\n# pnpm\npnpm add @modern-js/plugin-module-node-polyfill -D\n\n\n\n注册插件#\n\n在 Module Tools 中,你可以按照如下方式注册插件:\n\n\n\n\nexport default defineConfig({\n plugins: [\n moduleTools(),\n modulePluginNodePolyfill(),\n ],\n});\n\n\n\n配置#\n\n * 类型:\n\ntype NodePolyfillOptions = {\n exclude?: string[];\n overrides?: Record;\n}\n\n\n\nexclude#\n\n排除要注入的 Node Polyfill。\n\n\n\n\nexport default defineConfig({\n plugins: [\n moduleTools(),\n modulePluginNodePolyfill({\n exclude: ['console'],\n }),\n ],\n});\n\n\n\noverrides#\n\n覆盖内置的 Node Polyfill。\n\n\n\n\nexport default defineConfig({\n plugins: [\n moduleTools(),\n modulePluginNodePolyfill({\n overrides: {\n fs: path.join(__dirname, './custom-fs.js'),\n }\n }),\n ],\n});\n\n\n\nNode Polyfills#\n\n\nGlobals#\n\n * Buffer\n * process\n * console\n\n当你在代码中使用以上全局变量时,对应 polyfill 会被自动注入。\n\nconst bufferData = Buffer.from('xxxx');\n\n\n\nModules#\n\n * assert\n * buffer\n * console\n * constants\n * crypto\n * domain\n * events\n * http\n * https\n * os\n * path\n * punycode\n * process\n * querystring\n * stream\n * _stream_duplex\n * _stream_passthrough\n * _stream_readable\n * _stream_transform\n * _stream_writable\n * string_decoder\n * sys\n * timers\n * tty\n * url\n * util\n * vm\n * zlib\n\n当你通过 require 或 import 等语法在代码中引用以上模块时,对应 polyfill 会被注入。\n\n\n\nconst bufferData = Buffer.from('xxxx');\n\n\n\nFallbacks#\n\n * child_process\n * cluster\n * dgram\n * dns\n * fs\n * module\n * net\n * readline\n * repl\n * tls\n\n目前浏览器端没有以上模块的 polyfill,因此当你引用以上模块时,会自动 fallback 为一个空对象。\n\n\n\nconsole.log(fs); // -> {}\n","frontmatter":{},"_filepath":"/Users/bytedance/github/targeral/modern-js/packages/document/module-doc/docs/zh/plugins/official-list/plugin-node-polyfill.md","_relativePath":"zh/plugins/official-list/plugin-node-polyfill.md"},{"id":80,"title":"Polyfill 插件","routePath":"/module-tools/plugins/official-list/plugin-polyfill","lang":"zh","toc":[{"text":"快速开始","id":"快速开始","depth":2,"charIndex":197},{"text":"安装","id":"安装","depth":3,"charIndex":205},{"text":"注册插件","id":"注册插件","depth":3,"charIndex":376},{"text":"配置","id":"配置","depth":2,"charIndex":521},{"text":"targets","id":"targets","depth":3,"charIndex":585}],"domain":"","content":"#\n\nTIP\n\n通常情况下,我们不需要为 npm 包注入 polyfill,这一步应该在 Web\n应用的框架侧完成,但是在某些场景,为了让我们的库能够直接运行在低版本浏览器里,我们需要注入 polyfill。\n\n请注意,此插件并不会转化你的代码语法,只会为你的代码中使用到的不支持的功能注入 polyfill,把它们作为普通函数导入而不是污染全局。你需要安装\ncore-js-pure 依赖\n\n\n快速开始#\n\n\n安装#\n\n# npm\nnpm install @modern-js/plugin-module-polyfill -D\n\n# yarn\nyarn add @modern-js/plugin-module-polyfill -D\n\n# pnpm\npnpm add @modern-js/plugin-module-polyfill -D\n\n\n\n注册插件#\n\n在 Module Tools 中,你可以按照如下方式注册插件:\n\n\n\n\nexport default defineConfig({\n plugins: [\n moduleTools(),\n modulePluginPolyfill(),\n ],\n});\n\n\n\n配置#\n\n * 类型:\n\ntype options = {\n targets?: Record | string;\n}\n\n\n\ntargets#\n\n参考 Babel target.\n\n下面是一个例子:\n\n\n\n\nexport default defineConfig({\n plugins: [\n moduleTools(),\n modulePluginPolyfill({\n targets: \"> 0.25%, not dead\"\n }),\n ],\n});\n","frontmatter":{},"_filepath":"/Users/bytedance/github/targeral/modern-js/packages/document/module-doc/docs/zh/plugins/official-list/plugin-polyfill.md","_relativePath":"zh/plugins/official-list/plugin-polyfill.md"}]