@modern-js/module-tools-docs 2.59.0 → 2.60.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +4 -0
- package/doc_build/404.html +17 -0
- package/doc_build/api/config/build-config.html +1217 -0
- package/doc_build/api/config/build-preset.html +211 -0
- package/doc_build/api/config/dev.html +63 -0
- package/doc_build/api/config/plugins.html +54 -0
- package/doc_build/api/index.html +17 -0
- package/doc_build/api/plugin-api/plugin-hooks.html +395 -0
- package/doc_build/components/faq-build-exception.html +17 -0
- package/doc_build/components/faq-build-other.html +17 -0
- package/doc_build/components/faq-build-product.html +17 -0
- package/doc_build/components/faq-storybook.html +17 -0
- package/doc_build/components/publish-emo.html +17 -0
- package/doc_build/components/register-esbuild-plugin.html +27 -0
- package/doc_build/components/release-module-doc.html +17 -0
- package/doc_build/en/api/config/build-config.html +1220 -0
- package/doc_build/en/api/config/build-preset.html +206 -0
- package/doc_build/en/api/config/dev.html +63 -0
- package/doc_build/en/api/config/plugins.html +54 -0
- package/doc_build/en/api/index.html +17 -0
- package/doc_build/en/api/plugin-api/plugin-hooks.html +399 -0
- package/doc_build/en/components/faq-build-exception.html +17 -0
- package/doc_build/en/components/faq-build-other.html +17 -0
- package/doc_build/en/components/faq-build-product.html +17 -0
- package/doc_build/en/components/faq-storybook.html +17 -0
- package/doc_build/en/components/publish-emo.html +17 -0
- package/doc_build/en/components/register-esbuild-plugin.html +27 -0
- package/doc_build/en/components/release-module-doc.html +17 -0
- package/doc_build/en/guide/advance/asset.html +58 -0
- package/doc_build/en/guide/advance/build-umd.html +166 -0
- package/doc_build/en/guide/advance/copy.html +208 -0
- package/doc_build/en/guide/advance/external-dependency.html +62 -0
- package/doc_build/en/guide/advance/in-depth-about-build.html +302 -0
- package/doc_build/en/guide/advance/in-depth-about-dev-command.html +68 -0
- package/doc_build/en/guide/basic/before-getting-started.html +139 -0
- package/doc_build/en/guide/basic/command-preview.html +131 -0
- package/doc_build/en/guide/basic/modify-output-product.html +133 -0
- package/doc_build/en/guide/basic/publish-your-project.html +100 -0
- package/doc_build/en/guide/basic/use-micro-generator.html +54 -0
- package/doc_build/en/guide/basic/use-module-doc.html +397 -0
- package/doc_build/en/guide/basic/using-storybook.html +168 -0
- package/doc_build/en/guide/best-practices/components.html +198 -0
- package/doc_build/en/guide/best-practices/use-tailwindcss.html +243 -0
- package/doc_build/en/guide/faq/basic.html +23 -0
- package/doc_build/en/guide/faq/build.html +237 -0
- package/doc_build/en/guide/faq/index.html +23 -0
- package/doc_build/en/guide/faq/storybook.html +85 -0
- package/doc_build/en/guide/intro/getting-started.html +92 -0
- package/doc_build/en/guide/intro/welcome.html +27 -0
- package/doc_build/en/guide/intro/why-module-engineering-solution.html +25 -0
- package/doc_build/en/index.html +17 -0
- package/doc_build/en/plugins/guide/getting-started.html +70 -0
- package/doc_build/en/plugins/guide/plugin-object.html +74 -0
- package/doc_build/en/plugins/guide/setup-function.html +96 -0
- package/doc_build/en/plugins/official-list/overview.html +26 -0
- package/doc_build/en/plugins/official-list/plugin-babel.html +65 -0
- package/doc_build/en/plugins/official-list/plugin-banner.html +91 -0
- package/doc_build/en/plugins/official-list/plugin-import.html +111 -0
- package/doc_build/en/plugins/official-list/plugin-node-polyfill.html +128 -0
- package/doc_build/en/plugins/official-list/plugin-polyfill.html +72 -0
- package/doc_build/en/plugins/official-list/plugin-vue.html +66 -0
- package/doc_build/guide/advance/asset.html +55 -0
- package/doc_build/guide/advance/build-umd.html +170 -0
- package/doc_build/guide/advance/copy.html +208 -0
- package/doc_build/guide/advance/external-dependency.html +61 -0
- package/doc_build/guide/advance/in-depth-about-build.html +300 -0
- package/doc_build/guide/advance/in-depth-about-dev-command.html +68 -0
- package/doc_build/guide/basic/before-getting-started.html +139 -0
- package/doc_build/guide/basic/command-preview.html +131 -0
- package/doc_build/guide/basic/modify-output-product.html +134 -0
- package/doc_build/guide/basic/publish-your-project.html +99 -0
- package/doc_build/guide/basic/use-micro-generator.html +54 -0
- package/doc_build/guide/basic/use-module-doc.html +395 -0
- package/doc_build/guide/basic/using-storybook.html +177 -0
- package/doc_build/guide/best-practices/components.html +198 -0
- package/doc_build/guide/best-practices/use-tailwindcss.html +243 -0
- package/doc_build/guide/faq/basic.html +23 -0
- package/doc_build/guide/faq/build.html +234 -0
- package/doc_build/guide/faq/index.html +23 -0
- package/doc_build/guide/faq/storybook.html +85 -0
- package/doc_build/guide/intro/getting-started.html +89 -0
- package/doc_build/guide/intro/welcome.html +27 -0
- package/doc_build/guide/intro/why-module-engineering-solution.html +25 -0
- package/doc_build/index.html +17 -0
- package/doc_build/plugins/guide/getting-started.html +70 -0
- package/doc_build/plugins/guide/plugin-object.html +74 -0
- package/doc_build/plugins/guide/setup-function.html +95 -0
- package/doc_build/plugins/official-list/overview.html +26 -0
- package/doc_build/plugins/official-list/plugin-babel.html +64 -0
- package/doc_build/plugins/official-list/plugin-banner.html +94 -0
- package/doc_build/plugins/official-list/plugin-import.html +112 -0
- package/doc_build/plugins/official-list/plugin-node-polyfill.html +128 -0
- package/doc_build/plugins/official-list/plugin-polyfill.html +71 -0
- package/doc_build/plugins/official-list/plugin-vue.html +66 -0
- package/doc_build/static/css/styles.0b88df3a.css +1 -0
- package/doc_build/static/js/490.a066dbc0.js +6 -0
- package/doc_build/static/js/490.a066dbc0.js.LICENSE.txt +35 -0
- package/doc_build/static/js/async/1095.4ca5fdf0.js +1 -0
- package/doc_build/static/js/async/1148.ff6a84ca.js +1 -0
- package/doc_build/static/js/async/1306.8bc84d6b.js +1 -0
- package/doc_build/static/js/async/1507.fed31a58.js +1 -0
- package/doc_build/static/js/async/1527.4c6e53e2.js +1 -0
- package/doc_build/static/js/async/1657.d0d95d59.js +1 -0
- package/doc_build/static/js/async/1801.5d49a2fe.js +1 -0
- package/doc_build/static/js/async/1941.0b3cceee.js +1 -0
- package/doc_build/static/js/async/213.db8a0492.js +1 -0
- package/doc_build/static/js/async/2131.5dfdffa9.js +1 -0
- package/doc_build/static/js/async/2140.848412d7.js +1 -0
- package/doc_build/static/js/async/2206.f6b802b2.js +1 -0
- package/doc_build/static/js/async/2300.cba0106e.js +1 -0
- package/doc_build/static/js/async/2347.a480682f.js +1 -0
- package/doc_build/static/js/async/2365.daed0a9c.js +1 -0
- package/doc_build/static/js/async/2561.2e43400c.js +1 -0
- package/doc_build/static/js/async/2579.f7c71e6b.js +1 -0
- package/doc_build/static/js/async/2671.c711355f.js +1 -0
- package/doc_build/static/js/async/2704.561dadd9.js +1 -0
- package/doc_build/static/js/async/2712.5ffea5ba.js +1 -0
- package/doc_build/static/js/async/3023.5bef6325.js +1 -0
- package/doc_build/static/js/async/3039.3982622e.js +1 -0
- package/doc_build/static/js/async/3097.b043b3aa.js +1 -0
- package/doc_build/static/js/async/3213.df408a99.js +1 -0
- package/doc_build/static/js/async/3235.0c4d2c9b.js +1 -0
- package/doc_build/static/js/async/336.8387125c.js +1 -0
- package/doc_build/static/js/async/3493.5133deaa.js +1 -0
- package/doc_build/static/js/async/351.de7824af.js +1 -0
- package/doc_build/static/js/async/3597.cf46a69b.js +1 -0
- package/doc_build/static/js/async/36.eee0e8fe.js +1 -0
- package/doc_build/static/js/async/3628.726e3f10.js +1 -0
- package/doc_build/static/js/async/3724.bcc90bb4.js +1 -0
- package/doc_build/static/js/async/3761.949f5838.js +1 -0
- package/doc_build/static/js/async/4061.84ac839b.js +1 -0
- package/doc_build/static/js/async/4064.104b71cd.js +1 -0
- package/doc_build/static/js/async/4206.133ffe9e.js +1 -0
- package/doc_build/static/js/async/443.b519ce6b.js +1 -0
- package/doc_build/static/js/async/4501.c647ab73.js +1 -0
- package/doc_build/static/js/async/453.7358c1fd.js +1 -0
- package/doc_build/static/js/async/461.2d6ea16c.js +1 -0
- package/doc_build/static/js/async/4615.c4e5b749.js +1 -0
- package/doc_build/static/js/async/4655.bbe27e7b.js +1 -0
- package/doc_build/static/js/async/4812.ebd3f4cb.js +1 -0
- package/doc_build/static/js/async/4904.de72a299.js +1 -0
- package/doc_build/static/js/async/5105.28347c4d.js +1 -0
- package/doc_build/static/js/async/5453.87dcea50.js +1 -0
- package/doc_build/static/js/async/5455.9e038fda.js +1 -0
- package/doc_build/static/js/async/5493.3644c7b8.js +1 -0
- package/doc_build/static/js/async/5495.50aacc7e.js +1 -0
- package/doc_build/static/js/async/5555.40dabd12.js +1 -0
- package/doc_build/static/js/async/5558.073d18d0.js +1 -0
- package/doc_build/static/js/async/5844.b3a9d57a.js +1 -0
- package/doc_build/static/js/async/588.6de9811a.js +1 -0
- package/doc_build/static/js/async/5889.41a786b6.js +1 -0
- package/doc_build/static/js/async/5892.b0db6657.js +1 -0
- package/doc_build/static/js/async/5995.209e2925.js +1 -0
- package/doc_build/static/js/async/6046.963bbf59.js +1 -0
- package/doc_build/static/js/async/6308.6363792d.js +1 -0
- package/doc_build/static/js/async/6576.a753babb.js +1 -0
- package/doc_build/static/js/async/6615.154a2810.js +1 -0
- package/doc_build/static/js/async/6858.e2452605.js +1 -0
- package/doc_build/static/js/async/6975.be4ba201.js +1 -0
- package/doc_build/static/js/async/7080.1c684c7d.js +1 -0
- package/doc_build/static/js/async/7220.1c4ee8bb.js +1 -0
- package/doc_build/static/js/async/7406.b2acec42.js +1 -0
- package/doc_build/static/js/async/7521.ca744786.js +1 -0
- package/doc_build/static/js/async/7535.f50f0fd1.js +1 -0
- package/doc_build/static/js/async/7584.c3b673fd.js +1 -0
- package/doc_build/static/js/async/7600.03d9da89.js +1 -0
- package/doc_build/static/js/async/7663.86b79735.js +1 -0
- package/doc_build/static/js/async/769.2bc1c7b7.js +1 -0
- package/doc_build/static/js/async/7715.1bfe887f.js +1 -0
- package/doc_build/static/js/async/7837.5667c422.js +1 -0
- package/doc_build/static/js/async/8040.1cfb21ff.js +1 -0
- package/doc_build/static/js/async/8085.f9f71860.js +1 -0
- package/doc_build/static/js/async/8098.beeb77f3.js +1 -0
- package/doc_build/static/js/async/8134.068074a0.js +1 -0
- package/doc_build/static/js/async/8158.2834ced1.js +1 -0
- package/doc_build/static/js/async/8214.2fdfe2fe.js +1 -0
- package/doc_build/static/js/async/8233.24111213.js +1 -0
- package/doc_build/static/js/async/8451.5328c0c7.js +1 -0
- package/doc_build/static/js/async/8689.f8447ca1.js +1 -0
- package/doc_build/static/js/async/8694.077556c4.js +1 -0
- package/doc_build/static/js/async/8713.91395601.js +1 -0
- package/doc_build/static/js/async/8750.0f6872b3.js +1 -0
- package/doc_build/static/js/async/8802.463e3040.js +1 -0
- package/doc_build/static/js/async/9100.066e1017.js +1 -0
- package/doc_build/static/js/async/9250.8fb41a47.js +1 -0
- package/doc_build/static/js/async/9524.bb257861.js +1 -0
- package/doc_build/static/js/async/9611.b2543acb.js +1 -0
- package/doc_build/static/js/async/964.b00f3e9f.js +1 -0
- package/doc_build/static/js/async/9740.b27e6629.js +1 -0
- package/doc_build/static/js/index.6a5d779d.js +1 -0
- package/doc_build/static/js/lib-react.a93218f7.js +2 -0
- package/doc_build/static/js/lib-react.a93218f7.js.LICENSE.txt +39 -0
- package/doc_build/static/js/lib-router.f8d11890.js +2 -0
- package/doc_build/static/js/lib-router.f8d11890.js.LICENSE.txt +32 -0
- package/doc_build/static/js/styles.3f5a6140.js +1 -0
- package/doc_build/static/search_index.en.f19ea64b.json +1 -0
- package/doc_build/static/search_index.zh.e818eee4.json +1 -0
- package/doc_build/test-result.png +0 -0
- package/doc_build/why-module-solution.png +0 -0
- package/docs/en/api/config/dev.md +2 -2
- package/docs/en/guide/basic/command-preview.md +0 -16
- package/docs/en/guide/intro/welcome.md +0 -1
- package/docs/zh/api/config/dev.md +2 -2
- package/docs/zh/guide/basic/command-preview.md +0 -16
- package/docs/zh/guide/basic/using-storybook.mdx +1 -1
- package/docs/zh/guide/intro/welcome.md +0 -1
- package/package.json +4 -4
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/* NProgress, (c) 2013, 2014 Rico Sta. Cruz - http://ricostacruz.com/nprogress
|
|
2
|
+
* @license MIT */
|
|
3
|
+
|
|
4
|
+
/*! Bundled license information:
|
|
5
|
+
|
|
6
|
+
lodash-es/lodash.js:
|
|
7
|
+
(**
|
|
8
|
+
* @license
|
|
9
|
+
* Lodash (Custom Build) <https://lodash.com/>
|
|
10
|
+
* Build: `lodash modularize exports="es" -o ./`
|
|
11
|
+
* Copyright OpenJS Foundation and other contributors <https://openjsf.org/>
|
|
12
|
+
* Released under MIT license <https://lodash.com/license>
|
|
13
|
+
* Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
|
|
14
|
+
* Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
|
|
15
|
+
*)
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
/*! medium-zoom 1.1.0 | MIT License | https://github.com/francoischalifour/medium-zoom */
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Prism: Lightweight, robust, elegant syntax highlighting
|
|
22
|
+
*
|
|
23
|
+
* @license MIT <https://opensource.org/licenses/MIT>
|
|
24
|
+
* @author Lea Verou <https://lea.verou.me>
|
|
25
|
+
* @namespace
|
|
26
|
+
* @public
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
/**!
|
|
30
|
+
* FlexSearch.js
|
|
31
|
+
* Author and Copyright: Thomas Wilkerling
|
|
32
|
+
* Licence: Apache-2.0
|
|
33
|
+
* Hosted by Nextapps GmbH
|
|
34
|
+
* https://github.com/nextapps-de/flexsearch
|
|
35
|
+
*/
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";(self.webpackChunk_modern_js_module_tools_docs=self.webpackChunk_modern_js_module_tools_docs||[]).push([["1095"],{7341:function(e,n,s){s.r(n),s.d(n,{default:function(){return c}});var i=s(8093),d=s(5878);function l(e){let n=Object.assign({h1:"h1",a:"a",p:"p",h2:"h2",ol:"ol",li:"li",code:"code",pre:"pre",div:"div",h3:"h3",ul:"ul",strong:"strong",h4:"h4"},(0,d.ah)(),e.components);return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsxs)(n.h1,{id:"使用-tailwind-css",children:["使用 Tailwind CSS",(0,i.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#使用-tailwind-css",children:"#"})]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"https://tailwindcss.com/",target:"_blank",rel:"noopener noreferrer",children:"Tailwind CSS"})," 是一个以 Utility Class 为基础的 CSS 框架和设计系统,可以快速地为组件添加常用样式,同时支持主题样式的灵活扩展。"]}),"\n",(0,i.jsx)(n.p,{children:"Modern.js Module 支持使用 Tailwind CSS 开发组件样式。"}),"\n",(0,i.jsxs)(n.h2,{id:"启用-tailwind-css",children:["启用 Tailwind CSS",(0,i.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#启用-tailwind-css",children:"#"})]}),"\n",(0,i.jsxs)(n.p,{children:["在 Modern.js Module 中使用 ",(0,i.jsx)(n.a,{href:"https://tailwindcss.com/",target:"_blank",rel:"noopener noreferrer",children:"Tailwind CSS"}),",你只需要按照以下步骤操作:"]}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["在项目根目录下执行 ",(0,i.jsx)(n.code,{children:"pnpm run new"}),",按照如下进行选择:"]}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-text",children:"? 请选择你想要的操作 启用可选功能\n? 请选择功能名称 启用 「Tailwind CSS」 支持\n"})}),"\n",(0,i.jsxs)(n.p,{children:["成功开启后,你会看到 ",(0,i.jsx)(n.code,{children:"package.json"})," 中新增了 ",(0,i.jsx)(n.code,{children:"tailwindcss"})," 和 ",(0,i.jsx)(n.code,{children:"@modern-js/plugin-tailwindcss"})," 依赖。"]}),"\n",(0,i.jsxs)(n.ol,{start:"2",children:["\n",(0,i.jsxs)(n.li,{children:["在 ",(0,i.jsx)(n.code,{children:"modern.config.ts"})," 中注册 Tailwind 插件:"]}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-ts",meta:'title="modern.config.ts"',children:"import { tailwindcssPlugin } from '@modern-js/plugin-tailwindcss';\n\nexport default defineConfig({\n plugins: [..., tailwindcssPlugin()],\n});\n"})}),"\n",(0,i.jsxs)(n.ol,{start:"3",children:["\n",(0,i.jsxs)(n.li,{children:["创建 ",(0,i.jsx)(n.code,{children:"index.css"})," 文件,添加以下代码:"]}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-css",meta:'title="index.css"',children:"/* base 和 components 是可选的,请酌情添加 */\n@tailwind base;\n@tailwind components;\n@tailwind utilities;\n"})}),"\n",(0,i.jsxs)(n.div,{className:"rspress-directive info",children:[(0,i.jsx)(n.div,{className:"rspress-directive-title",children:"INFO"}),(0,i.jsx)(n.div,{className:"rspress-directive-content",children:(0,i.jsxs)(n.p,{children:["根据需求不同,你可以选择性地导入 Tailwind CSS 提供的 CSS 样式。请参考 ",(0,i.jsxs)(n.a,{href:"https://tailwindcss.com/docs/functions-and-directives#tailwind",target:"_blank",rel:"noopener noreferrer",children:[(0,i.jsx)(n.code,{children:"@tailwind"})," 文档"]})," 来了解 ",(0,i.jsx)(n.code,{children:"@tailwind"})," 指令的详细用法。\n"]})})]}),"\n",(0,i.jsxs)(n.ol,{start:"4",children:["\n",(0,i.jsxs)(n.li,{children:["引用 ",(0,i.jsx)(n.code,{children:"index.css"})," 文件,比如在入口的 ",(0,i.jsx)(n.code,{children:"src/index.jsx"})," 文件添加如下代码:"]}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-js",children:"import './index.css';\n"})}),"\n",(0,i.jsxs)(n.ol,{start:"5",children:["\n",(0,i.jsx)(n.li,{children:"然后即可在各个组件中使用 Tailwind CSS 提供的 Utility Class 了:"}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-tsx",children:'const Hello = () => (\n <div className="h-12 w-48">\n <p className="text-xl font-medium text-black">hello world</p>\n </div>\n);\n'})}),"\n",(0,i.jsxs)(n.h2,{id:"配置-tailwind-css",children:["配置 Tailwind CSS",(0,i.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#配置-tailwind-css",children:"#"})]}),"\n",(0,i.jsx)(n.p,{children:"在 Modern.js Module 中,你有两种方式来配置 Tailwind CSS:"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["使用 ",(0,i.jsx)(n.code,{children:"tailwind.config.{ts,js}"})," 文件,该用法与 Tailwind CSS 的官方用法一致,请参考 ",(0,i.jsx)(n.a,{href:"https://tailwindcss.com/docs/configuration",target:"_blank",rel:"noopener noreferrer",children:'"Tailwind CSS - Configuration"'})," 来了解更多用法。"]}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-ts",meta:'title="tailwind.config.ts"',children:"import type { Config } from 'tailwindcss';\n\nexport default {\n content: ['./src/**/*.{js,jsx,ts,tsx}'],\n} as Config;\n"})}),"\n",(0,i.jsxs)(n.div,{className:"rspress-directive tip",children:[(0,i.jsx)(n.div,{className:"rspress-directive-title",children:"TIP"}),(0,i.jsx)(n.div,{className:"rspress-directive-content",children:(0,i.jsxs)(n.p,{children:["请升级 Modern.js Module 到 >= 2.33.0 版本,以支持自动读取 ",(0,i.jsx)(n.code,{children:"tailwind.config.{ts,js}"})," 文件。\n"]})})]}),"\n",(0,i.jsxs)(n.ol,{start:"2",children:["\n",(0,i.jsxs)(n.li,{children:["使用 ",(0,i.jsx)(n.a,{href:"/api/config/build-config.html#styletailwindcss",children:"style.tailwindcss"})," 配置项,这是旧版本的用法,我们更推荐使用 ",(0,i.jsx)(n.code,{children:"tailwind.config.{ts,js}"})," 文件进行配置。"]}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-ts",meta:'title="modern.config.ts"',children:"export default {\n style: {\n tailwindcss: {\n content: ['./src/**/*.{js,jsx,ts,tsx}'],\n },\n },\n};\n"})}),"\n",(0,i.jsxs)(n.p,{children:["如果你同时使用了 ",(0,i.jsx)(n.code,{children:"tailwind.config.{ts,js}"})," 文件和 ",(0,i.jsx)(n.code,{children:"style.tailwindcss"})," 选项,那么 ",(0,i.jsx)(n.code,{children:"style.tailwindcss"})," 定义的配置会优先生效,并覆盖 ",(0,i.jsx)(n.code,{children:"tailwind.config.{ts,js}"})," 中定义的内容。"]}),"\n",(0,i.jsxs)(n.h2,{id:"tailwind-css-自动补全",children:["Tailwind CSS 自动补全",(0,i.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#tailwind-css-自动补全",children:"#"})]}),"\n",(0,i.jsxs)(n.p,{children:["Tailwind CSS 官方提供了 ",(0,i.jsx)(n.a,{href:"https://github.com/tailwindlabs/tailwindcss-intellisense",target:"_blank",rel:"noopener noreferrer",children:"Tailwind CSS IntelliSense"})," 插件,用于在 VS Code 中自动补全 Tailwind CSS 的 class names、CSS functions 和 directives。"]}),"\n",(0,i.jsx)(n.p,{children:"你可以参考以下步骤来启动自动补全功能:"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["在 VS Code 中安装 ",(0,i.jsx)(n.a,{href:"https://github.com/tailwindlabs/tailwindcss-intellisense",target:"_blank",rel:"noopener noreferrer",children:"Tailwind CSS IntelliSense"})," 插件。"]}),"\n",(0,i.jsxs)(n.li,{children:["如果项目的根目录没有 ",(0,i.jsx)(n.code,{children:"tailwind.config.{ts,js}"})," 文件,那么你需要创建该文件,并写入当前项目的 Tailwind CSS 配置,否则 IDE 插件将无法正确生效。"]}),"\n"]}),"\n",(0,i.jsxs)(n.h2,{id:"构建模式",children:["构建模式",(0,i.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#构建模式",children:"#"})]}),"\n",(0,i.jsx)(n.p,{children:"在使用 Tailwind CSS 时,请注意构建产物在 bundle 和 bundleless 两种模式下会有很大区别。"}),"\n",(0,i.jsxs)(n.div,{className:"rspress-directive tip",children:[(0,i.jsx)(n.div,{className:"rspress-directive-title",children:"TIP"}),(0,i.jsx)(n.div,{className:"rspress-directive-content",children:(0,i.jsxs)(n.p,{children:["关于 bundle 和 bundleless 的定义,可以查看 ",(0,i.jsx)(n.a,{href:"/guide/advance/in-depth-about-build",children:"「深入理解构建」"}),"\n"]})})]}),"\n",(0,i.jsxs)(n.h3,{id:"bundle-模式",children:["Bundle 模式",(0,i.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#bundle-模式",children:"#"})]}),"\n",(0,i.jsx)(n.p,{children:"在 Bundle 模式下,会生成一份单独的产物 CSS 文件,并且 JS 产物不会自动引用产物 CSS 文件。"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"源代码:"}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-tsx",meta:'title="./src/index.tsx"',children:"import './index.css';\n\nexport default () => {\n return <div className=\"bg-black\">hello world</div>;\n};\n"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"产物代码:"}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-js",meta:'title="./dist/es/index.js"',children:"// src/index.tsx\nimport { jsx } from 'react/jsx-runtime';\nvar src_default = () => {\n return /* @__PURE__ */ jsx('div', {\n className: 'bg-black',\n children: 'hello world',\n });\n};\nexport { src_default as default };\n"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-css",meta:'title="./dist/es/index.css"',children:".bg-black {\n --tw-bg-opacity: 1;\n background-color: rgb(0 0 0 / var(--tw-bg-opacity));\n}\n/** some more... */\n"})}),"\n",(0,i.jsxs)(n.p,{children:["如果你需要将样式注入 JS 产物中,可以开启 ",(0,i.jsx)(n.a,{href:"/api/config/build-config#styleinject",children:"style.inject"})," 选项。"]}),"\n",(0,i.jsxs)(n.p,{children:["如果你没有开启 ",(0,i.jsx)(n.code,{children:"style.inject"}),",那么也可以让用户手动引用产物 CSS 文件:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-js",children:"import 'your-package/dist/es/index.css';\n"})}),"\n",(0,i.jsxs)(n.h3,{id:"bundleless-模式",children:["Bundleless 模式",(0,i.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#bundleless-模式",children:"#"})]}),"\n",(0,i.jsx)(n.p,{children:"在 Bundleless 模式下,默认会引用产物 CSS 文件,无须进行额外处理。"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"产物代码:"}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-js",meta:'title="./dist/es/index.js"',children:"import { jsx as _jsx } from 'react/jsx-runtime';\nimport './index.css';\nexport default () =>\n /* @__PURE__ */ _jsx('div', {\n className: 'bg-black',\n children: 'hello world',\n });\n"})}),"\n",(0,i.jsxs)(n.h2,{id:"类名前缀",children:["类名前缀",(0,i.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#类名前缀",children:"#"})]}),"\n",(0,i.jsxs)(n.p,{children:["你可以通过 Tailwind CSS 提供的 ",(0,i.jsx)(n.a,{href:"https://tailwindcss.com/docs/configuration#prefix",target:"_blank",rel:"noopener noreferrer",children:"prefix"})," 选项来添加类名前缀,这样可以避免潜在的类名冲突问题(比如 App 和 Module 使用了不同版本的 Tailwind CSS)。"]}),"\n",(0,i.jsxs)(n.p,{children:["例如,通过 ",(0,i.jsx)(n.code,{children:"prefix"})," 选项添加 ",(0,i.jsx)(n.code,{children:"foo-"})," 前缀:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-js",meta:'title="tailwind.config.js"',children:"module.exports = {\n prefix: 'foo-',\n};\n"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"源代码:"}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-tsx",meta:'title="./src/index.tsx"',children:"import './index.css';\n\nexport default () => {\n return <div className=\"foo-bg-black\">hello world</div>;\n};\n"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"产物代码:"}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-css",meta:'title="./dist/es/index.css"',children:".foo-bg-black {\n --tw-bg-opacity: 1;\n background-color: rgb(0 0 0 / var(--tw-bg-opacity));\n}\n/** some more... */\n"})}),"\n",(0,i.jsxs)(n.h2,{id:"用法介绍",children:["用法介绍",(0,i.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#用法介绍",children:"#"})]}),"\n",(0,i.jsx)(n.p,{children:"下面是一些 Tailwind CSS 的用法示例。"}),"\n",(0,i.jsxs)(n.h3,{id:"html-类名",children:["HTML 类名",(0,i.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#html-类名",children:"#"})]}),"\n",(0,i.jsxs)(n.p,{children:["Tailwind CSS 支持在 HTML 标签上通过类名的方式增加样式。",(0,i.jsx)(n.strong,{children:"当使用 HTML 类名的时候,请注意必须要提前导入 Tailwind CSS 相应的 CSS 样式。"})]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-tsx",meta:'title="./src/index.tsx"',children:"import './index.css';\n\nexport default () => {\n return <div className=\"bg-black\">hello world</div>;\n};\n"})}),"\n",(0,i.jsx)(n.p,{children:"样式产物(此时是 bundle 构建):"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-css",meta:'title="./dist/es/index.css"',children:".bg-black {\n --tw-bg-opacity: 1;\n background-color: rgba(0, 0, 0, var(--tw-bg-opacity));\n}\n/** some more... */\n"})}),"\n",(0,i.jsxs)(n.h3,{id:"apply",children:[(0,i.jsx)(n.code,{children:"@apply"}),(0,i.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#apply",children:"#"})]}),"\n",(0,i.jsxs)(n.p,{children:["Tailwind CSS 提供了 ",(0,i.jsx)(n.a,{href:"https://v2.tailwindcss.com/docs/functions-and-directives#apply",target:"_blank",rel:"noopener noreferrer",children:(0,i.jsx)(n.code,{children:"@apply"})})," 指令,可以通过它将 Tailwind CSS 提供的样式内联到我们编写的样式中。"]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"@apply"})," 可以用于 CSS、Less、Sass 中。"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-css",children:".btn {\n @apply font-bold py-2 px-4 rounded;\n}\n"})}),"\n",(0,i.jsx)(n.p,{children:"但是使用过程中,对于 Less 和 Sass 有些情况需要注意:"}),"\n",(0,i.jsxs)(n.h4,{id:"sass",children:["Sass",(0,i.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#sass",children:"#"})]}),"\n",(0,i.jsxs)(n.p,{children:["当将 Tailwind 与 Sass 一起使用时,",(0,i.jsx)(n.code,{children:"@apply"})," 后面存在 ",(0,i.jsx)(n.code,{children:"!important"})," 的时候,需要使用插值来让 Sass 正确编译。"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"不能正常工作:"}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-sass",children:".alert {\n @apply bg-red-500 !important;\n}\n"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"能够正常工作:"}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-sass",children:".alert {\n @apply bg-red-500 #{!important};\n}\n"})}),"\n",(0,i.jsxs)(n.h4,{id:"less",children:["Less",(0,i.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#less",children:"#"})]}),"\n",(0,i.jsxs)(n.p,{children:["在与 Less 一起使用 Tailwind 时,你不能嵌套 Tailwind 的 ",(0,i.jsx)(n.code,{children:"@screen"})," 指令。"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"不能正常工作:"}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-less",children:".card {\n @apply rounded-none;\n\n @screen sm {\n @apply rounded-lg;\n }\n}\n"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["相反,使用常规的媒体查询和 ",(0,i.jsx)(n.code,{children:"theme()"})," 函数来引用你的屏幕尺寸,或者干脆不要嵌套你的 ",(0,i.jsx)(n.code,{children:"@screen"})," 指令。"]}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-less",meta:'title="方法一"',children:"// Use a regular media query and theme()\n.card {\n @apply rounded-none;\n\n @media (min-width: theme('screens.sm')) {\n @apply rounded-lg;\n }\n}\n"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-less",meta:'title="方法二"',children:"// Use the @screen directive at the top-level\n.card {\n @apply rounded-none;\n\n @media (min-width: theme('screens.sm')) {\n @apply rounded-lg;\n }\n}\n"})}),"\n",(0,i.jsxs)(n.h2,{id:"关于-designsystem-配置",children:["关于 ",(0,i.jsx)(n.code,{children:"designSystem"})," 配置",(0,i.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#关于-designsystem-配置",children:"#"})]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"designSystem"})," 是 Modern.js Module 中废弃的配置项。"]}),"\n",(0,i.jsxs)(n.p,{children:["从 Modern.js Module v2.33.0 版本开始,你可以使用 Tailwind CSS 的 ",(0,i.jsx)(n.code,{children:"theme"})," 配置项来代替 ",(0,i.jsx)(n.code,{children:"designSystem"}),",不再需要将 ",(0,i.jsx)(n.code,{children:"theme"})," 配置拆分并设置到 ",(0,i.jsx)(n.code,{children:"designSystem"})," 上。"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"旧版本用法:"}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-ts",meta:'title="modern.config.ts"',children:"const { theme, ...rest } = tailwindConfig;\n\nexport default {\n style: {\n tailwindcss: rest,\n },\n designSystem: theme,\n};\n"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"当前版本用法:"}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-ts",meta:'title="modern.config.ts"',children:"export default {\n style: {\n tailwindcss: tailwindConfig,\n },\n};\n"})})]})}function r(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},{wrapper:n}=Object.assign({},(0,d.ah)(),e.components);return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}let c=r;r.__RSPRESS_PAGE_META={},r.__RSPRESS_PAGE_META["zh%2Fguide%2Fbest-practices%2Fuse-tailwindcss.mdx"]={toc:[{text:"启用 Tailwind CSS",id:"启用-tailwind-css",depth:2},{text:"配置 Tailwind CSS",id:"配置-tailwind-css",depth:2},{text:"Tailwind CSS 自动补全",id:"tailwind-css-自动补全",depth:2},{text:"构建模式",id:"构建模式",depth:2},{text:"Bundle 模式",id:"bundle-模式",depth:3},{text:"Bundleless 模式",id:"bundleless-模式",depth:3},{text:"类名前缀",id:"类名前缀",depth:2},{text:"用法介绍",id:"用法介绍",depth:2},{text:"HTML 类名",id:"html-类名",depth:3},{text:"`@apply`",id:"apply",depth:3},{text:"Sass",id:"sass",depth:4},{text:"Less",id:"less",depth:4},{text:"关于 `designSystem` 配置",id:"关于-designsystem-配置",depth:2}],title:"使用 Tailwind CSS",frontmatter:{sidebar_position:2}}}}]);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";(self.webpackChunk_modern_js_module_tools_docs=self.webpackChunk_modern_js_module_tools_docs||[]).push([["1148"],{6247:function(e,n,r){r.r(n),r.d(n,{default:function(){return l}});var s=r(8093),t=r(5878);function i(e){let n=Object.assign({h1:"h1",a:"a",p:"p",ul:"ul",li:"li",strong:"strong",code:"code",h3:"h3",div:"div",pre:"pre",em:"em",h2:"h2"},(0,t.ah)(),e.components);return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsxs)(n.h1,{id:"buildpreset",children:["buildPreset",(0,s.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#buildpreset",children:"#"})]}),"\n",(0,s.jsx)(n.p,{children:"A build preset string or preset function. Provides out-of-the-box build configuration"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Type"}),": ",(0,s.jsx)(n.code,{children:"string | Function"})]}),"\n"]}),"\n",(0,s.jsxs)(n.h3,{id:"npm-library",children:[(0,s.jsx)(n.code,{children:"npm-library"}),(0,s.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#npm-library",children:"#"})]}),"\n",(0,s.jsxs)(n.p,{children:["Library generic schema used under class ",(0,s.jsx)(n.a,{href:"https://www.npmjs.com/",target:"_blank",rel:"noopener noreferrer",children:"NPM"})," package manager, contains ",(0,s.jsx)(n.code,{children:"esm"})," and ",(0,s.jsx)(n.code,{children:"cjs"})," bundle artifacts, and includes a type file."]}),"\n",(0,s.jsxs)(n.div,{className:"rspress-directive info",children:[(0,s.jsx)(n.div,{className:"rspress-directive-title",children:"INFO"}),(0,s.jsxs)(n.div,{className:"rspress-directive-content",children:[(0,s.jsxs)(n.p,{children:["About the class ",(0,s.jsx)(n.a,{href:"https://www.npmjs.com/",target:"_blank",rel:"noopener noreferrer",children:"NPM"})," Package Manager"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://www.npmjs.com",target:"_blank",rel:"noopener noreferrer",children:"npm"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://yarnpkg.com/",target:"_blank",rel:"noopener noreferrer",children:"yarn"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://pnpm.io/",target:"_blank",rel:"noopener noreferrer",children:"pnpm"})}),"\n"]}),"\n"]})]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",meta:'title="package.json"',children:'{\n "main": "./dist/lib/index.js",\n "module": "./dist/es/index.js",\n "types": "./dist/types/index.d.ts"\n}\n'})}),"\n",(0,s.jsx)(n.p,{children:"The build configuration corresponding to the preset string."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-js",children:"export const buildConfig = [\n {\n format: 'cjs',\n target: 'es6',\n buildType: 'bundle',\n outDir: './dist/lib',\n dts: false,\n },\n {\n format: 'esm',\n target: 'es6',\n buildType: 'bundle',\n outDir: './dist/es',\n dts: false,\n },\n {\n buildType: 'bundle',\n outDir: './dist/types',\n dts: {\n only: true,\n },\n },\n];\n"})}),"\n",(0,s.jsxs)(n.h3,{id:"npm-library-with-umd",children:[(0,s.jsx)(n.code,{children:"npm-library-with-umd"}),(0,s.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#npm-library-with-umd",children:"#"})]}),"\n",(0,s.jsxs)(n.p,{children:["Used under class ",(0,s.jsx)(n.a,{href:"https://www.npmjs.com/",target:"_blank",rel:"noopener noreferrer",children:"NPM"})," package manager, and Library supports a similar pattern to ",(0,s.jsx)(n.a,{href:"https://unpkg.com/",target:"_blank",rel:"noopener noreferrer",children:"unpkg"}),". Additional ",(0,s.jsx)(n.code,{children:"umd"})," artifacts are provided on top of the pre-defined ",(0,s.jsx)(n.code,{children:"npm-library"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",meta:'title="package.json"',children:'{\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",(0,s.jsx)(n.p,{children:"The build configuration corresponding to the preset string."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-js",children:"export const buildConfig = [\n {\n format: 'cjs',\n target: 'es6',\n buildType: 'bundle',\n outDir: './dist/lib',\n dts: false,\n },\n {\n format: 'esm',\n target: 'es6',\n buildType: 'bundle',\n outDir: './dist/es',\n dts: false,\n },\n {\n format: 'umd',\n target: 'es6',\n platform: 'browser',\n buildType: 'bundle',\n outDir: './dist/umd',\n dts: false,\n },\n {\n buildType: 'bundle',\n outDir: './dist/types',\n dts: {\n only: true,\n },\n },\n];\n"})}),"\n",(0,s.jsxs)(n.h3,{id:"npm-component",children:[(0,s.jsx)(n.code,{children:"npm-component"}),(0,s.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#npm-component",children:"#"})]}),"\n",(0,s.jsxs)(n.p,{children:["A generic pattern for components (libraries) used under the class ",(0,s.jsx)(n.a,{href:"https://www.npmjs.com/",target:"_blank",rel:"noopener noreferrer",children:"NPM"})," package manager. Contains both ",(0,s.jsx)(n.code,{children:"esm"})," and ",(0,s.jsx)(n.code,{children:"cjs"})," Bundleless artifacts (for easy ",(0,s.jsx)(n.em,{children:(0,s.jsx)(n.a,{href:"https://developer.mozilla.org/zh-CN/docs/Glossary/Tree_shaking",target:"_blank",rel:"noopener noreferrer",children:"Tree shaking"})})," optimization), as well as including a copy of the type file."]}),"\n",(0,s.jsx)(n.p,{children:"For style files included in the source code, the artifacts provide the compiled files of the style and the source file of the style."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",meta:'title="package.json"',children:'{\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",(0,s.jsx)(n.p,{children:"The pre-defined strings correspond to the build configuration."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-js",children:"export const buildConfig = [\n {\n format: 'cjs',\n target: 'es6',\n buildType: 'bundleless',\n outDir: './dist/lib',\n dts: false,\n },\n {\n format: 'esm',\n target: 'es6',\n buildType: 'bundleless',\n outDir: './dist/es',\n dts: false,\n },\n {\n buildType: 'bundleless',\n outDir: './dist/types',\n dts: {\n only: true,\n },\n },\n];\n"})}),"\n",(0,s.jsxs)(n.h3,{id:"npm-component-with-umd",children:[(0,s.jsx)(n.code,{children:"npm-component-with-umd"}),(0,s.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#npm-component-with-umd",children:"#"})]}),"\n",(0,s.jsxs)(n.p,{children:["Component (library) used under class ",(0,s.jsx)(n.a,{href:"https://www.npmjs.com/",target:"_blank",rel:"noopener noreferrer",children:"NPM"})," package manager, with support for class ",(0,s.jsx)(n.a,{href:"https://unpkg.com/",target:"_blank",rel:"noopener noreferrer",children:"unpkg"})," schema. Additional ",(0,s.jsx)(n.code,{children:"umd"})," artifacts are provided on top of the pre-defined ",(0,s.jsx)(n.code,{children:"npm-component"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",meta:'title="package.json"',children:'{\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",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-js",children:"export const buildConfig = [\n {\n format: 'cjs',\n target: 'es6',\n buildType: 'bundleless',\n outDir: './dist/lib',\n dts: false,\n },\n {\n format: 'esm',\n target: 'es6',\n buildType: 'bundleless',\n outDir: './dist/es',\n dts: false,\n },\n {\n format: 'umd',\n target: 'es6',\n platform: 'browser',\n buildType: 'bundle',\n outDir: './dist/umd',\n dts: false,\n },\n {\n buildType: 'bundleless',\n outDir: './dist/types',\n dts: {\n only: true,\n },\n },\n];\n"})}),"\n",(0,s.jsxs)(n.h3,{id:"npm-library-es5esnext",children:[(0,s.jsx)(n.code,{children:"npm-library-{es5...esnext}"}),(0,s.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#npm-library-es5esnext",children:"#"})]}),"\n",(0,s.jsxs)(n.p,{children:["When you want to use a ",(0,s.jsx)(n.code,{children:"buildPreset"})," preset that supports other ECMAScript versions, you can directly add the supported versions to the ",(0,s.jsx)(n.code,{children:"'npm-library'"}),", ",(0,s.jsx)(n.code,{children:"'npm-library-with-umd'"}),", ",(0,s.jsx)(n.code,{children:"'npm-component'"}),", ",(0,s.jsx)(n.code,{children:"'npm-component-with-umd'"})," presets."]}),"\n",(0,s.jsxs)(n.p,{children:["For example, if you want the ",(0,s.jsx)(n.code,{children:"'npm-library'"})," preset to support ",(0,s.jsx)(n.code,{children:"'es2017'"}),", you can configure it as follows."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-js",meta:'title="modern.config.ts"',children:"import { defineConfig } from '@modern-js/module-tools';\n\nexport default defineConfig({\n buildPreset: 'npm-library-es2017',\n});\n"})}),"\n",(0,s.jsxs)(n.h2,{id:"string--function",children:["string / function",(0,s.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#string--function",children:"#"})]}),"\n",(0,s.jsx)(n.p,{children:"The buildPreset not only supports basic string forms, but also function forms, which can obtain the default values we provide through the preset or extend Preset parameter and then modify them."}),"\n",(0,s.jsx)(n.p,{children:"Here are two examples using preset and extend Preset:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-js",meta:'title="modern.config.ts"',children:"import { defineConfig } from '@modern-js/module-tools';\n\nexport default defineConfig({\n buildPreset({ preset }) {\n const { NPM_LIBRARY } = preset;\n return NPM_LIBRARY.map(config => {\n config.define = {\n VERSION: '1.0.1',\n };\n return config;\n });\n },\n});\n"})}),"\n",(0,s.jsxs)(n.p,{children:["In the ",(0,s.jsx)(n.code,{children:"extend Preset"}),", lodash.merge is used for configuration merge."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ts",meta:'title="modern.config.ts"',children:"import { defineConfig } from '@modern-js/module-tools';\n\nexport default defineConfig({\n buildPreset({ extendPreset }) {\n return extendPreset('npm-library', {\n define: {\n VERSION: '1.0.1',\n },\n });\n },\n});\n"})})]})}function d(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},{wrapper:n}=Object.assign({},(0,t.ah)(),e.components);return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(i,{...e})}):i(e)}let l=d;d.__RSPRESS_PAGE_META={},d.__RSPRESS_PAGE_META["en%2Fapi%2Fconfig%2Fbuild-preset.mdx"]={toc:[{text:"`npm-library`",id:"npm-library",depth:3},{text:"`npm-library-with-umd`",id:"npm-library-with-umd",depth:3},{text:"`npm-component`",id:"npm-component",depth:3},{text:"`npm-component-with-umd`",id:"npm-component-with-umd",depth:3},{text:"`npm-library-{es5...esnext}`",id:"npm-library-es5esnext",depth:3},{text:"string / function",id:"string--function",depth:2}],title:"buildPreset",frontmatter:{sidebar_position:2}}}}]);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";(self.webpackChunk_modern_js_module_tools_docs=self.webpackChunk_modern_js_module_tools_docs||[]).push([["1306"],{2212:function(e,n,i){i.r(n),i.d(n,{default:function(){return h}});var r=i(8093),d=i(5878);function s(e){let n=Object.assign({h1:"h1",a:"a",p:"p",ul:"ul",li:"li",code:"code",h2:"h2",h3:"h3",pre:"pre",h4:"h4"},(0,d.ah)(),e.components);return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsxs)(n.h1,{id:"plugins",children:["plugins",(0,r.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#plugins",children:"#"})]}),"\n",(0,r.jsx)(n.p,{children:"本章介绍注册 Modern.js Module 插件的配置。"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["类型:",(0,r.jsx)(n.code,{children:"ModuleToolsPlugin[]"})]}),"\n",(0,r.jsxs)(n.li,{children:["默认值:",(0,r.jsx)(n.code,{children:"undefined"})]}),"\n"]}),"\n",(0,r.jsxs)(n.h2,{id:"插件执行顺序",children:["插件执行顺序",(0,r.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#插件执行顺序",children:"#"})]}),"\n",(0,r.jsxs)(n.p,{children:["默认情况下,自定义插件会按照 ",(0,r.jsx)(n.code,{children:"plugins"})," 数组的顺序依次执行,Modern.js Module 内置插件的执行时机早于自定义插件。"]}),"\n",(0,r.jsxs)(n.p,{children:["当插件内部使用了控制顺序的相关字段,比如 ",(0,r.jsx)(n.code,{children:"pre"}),"、",(0,r.jsx)(n.code,{children:"post"})," 时,会基于声明的字段对执行顺序进行调整,详见 ",(0,r.jsx)(n.a,{href:"https://modernjs.dev/guides/topic-detail/framework-plugin/relationship",target:"_blank",rel:"noopener noreferrer",children:"插件之间的关系"}),"。"]}),"\n",(0,r.jsxs)(n.h2,{id:"开发插件",children:["开发插件",(0,r.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#开发插件",children:"#"})]}),"\n",(0,r.jsxs)(n.p,{children:["关于如何编写插件,可以查看",(0,r.jsx)(n.a,{href:"/plugins/guide/getting-started",children:"「插件编写指南」"}),"。"]}),"\n",(0,r.jsxs)(n.h2,{id:"示例",children:["示例",(0,r.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#示例",children:"#"})]}),"\n",(0,r.jsxs)(n.h3,{id:"使用-npm-上的插件",children:["使用 npm 上的插件",(0,r.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#使用-npm-上的插件",children:"#"})]}),"\n",(0,r.jsx)(n.p,{children:"使用 npm 上的插件,需要通过包管理器安装插件,并通过 import 引入。"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-js",meta:'title="modern.config.ts"',children:"import { myPlugin } from 'my-plugin';\n\nexport default defineConfig({\n plugins: [myPlugin()],\n});\n"})}),"\n",(0,r.jsxs)(n.h4,{id:"使用本地插件",children:["使用本地插件",(0,r.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#使用本地插件",children:"#"})]}),"\n",(0,r.jsx)(n.p,{children:"使用本地代码仓库中的插件,直接通过相对路径 import 引入即可。"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-js",meta:'title="modern.config.ts"',children:"import { myPlugin } from './plugins/myPlugin';\n\nexport default defineConfig({\n plugins: [myPlugin()],\n});\n"})}),"\n",(0,r.jsxs)(n.h3,{id:"插件配置项",children:["插件配置项",(0,r.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#插件配置项",children:"#"})]}),"\n",(0,r.jsx)(n.p,{children:"如果插件提供了一些自定义的配置项,你可以通过插件函数的参数传入配置。"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-js",meta:'title="modern.config.ts"',children:"import { myPlugin } from 'my-plugin';\n\nexport default defineConfig({\n plugins: [\n myPlugin({\n foo: 1,\n bar: 2,\n }),\n ],\n});\n"})})]})}function l(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},{wrapper:n}=Object.assign({},(0,d.ah)(),e.components);return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(s,{...e})}):s(e)}let h=l;l.__RSPRESS_PAGE_META={},l.__RSPRESS_PAGE_META["zh%2Fapi%2Fconfig%2Fplugins.md"]={toc:[{text:"插件执行顺序",id:"插件执行顺序",depth:2},{text:"开发插件",id:"开发插件",depth:2},{text:"示例",id:"示例",depth:2},{text:"使用 npm 上的插件",id:"使用-npm-上的插件",depth:3},{text:"使用本地插件",id:"使用本地插件",depth:4},{text:"插件配置项",id:"插件配置项",depth:3}],title:"plugins",frontmatter:{sidebar_position:4}}}}]);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";(self.webpackChunk_modern_js_module_tools_docs=self.webpackChunk_modern_js_module_tools_docs||[]).push([["1507"],{838:function(e,n,i){i.r(n),i.d(n,{default:function(){return d}});var o=i(8093),t=i(5878);function r(e){let n=Object.assign({h1:"h1",a:"a",p:"p",h2:"h2",code:"code",ul:"ul",li:"li",pre:"pre",blockquote:"blockquote",h3:"h3"},(0,t.ah)(),e.components);return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsxs)(n.h1,{id:"use-the-copy-tools",children:["Use the Copy Tools",(0,o.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#use-the-copy-tools",children:"#"})]}),"\n",(0,o.jsx)(n.p,{children:"Modern.js Module provides the Copy utility for copying already existing individual files or entire directories into the output directory. Next we learn how to use it."}),"\n",(0,o.jsxs)(n.h2,{id:"understanding-the-copy-api",children:["Understanding the Copy API",(0,o.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#understanding-the-copy-api",children:"#"})]}),"\n",(0,o.jsxs)(n.p,{children:["We can use the Copy tool via the ",(0,o.jsx)(n.a,{href:"/en/api/config/build-config#copy",children:(0,o.jsx)(n.code,{children:"buildConfig.copy"})})," API, which contains the following two main configurations."]}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsx)(n.li,{children:(0,o.jsx)(n.a,{href:"/en/api/config/build-config#copypatterns",children:(0,o.jsx)(n.code,{children:"patterns"})})}),"\n",(0,o.jsx)(n.li,{children:(0,o.jsx)(n.a,{href:"/en/api/config/build-config#copyoptions",children:(0,o.jsx)(n.code,{children:"options"})})}),"\n"]}),"\n",(0,o.jsxs)(n.h2,{id:"api-description",children:["API Description",(0,o.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#api-description",children:"#"})]}),"\n",(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.code,{children:"copy.patterns"})," is used to find files to be copied and configure the output path."]}),"\n",(0,o.jsxs)(n.p,{children:["The ",(0,o.jsx)(n.code,{children:"patterns.from"})," parameter is used to specify the file or directory to be copied. It accepts either a Glob pattern string or a specific path. A Glob pattern string refers to the ",(0,o.jsx)(n.a,{href:"https://github.com/mrmlnc/fast-glob#pattern-syntax",target:"_blank",rel:"noopener noreferrer",children:"fast-glob pattern syntax"}),". Therefore, we can use it in two ways as follows:"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-ts",children:"export default defineConfig({\n buildConfig: {\n copy: {\n patterns: [\n { from: './index.html', to: '' },\n { from: './*.html', to: '' },\n ],\n },\n },\n});\n"})}),"\n",(0,o.jsxs)(n.p,{children:["The ",(0,o.jsx)(n.code,{children:"patterns.context"})," parameter is generally used in conjunction with ",(0,o.jsx)(n.code,{children:"patterns.from"}),". By default, its value is the same as ",(0,o.jsx)(n.a,{href:"/api/config/build-config#sourcedir",children:(0,o.jsx)(n.code,{children:"buildConfig.sourceDir"})}),". Therefore, we can specify the file ",(0,o.jsx)(n.code,{children:"src/data.json"})," to be copied in the following way:"]}),"\n",(0,o.jsxs)(n.blockquote,{children:["\n",(0,o.jsxs)(n.p,{children:["By default, ",(0,o.jsx)(n.code,{children:"buildConfig.sourceDir"})," is set to ",(0,o.jsx)(n.code,{children:"src"}),"."]}),"\n"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-ts",children:"export default defineConfig({\n buildConfig: {\n copy: {\n patterns: [\n { from: './data.json' to: ''},\n ],\n },\n },\n});\n"})}),"\n",(0,o.jsxs)(n.p,{children:["When the specified file is not in the source code directory, you can modify the ",(0,o.jsx)(n.code,{children:"context"})," configuration. For example, to specify the file ",(0,o.jsx)(n.code,{children:"temp/index.html"})," in the project directory to be copied:"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-ts",children:"import path from 'path';\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",(0,o.jsxs)(n.p,{children:["The ",(0,o.jsx)(n.code,{children:"patterns.to"})," parameter is used to specify the output path for the copied files. By default, its value corresponds to ",(0,o.jsx)(n.a,{href:"/api/config/build-config#outdir",children:"buildConfig.outDir"}),". Therefore, we can copy ",(0,o.jsx)(n.code,{children:"src/index.html"})," to the ",(0,o.jsx)(n.code,{children:"dist"})," directory as follows:"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-ts",children:"export default defineConfig({\n buildConfig: {\n copy: {\n patterns: [{ from: './index.html' }],\n },\n },\n});\n"})}),"\n",(0,o.jsxs)(n.p,{children:["When we configure ",(0,o.jsx)(n.code,{children:"patterns.to"}),":"]}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["If it is a relative path, the path will be calculated relative to ",(0,o.jsx)(n.code,{children:"buildConfig.outDir"})," to determine the absolute path for copying the files."]}),"\n",(0,o.jsx)(n.li,{children:"If it is an absolute path, the value will be used directly."}),"\n"]}),"\n",(0,o.jsxs)(n.p,{children:["Finally, ",(0,o.jsx)(n.code,{children:"patterns.globOptions"})," is used to configure the ",(0,o.jsx)(n.a,{href:"https://github.com/sindresorhus/globby",target:"_blank",rel:"noopener noreferrer",children:"globby"})," object for finding files to copy. Its configuration can be referenced from:"]}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsx)(n.li,{children:(0,o.jsx)(n.a,{href:"https://github.com/sindresorhus/globby#options",target:"_blank",rel:"noopener noreferrer",children:"globby.options"})}),"\n"]}),"\n",(0,o.jsxs)(n.h2,{id:"examples-of-different-scenarios",children:["Examples of Different Scenarios",(0,o.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#examples-of-different-scenarios",children:"#"})]}),"\n",(0,o.jsxs)(n.h3,{id:"copying-files",children:["Copying Files",(0,o.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#copying-files",children:"#"})]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-ts",children:"export 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",(0,o.jsxs)(n.h3,{id:"copying-files-to-a-directory",children:["Copying Files to a Directory",(0,o.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#copying-files-to-a-directory",children:"#"})]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-ts",children:"export 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",(0,o.jsxs)(n.h3,{id:"copying-from-directory-to-directory",children:["Copying from Directory to Directory",(0,o.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#copying-from-directory-to-directory",children:"#"})]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-ts",children:"export 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",(0,o.jsxs)(n.h3,{id:"copying-from-directory-to-file",children:["Copying from Directory to File",(0,o.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#copying-from-directory-to-file",children:"#"})]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-ts",children:"export 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",(0,o.jsxs)(n.h3,{id:"using-glob",children:["Using Glob",(0,o.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#using-glob",children:"#"})]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-ts",children:"export 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"})})]})}function s(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},{wrapper:n}=Object.assign({},(0,t.ah)(),e.components);return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(r,{...e})}):r(e)}let d=s;s.__RSPRESS_PAGE_META={},s.__RSPRESS_PAGE_META["en%2Fguide%2Fadvance%2Fcopy.md"]={toc:[{text:"Understanding the Copy API",id:"understanding-the-copy-api",depth:2},{text:"API Description",id:"api-description",depth:2},{text:"Examples of Different Scenarios",id:"examples-of-different-scenarios",depth:2},{text:"Copying Files",id:"copying-files",depth:3},{text:"Copying Files to a Directory",id:"copying-files-to-a-directory",depth:3},{text:"Copying from Directory to Directory",id:"copying-from-directory-to-directory",depth:3},{text:"Copying from Directory to File",id:"copying-from-directory-to-file",depth:3},{text:"Using Glob",id:"using-glob",depth:3}],title:"Use the Copy Tools",frontmatter:{sidebar_position:3}}}}]);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";(self.webpackChunk_modern_js_module_tools_docs=self.webpackChunk_modern_js_module_tools_docs||[]).push([["1527"],{7774:function(e,n,s){s.r(n),s.d(n,{default:function(){return t}});var i=s(8093),r=s(5878);function d(e){let n=Object.assign({h1:"h1",a:"a",p:"p",code:"code",h2:"h2",pre:"pre",h3:"h3",div:"div",ul:"ul",li:"li"},(0,r.ah)(),e.components);return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsxs)(n.h1,{id:"setup-函数",children:["Setup 函数",(0,i.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#setup-函数",children:"#"})]}),"\n",(0,i.jsxs)(n.p,{children:["在",(0,i.jsx)(n.a,{href:"/plugins/guide/plugin-object",children:"「插件对象」"})," 部分我们知道插件对象包含了一个 ",(0,i.jsx)(n.code,{children:"setup"})," 函数,该函数不仅包含了一个 ",(0,i.jsx)(n.code,{children:"api"})," 对象参数,同时还可以返回一个 Hooks 对象。"]}),"\n",(0,i.jsxs)(n.h2,{id:"插件-api-对象",children:["插件 API 对象",(0,i.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#插件-api-对象",children:"#"})]}),"\n",(0,i.jsxs)(n.p,{children:["插件的 ",(0,i.jsx)(n.code,{children:"setup"})," 函数会提供一个 ",(0,i.jsx)(n.code,{children:"api"})," 对象参数,你可以调用该对象上提供的一些方法来获取到配置、项目上下文等信息。"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-ts",children:"export const myPlugin = (): CliPlugin<ModuleTools> => ({\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",(0,i.jsxs)(n.h3,{id:"apiuseappcontext",children:[(0,i.jsx)(n.code,{children:"api.useAppContext"}),(0,i.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#apiuseappcontext",children:"#"})]}),"\n",(0,i.jsx)(n.p,{children:"用于获取项目上下文信息。"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-ts",children:"const useAppContext: () => IAppContext;\n\ninterface IAppContext {\n appDirectory: string;\n configFile: string | false;\n packageName: string;\n nodeModulesDirectory: string;\n internalDirectory: string;\n plugins: {\n cli?: any;\n server?: any;\n }[];\n}\n"})}),"\n",(0,i.jsxs)(n.div,{className:"rspress-directive info",children:[(0,i.jsx)(n.div,{className:"rspress-directive-title",children:"INFO"}),(0,i.jsx)(n.div,{className:"rspress-directive-content",children:(0,i.jsx)(n.p,{children:"通过实际的类型文件,我们可以看到还存在一些其他字段,不过目前对于 Modern.js Module 有意义的字段只有以上内容,api 对象其他的方法也是如此。"})})]}),"\n",(0,i.jsxs)(n.h3,{id:"apiuseresolvedconfigcontext",children:[(0,i.jsx)(n.code,{children:"api.useResolvedConfigContext"}),(0,i.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#apiuseresolvedconfigcontext",children:"#"})]}),"\n",(0,i.jsx)(n.p,{children:"用于获取解析之后的最终配置。"}),"\n",(0,i.jsxs)(n.div,{className:"rspress-directive info",children:[(0,i.jsx)(n.div,{className:"rspress-directive-title",children:"INFO"}),(0,i.jsx)(n.div,{className:"rspress-directive-content",children:(0,i.jsxs)(n.p,{children:["如果需要获取构建相关的最终配置,需要使用 ",(0,i.jsx)(n.code,{children:"beforeBuild"})," Hook。\n"]})})]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-ts",children:"const useResolvedConfigContext: () => NormalizedConfig;\n\ninterface NormalizedConfig {\n buildConfig: PartialBuildConfig;\n buildPreset: BuildPreset;\n dev: Dev;\n plugins: PluginConfig;\n runtime: RuntimeConfig;\n runtimeByEntries?: RuntimeByEntriesConfig;\n _raw: UserConfig;\n}\n"})}),"\n",(0,i.jsxs)(n.h3,{id:"apiusehookrunners",children:[(0,i.jsx)(n.code,{children:"api.useHookRunners"}),(0,i.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#apiusehookrunners",children:"#"})]}),"\n",(0,i.jsx)(n.p,{children:"用于获取 Hooks 的执行器,并触发特定的 Hook 执行。"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-ts",children:"import type { CliPlugin } from '@modern-js/core';\n\nexport const myPlugin = (): CliPlugin => ({\n name: 'my-plugin',\n\n async setup(api) {\n const hookRunners = api.useHookRunners();\n // 触发 afterBuild Hook\n await hookRunners.afterBuild();\n },\n});\n"})}),"\n",(0,i.jsxs)(n.h2,{id:"异步-setup",children:["异步 setup",(0,i.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#异步-setup",children:"#"})]}),"\n",(0,i.jsx)(n.p,{children:"CLI 插件的 setup 可以是一个异步函数,在初始化过程中执行异步逻辑。"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-ts",children:"export const myPlugin = (): CliPlugin<ModuleTools> => ({\n name: 'my-plugin',\n\n async setup(api) {\n await doSomething();\n },\n});\n"})}),"\n",(0,i.jsx)(n.p,{children:"注意,只有当前插件的 setup 异步函数执行完毕,才会继续执行下一个插件的 setup 函数。因此,你需要避免在 setup 函数中进行耗时过长的异步操作,防止影响 CLI 启动性能。"}),"\n",(0,i.jsxs)(n.h2,{id:"生命周期钩子",children:["生命周期钩子",(0,i.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#生命周期钩子",children:"#"})]}),"\n",(0,i.jsxs)(n.p,{children:["我们知道 ",(0,i.jsx)(n.code,{children:"setup"})," 函数会返回一个 Hooks 对象,所谓 Hooks 对象也可以理解是具有 Modern.js Module 生命周期钩子的对象。"]}),"\n",(0,i.jsx)(n.p,{children:"目前主要包含两类钩子:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["构建钩子:仅在执行 ",(0,i.jsx)(n.code,{children:"build"})," 命令构建源码产物时触发。"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"buildPlatform"})," 钩子:仅在执行 ",(0,i.jsx)(n.code,{children:"build --platform"})," 命令生成其他构建产物时触发。"]}),"\n",(0,i.jsxs)(n.li,{children:["调试钩子:运行 ",(0,i.jsx)(n.code,{children:"dev"})," 命令时会触发的钩子。"]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["关于生命周期钩子的完整列表参考 ",(0,i.jsx)(n.a,{href:"/api/plugin-api/plugin-hooks",children:"API 文档"}),"。"]})]})}function o(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},{wrapper:n}=Object.assign({},(0,r.ah)(),e.components);return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}let t=o;o.__RSPRESS_PAGE_META={},o.__RSPRESS_PAGE_META["zh%2Fplugins%2Fguide%2Fsetup-function.mdx"]={toc:[{text:"插件 API 对象",id:"插件-api-对象",depth:2},{text:"`api.useAppContext`",id:"apiuseappcontext",depth:3},{text:"`api.useResolvedConfigContext`",id:"apiuseresolvedconfigcontext",depth:3},{text:"`api.useHookRunners`",id:"apiusehookrunners",depth:3},{text:"异步 setup",id:"异步-setup",depth:2},{text:"生命周期钩子",id:"生命周期钩子",depth:2}],title:"Setup 函数",frontmatter:{sidebar_position:3}}}}]);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";(self.webpackChunk_modern_js_module_tools_docs=self.webpackChunk_modern_js_module_tools_docs||[]).push([["1657"],{830:function(e,n,r){r.r(n),r.d(n,{default:function(){return d}});var s=r(8093),i=r(5878);function l(e){let n=Object.assign({h1:"h1",a:"a",p:"p",ul:"ul",li:"li",code:"code",h2:"h2",h3:"h3",pre:"pre",blockquote:"blockquote"},(0,i.ah)(),e.components);return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsxs)(n.h1,{id:"plugin-hooks",children:["Plugin Hooks",(0,s.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#plugin-hooks",children:"#"})]}),"\n",(0,s.jsx)(n.p,{children:"This chapter describes the lifecycle hooks supported by module-tools."}),"\n",(0,s.jsx)(n.p,{children:"Currently there are following main types of lifecycle hooks."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Config hooks: change user config."}),"\n",(0,s.jsxs)(n.li,{children:["Build hooks: triggered only when the ",(0,s.jsx)(n.code,{children:"build"})," command is executed to build the source code product."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"buildPlatform"})," hook: triggered only when the ",(0,s.jsx)(n.code,{children:"build --platform"})," command is executed to generate other build artifacts."]}),"\n",(0,s.jsxs)(n.li,{children:["dev hooks: hooks that are triggered when running the ",(0,s.jsx)(n.code,{children:"dev"})," command."]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"https://modernjs.dev/guides/topic-detail/framework-plugin/hook.html",target:"_blank",rel:"noopener noreferrer",children:"Hook Model"})," is explained in detail here."]}),"\n",(0,s.jsxs)(n.h2,{id:"config-hooks",children:["Config hooks",(0,s.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#config-hooks",children:"#"})]}),"\n",(0,s.jsxs)(n.h3,{id:"resolvemoduleuserconfig",children:[(0,s.jsx)(n.code,{children:"resolveModuleUserConfig"}),(0,s.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#resolvemoduleuserconfig",children:"#"})]}),"\n",(0,s.jsx)(n.p,{children:"chang user config."}),"\n",(0,s.jsxs)(n.p,{children:["type: ",(0,s.jsx)(n.code,{children:"AsyncWaterfall"})]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ts",children:"export const myPlugin = (): CliPlugin<ModuleTools> => ({\n name: 'my-plugin',\n\n setup() {\n return {\n resolveModuleUserConfig(config: ModuleUserConfig): ModuleUserConfig {},\n };\n },\n});\n"})}),"\n",(0,s.jsxs)(n.h2,{id:"build-hooks",children:["build hooks",(0,s.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#build-hooks",children:"#"})]}),"\n",(0,s.jsxs)(n.p,{children:["The following Hooks are triggered in order when the ",(0,s.jsx)(n.code,{children:"build"})," command is executed."]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"beforeBuild"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"beforeBuildTask"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"afterBuildTask"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"afterBuild"})}),"\n"]}),"\n",(0,s.jsxs)(n.h3,{id:"beforebuild",children:[(0,s.jsx)(n.code,{children:"beforeBuild"}),(0,s.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#beforebuild",children:"#"})]}),"\n",(0,s.jsx)(n.p,{children:"Triggered before the execution of the overall build process."}),"\n",(0,s.jsxs)(n.p,{children:["type: ",(0,s.jsx)(n.code,{children:"ParallelWorkflow"})]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ts",children:"export const myPlugin = (): CliPlugin<ModuleTools> => ({\n name: 'my-plugin',\n\n setup() {\n return {\n beforeBuild(options: Options): void {},\n };\n },\n});\n"})}),"\n",(0,s.jsx)(n.p,{children:"Parameters value types."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ts",children:"type Options = {\n options: { config: BaseBuildConfig[]; cliOptions: BuildCommandOptions };\n};\n\nexport interface BuildCommandOptions {\n config: string;\n clear?: boolean;\n dts?: boolean;\n platform?: boolean | string[];\n tsconfig: string;\n watch?: boolean;\n}\n"})}),"\n",(0,s.jsxs)(n.blockquote,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"BuildConfig"})," type reference ",(0,s.jsx)(n.a,{href:"/en/api/",children:"API configuration"})]}),"\n"]}),"\n",(0,s.jsxs)(n.h3,{id:"beforebuildtask",children:[(0,s.jsx)(n.code,{children:"beforeBuildTask"}),(0,s.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#beforebuildtask",children:"#"})]}),"\n",(0,s.jsx)(n.p,{children:"Based on the build configuration, Modern.js Module will split the overall build into multiple sub-build tasks. The Hook will be triggered before each build subtask."}),"\n",(0,s.jsxs)(n.p,{children:["type: ",(0,s.jsx)(n.code,{children:"AsyncWaterfall"})]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ts",children:"export const myPlugin = (): CliPlugin<ModuleTools> => ({\n name: 'my-plugin',\n\n setup() {\n return {\n beforeBuildTask(config: BaseBuildConfig): BaseBuildConfig {\n return config;\n },\n };\n },\n});\n"})}),"\n",(0,s.jsx)(n.p,{children:"Parameters and return value types."}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"BaseBuildConfig"})," type reference ",(0,s.jsx)(n.a,{href:"/en/api/",children:"API configuration"})]}),"\n",(0,s.jsxs)(n.h3,{id:"afterbuildtask",children:[(0,s.jsx)(n.code,{children:"afterBuildTask"}),(0,s.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#afterbuildtask",children:"#"})]}),"\n",(0,s.jsx)(n.p,{children:"Triggered after the end of each build subtask."}),"\n",(0,s.jsxs)(n.p,{children:["type: ",(0,s.jsx)(n.code,{children:"ParallelWorkflow"})]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ts",children:"export const myPlugin = (): CliPlugin<ModuleTools> => ({\n name: 'my-plugin',\n\n setup() {\n return {\n afterBuildTask(options: BuildTaskResult): void {\n // ...\n },\n };\n },\n});\n"})}),"\n",(0,s.jsx)(n.p,{children:"Parameters and return value types."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ts",children:"export interface BuildTaskResult {\n status: 'success' | 'fail';\n message?: string;\n config: BaseBuildConfig;\n}\n"})}),"\n",(0,s.jsxs)(n.h3,{id:"afterbuild",children:[(0,s.jsx)(n.code,{children:"afterBuild"}),(0,s.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#afterbuild",children:"#"})]}),"\n",(0,s.jsx)(n.p,{children:"Triggered after the end of the overall build process."}),"\n",(0,s.jsxs)(n.p,{children:["type: ",(0,s.jsx)(n.code,{children:"ParallelWorkflow"})]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ts",children:"export const myPlugin = (): CliPlugin<ModuleTools> => ({\n name: 'my-plugin',\n\n setup() {\n return {\n afterBuild(options: BuildResult): void {\n // ...\n },\n };\n },\n});\n"})}),"\n",(0,s.jsx)(n.p,{children:"Parameters and return value types."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ts",children:"export interface BuildResult {\n status: 'success' | 'fail';\n message?: string;\n config: BuildConfig;\n commandOptions: BuildCommandOptions;\n totalDuration: number;\n}\n"})}),"\n",(0,s.jsxs)(n.h2,{id:"buildplatform-hooks",children:["buildPlatform hooks",(0,s.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#buildplatform-hooks",children:"#"})]}),"\n",(0,s.jsxs)(n.p,{children:["module-tools also provides the ",(0,s.jsx)(n.code,{children:"build --platform"})," command to perform specific build tasks."]}),"\n",(0,s.jsxs)(n.p,{children:["For example, after installing the Module Doc plugin, you can run ",(0,s.jsx)(n.code,{children:"build --platform"})," or ",(0,s.jsx)(n.code,{children:"build --platform doc"})," to perform Doc build tasks."]}),"\n",(0,s.jsxs)(n.p,{children:["Hooks are triggered in the following order after executing ",(0,s.jsx)(n.code,{children:"build --platform"}),"."]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"registerBuildPlatform"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"beforeBuildPlatform"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"buildPlatform"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"afterBuildPlatform"})}),"\n"]}),"\n",(0,s.jsxs)(n.h3,{id:"registerbuildplatform",children:[(0,s.jsx)(n.code,{children:"registerBuildPlatform"}),(0,s.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#registerbuildplatform",children:"#"})]}),"\n",(0,s.jsxs)(n.p,{children:["Gets information about the tasks that need to be run when executing the ",(0,s.jsx)(n.code,{children:"build --platform"})," command."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ts",children:"export const myPlugin = (): CliPlugin<ModuleTools> => ({\n name: 'my-plugin',\n\n setup() {\n return {\n registerBuildPlatform(): RegisterBuildPlatformResult {\n // ...\n return {\n platform: 'doc',\n build() {\n // logic\n },\n }, };\n },\n };\n },\n});\n"})}),"\n",(0,s.jsx)(n.p,{children:"Types of parameters entered and returned."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ts",children:"export interface RegisterBuildPlatformResult {\n platform: string | string[];\n build: (\n currentPlatform: string, // the currently running platform build task\n context: { isTsProject: boolean },\n ) => void | Promise<void>;\n}\n"})}),"\n",(0,s.jsxs)(n.h3,{id:"beforebuildplatform",children:[(0,s.jsx)(n.code,{children:"beforeBuildPlatform"}),(0,s.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#beforebuildplatform",children:"#"})]}),"\n",(0,s.jsxs)(n.p,{children:["Triggers all registered build tasks when the ",(0,s.jsx)(n.code,{children:"build --platform"})," command is executed. ",(0,s.jsx)(n.code,{children:"beforeBuildPlatform"})," will be triggered before the execution of the overall build task."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ts",children:"export const myPlugin = (): CliPlugin<ModuleTools> => ({\n name: 'my-plugin',\n\n setup() {\n return {\n beforeBuildPlatform(platforms: RegisterBuildPlatformResult[]): void {\n console.info(`have ${platforms.length} platform tasks`);\n },\n };\n },\n});\n"})}),"\n",(0,s.jsx)(n.p,{children:"Types of parameters entered and returned."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ts",children:"export interface RegisterBuildPlatformResult {\n platform: string | string[];\n build: (\n currentPlatform: string, // the currently running platform build task\n context: { isTsProject: boolean },\n ) => void | Promise<void>;\n}\n"})}),"\n",(0,s.jsxs)(n.h3,{id:"buildplatform",children:[(0,s.jsx)(n.code,{children:"buildPlatform"}),(0,s.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#buildplatform",children:"#"})]}),"\n",(0,s.jsxs)(n.p,{children:["When the ",(0,s.jsx)(n.code,{children:"build --platform"})," command is executed, all registered build tasks will be triggered. ",(0,s.jsx)(n.code,{children:"buildPlatform"})," will be triggered before each build task is executed."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ts",children:"export const myPlugin = (): CliPlugin<ModuleTools> => ({\n name: 'my-plugin',\n\n setup() {\n return {\n buildPlatform({ platform }: Options): void {\n console.info(`current task is ${platform}`);\n },\n };\n },\n});\n"})}),"\n",(0,s.jsx)(n.p,{children:"Types of parameters entered and returned."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ts",children:"export interface Options {\n platform: string;\n}\n"})}),"\n",(0,s.jsxs)(n.h3,{id:"afterbuildplatform",children:[(0,s.jsx)(n.code,{children:"afterBuildPlatform"}),(0,s.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#afterbuildplatform",children:"#"})]}),"\n",(0,s.jsxs)(n.p,{children:["When the ",(0,s.jsx)(n.code,{children:"build --platform"})," command is executed, all registered build tasks will be triggered. ",(0,s.jsx)(n.code,{children:"afterBuildPlatform"})," will be triggered after the overall platform build task is finished."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ts",children:"export const myPlugin = (): CliPlugin<ModuleTools> => ({\n name: 'my-plugin',\n\n setup() {\n return {\n afterBuildPlatform(result: BuildPlatformResult): void {\n if (result.status === 'success') {\n console.info(`all platform build task success`);\n } else {\n console.error(result.message);\n }\n },\n };\n },\n});\n"})}),"\n",(0,s.jsx)(n.p,{children:"Types of parameters entered and returned."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ts",children:"export interface BuildPlatformResult {\n status: 'success' | 'fail';\n message: string | Error | null;\n}\n"})}),"\n",(0,s.jsxs)(n.h2,{id:"dev-hooks",children:["Dev Hooks",(0,s.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#dev-hooks",children:"#"})]}),"\n",(0,s.jsxs)(n.p,{children:["The following Hooks are triggered in order when the ",(0,s.jsx)(n.code,{children:"dev"})," command is executed."]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"registerDev"}),": triggered when getting dev function information."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"beforeDev"}),": Triggered before starting the dev process as a whole."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"beforeDevMenu"}),": triggered before the dev list/menu appears."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"afterDevMenu"}),": triggered after dev list/menu option is selected."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"beforeDevTask"}),": Triggered before executing the dev task."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"afterDev"}),": Triggered at the end of the overall dev process."]}),"\n"]}),"\n",(0,s.jsxs)(n.h3,{id:"registerdev",children:[(0,s.jsx)(n.code,{children:"registerDev"}),(0,s.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#registerdev",children:"#"})]}),"\n",(0,s.jsx)(n.p,{children:"Register dev tool related data. Mainly contains."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"the name of the dev tool"}),"\n",(0,s.jsx)(n.li,{children:"The name of the item displayed in the menu list and the corresponding value."}),"\n",(0,s.jsxs)(n.li,{children:["The definition of the ",(0,s.jsx)(n.code,{children:"dev"})," subcommand."]}),"\n",(0,s.jsx)(n.li,{children:"Whether to execute the source code build before running the dev task"}),"\n",(0,s.jsx)(n.li,{children:"The function to execute the dev task."}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ts",children:"export const myPlugin = (): CliPlugin<ModuleTools> => ({\n name: 'my-plugin',\n\n setup() {\n return {\n registerDev() {\n return {\n // Dev tool name\n name: 'storybook',\n // Menu content\n menuItem: {\n name: 'Storybook',\n value: 'storybook',\n },\n // Defined dev subcommands\n subCommands: ['storybook', 'story'],\n async action() {\n // dev logic\n },\n };\n },\n };\n },\n});\n"})}),"\n",(0,s.jsx)(n.p,{children:"Types of parameters entered and returned."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ts",children:"export interface DevToolData {\n name: string;\n subCommands?: string[];\n menuItem?: {\n name: string;\n value: string;\n };\n action: (\n options: { port?: string },\n context: { isTsProject?: boolean },\n ) => void | Promise<void>;\n}\n"})}),"\n",(0,s.jsxs)(n.h3,{id:"beforedev",children:[(0,s.jsx)(n.code,{children:"beforeDev"}),(0,s.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#beforedev",children:"#"})]}),"\n",(0,s.jsx)(n.p,{children:"Triggered before the dev task is executed after all dev tool metadata has been collected."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ts",children:"export const myPlugin = (): CliPlugin<ModuleTools> => ({\n name: 'my-plugin',\n\n setup() {\n return {\n beforeDev(metas: DevToolData[]) {\n console.info(`have ${metas.length} dev tools`);\n },\n };\n },\n});\n"})}),"\n",(0,s.jsx)(n.p,{children:"Types of parameters entered and returned."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ts",children:"export interface DevToolData {\n name: string;\n subCommands?: string[];\n menuItem?: {\n name: string;\n value: string;\n };\n action: (\n options: { port?: string },\n context: { isTsProject?: boolean },\n ) => void | Promise<void>;\n}\n"})}),"\n",(0,s.jsxs)(n.h3,{id:"beforeafterdevmenu",children:[(0,s.jsx)(n.code,{children:"(before|after)DevMenu"}),(0,s.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#beforeafterdevmenu",children:"#"})]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"beforeDevMenu"})," is triggered before the dev list/menu appears. Receives ",(0,s.jsx)(n.a,{href:"https://github.com/SBoudrias/Inquirer.js#question",target:"_blank",rel:"noopener noreferrer",children:"inquirer question"})," as argument. Default value is."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ts",children:"const question = [\n {\n name: 'choiceDevTool',\n message: 'Select dev tool',\n type: 'list',\n // Registered dev messages\n choices,\n },\n];\n"})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"afterDevMenu"})," Triggered after selecting dev list/menu options."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ts",children:"export const myPlugin = (): CliPlugin<ModuleTools> => ({\n name: 'my-plugin',\n\n setup() {\n return {\n beforeDevMenu(questions) {\n questions[0].message += '!';\n return questions; // required\n },\n afterDevMenu(options: Options) {\n console.info(`choise ${options.result.choiceDevTool} dev tools`);\n },\n };\n },\n});\n"})}),"\n",(0,s.jsx)(n.p,{children:"Types of parameters entered and returned."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ts",children:"export type { QuestionCollection } from 'inquirer';\n\nexport interface Options {\n result: PromptResult;\n devTools: DevToolData[];\n}\n\nexport type PromptResult = { choiceDevTool: string };\nexport interface DevToolData {\n name: string;\n subCommands?: string[];\n menuItem?: {\n name: string;\n value: string;\n };\n action: (\n options: { port?: string },\n context: { isTsProject?: boolean },\n ) => void | Promise<void>;\n}\n"})}),"\n",(0,s.jsxs)(n.h3,{id:"beforedevtask",children:[(0,s.jsx)(n.code,{children:"beforeDevTask"}),(0,s.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#beforedevtask",children:"#"})]}),"\n",(0,s.jsx)(n.p,{children:"Triggered before the dev task is executed."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ts",children:"export const myPlugin = (): CliPlugin<ModuleTools> => ({\n name: 'my-plugin',\n\n setup() {\n return {\n beforeDevTask(currentDevData: DevToolData) {\n console.info(`${currentDevData.name} running`);\n },\n };\n },\n});\n"})}),"\n",(0,s.jsx)(n.p,{children:"Types of parameters entered and returned."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ts",children:"export interface DevToolData {\n name: string;\n subCommands?: string[];\n menuItem?: {\n name: string;\n value: string;\n };\n action: (\n options: { port?: string },\n context: { isTsProject?: boolean },\n ) => void | Promise<void>;\n}\n"})}),"\n",(0,s.jsxs)(n.h3,{id:"afterdev",children:[(0,s.jsx)(n.code,{children:"afterDev"}),(0,s.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#afterdev",children:"#"})]}),"\n",(0,s.jsx)(n.p,{children:"Triggered when the dev task process is interrupted."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ts",children:"export const myPlugin = (): CliPlugin<ModuleTools> => ({\n name: 'my-plugin',\n\n setup() {\n return {\n afterDev() {\n console.info(`exit!`);\n },\n };\n },\n});\n"})})]})}function o(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},{wrapper:n}=Object.assign({},(0,i.ah)(),e.components);return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}let d=o;o.__RSPRESS_PAGE_META={},o.__RSPRESS_PAGE_META["en%2Fapi%2Fplugin-api%2Fplugin-hooks.md"]={toc:[{text:"Config hooks",id:"config-hooks",depth:2},{text:"`resolveModuleUserConfig`",id:"resolvemoduleuserconfig",depth:3},{text:"build hooks",id:"build-hooks",depth:2},{text:"`beforeBuild`",id:"beforebuild",depth:3},{text:"`beforeBuildTask`",id:"beforebuildtask",depth:3},{text:"`afterBuildTask`",id:"afterbuildtask",depth:3},{text:"`afterBuild`",id:"afterbuild",depth:3},{text:"buildPlatform hooks",id:"buildplatform-hooks",depth:2},{text:"`registerBuildPlatform`",id:"registerbuildplatform",depth:3},{text:"`beforeBuildPlatform`",id:"beforebuildplatform",depth:3},{text:"`buildPlatform`",id:"buildplatform",depth:3},{text:"`afterBuildPlatform`",id:"afterbuildplatform",depth:3},{text:"Dev Hooks",id:"dev-hooks",depth:2},{text:"`registerDev`",id:"registerdev",depth:3},{text:"`beforeDev`",id:"beforedev",depth:3},{text:"`(before|after)DevMenu`",id:"beforeafterdevmenu",depth:3},{text:"`beforeDevTask`",id:"beforedevtask",depth:3},{text:"`afterDev`",id:"afterdev",depth:3}],title:"Plugin Hooks",frontmatter:{}}}}]);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";(self.webpackChunk_modern_js_module_tools_docs=self.webpackChunk_modern_js_module_tools_docs||[]).push([["1801"],{6452:function(e,d,r){r.r(d),r.d(d,{default:function(){return i}});var n=r(8093),s=r(5878);function l(e){let d=Object.assign({h1:"h1",a:"a",h2:"h2",p:"p"},(0,s.ah)(),e.components);return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsxs)(d.h1,{id:"通用类问题",children:["通用类问题",(0,n.jsx)(d.a,{className:"header-anchor","aria-hidden":"true",href:"#通用类问题",children:"#"})]}),"\n",(0,n.jsxs)(d.h2,{id:"modernjs-module-和-rsbuild-的关系",children:["Modern.js Module 和 Rsbuild 的关系?",(0,n.jsx)(d.a,{className:"header-anchor","aria-hidden":"true",href:"#modernjs-module-和-rsbuild-的关系",children:"#"})]}),"\n",(0,n.jsx)(d.p,{children:"Modern.js Module 使用 esbuild 构建工具库和组件库,Rsbuild 专注于解决 Web 应用构建场景。"}),"\n",(0,n.jsxs)(d.h2,{id:"modernjs-module-是否可以使用-webpack-plugin-或者-loader",children:["Modern.js Module 是否可以使用 webpack plugin 或者 loader?",(0,n.jsx)(d.a,{className:"header-anchor","aria-hidden":"true",href:"#modernjs-module-是否可以使用-webpack-plugin-或者-loader",children:"#"})]}),"\n",(0,n.jsxs)(d.p,{children:["Modern.js Module 基于 esbuild 构建,无法使用 webpack 相关生态的工具。\n",(0,n.jsx)(d.a,{href:"https://github.com/esbuild/community-plugins",target:"_blank",rel:"noopener noreferrer",children:"这里"}),"可以发现更多 esbuild 社区插件"]}),"\n",(0,n.jsxs)(d.p,{children:["如果 Modern.js Module 生产的 UMD 产物达不到你的要求,可以使用 Rsbuild 并添加 ",(0,n.jsx)(d.a,{href:"https://github.com/rspack-contrib/rsbuild-plugin-umd",target:"_blank",rel:"noopener noreferrer",children:"UMD Plugin"})," 构建 UMD 产物。"]})]})}function o(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},{wrapper:d}=Object.assign({},(0,s.ah)(),e.components);return d?(0,n.jsx)(d,{...e,children:(0,n.jsx)(l,{...e})}):l(e)}let i=o;o.__RSPRESS_PAGE_META={},o.__RSPRESS_PAGE_META["zh%2Fguide%2Ffaq%2Fbasic.mdx"]={toc:[{text:"Modern.js Module 和 Rsbuild 的关系?",id:"modernjs-module-和-rsbuild-的关系",depth:2},{text:"Modern.js Module 是否可以使用 webpack plugin 或者 loader?",id:"modernjs-module-是否可以使用-webpack-plugin-或者-loader",depth:2}],title:"通用类问题",frontmatter:{}}}}]);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";(self.webpackChunk_modern_js_module_tools_docs=self.webpackChunk_modern_js_module_tools_docs||[]).push([["1941"],{8573:function(e,t,n){n.r(t),n.d(t,{default:function(){return c}});var o=n(8093),s=n(5878);function r(e){return(0,o.jsx)(o.Fragment,{})}function _(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},{wrapper:t}=Object.assign({},(0,s.ah)(),e.components);return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(r,{...e})}):r(e)}let c=_;_.__RSPRESS_PAGE_META={},_.__RSPRESS_PAGE_META["zh%2Fcomponents%2Frelease-module-doc.mdx"]={toc:[],title:"",frontmatter:{}}}}]);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";(self.webpackChunk_modern_js_module_tools_docs=self.webpackChunk_modern_js_module_tools_docs||[]).push([["213"],{1513:function(e,n,d){d.r(n),d.d(n,{default:function(){return l}});var s=d(8093),c=d(5878);function i(e){let n=Object.assign({h1:"h1",a:"a",p:"p",code:"code",pre:"pre",h2:"h2",strong:"strong",h3:"h3",ul:"ul",li:"li",blockquote:"blockquote"},(0,c.ah)(),e.components);return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsxs)(n.h1,{id:"处理三方依赖",children:["处理三方依赖",(0,s.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#处理三方依赖",children:"#"})]}),"\n",(0,s.jsxs)(n.p,{children:["一般来说,项目所需要的第三方依赖可以通过包管理器的 ",(0,s.jsx)(n.code,{children:"install"})," 命令安装,在安装第三方依赖成功后,这些第三方依赖一般会出现在项目 ",(0,s.jsx)(n.code,{children:"package.json"})," 的 ",(0,s.jsx)(n.code,{children:"dependencies"})," 和 ",(0,s.jsx)(n.code,{children:"devDependencies"})," 下。"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",meta:'title="pacakge.json"',children:'{\n "dependencies": {},\n "devDependencies": {}\n}\n'})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:'"dependencies"'})," 下的依赖通常来说是这个包运行所需的依赖, ",(0,s.jsx)(n.code,{children:'"devDependencies"'})," 则代表着开发依赖。"]}),"\n",(0,s.jsxs)(n.p,{children:["除了 ",(0,s.jsx)(n.code,{children:'"dependencies"'})," 以外,",(0,s.jsx)(n.a,{href:"/guide/basic/before-getting-started#peerdependencies",children:(0,s.jsx)(n.code,{children:'"peerDependencies"'})})," 也可以声明在生产环境下运行所需要的依赖,此时会和它的宿主共享一份依赖。"]}),"\n",(0,s.jsxs)(n.h2,{id:"第三方依赖的默认处理",children:["第三方依赖的默认处理",(0,s.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#第三方依赖的默认处理",children:"#"})]}),"\n",(0,s.jsxs)(n.p,{children:["在 Modern.js Module 里,",(0,s.jsxs)(n.strong,{children:["默认情况下不会对 ",(0,s.jsx)(n.code,{children:'"dependencies"'})," 以及 ",(0,s.jsx)(n.code,{children:'"peerDependencies"'})," 下的第三方依赖进行打包处理"]}),"。"]}),"\n",(0,s.jsxs)(n.p,{children:["这是因为在安装 npm 包时,其 ",(0,s.jsx)(n.code,{children:'"dependencies"'})," 也会被安装。不打包 ",(0,s.jsx)(n.code,{children:'"dependencies"'}),",可以减小包产物的体积。"]}),"\n",(0,s.jsxs)(n.p,{children:["如果需要打包某些依赖,建议将它们从 ",(0,s.jsx)(n.code,{children:'"dependencies"'})," 挪到 ",(0,s.jsx)(n.code,{children:'"devDependencies"'})," ,这相当于对依赖进行 ",(0,s.jsx)(n.strong,{children:"prebundle"})," ,可以减小依赖安装的体积。"]}),"\n",(0,s.jsxs)(n.h3,{id:"示例",children:["示例",(0,s.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#示例",children:"#"})]}),"\n",(0,s.jsxs)(n.p,{children:["如果项目依赖了 ",(0,s.jsx)(n.code,{children:"react"}),":"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",meta:'title="package.json"',children:'{\n "dependencies": {\n "react": "^17"\n },\n // or\n "peerDependencies": {\n "react": "^17"\n }\n}\n'})}),"\n",(0,s.jsxs)(n.p,{children:["当源码中使用了 ",(0,s.jsx)(n.code,{children:"react"})," 依赖:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-tsx",meta:'title="src/index.ts"',children:"import React from 'react';\nconsole.info(React);\n"})}),"\n",(0,s.jsxs)(n.p,{children:["此时产物中不会包含 ",(0,s.jsx)(n.code,{children:"react"})," 的代码:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-js",meta:'title="dist/index.js"',children:"import React from 'react';\nconsole.info(React);\n"})}),"\n",(0,s.jsx)(n.p,{children:"如果想要修改默认的处理方式,可以通过下面的 API 进行修改:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"/api/config/build-config#autoexternal",children:(0,s.jsx)(n.code,{children:"buildConfig.autoExternal"})})}),"\n"]}),"\n",(0,s.jsxs)(n.h2,{id:"排除指定第三方依赖",children:["排除指定第三方依赖",(0,s.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#排除指定第三方依赖",children:"#"})]}),"\n",(0,s.jsxs)(n.p,{children:["在上面我们提到了 ",(0,s.jsx)(n.code,{children:"buildConfig.autoExternal"})," API 的用途,同时 ",(0,s.jsx)(n.a,{href:"/api/config/build-config#externals",children:(0,s.jsx)(n.code,{children:"buildConfig.externals"})})," 可以实现对三方依赖更细微的处理。"]}),"\n",(0,s.jsx)(n.p,{children:"例如当我们需要仅对某些依赖不进行打包处理的时候,可以按照如下方式进行配置:"}),"\n",(0,s.jsxs)(n.blockquote,{children:["\n",(0,s.jsx)(n.p,{children:"一般这种情况,可能是某些依赖不适合进行打包处理。如果遇到这种情况,则可以按照下面的方式进行处理。"}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ts",children:"epxort default defineConfig({\n buildConfig: {\n autoExternal: false,\n externals: ['pkg-1', /pkg-2/],\n }\n});\n"})})]})}function r(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},{wrapper:n}=Object.assign({},(0,c.ah)(),e.components);return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(i,{...e})}):i(e)}let l=r;r.__RSPRESS_PAGE_META={},r.__RSPRESS_PAGE_META["zh%2Fguide%2Fadvance%2Fexternal-dependency.mdx"]={toc:[{text:"第三方依赖的默认处理",id:"第三方依赖的默认处理",depth:2},{text:"示例",id:"示例",depth:3},{text:"排除指定第三方依赖",id:"排除指定第三方依赖",depth:2}],title:"处理三方依赖",frontmatter:{sidebar_position:4}}}}]);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";(self.webpackChunk_modern_js_module_tools_docs=self.webpackChunk_modern_js_module_tools_docs||[]).push([["2131"],{9019:function(e,n,s){s.r(n),s.d(n,{default:function(){return t}});var i=s(8093),r=s(5878);function d(e){let n=Object.assign({h1:"h1",a:"a",p:"p",code:"code",div:"div",h2:"h2",strong:"strong",ul:"ul",li:"li",pre:"pre",h3:"h3",h4:"h4"},(0,r.ah)(),e.components);return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsxs)(n.h1,{id:"in-depth-understanding-of-build",children:["In-depth understanding of build",(0,i.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#in-depth-understanding-of-build",children:"#"})]}),"\n",(0,i.jsxs)(n.p,{children:['In the "Basic Usage" section, we already knew that you can modify the output files of a project through the ',(0,i.jsx)(n.code,{children:"buildConfig"})," configuration. ",(0,i.jsx)(n.code,{children:"buildConfig"})," not only describes some of the features of the product, but also provides some functionality for building the product."]}),"\n",(0,i.jsxs)(n.div,{className:"rspress-directive tip",children:[(0,i.jsx)(n.div,{className:"rspress-directive-title",children:"TIP"}),(0,i.jsx)(n.div,{className:"rspress-directive-content",children:(0,i.jsxs)(n.p,{children:["If you are not familiar with ",(0,i.jsx)(n.code,{children:"buildConfig"}),", please read ",(0,i.jsx)(n.a,{href:"/en/guide/basic/modify-output-product",children:"modify-output-product"}),".\n"]})})]}),"\n",(0,i.jsxs)(n.p,{children:["In this chapter we'll dive into the use of certain build configurations and understand what happens when the ",(0,i.jsx)(n.code,{children:"modern build"})," command is executed."]}),"\n",(0,i.jsxs)(n.h2,{id:"bundle--bundleless",children:[(0,i.jsx)(n.code,{children:"bundle"})," / ",(0,i.jsx)(n.code,{children:"bundleless"}),(0,i.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#bundle--bundleless",children:"#"})]}),"\n",(0,i.jsx)(n.p,{children:"So first let's understand bundle and bundleless."}),"\n",(0,i.jsxs)(n.p,{children:["A bundle is a package of build artifacts, which may be a single file or multiple files based on a certain ",(0,i.jsx)(n.a,{href:"https://esbuild.github.io/api/#splitting",target:"_blank",rel:"noopener noreferrer",children:"code splitting strategy"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["bundleless, on the other hand, means that each source file is compiled and built separately, but not bundled together. Each output file can be found with its corresponding source code file. The process of ",(0,i.jsx)(n.strong,{children:"bundleless build can also be understood as the process of code conversion of source files only"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"They have their own benefits."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"bundle can reduce the size of build artifacts and also pre-package dependencies to reduce the size of installed dependencies. Packaging libraries in advance can speed up application project builds."}),"\n",(0,i.jsx)(n.li,{children:"bundleless maintains the original file structure and is more conducive to debugging and tree shaking."}),"\n"]}),"\n",(0,i.jsxs)(n.div,{className:"rspress-directive warning",children:[(0,i.jsx)(n.div,{className:"rspress-directive-title",children:"WARNING"}),(0,i.jsx)(n.div,{className:"rspress-directive-content",children:(0,i.jsxs)(n.p,{children:["bundleless is a single-file compilation mode, so for referencing and exporting types, you need to add the ",(0,i.jsx)(n.code,{children:"type"})," keyword. For example, ",(0,i.jsx)(n.code,{children:"import type { A } from './types'"}),". Please refer to the ",(0,i.jsx)(n.a,{href:"https://esbuild.github.io/content-types/#isolated-modules",target:"_blank",rel:"noopener noreferrer",children:"esbuild documentation"})," for more information.\n"]})})]}),"\n",(0,i.jsxs)(n.p,{children:["In ",(0,i.jsx)(n.code,{children:"buildConfig"})," you can specify whether the current build task is bundle or bundleless by using ",(0,i.jsx)(n.a,{href:"/en/api/config/build-config#buildtype",children:(0,i.jsx)(n.code,{children:"buildConfig.buildType"})}),"."]}),"\n",(0,i.jsxs)(n.h2,{id:"input--sourcedir",children:[(0,i.jsx)(n.code,{children:"input"})," / ",(0,i.jsx)(n.code,{children:"sourceDir"}),(0,i.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#input--sourcedir",children:"#"})]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"/api/config/build-config#input",children:(0,i.jsx)(n.code,{children:"buildConfig.input"})})," is used to specify the path to a file or directory from which to read the source code, the default value of which varies between bundle and bundleless builds:"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["When ",(0,i.jsx)(n.code,{children:"buildType: 'bundle'"}),", ",(0,i.jsx)(n.code,{children:"input"})," defaults to ",(0,i.jsx)(n.code,{children:"src/index.(j|t)sx?"}),"."]}),"\n",(0,i.jsxs)(n.li,{children:["When ",(0,i.jsx)(n.code,{children:"buildType: 'bundleless'"}),", ",(0,i.jsx)(n.code,{children:"input"})," defaults to ",(0,i.jsx)(n.code,{children:"['src']"}),"."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["From the default value, we know that ",(0,i.jsx)(n.strong,{children:"building in bundle mode usually specifies one or more files as the entry point for the build, while building in bundleless mode specifies a directory and uses all the files in that directory as the entry point"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"/api/config/build-config#sourcedir",children:(0,i.jsx)(n.code,{children:"sourceDir"})})," is used to specify the source directory, which is ",(0,i.jsx)(n.strong,{children:"only"})," related to the following two elements:"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Type file generation"}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.a,{href:"https://esbuild.github.io/api/#outbase",target:"_blank",rel:"noopener noreferrer",children:(0,i.jsx)(n.code,{children:"outbase"})})," for specifying the build process"]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"So we can get its best practices:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsxs)(n.strong,{children:["Only specify ",(0,i.jsx)(n.code,{children:"input"})," during the bundle build."]})}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsxs)(n.strong,{children:["In general, bundleless only needs to specify ",(0,i.jsx)(n.code,{children:"sourceDir"})," (where ",(0,i.jsx)(n.code,{children:"input"})," will be aligned with ",(0,i.jsx)(n.code,{children:"sourceDir"}),")."]})," If we want to use the ",(0,i.jsx)(n.code,{children:"input"})," in bundleless, we only need to specify ",(0,i.jsx)(n.code,{children:"sourceDir"}),"."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["If you want to convert only some of the files in bundleless, e.g. only the files in the ",(0,i.jsx)(n.code,{children:"src/runtime"})," directory, you need to configure ",(0,i.jsx)(n.code,{children:"input"}),":"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-js",meta:'title="modern.config.ts"',children:"import { defineConfig } from '@modern-js/module-tools';\n\nexport default defineConfig({\n buildConfig: {\n input: ['src/runtime'],\n sourceDir: 'src',\n },\n});\n"})}),"\n",(0,i.jsxs)(n.h2,{id:"use-swc",children:["use swc",(0,i.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#use-swc",children:"#"})]}),"\n",(0,i.jsx)(n.p,{children:"In some scenarios, esbuild is not enough to meet our needs, and we will use swc to do the code conversion."}),"\n",(0,i.jsxs)(n.p,{children:["Starting from version ",(0,i.jsx)(n.strong,{children:"2.36.0"}),", the Modern.js Module will use swc by default when it comes to the following functionality, but that doesn't mean we don't use esbuild any more, the rest of the functionality will still use esbuild."]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"/api/config/build-config#transformimport",children:"transformImport"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"/api/config/build-config#transformlodash",children:"transformLodash"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"/api/config/build-config#externalhelpers",children:"externalHelpers"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"/api/config/build-config#format-umd",children:"format: umd"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"/api/config/build-config#target",children:"target: es5"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"https://www.typescriptlang.org/tsconfig#emitDecoratorMetadata",target:"_blank",rel:"noopener noreferrer",children:"emitDecoratorMetadata: true"})}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["In fact, we've been using swc for full code conversion since version ",(0,i.jsx)(n.strong,{children:"2.16.0"}),". However, swc also has some limitations, so we added ",(0,i.jsx)(n.a,{href:"/api/config/build-config#sourcetype",children:"sourceType"})," to turn off swc when the source is formatted as 'commonjs', which isn't really user-intuitive, and the cjs mode of the swc formatted outputs don't have annotate each export name, which can cause problems in node.\nSo we deprecated this behaviour and went back to the original design - ",(0,i.jsx)(n.strong,{children:"using swc as a supplement only in situations where it was needed"}),"."]}),"\n",(0,i.jsxs)(n.h2,{id:"using-hooks-to-intervene-in-the-build-process",children:["Using Hooks to Intervene in the Build Process",(0,i.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#using-hooks-to-intervene-in-the-build-process",children:"#"})]}),"\n",(0,i.jsxs)(n.p,{children:["The Modern.js Module provides a Hook mechanism that allows us to inject custom logic at different stages of the build process.\nThe Modern.js Module Hook is implemented using ",(0,i.jsx)(n.a,{href:"https://github.com/webpack/tapable",target:"_blank",rel:"noopener noreferrer",children:"tapable"}),", which extends esbuild's plugin mechanism, and is recommended to be used directly if esbuild plugins already meet your needs.\nHere's how to use it:"]}),"\n",(0,i.jsxs)(n.h3,{id:"hook-type",children:["Hook type",(0,i.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#hook-type",children:"#"})]}),"\n",(0,i.jsxs)(n.h4,{id:"asyncseriesbailhook",children:["AsyncSeriesBailHook",(0,i.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#asyncseriesbailhook",children:"#"})]}),"\n",(0,i.jsx)(n.p,{children:"Serial hooks that stop the execution of other tapped functions if a tapped function returns a non-undefined result."}),"\n",(0,i.jsxs)(n.h4,{id:"asyncserieswaterfallhooks",children:["AsyncSeriesWaterFallHooks",(0,i.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#asyncserieswaterfallhooks",children:"#"})]}),"\n",(0,i.jsx)(n.p,{children:"Serial hooks whose results are passed to the next tapped function."}),"\n",(0,i.jsxs)(n.h3,{id:"hook-order",children:["Hook Order",(0,i.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#hook-order",children:"#"})]}),"\n",(0,i.jsxs)(n.p,{children:["The execution order of hooks follows the registration order. You can control whether a hook is registered before or after the built-in hooks using ",(0,i.jsx)(n.code,{children:"applyAfterBuiltIn"}),"."]}),"\n",(0,i.jsxs)(n.h3,{id:"hook-api",children:["Hook API",(0,i.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#hook-api",children:"#"})]}),"\n",(0,i.jsxs)(n.h4,{id:"load",children:["load",(0,i.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#load",children:"#"})]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"AsyncSeriesBailHook"}),"\n",(0,i.jsxs)(n.li,{children:["Triggered at esbuild ",(0,i.jsx)(n.a,{href:"https://esbuild.github.io/plugins/#on-load",target:"_blank",rel:"noopener noreferrer",children:"onLoad callbacks"})," to fetch module content based on the module path"]}),"\n",(0,i.jsx)(n.li,{children:"Input parameters"}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-ts",children:"interface LoadArgs {\n path: string;\n namespace: string;\n suffix: string;\n}\n"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Return parameters"}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-ts",children:"type LoadResult =\n | {\n contents: string; // module contents\n map?: SourceMap; // https://esbuild.github.io/api/#sourcemap\n loader?: Loader; // https://esbuild.github.io/api/#loader\n resolveDir?: string;\n }\n | undefined;\n"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Example"}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-ts",children:"compiler.hooks.load.tapPromise('load content from memfs', async args => {\n const contents = memfs.readFileSync(args.path);\n return {\n contents: contents,\n loader: 'js',\n };\n});\n"})}),"\n",(0,i.jsxs)(n.h4,{id:"transform",children:["transform",(0,i.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#transform",children:"#"})]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"AsyncSeriesWaterFallHooks"}),"\n",(0,i.jsxs)(n.li,{children:["Triggered at esbuild ",(0,i.jsx)(n.a,{href:"https://esbuild.github.io/plugins/#on-load",target:"_blank",rel:"noopener noreferrer",children:"onLoad callbacks"}),".\nTransforms the contents of the module fetched during the load phase"]}),"\n",(0,i.jsx)(n.li,{children:"Input parameters (return parameters)"}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-ts",children:"export type Source = {\n code: string;\n map?: SourceMap;\n path: string;\n loader?: string;\n};\n"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Example"}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-ts",children:"compiler.hooks.transform.tapPromise('6to5', async args => {\n const result = babelTransform(args.code, { presets: ['@babel/preset-env'] });\n return {\n code: result.code,\n map: result.map,\n };\n});\n"})}),"\n",(0,i.jsxs)(n.h4,{id:"renderchunk",children:["renderChunk",(0,i.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#renderchunk",children:"#"})]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"AsyncSeriesWaterFallHooks"}),"\n",(0,i.jsxs)(n.li,{children:["Triggered at esbuild ",(0,i.jsx)(n.a,{href:"https://esbuild.github.io/plugins/#on-end",target:"_blank",rel:"noopener noreferrer",children:"onEnd callbacks"}),".\nThis is similar to the transform hook, but works on the artifacts generated by esbuild."]}),"\n",(0,i.jsx)(n.li,{children:"Input parameters (return parameters)"}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-ts",children:"export type AssetChunk = {\n type: 'asset';\n contents: string | Buffer;\n entryPoint?: string;\n /**\n * absolute file path\n */\n fileName: string;\n originalFileName?: string;\n};\n\nexport type JsChunk = {\n type: 'chunk';\n contents: string;\n entryPoint?: string;\n /**\n * absolute file path\n */\n fileName: string;\n map?: SourceMap;\n modules?: Record<string, any>;\n originalFileName?: string;\n};\n\nexport type Chunk = AssetChunk | JsChunk;\n"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Examples"}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-ts",children:"compiler.hooks.renderChunk.tapPromise('minify', async chunk => {\n if (chunk.type === 'chunk') {\n const code = chunk.contents.toString();\n const result = await minify.call(compiler, code);\n return {\n ...chunk,\n contents: result.code,\n map: result.map,\n };\n }\n return chunk;\n});\n"})}),"\n",(0,i.jsxs)(n.h2,{id:"dts",children:["dts",(0,i.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#dts",children:"#"})]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.a,{href:"/en/api/config/build-config#dts",children:(0,i.jsx)(n.code,{children:"buildConfig.dts"})})," configuration is mainly used for type file generation."]}),"\n",(0,i.jsxs)(n.h3,{id:"turn-off-type-generation",children:["Turn off type generation",(0,i.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#turn-off-type-generation",children:"#"})]}),"\n",(0,i.jsx)(n.p,{children:"Type generation is turned on by default, if you need to turn it off, you can configure it as follows:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-js",meta:'title="modern.config.ts"',children:"import { defineConfig } from '@modern-js/module-tools';\n\nexport default defineConfig({\n buildConfig: {\n dts: false,\n },\n});\n"})}),"\n",(0,i.jsxs)(n.div,{className:"rspress-directive tip",children:[(0,i.jsx)(n.div,{className:"rspress-directive-title",children:"TIP"}),(0,i.jsx)(n.div,{className:"rspress-directive-content",children:(0,i.jsx)(n.p,{children:"The build speed is generally improved by closing the type file."})})]}),"\n",(0,i.jsxs)(n.h3,{id:"build-type-files",children:["Build type files",(0,i.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#build-type-files",children:"#"})]}),"\n",(0,i.jsxs)(n.p,{children:["With ",(0,i.jsx)(n.code,{children:"buildType: 'bundleless'"}),", type files are generated using the project's ",(0,i.jsx)(n.code,{children:"tsc"})," command to complete production."]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.strong,{children:"Modern.js Module also supports bundling of type files"}),", although care needs to be taken when using this feature."]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Bundle type files does not enable type checking."}),"\n",(0,i.jsxs)(n.li,{children:["Some third-party dependencies have incorrect syntax that can cause the bundling process to fail. So in this case, you need to exclude such third-party packages manually with ",(0,i.jsx)(n.a,{href:"/en/api/config/build-config#externals",children:(0,i.jsx)(n.code,{children:"buildConfig.externals"})})," or close ",(0,i.jsx)(n.a,{href:"/api/config/build-config#dtsrespectexternal",children:"dts.respectExternal"})," to external all third-party packages types."]}),"\n",(0,i.jsxs)(n.li,{children:["It is not possible to handle the case where the type file of a third-party dependency points to a ",(0,i.jsx)(n.code,{children:".ts"})," file. For example, the ",(0,i.jsx)(n.code,{children:"package.json"})," of a third-party dependency contains something like this: ",(0,i.jsx)(n.code,{children:'{"types": ". /src/index.ts"}'}),"."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["For the above problems, our recommended approach is to first use ",(0,i.jsx)(n.code,{children:"tsc"})," to generate d.ts files, then package the index.d.ts as the entry and close ",(0,i.jsx)(n.code,{children:"dts.respectExternal"}),". In the future evolution, we will gradually move towards this handling approach."]}),"\n",(0,i.jsxs)(n.h3,{id:"alias-conversion",children:["Alias Conversion",(0,i.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#alias-conversion",children:"#"})]}),"\n",(0,i.jsx)(n.p,{children:"During the bundleless build process, if an alias appears in the source code, e.g."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-js",meta:'title="./src/index.ts"',children:"import utils from '@common/utils';\n"})}),"\n",(0,i.jsxs)(n.p,{children:["The type files generated with ",(0,i.jsx)(n.code,{children:"tsc"})," will also contain these aliases. However, Modern.js Module will convert the aliases in the type file generated by ",(0,i.jsx)(n.code,{children:"tsc"}),"."]}),"\n",(0,i.jsxs)(n.h3,{id:"some-examples-of-the-use-of-dts",children:["Some examples of the use of ",(0,i.jsx)(n.code,{children:"dts"}),(0,i.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#some-examples-of-the-use-of-dts",children:"#"})]}),"\n",(0,i.jsx)(n.p,{children:"General usage:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-js",children:"import { defineConfig } from '@modern-js/module-tools';\n\nexport default defineConfig({\n // The output path of the bundled type file at this point is `./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",(0,i.jsxs)(n.p,{children:["For the use of ",(0,i.jsx)(n.code,{children:"dts.only"}),":"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-js",children:"import { defineConfig } from '@modern-js/module-tools';\n\nexport default defineConfig({\n // At this moment the type file is not bundled and the output path is `./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",(0,i.jsxs)(n.h2,{id:"build-process",children:["Build process",(0,i.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#build-process",children:"#"})]}),"\n",(0,i.jsxs)(n.p,{children:["When the ",(0,i.jsx)(n.code,{children:"modern build"})," command is executed, the"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["Clear the output directory according to ",(0,i.jsx)(n.code,{children:"buildConfig.outDir"}),"."]}),"\n",(0,i.jsxs)(n.li,{children:["Compile ",(0,i.jsx)(n.code,{children:"js/ts"})," source code to generate the JS build artifacts for bundle/bundleless."]}),"\n",(0,i.jsxs)(n.li,{children:["Generate bundle/bundleless type files using ",(0,i.jsx)(n.code,{children:"tsc"}),"."]}),"\n",(0,i.jsx)(n.li,{children:"Handle Copy tasks."}),"\n"]}),"\n",(0,i.jsxs)(n.h2,{id:"build-errors",children:["Build errors",(0,i.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#build-errors",children:"#"})]}),"\n",(0,i.jsx)(n.p,{children:"When a build error occurs, based on the information learned above, it is easy to understand what error appears in the terminal."}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Errors reported for js or ts builds:"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'error ModuleBuildError:\n\n╭───────────────────────╮\n│ bundle failed: │\n│ - format is "cjs" │\n│ - target is "esnext" │\n╰───────────────────────╯\n\nDetailed Information:\n'})}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Errors reported for the type file generation process:"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"error ModuleBuildError:\n\nbundle DTS failed:\n"})}),"\n",(0,i.jsxs)(n.p,{children:["For ",(0,i.jsx)(n.code,{children:"js/ts"})," build errors, we can tell from the error message."]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["By ",(0,i.jsx)(n.code,{children:"'bundle failed:'"})," to determine if the error is reported for a bundle build or a bundleless build"]}),"\n",(0,i.jsxs)(n.li,{children:["What is the ",(0,i.jsx)(n.code,{children:"format"})," of the build process"]}),"\n",(0,i.jsxs)(n.li,{children:["What is the ",(0,i.jsx)(n.code,{children:"target"})," of the build process"]}),"\n",(0,i.jsx)(n.li,{children:"The specific error message"}),"\n"]}),"\n",(0,i.jsxs)(n.h2,{id:"debug-mode",children:["Debug mode",(0,i.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#debug-mode",children:"#"})]}),"\n",(0,i.jsxs)(n.p,{children:["From ",(0,i.jsx)(n.strong,{children:"2.36.0"}),", For troubleshooting purposes, the Modern.js Module provides a debug mode, which you can enable by adding the DEBUG=module environment variable when executing a build."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"DEBUG=module modern build\n"})}),"\n",(0,i.jsx)(n.p,{children:"In debug mode, you'll see more detailed build logs output in Shell, which are mainly process logs:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"module run beforeBuildTask hooks +6ms\nmodule run beforeBuildTask hooks done +0ms\nmodule [DTS] Build Start +139ms\nmodule [CJS] Build Start +1ms\n"})}),"\n",(0,i.jsxs)(n.p,{children:["In addition, Module provides the ability to debug internal workflows. You can enable more detailed debugging logging by setting the ",(0,i.jsx)(n.code,{children:"DEBUG=module:*"})," environment variable."]}),"\n",(0,i.jsxs)(n.p,{children:["Currently, only ",(0,i.jsx)(n.code,{children:"DEBUG=module:resolve"})," is supported, which allows you to see a detailed log of module resolution within the Module."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:" module:resolve onResolve args: {\n path: './src/hooks/misc.ts',\n importer: '',\n namespace: 'file',\n resolveDir: '/Users/bytedance/modern.js/packages/solutions/module-tools',\n kind: 'entry-point',\n pluginData: undefined\n} +0ms\n module:resolve onResolve result: {\n path: '/Users/bytedance/modern.js/packages/solutions/module-tools/src/hooks/misc.ts',\n external: false,\n namespace: 'file',\n sideEffects: undefined,\n suffix: ''\n} +0ms\n"})})]})}function o(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},{wrapper:n}=Object.assign({},(0,r.ah)(),e.components);return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}let t=o;o.__RSPRESS_PAGE_META={},o.__RSPRESS_PAGE_META["en%2Fguide%2Fadvance%2Fin-depth-about-build.md"]={toc:[{text:"`bundle` / `bundleless`",id:"bundle--bundleless",depth:2},{text:"`input` / `sourceDir`",id:"input--sourcedir",depth:2},{text:"use swc",id:"use-swc",depth:2},{text:"Using Hooks to Intervene in the Build Process",id:"using-hooks-to-intervene-in-the-build-process",depth:2},{text:"Hook type",id:"hook-type",depth:3},{text:"AsyncSeriesBailHook",id:"asyncseriesbailhook",depth:4},{text:"AsyncSeriesWaterFallHooks",id:"asyncserieswaterfallhooks",depth:4},{text:"Hook Order",id:"hook-order",depth:3},{text:"Hook API",id:"hook-api",depth:3},{text:"load",id:"load",depth:4},{text:"transform",id:"transform",depth:4},{text:"renderChunk",id:"renderchunk",depth:4},{text:"dts",id:"dts",depth:2},{text:"Turn off type generation",id:"turn-off-type-generation",depth:3},{text:"Build type files",id:"build-type-files",depth:3},{text:"Alias Conversion",id:"alias-conversion",depth:3},{text:"Some examples of the use of `dts`",id:"some-examples-of-the-use-of-dts",depth:3},{text:"Build process",id:"build-process",depth:2},{text:"Build errors",id:"build-errors",depth:2},{text:"Debug mode",id:"debug-mode",depth:2}],title:"In-depth understanding of build",frontmatter:{sidebar_position:1}}}}]);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";(self.webpackChunk_modern_js_module_tools_docs=self.webpackChunk_modern_js_module_tools_docs||[]).push([["2140"],{3401:function(e,n,a){a.r(n),a.d(n,{default:function(){return r}});var i=a(8093),t=a(5878);function l(e){let n=Object.assign({h1:"h1",a:"a",p:"p",strong:"strong",ul:"ul",li:"li",pre:"pre",code:"code",h2:"h2",h3:"h3"},(0,t.ah)(),e.components);return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsxs)(n.h1,{id:"build-umd-artifacts",children:["Build umd artifacts",(0,i.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#build-umd-artifacts",children:"#"})]}),"\n",(0,i.jsxs)(n.p,{children:["The full name of umd is ",(0,i.jsx)(n.strong,{children:"Universal Module Definition"}),", and JS files in this format can run in multiple runtime environments: the"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Browser environment: module loading based on AMD specification"}),"\n",(0,i.jsx)(n.li,{children:"Node.js environment: module loading based on CommonJS"}),"\n",(0,i.jsx)(n.li,{children:"Other cases: mount the module on a global object."}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"We can therefore specify the build artifacts of the project as an umd artifact in the following way:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-ts",children:"export default defineConfig({\n buildConfig: {\n format: 'umd',\n },\n});\n"})}),"\n",(0,i.jsxs)(n.h2,{id:"third-party-dependency-handling-for-umd-artifacts",children:["Third-party dependency handling for umd artifacts",(0,i.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#third-party-dependency-handling-for-umd-artifacts",children:"#"})]}),"\n",(0,i.jsxs)(n.p,{children:["In the ",(0,i.jsx)(n.a,{href:"/en/guide/advance/external-dependency",children:'"How to handle third-party dependencies"'})," chapter, we know that we can control whether or not the project packages third-party dependencies via the ",(0,i.jsx)(n.a,{href:"/en/api/config/build-config#autoexternal",children:(0,i.jsx)(n.code,{children:"autoExternals"})})," and ",(0,i.jsx)(n.a,{href:"/en/api/config/build-config#externals",children:(0,i.jsx)(n.code,{children:"externals"})})," APIs.\nSo when building umd artifacts, we can also use it like this:"]}),"\n",(0,i.jsxs)(n.h3,{id:"example",children:["Example",(0,i.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#example",children:"#"})]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["If the project depends on ",(0,i.jsx)(n.code,{children:"react"}),":"]}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-json",meta:'title="package.json"',children:'{\n "dependencies": {\n "react": "^17"\n }\n}\n'})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"modern.config.ts"}),":"]}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-ts",children:"export default defineConfig({\n buildConfig: {\n format: 'umd',\n autoExternal: false,\n externals: ['react'],\n },\n});\n"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["When a ",(0,i.jsx)(n.code,{children:"react"})," dependency is used in the source code:"]}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-tsx",meta:'title="src/index.ts"',children:"import React from 'react';\nconsole.info(React);\n"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["The ",(0,i.jsx)(n.code,{children:"react"})," code is not bundled into the artifact at this point:"]}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-js",meta:'title="dist/index.js"',children:"(function (global, factory) {\n if (typeof module === 'object' && typeof module.exports === 'object')\n factory(exports, require('react'));\n else if (typeof define === 'function' && define.amd)\n define(['exports', 'react'], factory);\n else if (\n (global = typeof globalThis !== 'undefined' ? globalThis : global || self)\n )\n factory((global.index = {}), global.react);\n})(this, function (exports, _react) {\n 'use strict';\n Object.defineProperty(exports, '__esModule', {\n value: true,\n });\n _react = /*#__PURE__*/ _interopRequireDefault(_react);\n function _interopRequireDefault(obj) {\n return obj && obj.__esModule\n ? obj\n : {\n default: obj,\n };\n }\n console.info(_react.default);\n});\n"})}),"\n",(0,i.jsxs)(n.p,{children:["We know from the above example that when using the ",(0,i.jsx)(n.code,{children:"autoExternal"})," and ",(0,i.jsx)(n.code,{children:"externals"})," APIs."]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["In a Node.js environment, you can get the react dependency with ",(0,i.jsx)(n.code,{children:"require('react')"}),"."]}),"\n",(0,i.jsxs)(n.li,{children:["In a browser environment, you can get the react dependency via ",(0,i.jsx)(n.code,{children:"global.react"}),"."]}),"\n"]}),"\n",(0,i.jsxs)(n.h3,{id:"global-variable-names-of-third-party-dependencies",children:["Global variable names of third-party dependencies",(0,i.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#global-variable-names-of-third-party-dependencies",children:"#"})]}),"\n",(0,i.jsxs)(n.p,{children:["However, in the browser environment, when getting third-party dependencies, ",(0,i.jsx)(n.strong,{children:"global variable names are not necessarily identical to the dependency names"}),", so you have to use the ",(0,i.jsx)(n.a,{href:"/en/api/config/build-config#umdglobals",children:(0,i.jsx)(n.code,{children:"buildConfig.umdGlobals"})})," API."]}),"\n",(0,i.jsxs)(n.p,{children:["Again using the previous example, when the ",(0,i.jsx)(n.code,{children:"react"})," dependency exists in the browser environment as a ",(0,i.jsx)(n.code,{children:"windows.React"})," or ",(0,i.jsx)(n.code,{children:"global.React"})," global variable, then:"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"modern.config.ts"})," config file:"]}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-ts",children:"export default defineConfig({\n buildConfig: {\n format: 'umd',\n umdGlobals: {\n react: 'React',\n },\n },\n});\n"})}),"\n",(0,i.jsxs)(n.p,{children:["When a ",(0,i.jsx)(n.code,{children:"react"})," dependency is used in the source code:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-tsx",meta:'title="src/index.ts"',children:"import React from 'react';\nconsole.info(React);\n"})}),"\n",(0,i.jsx)(n.p,{children:"At this point we will see the output code like this:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-js",meta:'title="dist/index.js"',children:"(function (global, factory) {\n if (typeof module === 'object' && typeof module.exports === 'object')\n factory();\n else if (typeof define === 'function' && define.amd) define([], factory);\n else if (\n (global = typeof globalThis !== 'undefined' ? globalThis : global || self)\n )\n factory();\n})(this, function () {\n // ...\n // libuild:globals:react\n var require_react = __commonJS({\n 'libuild:globals:react'(exports, module1) {\n module1.exports = Function('return this')()['React'];\n },\n });\n // src/index.ts\n var import_react = __toESM(require_react());\n console.info(import_react.default);\n});\n"})}),"\n",(0,i.jsxs)(n.p,{children:["The project can then run in the browser and use the ",(0,i.jsx)(n.code,{children:"React"})," variables that exist on the global object."]}),"\n",(0,i.jsxs)(n.h2,{id:"changing-the-name-of-a-global-variable-in-a-project",children:["Changing the name of a global variable in a project",(0,i.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#changing-the-name-of-a-global-variable-in-a-project",children:"#"})]}),"\n",(0,i.jsxs)(n.p,{children:["When we package the following code into an umd artifact and run it in the browser, we can use the module via ",(0,i.jsx)(n.code,{children:"window.index"}),"."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-ts",meta:'title="./src/index.ts"',children:"export default () => {\n console.info('hello world');\n};\n"})}),"\n",(0,i.jsx)(n.p,{children:"** By default, the name of the source file is used as the name of the module's global variable in the browser. **For the above example, the artifact would read as follows:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-js",meta:'title="./dist/index.js"',children:"(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",(0,i.jsxs)(n.p,{children:["If you need to modify it, you need to use the ",(0,i.jsx)(n.a,{href:"/en/api/config/build-config#umdmodulename",children:(0,i.jsx)(n.code,{children:"buildConfig.umdModuleName"})})," API."]}),"\n",(0,i.jsx)(n.p,{children:"When this API is used:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-ts",children:"export default defineConfig({\n buildConfig: {\n format: 'umd',\n umdModuleName: 'myLib',\n },\n});\n"})}),"\n",(0,i.jsx)(n.p,{children:"The build artifact at this point are:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-js",meta:'title="./dist/index.js"',children:"(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"})})]})}function o(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},{wrapper:n}=Object.assign({},(0,t.ah)(),e.components);return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}let r=o;o.__RSPRESS_PAGE_META={},o.__RSPRESS_PAGE_META["en%2Fguide%2Fadvance%2Fbuild-umd.mdx"]={toc:[{text:"Third-party dependency handling for umd artifacts",id:"third-party-dependency-handling-for-umd-artifacts",depth:2},{text:"Example",id:"example",depth:3},{text:"Global variable names of third-party dependencies",id:"global-variable-names-of-third-party-dependencies",depth:3},{text:"Changing the name of a global variable in a project",id:"changing-the-name-of-a-global-variable-in-a-project",depth:2}],title:"Build umd artifacts",frontmatter:{sidebar_position:5}}}}]);
|