@modern-js/main-doc 2.0.0-beta.2 → 2.0.0-beta.4
Sign up to get free protection for your applications and to get access to all the features.
- package/.turbo/turbo-build.log +1 -1
- package/en/docusaurus-plugin-content-docs/current/apis/app/commands/inspect.md +0 -4
- package/en/docusaurus-plugin-content-docs/current/apis/app/commands/new.md +0 -2
- package/en/docusaurus-plugin-content-docs/current/apis/app/runtime/core/bootstrap.md +17 -3
- package/en/docusaurus-plugin-content-docs/current/apis/app/runtime/model/create-app.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/apis/app/runtime/model/use-store.md +0 -22
- package/en/docusaurus-plugin-content-docs/current/components/init-app.md +42 -0
- package/en/docusaurus-plugin-content-docs/current/components/reduck-migration.md +1 -0
- package/en/docusaurus-plugin-content-docs/current/configure/app/dev/asset-prefix.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/configure/app/dev/hmr.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/configure/app/dev/https.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/configure/app/dev/port.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/configure/app/dev/progress-bar.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/configure/app/dev/start-url.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/configure/app/experiments/lazy-compilation.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/configure/app/html/app-icon.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/configure/app/html/crossorigin.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/configure/app/html/disable-html-folder.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/configure/app/html/favicon-by-entries.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/configure/app/html/favicon.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/configure/app/html/inject-by-entries.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/configure/app/html/inject.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/configure/app/html/meta-by-entries.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/configure/app/html/meta.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/configure/app/html/mount-id.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/configure/app/html/template-by-entries.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/configure/app/html/template-parameters-by-entries.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/configure/app/html/template-parameters.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/configure/app/html/template.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/configure/app/html/title-by-entries.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/configure/app/html/title.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/configure/app/output/asset-prefix.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/configure/app/output/assets-retry.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/configure/app/output/charset.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/configure/app/output/clean-dist-path.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/configure/app/output/convert-to-rem.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/configure/app/output/copy.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/configure/app/output/css-module-local-ident-name.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/configure/app/output/data-uri-limit.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/configure/app/output/disable-css-extract.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/configure/app/output/disable-css-module-extension.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/configure/app/output/disable-filename-hash.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/configure/app/output/disable-inline-runtime-chunk.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/configure/app/output/disable-minimize.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/configure/app/output/disable-source-map.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/configure/app/output/disable-ts-checker.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/configure/app/output/dist-path.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/configure/app/output/enable-asset-fallback.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/configure/app/output/enable-asset-manifest.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/configure/app/output/enable-css-module-tsdeclaration.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/configure/app/output/enable-inline-scripts.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/configure/app/output/enable-inline-styles.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/configure/app/output/enable-latest-decorators.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/configure/app/output/externals.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/configure/app/output/filename.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/configure/app/output/legal-comments.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/configure/app/output/override-browserslist.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/configure/app/output/polyfill.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/configure/app/output/svg-default-export.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/configure/app/performance/build-cache.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/configure/app/performance/bundle-analyze.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/configure/app/performance/chunk-split.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/configure/app/performance/print-file-size.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/configure/app/performance/profile.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/configure/app/performance/remove-console.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/configure/app/performance/remove-moment-locale.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/configure/app/plugins.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/configure/app/security/sri.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/configure/app/server/routes.md +2 -4
- package/en/docusaurus-plugin-content-docs/current/configure/app/source/alias.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/configure/app/source/compile-js-data-uri.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/configure/app/source/define.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/configure/app/source/exclude.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/configure/app/source/global-vars.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/configure/app/source/include.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/configure/app/source/module-scopes.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/configure/app/source/pre-entry.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/configure/app/source/resolve-extension-prefix.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/configure/app/source/resolve-main-fields.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/configure/app/tools/autoprefixer.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/configure/app/tools/babel.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/configure/app/tools/css-extract.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/configure/app/tools/css-loader.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/configure/app/tools/dev-server.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/configure/app/tools/esbuild.md +16 -39
- package/en/docusaurus-plugin-content-docs/current/configure/app/tools/html-plugin.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/configure/app/tools/inspector.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/configure/app/tools/less.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/configure/app/tools/minify-css.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/configure/app/tools/postcss.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/configure/app/tools/pug.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/configure/app/tools/sass.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/configure/app/tools/style-loader.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/configure/app/tools/styled-components.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/configure/app/tools/swc.md +42 -0
- package/en/docusaurus-plugin-content-docs/current/configure/app/tools/terser.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/configure/app/tools/ts-checker.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/configure/app/tools/ts-loader.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/configure/app/tools/webpack-chain.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/configure/app/tools/webpack.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/guides/basic-features/builder.md +46 -0
- package/en/docusaurus-plugin-content-docs/current/guides/basic-features/css/css-in-js.md +38 -0
- package/en/docusaurus-plugin-content-docs/current/guides/basic-features/css/css-modules.md +86 -0
- package/en/docusaurus-plugin-content-docs/current/guides/basic-features/css/less-sass.md +17 -0
- package/en/docusaurus-plugin-content-docs/current/guides/basic-features/css/postcss.md +81 -0
- package/en/docusaurus-plugin-content-docs/current/guides/basic-features/css/tailwindcss.md +95 -0
- package/en/docusaurus-plugin-content-docs/current/guides/basic-features/data-fetch.md +66 -0
- package/en/docusaurus-plugin-content-docs/current/guides/basic-features/routes.md +270 -0
- package/en/docusaurus-plugin-content-docs/current/guides/concept/entries.md +116 -0
- package/en/docusaurus-plugin-content-docs/current/guides/concept/lifecycle.md +15 -0
- package/en/docusaurus-plugin-content-docs/current/guides/get-started/quick-start.md +162 -0
- package/en/docusaurus-plugin-content-docs/current/guides/get-started/upgrade.md +78 -0
- package/{zh/tutorials/first-app → en/docusaurus-plugin-content-docs/current/guides}/overview.md +4 -4
- package/en/docusaurus-plugin-content-docs/current/tutorials/foundations/introduction.md +1 -1
- package/en/docusaurus-plugin-content-docs/current.json +29 -29
- package/package.json +3 -3
- package/scripts/config.ts +2 -2
- package/zh/apis/app/commands/inspect.md +0 -4
- package/zh/apis/app/commands/new.md +1 -3
- package/zh/apis/app/hooks/src/index_.md +6 -5
- package/zh/apis/app/runtime/app/_category_.json +1 -1
- package/zh/apis/app/runtime/bff/_category_.json +1 -1
- package/zh/apis/app/runtime/core/_category_.json +1 -1
- package/zh/apis/app/runtime/core/bootstrap.md +17 -3
- package/zh/apis/app/runtime/model/_category_.json +1 -1
- package/zh/apis/app/runtime/model/create-app.md +1 -1
- package/zh/apis/app/runtime/model/use-store.md +1 -23
- package/zh/apis/app/runtime/router/_category_.json +1 -1
- package/zh/apis/app/runtime/ssr/_category_.json +1 -1
- package/zh/apis/app/runtime/testing/_category_.json +1 -1
- package/zh/apis/app/runtime/utility/_category_.json +1 -1
- package/zh/apis/app/runtime/web-server/_category_.json +1 -1
- package/zh/components/debug-app.md +18 -0
- package/zh/components/global-proxy.md +28 -0
- package/zh/components/init-app.md +44 -0
- package/zh/components/prerequisites.md +19 -0
- package/zh/components/reduck-migration.md +1 -0
- package/zh/configure/app/dev/asset-prefix.md +1 -1
- package/zh/configure/app/dev/hmr.md +1 -1
- package/zh/configure/app/dev/https.md +1 -1
- package/zh/configure/app/dev/port.md +1 -1
- package/zh/configure/app/dev/progress-bar.md +1 -1
- package/zh/configure/app/dev/start-url.md +1 -1
- package/zh/configure/app/experiments/_category_.json +4 -0
- package/zh/configure/app/experiments/lazy-compilation.md +1 -1
- package/zh/configure/app/html/_category_.json +4 -0
- package/zh/configure/app/html/app-icon.md +1 -1
- package/zh/configure/app/html/crossorigin.md +1 -1
- package/zh/configure/app/html/disable-html-folder.md +1 -1
- package/zh/configure/app/html/favicon-by-entries.md +1 -1
- package/zh/configure/app/html/favicon.md +1 -1
- package/zh/configure/app/html/inject-by-entries.md +1 -1
- package/zh/configure/app/html/inject.md +1 -1
- package/zh/configure/app/html/meta-by-entries.md +1 -1
- package/zh/configure/app/html/meta.md +1 -1
- package/zh/configure/app/html/mount-id.md +1 -1
- package/zh/configure/app/html/template-by-entries.md +1 -1
- package/zh/configure/app/html/template-parameters-by-entries.md +1 -1
- package/zh/configure/app/html/template-parameters.md +1 -1
- package/zh/configure/app/html/template.md +1 -1
- package/zh/configure/app/html/title-by-entries.md +1 -1
- package/zh/configure/app/html/title.md +1 -1
- package/zh/configure/app/output/asset-prefix.md +1 -1
- package/zh/configure/app/output/assets-retry.md +1 -1
- package/zh/configure/app/output/charset.md +1 -1
- package/zh/configure/app/output/clean-dist-path.md +1 -1
- package/zh/configure/app/output/convert-to-rem.md +1 -1
- package/zh/configure/app/output/copy.md +1 -1
- package/zh/configure/app/output/css-module-local-ident-name.md +1 -1
- package/zh/configure/app/output/data-uri-limit.md +1 -1
- package/zh/configure/app/output/disable-css-extract.md +1 -1
- package/zh/configure/app/output/disable-css-module-extension.md +1 -1
- package/zh/configure/app/output/disable-filename-hash.md +1 -1
- package/zh/configure/app/output/disable-inline-runtime-chunk.md +1 -1
- package/zh/configure/app/output/disable-minimize.md +1 -1
- package/zh/configure/app/output/disable-source-map.md +1 -1
- package/zh/configure/app/output/disable-ts-checker.md +1 -1
- package/zh/configure/app/output/dist-path.md +1 -1
- package/zh/configure/app/output/enable-asset-fallback.md +1 -1
- package/zh/configure/app/output/enable-asset-manifest.md +1 -1
- package/zh/configure/app/output/enable-css-module-tsdeclaration.md +1 -1
- package/zh/configure/app/output/enable-inline-scripts.md +1 -1
- package/zh/configure/app/output/enable-inline-styles.md +1 -1
- package/zh/configure/app/output/enable-latest-decorators.md +1 -1
- package/zh/configure/app/output/externals.md +1 -1
- package/zh/configure/app/output/filename.md +1 -1
- package/zh/configure/app/output/legal-comments.md +1 -1
- package/zh/configure/app/output/override-browserslist.md +1 -1
- package/zh/configure/app/output/polyfill.md +1 -1
- package/zh/configure/app/output/ssg.md +118 -114
- package/zh/configure/app/output/svg-default-export.md +1 -1
- package/zh/configure/app/performance/_category_.json +4 -0
- package/zh/configure/app/performance/build-cache.md +1 -1
- package/zh/configure/app/performance/bundle-analyze.md +1 -1
- package/zh/configure/app/performance/chunk-split.md +1 -1
- package/zh/configure/app/performance/print-file-size.md +1 -1
- package/zh/configure/app/performance/profile.md +1 -1
- package/zh/configure/app/performance/remove-console.md +1 -1
- package/zh/configure/app/performance/remove-moment-locale.md +1 -1
- package/zh/configure/app/plugins.md +1 -1
- package/zh/configure/app/runtime/state.md +13 -0
- package/zh/configure/app/security/_category_.json +4 -0
- package/zh/configure/app/security/sri.md +1 -1
- package/zh/configure/app/server/routes.md +2 -4
- package/zh/configure/app/server/ssr.md +0 -2
- package/zh/configure/app/source/alias.md +1 -1
- package/zh/configure/app/source/compile-js-data-uri.md +1 -1
- package/zh/configure/app/source/define.md +1 -1
- package/zh/configure/app/source/exclude.md +1 -1
- package/zh/configure/app/source/global-vars.md +1 -1
- package/zh/configure/app/source/include.md +1 -1
- package/zh/configure/app/source/module-scopes.md +1 -1
- package/zh/configure/app/source/pre-entry.md +1 -1
- package/zh/configure/app/source/resolve-extension-prefix.md +1 -1
- package/zh/configure/app/source/resolve-main-fields.md +1 -1
- package/zh/configure/app/tools/autoprefixer.md +1 -1
- package/zh/configure/app/tools/babel.md +1 -1
- package/zh/configure/app/tools/css-extract.md +1 -1
- package/zh/configure/app/tools/css-loader.md +1 -1
- package/zh/configure/app/tools/dev-server.md +1 -1
- package/zh/configure/app/tools/esbuild.md +16 -39
- package/zh/configure/app/tools/html-plugin.md +1 -1
- package/zh/configure/app/tools/inspector.md +1 -1
- package/zh/configure/app/tools/less.md +1 -1
- package/zh/configure/app/tools/minify-css.md +1 -1
- package/zh/configure/app/tools/postcss.md +1 -1
- package/zh/configure/app/tools/pug.md +1 -1
- package/zh/configure/app/tools/sass.md +1 -1
- package/zh/configure/app/tools/style-loader.md +1 -1
- package/zh/configure/app/tools/styled-components.md +1 -1
- package/zh/configure/app/tools/swc.md +42 -0
- package/zh/configure/app/tools/terser.md +1 -1
- package/zh/configure/app/tools/ts-checker.md +1 -1
- package/zh/configure/app/tools/ts-loader.md +1 -1
- package/zh/configure/app/tools/webpack-chain.md +1 -1
- package/zh/configure/app/tools/webpack.md +1 -1
- package/zh/guides/advanced-features/bff/bff-proxy.md +1 -1
- package/zh/guides/advanced-features/compatibility.md +2 -38
- package/zh/guides/advanced-features/custom-app.md +23 -19
- package/zh/guides/advanced-features/ssg.md +73 -62
- package/zh/guides/advanced-features/ssr.md +142 -36
- package/zh/guides/advanced-features/testing.md +33 -1
- package/zh/guides/advanced-features/web-server.md +2 -2
- package/zh/guides/basic-features/builder.md +46 -0
- package/zh/guides/basic-features/css/_category_.json +1 -1
- package/zh/guides/basic-features/css/less-sass.md +1 -14
- package/zh/guides/basic-features/css/tailwindcss.md +2 -6
- package/zh/guides/basic-features/data-fetch.md +1 -1
- package/zh/guides/basic-features/env-vars.md +34 -0
- package/zh/guides/basic-features/html.md +182 -0
- package/zh/guides/basic-features/mock.md +3 -9
- package/zh/guides/basic-features/proxy.md +2 -27
- package/zh/guides/basic-features/routes.md +32 -35
- package/zh/guides/concept/entries.md +8 -9
- package/zh/guides/get-started/quick-start.md +6 -78
- package/zh/guides/get-started/upgrade.md +8 -8
- package/zh/guides/topic-detail/framework-plugin/extend.md +3 -4
- package/zh/{apis/app/runtime/plugin/hook-api.md → guides/topic-detail/framework-plugin/hook-list.md} +42 -135
- package/zh/{apis/app/runtime/plugin → guides/topic-detail/framework-plugin}/hook.md +2 -3
- package/zh/guides/topic-detail/framework-plugin/implement.md +21 -10
- package/zh/guides/topic-detail/framework-plugin/introduction.md +49 -0
- package/{en/docusaurus-plugin-content-docs/current/apis/app/runtime/plugin → zh/guides/topic-detail/framework-plugin}/plugin-api.md +3 -4
- package/zh/guides/topic-detail/framework-plugin/relationship.md +2 -3
- package/zh/guides/topic-detail/model/quick-start.md +5 -1
- package/zh/guides/topic-detail/model/test-model.md +2 -2
- package/zh/guides/topic-detail/monorepo/intro.md +1 -1
- package/zh/guides/troubleshooting/dependencies.md +0 -69
- package/zh/tutorials/first-app/_category_.json +1 -1
- package/zh/tutorials/first-app/c01-start.md +94 -0
- package/zh/tutorials/first-app/c02-component.md +56 -0
- package/zh/tutorials/first-app/c03-css.md +305 -0
- package/zh/tutorials/first-app/c04-routes.md +169 -0
- package/zh/tutorials/first-app/c05-loader.md +82 -0
- package/zh/tutorials/first-app/c06-model.md +256 -0
- package/zh/tutorials/first-app/c07-container.md +268 -0
- package/zh/tutorials/first-app/c08-entries.md +134 -0
- package/zh/tutorials/foundations/introduction.md +2 -2
- package/en/docusaurus-plugin-content-docs/current/apis/app/runtime/default-alias.md +0 -25
- package/en/docusaurus-plugin-content-docs/current/apis/app/runtime/plugin/_category_.json +0 -4
- package/en/docusaurus-plugin-content-docs/current/apis/app/runtime/plugin/abstract.md +0 -26
- package/en/docusaurus-plugin-content-docs/current/apis/app/runtime/plugin/hook-api.md +0 -896
- package/en/docusaurus-plugin-content-docs/current/apis/app/runtime/plugin/hook.md +0 -170
- package/en/docusaurus-plugin-content-docs/current/configure/app/output/enable-modern-mode.md +0 -34
- package/zh/apis/app/runtime/default-alias.md +0 -23
- package/zh/apis/app/runtime/plugin/_category_.json +0 -4
- package/zh/apis/app/runtime/plugin/abstract.md +0 -26
- package/zh/apis/app/runtime/plugin/plugin-api.md +0 -117
- package/zh/apis/generator/overview.md +0 -32
- package/zh/configure/app/output/enable-modern-mode.md +0 -34
- package/zh/guides/basic-features/image.md +0 -43
- package/zh/guides/topic-detail/compile-speed.md +0 -182
- package/zh/guides/topic-detail/framework-plugin/abstract.md +0 -27
- package/zh/guides/topic-detail/monorepo/deploy.md +0 -43
- package/zh/guides/troubleshooting/compile.md +0 -379
- package/zh/tutorials/first-app/c01-getting-started/1.1-prerequisites.md +0 -25
- package/zh/tutorials/first-app/c01-getting-started/1.2-minimal-mwa.md +0 -118
- package/zh/tutorials/first-app/c01-getting-started/1.3-dev-command.md +0 -29
- package/zh/tutorials/first-app/c01-getting-started/1.4-enable-ssr.md +0 -44
- package/zh/tutorials/first-app/c01-getting-started/1.5-start-command.md +0 -18
- package/zh/tutorials/first-app/c01-getting-started/1.6-create-repo.md +0 -31
- package/zh/tutorials/first-app/c01-getting-started/_category_.json +0 -3
- package/zh/tutorials/first-app/c02-generator-and-studio/2.1-generator.md +0 -79
- package/zh/tutorials/first-app/c02-generator-and-studio/2.2-boilerplates.md +0 -36
- package/zh/tutorials/first-app/c02-generator-and-studio/2.3-configuration.md +0 -21
- package/zh/tutorials/first-app/c02-generator-and-studio/_category_.json +0 -3
- package/zh/tutorials/first-app/c03-ide/3.1-setting-up.md +0 -55
- package/zh/tutorials/first-app/c03-ide/3.2-hints-in-ide.md +0 -66
- package/zh/tutorials/first-app/c03-ide/3.3-autofix-in-ide.md +0 -11
- package/zh/tutorials/first-app/c03-ide/3.4-autofix-in-cli.md +0 -63
- package/zh/tutorials/first-app/c03-ide/_category_.json +0 -3
- package/zh/tutorials/first-app/c04-es6-plus-and-ts/4.1-use-es6-plus.md +0 -67
- package/zh/tutorials/first-app/c04-es6-plus-and-ts/4.2-use-typescript.md +0 -111
- package/zh/tutorials/first-app/c04-es6-plus-and-ts/4.3-compatibility.md +0 -67
- package/zh/tutorials/first-app/c04-es6-plus-and-ts/_category_.json +0 -3
- package/zh/tutorials/first-app/c05-component/5.1-use-ui-library.md +0 -68
- package/zh/tutorials/first-app/c05-component/5.2-use-standalone-component.md +0 -92
- package/zh/tutorials/first-app/c05-component/_category_.json +0 -3
- package/zh/tutorials/first-app/c06-css-and-component/6.1-css-in-js.md +0 -110
- package/zh/tutorials/first-app/c06-css-and-component/6.2-utility-class.md +0 -148
- package/zh/tutorials/first-app/c06-css-and-component/6.3-postcss.md +0 -84
- package/zh/tutorials/first-app/c06-css-and-component/6.4-design-system.md +0 -83
- package/zh/tutorials/first-app/c06-css-and-component/6.5-storybook.md +0 -77
- package/zh/tutorials/first-app/c06-css-and-component/6.6-testing.md +0 -113
- package/zh/tutorials/first-app/c06-css-and-component/_category_.json +0 -3
- package/zh/tutorials/first-app/c07-app-entry/7.1-intro.md +0 -64
- package/zh/tutorials/first-app/c07-app-entry/7.2-add-entry-in-cli.md +0 -100
- package/zh/tutorials/first-app/c07-app-entry/7.3-manage-entries-by-hand.md +0 -74
- package/zh/tutorials/first-app/c07-app-entry/_category_.json +0 -3
- package/zh/tutorials/first-app/c08-client-side-routing/8.1-code-based-routing.md +0 -153
- package/zh/tutorials/first-app/c08-client-side-routing/8.2-file-based-routing.md +0 -310
- package/zh/tutorials/first-app/c08-client-side-routing/_category_.json +0 -3
- package/zh/tutorials/first-app/c09-bff/9.1-serverless.md +0 -30
- package/zh/tutorials/first-app/c09-bff/9.2-enable-bff.md +0 -93
- package/zh/tutorials/first-app/c09-bff/9.3-fetch-bff.md +0 -205
- package/zh/tutorials/first-app/c09-bff/_category_.json +0 -3
- package/zh/tutorials/first-app/c10-model/10.1-application-architecture.md +0 -23
- package/zh/tutorials/first-app/c10-model/10.2-add-model.md +0 -185
- package/zh/tutorials/first-app/c10-model/10.3-use-model.md +0 -54
- package/zh/tutorials/first-app/c10-model/10.4-testing.md +0 -69
- package/zh/tutorials/first-app/c10-model/_category_.json +0 -3
- package/zh/tutorials/first-app/c11-container/11.1-use-model-with-app-state.md +0 -274
- package/zh/tutorials/first-app/c11-container/11.2-add-container.md +0 -106
- package/zh/tutorials/first-app/c11-container/11.3-use-loader.md +0 -61
- package/zh/tutorials/first-app/c11-container/11.4-testing.md +0 -56
- package/zh/tutorials/first-app/c11-container/_category_.json +0 -3
@@ -0,0 +1,256 @@
|
|
1
|
+
---
|
2
|
+
title: 添加业务模型(状态管理)
|
3
|
+
---
|
4
|
+
|
5
|
+
上一章节中,我们把硬编码的 `mockData` 改成从 Data Loader 中加载。
|
6
|
+
|
7
|
+
这一章节中,我们会进一步实现项目的功能,例如实现 **Archive** 按钮的功能,把联系人归档。
|
8
|
+
|
9
|
+
因此会开始编写一些跟 UI 完全无关的业务逻辑,如果继续写在组件代码中,会产生越来越多的面条式代码。为此,我们引入了一种叫做**业务模型(Model)**的代码模块,将这些业务逻辑和 UI 解耦。
|
10
|
+
|
11
|
+
## 实现 Model
|
12
|
+
|
13
|
+
创建一个完整的 Model 首先需要定义**状态(state)**,包括状态中数据的名称和初始值。
|
14
|
+
|
15
|
+
我们使用 Model 来管理联系人列表的数据,因此定义如下数据状态:
|
16
|
+
|
17
|
+
```js
|
18
|
+
const state = {
|
19
|
+
items: [],
|
20
|
+
};
|
21
|
+
```
|
22
|
+
|
23
|
+
使用 TS 语法,可以定义更完整的类型信息,比如 items 里每个对象都应该有 `name`、`email` 字段。为了实现归档功能,还需要创建 `archived` 字段保存这个联系人是否已被归档的状态。
|
24
|
+
|
25
|
+
我们还需要一个字段用来访问所有已归档的联系人,可以定义 **computed** 类型的字段,对已有的数据做转换:
|
26
|
+
|
27
|
+
```js
|
28
|
+
const computed = {
|
29
|
+
archived: ({ items }) => {
|
30
|
+
return items.filter(item => item.archived);
|
31
|
+
},
|
32
|
+
};
|
33
|
+
```
|
34
|
+
|
35
|
+
computed 类型字段的定义方式是函数,但使用时可以像普通字段一样通过 state 访问。
|
36
|
+
|
37
|
+
:::info
|
38
|
+
Modern.js 集成了 [Immer](https://immerjs.github.io/immer/),能够像操作 JS 中常规的可变数据一样,去写这种状态转移的逻辑。
|
39
|
+
:::
|
40
|
+
|
41
|
+
实现 Archive 按钮时,我们需要一个 `archive` 函数,负责修改指定联系人的 `archived` 字段,我们把这种函数都叫作 **action**:
|
42
|
+
|
43
|
+
```js
|
44
|
+
const actions = {
|
45
|
+
archive(draft, payload) {
|
46
|
+
const target = draft.items.find(item => item.email === payload);
|
47
|
+
if (target) {
|
48
|
+
target.archived = true;
|
49
|
+
}
|
50
|
+
},
|
51
|
+
};
|
52
|
+
```
|
53
|
+
|
54
|
+
action 函数是一种**纯函数**,确定的输入得到确定的输出(转移后的状态),不应该有任何副作用。
|
55
|
+
|
56
|
+
函数的第一个参数是 Immer 提供的 Draft State,第二个参数是 action 被调用时传入的参数(后面会介绍怎么调用)。
|
57
|
+
|
58
|
+
我们尝试完整实现它们:
|
59
|
+
|
60
|
+
```js
|
61
|
+
const state = {
|
62
|
+
items: [],
|
63
|
+
pending: false,
|
64
|
+
error: null,
|
65
|
+
};
|
66
|
+
|
67
|
+
const computed = {
|
68
|
+
archived: ({ items }) => {
|
69
|
+
return items.filter(item => item.archived);
|
70
|
+
},
|
71
|
+
};
|
72
|
+
|
73
|
+
const actions = {
|
74
|
+
archive(draft, payload) {
|
75
|
+
const target = draft.items.find(item => item.email === payload);
|
76
|
+
if (target) {
|
77
|
+
target.archived = true;
|
78
|
+
}
|
79
|
+
},
|
80
|
+
};
|
81
|
+
```
|
82
|
+
|
83
|
+
接下来我们把上面的代码连起来,放在同一个 Model 文件里。首先执行以下命令,创建新的文件目录:
|
84
|
+
|
85
|
+
```bash
|
86
|
+
mkdir -p src/models/
|
87
|
+
touch src/models/contacts.ts
|
88
|
+
```
|
89
|
+
|
90
|
+
添加 `src/models/contacts.ts` 的内容:
|
91
|
+
|
92
|
+
```tsx
|
93
|
+
import { model } from "@modern-js/runtime/model";
|
94
|
+
|
95
|
+
type State = {
|
96
|
+
items: {
|
97
|
+
avatar: string;
|
98
|
+
name: string;
|
99
|
+
email: string;
|
100
|
+
archived?: boolean;
|
101
|
+
}[];
|
102
|
+
pending: boolean;
|
103
|
+
error: null | Error;
|
104
|
+
};
|
105
|
+
|
106
|
+
export default model<State>("contacts").define({
|
107
|
+
state: {
|
108
|
+
items: [],
|
109
|
+
pending: false,
|
110
|
+
error: null,
|
111
|
+
},
|
112
|
+
computed: {
|
113
|
+
archived: ({ items }: State) => items.filter((item) => item.archived),
|
114
|
+
},
|
115
|
+
actions: {
|
116
|
+
archive(draft, payload) {
|
117
|
+
const target = draft.items.find((item) => item.email === payload)!;
|
118
|
+
if (target) {
|
119
|
+
target.archived = true;
|
120
|
+
}
|
121
|
+
},
|
122
|
+
},
|
123
|
+
});
|
124
|
+
```
|
125
|
+
|
126
|
+
我们把一个包含 state,action 等要素的 plain object 称作 **Model Spec**,Modern.js 提供了 [Model API](/docs/apis/app/runtime/model/model_),可以根据 Model Spec 生成 **Model**。
|
127
|
+
|
128
|
+
## 使用 Model
|
129
|
+
|
130
|
+
现在我们直接使用这个 Model,把项目的逻辑补充起来。
|
131
|
+
|
132
|
+
首先修改 `src/components/Item/index.tsx`,添加 **Archive 按钮**的 UI 和交互,内容如下:
|
133
|
+
|
134
|
+
```tsx
|
135
|
+
import Avatar from "../Avatar";
|
136
|
+
|
137
|
+
type InfoProps = {
|
138
|
+
avatar: string;
|
139
|
+
name: string;
|
140
|
+
email: string;
|
141
|
+
archived?: boolean;
|
142
|
+
};
|
143
|
+
|
144
|
+
const Item = ({
|
145
|
+
info,
|
146
|
+
onArchive,
|
147
|
+
}: {
|
148
|
+
info: InfoProps;
|
149
|
+
onArchive?: () => void;
|
150
|
+
}) => {
|
151
|
+
const { avatar, name, email, archived } = info;
|
152
|
+
return (
|
153
|
+
<div className="flex p-4 items-center border-gray-200 border-b">
|
154
|
+
<Avatar src={avatar} />
|
155
|
+
<div className="ml-4 custom-text-gray flex-1 flex justify-between">
|
156
|
+
<div className="flex-1">
|
157
|
+
<p>{name}</p>
|
158
|
+
<p>{email}</p>
|
159
|
+
</div>
|
160
|
+
<button
|
161
|
+
type="button"
|
162
|
+
disabled={archived}
|
163
|
+
onClick={onArchive}
|
164
|
+
className={`text-white font-bold py-2 px-4 rounded-full ${
|
165
|
+
archived
|
166
|
+
? "bg-gray-400 cursor-default"
|
167
|
+
: "bg-blue-500 hover:bg-blue-700"
|
168
|
+
}`}
|
169
|
+
>
|
170
|
+
{archived ? "Archived" : "Archive"}
|
171
|
+
</button>
|
172
|
+
</div>
|
173
|
+
</div>
|
174
|
+
);
|
175
|
+
};
|
176
|
+
|
177
|
+
export default Item;
|
178
|
+
```
|
179
|
+
|
180
|
+
接下来,我们修改 `src/routes/page.tsx`,为 `<Item>` 组件传递更多参数:
|
181
|
+
|
182
|
+
```tsx
|
183
|
+
import { Helmet } from "@modern-js/runtime/head";
|
184
|
+
import { useModel } from "@modern-js/runtime/model";
|
185
|
+
import { useLoaderData } from "@modern-js/runtime/router";
|
186
|
+
import { List } from "antd";
|
187
|
+
import { name, internet } from "faker";
|
188
|
+
import Item from "../components/Item";
|
189
|
+
import contacts from "../models/contacts";
|
190
|
+
|
191
|
+
type LoaderData = {
|
192
|
+
code: number;
|
193
|
+
data: {
|
194
|
+
name: string;
|
195
|
+
avatar: string;
|
196
|
+
email: string;
|
197
|
+
}[];
|
198
|
+
};
|
199
|
+
|
200
|
+
export const loader = async (): Promise<LoaderData> => {
|
201
|
+
const data = new Array(20).fill(0).map(() => {
|
202
|
+
const firstName = name.firstName();
|
203
|
+
return {
|
204
|
+
name: firstName,
|
205
|
+
avatar: `https://avatars.dicebear.com/api/identicon/${firstName}.svg`,
|
206
|
+
email: internet.email(),
|
207
|
+
archived: false,
|
208
|
+
};
|
209
|
+
});
|
210
|
+
|
211
|
+
return {
|
212
|
+
code: 200,
|
213
|
+
data,
|
214
|
+
};
|
215
|
+
};
|
216
|
+
|
217
|
+
function Index() {
|
218
|
+
const { data } = useLoaderData() as LoaderData;
|
219
|
+
const [{ items }, { archive, setItem }] = useModel(contacts);
|
220
|
+
if (items.length === 0) {
|
221
|
+
setItem(data);
|
222
|
+
}
|
223
|
+
|
224
|
+
return (
|
225
|
+
<div className="container lg mx-auto">
|
226
|
+
<Helmet>
|
227
|
+
<title>All</title>
|
228
|
+
</Helmet>
|
229
|
+
<List
|
230
|
+
dataSource={items}
|
231
|
+
renderItem={(info) => (
|
232
|
+
<Item
|
233
|
+
key={info.name}
|
234
|
+
info={info}
|
235
|
+
onArchive={() => {
|
236
|
+
archive(info.email);
|
237
|
+
}}
|
238
|
+
/>
|
239
|
+
)}
|
240
|
+
/>
|
241
|
+
</div>
|
242
|
+
);
|
243
|
+
}
|
244
|
+
|
245
|
+
export default Index;
|
246
|
+
```
|
247
|
+
|
248
|
+
`useModel` 是 Modern.js 提供的 hooks API。可以在组件中提供 Model 中定义的 state,或通过 actions 调用 Model 中定义的 side effect 与 action,从而改变 Model 的 state。
|
249
|
+
|
250
|
+
Model 是业务逻辑,是计算过程,本身不创建也不持有状态。只有在被组件用 hooks API 使用后,才在指定的地方创建状态。
|
251
|
+
|
252
|
+
执行 `pnpm run dev`,点击 **Archive 按钮**,可以看到页面 UI 发生了变化。
|
253
|
+
|
254
|
+
:::note
|
255
|
+
上述例子中,`useLoaderData` 其实在每次切换路由时都会执行。因为我们在 Data Loader 里使用了 fake 数据,每次返回的数据是不同的。但我们优先使用了 Model 中的数据,因此切换路由时数据没有发生改变。
|
256
|
+
:::
|
@@ -0,0 +1,268 @@
|
|
1
|
+
---
|
2
|
+
title: 添加容器组件
|
3
|
+
---
|
4
|
+
|
5
|
+
import Tabs from '@theme/Tabs';
|
6
|
+
import TabItem from '@theme/TabItem';
|
7
|
+
|
8
|
+
上一章节中,我们初步引入**业务模型**,从 UI 组件中拆分出这部分逻辑。`page.tsx` 中不再包含 UI 无关的业务逻辑实现细节,只需要使用 Model,就能实现同样的功能。
|
9
|
+
|
10
|
+
这一章节中,我们要进一步利用 Model 中实现的业务逻辑,让 `page.tsx` 和 `archived/page.tsx` 获取同一份数据。并实现 Archive 按钮,点击按钮能把联系人归档,只显示在 Archives 列表里,不显示在 All 列表里。
|
11
|
+
|
12
|
+
## 使用完整 Model
|
13
|
+
|
14
|
+
因为两个页面需要共用同一套状态(联系人列表数据、联系人是否被归档),都需要包含加载初始数据的逻辑,因此我们需要在更上一层完成数据获取。
|
15
|
+
|
16
|
+
Modern.js 支持在 `layout.tsx` 通过 Data Loader 获取数据,我们先数据获取这部分代码移动到 `src/routes/layout.tsx` 中:
|
17
|
+
|
18
|
+
```tsx
|
19
|
+
import { name, internet } from "faker";
|
20
|
+
import { useModel } from "@modern-js/runtime/model";
|
21
|
+
import contacts from "../models/contacts";
|
22
|
+
|
23
|
+
type LoaderData = {
|
24
|
+
code: number;
|
25
|
+
data: {
|
26
|
+
name: string;
|
27
|
+
avatar: string;
|
28
|
+
email: string;
|
29
|
+
}[];
|
30
|
+
};
|
31
|
+
|
32
|
+
export const loader = async (): Promise<LoaderData> => {
|
33
|
+
const data = new Array(20).fill(0).map(() => {
|
34
|
+
const firstName = name.firstName();
|
35
|
+
return {
|
36
|
+
name: firstName,
|
37
|
+
avatar: `https://avatars.dicebear.com/api/identicon/${firstName}.svg`,
|
38
|
+
email: internet.email(),
|
39
|
+
archived: false,
|
40
|
+
};
|
41
|
+
});
|
42
|
+
|
43
|
+
return {
|
44
|
+
code: 200,
|
45
|
+
data,
|
46
|
+
};
|
47
|
+
};
|
48
|
+
|
49
|
+
export default function Layout() {
|
50
|
+
const { data } = useLoaderData() as LoaderData;
|
51
|
+
const [{ items }, { setItem }] = useModel(contacts);
|
52
|
+
if (items.length === 0) {
|
53
|
+
setItem(data);
|
54
|
+
}
|
55
|
+
|
56
|
+
const navigate = useNavigate();
|
57
|
+
...
|
58
|
+
}
|
59
|
+
```
|
60
|
+
|
61
|
+
在 `src/routes/page.tsx` 中,直接使用 Model,获取数据:
|
62
|
+
|
63
|
+
```tsx
|
64
|
+
import { Helmet } from "@modern-js/runtime/head";
|
65
|
+
import { useModel } from "@modern-js/runtime/model";
|
66
|
+
import { List } from "antd";
|
67
|
+
import Item from "../components/Item";
|
68
|
+
import contacts from "../models/contacts";
|
69
|
+
|
70
|
+
function Index() {
|
71
|
+
const [{ items }, { archive }] = useModel(contacts);
|
72
|
+
|
73
|
+
return (
|
74
|
+
<div className="container lg mx-auto">
|
75
|
+
<Helmet>
|
76
|
+
<title>All</title>
|
77
|
+
</Helmet>
|
78
|
+
<List
|
79
|
+
dataSource={items}
|
80
|
+
renderItem={(info) => (
|
81
|
+
<Item
|
82
|
+
key={info.name}
|
83
|
+
info={info}
|
84
|
+
onArchive={() => {
|
85
|
+
archive(info.email);
|
86
|
+
}}
|
87
|
+
/>
|
88
|
+
)}
|
89
|
+
/>
|
90
|
+
</div>
|
91
|
+
);
|
92
|
+
}
|
93
|
+
|
94
|
+
export default Index;
|
95
|
+
```
|
96
|
+
|
97
|
+
同样在 `archived/page.tsx` 中,删除原本的 `mockData` 逻辑,使用 Model 中 computed 的 `archived` 值作为数据源:
|
98
|
+
|
99
|
+
```tsx
|
100
|
+
import { Helmet } from "@modern-js/runtime/head";
|
101
|
+
import { useModel } from "@modern-js/runtime/model";
|
102
|
+
import { List } from "antd";
|
103
|
+
import Item from "../../components/Item";
|
104
|
+
import contacts from "../../models/contacts";
|
105
|
+
|
106
|
+
function Index() {
|
107
|
+
const [{ archived }, { archive }] = useModel(contacts);
|
108
|
+
|
109
|
+
return (
|
110
|
+
<div className="container lg mx-auto">
|
111
|
+
<Helmet>
|
112
|
+
<title>Archives</title>
|
113
|
+
</Helmet>
|
114
|
+
<List
|
115
|
+
dataSource={archived}
|
116
|
+
renderItem={(info) => (
|
117
|
+
<Item
|
118
|
+
key={info.name}
|
119
|
+
info={info}
|
120
|
+
onArchive={() => {
|
121
|
+
archive(info.email);
|
122
|
+
}}
|
123
|
+
/>
|
124
|
+
)}
|
125
|
+
/>
|
126
|
+
</div>
|
127
|
+
);
|
128
|
+
}
|
129
|
+
|
130
|
+
export default Index;
|
131
|
+
```
|
132
|
+
|
133
|
+
执行 `pnpm run dev`,访问 `http://localhost:8080/`,点击 Archive 按钮后,可以看到按钮置灰:
|
134
|
+
|
135
|
+

|
136
|
+
|
137
|
+
接下来点击顶部导航,切换到 Archives 列表,可以发现刚才 **Archive** 的联系人已经出现在列表当中:
|
138
|
+
|
139
|
+

|
140
|
+
|
141
|
+
## 抽离容器组件
|
142
|
+
|
143
|
+
前面章节中,我们把项目中的业务逻辑拆分成了两个 layer,一个是**视图组件**,另一个是**业务模块**。前者负责 UI 展示、交互等,后者负责实现 UI 无关的业务逻辑,专门管理状态。
|
144
|
+
|
145
|
+
像 `src/routes/page.tsx` 和 `src/routes/archives/page.tsx` 这样使用了 `useModel` API 的组件,负责把 View 和 Model 这两个 layer 连接起来,类似传统 MVC 架构中 Controller 的角色,在 Modern.js 里我们沿用习惯,把它们称作**容器组件(Container)**。
|
146
|
+
|
147
|
+
容器组件推荐放在专门的 `containers/` 目录里,我们执行以下命令,创建新的文件:
|
148
|
+
|
149
|
+
<Tabs>
|
150
|
+
<TabItem value="macOS" label="macOS" default>
|
151
|
+
|
152
|
+
```bash
|
153
|
+
mkdir -p src/containers
|
154
|
+
touch src/containers/Contacts.tsx
|
155
|
+
```
|
156
|
+
|
157
|
+
</TabItem>
|
158
|
+
<TabItem value="Windows" label="Windows">
|
159
|
+
|
160
|
+
```powershell
|
161
|
+
mkdir -p src/containers
|
162
|
+
ni src/containers/Contacts.tsx
|
163
|
+
```
|
164
|
+
|
165
|
+
</TabItem>
|
166
|
+
</Tabs>
|
167
|
+
|
168
|
+
我们将原本两个 `page.tsx` 中公共的部分抽离出来,`src/containers/Contacts.tsx` 的代码如下:
|
169
|
+
|
170
|
+
```tsx
|
171
|
+
import { Helmet } from "@modern-js/runtime/head";
|
172
|
+
import { useModel } from "@modern-js/runtime/model";
|
173
|
+
import { List } from "antd";
|
174
|
+
import Item from "../components/Item";
|
175
|
+
import contacts from "../models/contacts";
|
176
|
+
|
177
|
+
function Contacts({
|
178
|
+
title,
|
179
|
+
source,
|
180
|
+
}: {
|
181
|
+
title: string;
|
182
|
+
source: "items" | "archived";
|
183
|
+
}) {
|
184
|
+
const [state, { archive }] = useModel(contacts);
|
185
|
+
|
186
|
+
return (
|
187
|
+
<div className="container lg mx-auto">
|
188
|
+
<Helmet>
|
189
|
+
<title>{title}</title>
|
190
|
+
</Helmet>
|
191
|
+
<List
|
192
|
+
dataSource={state[source]}
|
193
|
+
renderItem={(info) => (
|
194
|
+
<Item
|
195
|
+
key={info.name}
|
196
|
+
info={info}
|
197
|
+
onArchive={() => {
|
198
|
+
archive(info.email);
|
199
|
+
}}
|
200
|
+
/>
|
201
|
+
)}
|
202
|
+
/>
|
203
|
+
</div>
|
204
|
+
);
|
205
|
+
}
|
206
|
+
|
207
|
+
export default Contacts;
|
208
|
+
```
|
209
|
+
|
210
|
+
修改 `src/routes/page.tsx` 和 `src/routes/archives/page.tsx` 的代码:
|
211
|
+
|
212
|
+
```tsx title="src/routes/page.tsx"
|
213
|
+
import Contacts from "../containers/Contacts";
|
214
|
+
|
215
|
+
function Index() {
|
216
|
+
return <Contacts title="All" source="items" />;
|
217
|
+
}
|
218
|
+
|
219
|
+
export default Index;
|
220
|
+
```
|
221
|
+
|
222
|
+
```tsx title="src/routes/archives/page.tsx"
|
223
|
+
import Contacts from "../../containers/Contacts";
|
224
|
+
|
225
|
+
function Index() {
|
226
|
+
return <Contacts title="Archives" source="archived" />;
|
227
|
+
}
|
228
|
+
|
229
|
+
export default Index;
|
230
|
+
```
|
231
|
+
|
232
|
+
重构完成,现在的项目结构是:
|
233
|
+
|
234
|
+
```md
|
235
|
+
.
|
236
|
+
├── README.md
|
237
|
+
├── dist
|
238
|
+
├── modern.config.ts
|
239
|
+
├── node_modules
|
240
|
+
├── package.json
|
241
|
+
├── pnpm-lock.yaml
|
242
|
+
├── src
|
243
|
+
│ ├── components
|
244
|
+
│ │ ├── Avatar
|
245
|
+
│ │ │ └── index.tsx
|
246
|
+
│ │ └── Item
|
247
|
+
│ │ └── index.tsx
|
248
|
+
│ ├── containers
|
249
|
+
│ │ └── Contacts.tsx
|
250
|
+
│ ├── models
|
251
|
+
│ │ └── contacts.ts
|
252
|
+
│ ├── modern-app-env.d.ts
|
253
|
+
│ ├── routes
|
254
|
+
│ │ ├── archives
|
255
|
+
│ │ │ └── page.tsx
|
256
|
+
│ │ ├── layout.tsx
|
257
|
+
│ │ └── page.tsx
|
258
|
+
│ └── styles
|
259
|
+
│ └── utils.css
|
260
|
+
└── tsconfig.json
|
261
|
+
```
|
262
|
+
|
263
|
+
`components/` 里的**视图组件**,都是目录形式,如 `Avatar/index.tsx`。而 `containers/` 里的**容器组件**,都是单文件形式,如 `contacts.tsx`。**这是我们推荐的一种最佳实践**。
|
264
|
+
|
265
|
+
在 [添加 UI 组件(Component)](./c02-component.md) 章节提到过,视图组件用目录形式,是因为视图组件负责实现 UI 展示和交互细节,可以演变的复杂。用目录形式,可以方便增加子文件,包括专用的资源(图片等)、专用子组件、CSS 文件等。在这个目录内部可以随意重构,只考虑最小局部。
|
266
|
+
|
267
|
+
而容器组件只负责连接,是一个胶水层,复杂的业务逻辑和实现细节都交给 View 层和 Model 层去实现。容器组件自己应该保持简单清晰,不应该包含复杂实现细节,所以不应该有内部结构。采用单文件形式不但更简洁,也能起到约束作用,提醒开发者不要把容器组件写复杂。
|
268
|
+
|
@@ -0,0 +1,134 @@
|
|
1
|
+
---
|
2
|
+
title: 添加应用入口
|
3
|
+
---
|
4
|
+
|
5
|
+
上一个章节中,我们基本完成了联系人列表应用的开发,介绍了 Modern.js 中部分功能的用法,以及推荐的最佳实践。
|
6
|
+
|
7
|
+
这一章节中,我们将介绍如何为应用添加新的入口。
|
8
|
+
|
9
|
+
## 新建入口
|
10
|
+
|
11
|
+
一个完整的项目可能需要多个入口,Modern.js 支持自动创建新入口,前面的章节中提到过,`pnpm run new` 可以启用可选功能。
|
12
|
+
|
13
|
+
我们也可以通过它来创建新的工程元素,在项目根目录下执行 `pnpm run new`:
|
14
|
+
|
15
|
+
```bash
|
16
|
+
? 请选择你想要的操作 创建工程元素
|
17
|
+
? 创建工程元素 新建「应用入口」
|
18
|
+
? 请填写入口名称 (entry) landing-page
|
19
|
+
```
|
20
|
+
|
21
|
+
创建完成,项目会变成这样:
|
22
|
+
|
23
|
+
```md
|
24
|
+
.
|
25
|
+
├── README.md
|
26
|
+
├── modern.config.ts
|
27
|
+
├── node_modules
|
28
|
+
├── package.json
|
29
|
+
├── pnpm-lock.yaml
|
30
|
+
├── src
|
31
|
+
│ ├── modern-app-env.d.ts
|
32
|
+
│ ├── landing-page
|
33
|
+
│ │ └── routes
|
34
|
+
│ │ ├── index.css
|
35
|
+
│ │ ├── layout.tsx
|
36
|
+
│ │ └── page.tsx
|
37
|
+
│ └── myapp
|
38
|
+
│ ├── components
|
39
|
+
│ │ ├── Avatar
|
40
|
+
│ │ │ └── index.tsx
|
41
|
+
│ │ └── Item
|
42
|
+
│ │ └── index.tsx
|
43
|
+
│ ├── containers
|
44
|
+
│ │ └── Contacts.tsx
|
45
|
+
│ ├── models
|
46
|
+
│ │ └── contacts.ts
|
47
|
+
│ ├── routes
|
48
|
+
│ │ ├── archives
|
49
|
+
│ │ │ └── page.tsx
|
50
|
+
│ │ ├── layout.tsx
|
51
|
+
│ │ └── page.tsx
|
52
|
+
│ └── styles
|
53
|
+
│ └── utils.css
|
54
|
+
└── tsconfig.json
|
55
|
+
|
56
|
+
```
|
57
|
+
|
58
|
+
可以看到联系人列表应用的文件,都被自动重构到 `src/myapp/` 里。
|
59
|
+
|
60
|
+
同时新建了一个 `src/landing-page/`,里面同样有 `routes/*`(`pnpm run new` 命令只做了这些事,所以你也可以很容易的手动创建新入口或修改入口)
|
61
|
+
|
62
|
+
执行 `pnpm run dev`,显示:
|
63
|
+
|
64
|
+

|
65
|
+
|
66
|
+
访问 `http://localhost:8080/`,可以像之前一样看到应用程序。
|
67
|
+
|
68
|
+
访问 `http://localhost:8080/landing-page`,可以看到刚创建的新入口 `landing-page` 的页面(Modern.js 自动生成的默认页面)。
|
69
|
+
|
70
|
+
Modern.js 框架的设计原则之一是【[约定优于配置(Convention over Configuration)](https://en.wikipedia.org/wiki/Convention_over_configuration)】,多数情况下可以按约定直接写代码,不需要做任何配置,这里 `src/` 中的目录结构就是一种约定:
|
71
|
+
|
72
|
+
`src/myapp/` 和 `src/landing-page/` 被自动识别为两个应用入口:myapp 和 landing-page。
|
73
|
+
|
74
|
+
其中 `src/myapp/` 的目录名跟项目名(`package.json` 里的 `name`)一致,会被认为是项目**主入口**,项目 URL 的根路径(开发环境里默认是 `http://localhost:8080/`)会自动指向主入口。
|
75
|
+
|
76
|
+
其他入口的 URL,是在根路径后追加入口名,比如 `http://localhost:8080/landing-page`。
|
77
|
+
|
78
|
+
接下来,我们把 `src/myapp/` 重命名为 `src/contacts/`:
|
79
|
+
|
80
|
+
```bash
|
81
|
+
mv src/myapp src/contacts
|
82
|
+
```
|
83
|
+
|
84
|
+
再次执行 `pnpm run dev`,结果变成:
|
85
|
+
|
86
|
+

|
87
|
+
|
88
|
+
现在不再有主入口,联系人列表现在是一个普通入口,需要用 `http://localhost:8080/contacts` 访问。
|
89
|
+
|
90
|
+
|
91
|
+
## 按入口修改配置
|
92
|
+
|
93
|
+
我们可以在 Modern.js 配置文件里,自己写代码来控制项目的配置。
|
94
|
+
|
95
|
+
现在,修改 `modern.config.ts` 里面添加内容:
|
96
|
+
|
97
|
+
```typescript
|
98
|
+
import { defineConfig } from '@modern-js/app-tools';
|
99
|
+
|
100
|
+
export default defineConfig({
|
101
|
+
runtime: {
|
102
|
+
router: true,
|
103
|
+
state: true,
|
104
|
+
},
|
105
|
+
server: {
|
106
|
+
ssr: true,
|
107
|
+
ssrByEntries: {
|
108
|
+
'landing-page': false,
|
109
|
+
},
|
110
|
+
},
|
111
|
+
});
|
112
|
+
```
|
113
|
+
|
114
|
+
执行 `pnpm run dev`,再用浏览器打开 `view-source:http://localhost:8080/landing-page`,可以看到 `landing-page` 网页内容是通过 js 动态加载的,且此页面的 SSR 功能被关闭。
|
115
|
+
|
116
|
+
如果注释掉 `ssrByEntries` 和它的值,landing-page 的 SSR 功能就恢复开启了。
|
117
|
+
|
118
|
+
还有一些时候,需要一些更复杂的逻辑来做设置,比如需要 JS 变量、表达式、导入模块等,例如在只在开发环境里开启 SSR:
|
119
|
+
|
120
|
+
```js
|
121
|
+
export default defineConfig({
|
122
|
+
server: {
|
123
|
+
ssrByEntries: {
|
124
|
+
'landing-page': process.env.NODE_ENV !== 'production',
|
125
|
+
},
|
126
|
+
},
|
127
|
+
};
|
128
|
+
```
|
129
|
+
|
130
|
+
到底为止,我们的联系人列表应用的雏形就基本完成了 👏👏👏。
|
131
|
+
|
132
|
+
## 下一步
|
133
|
+
|
134
|
+
接下来你可以通过了解[指南](/docs/guides/overview)、[配置](/docs/configure/app/usage) 等更多教程,进一步完善你的应用。
|
@@ -31,11 +31,11 @@ Modern.js 能为开发者提供极致的**开发体验(Development Experience
|
|
31
31
|
- 🏠 **一体化**:开发与生产环境 Web Server 唯一,CSR 和 SSR 同构开发,函数即接口的 API 服务调用。
|
32
32
|
- 📦 **开箱即用**:默认 TS 支持,内置构建、ESLint、调试工具,全功能可测试。
|
33
33
|
- 🌏 **周边生态**:自研状态管理、微前端、模块打包、Monorepo 方案等周边需求。
|
34
|
-
- 🕸
|
34
|
+
- 🕸 **多种路由模式**:包含自控路由、基于文件约定的路由(嵌套路由)等。
|
35
35
|
- 🚀 **独立构建核心**:支持多种打包工具,深度优化构建产物。
|
36
36
|
|
37
37
|
## 下一步
|
38
38
|
|
39
39
|
如果你是前端初学者,可能会觉得这些概念有些复杂。我们提供了一些 [JavaScript 和 React](/docs/tutorials/foundations/basic) 的学习资料,你可以先对它们做些了解。
|
40
40
|
|
41
|
-
如果你是有经验的开发者,希望了解如何使用 Modern.js,你可以尝试[创建第一个应用](/docs/tutorials/first-app/
|
41
|
+
如果你是有经验的开发者,希望了解如何使用 Modern.js,你可以尝试[创建第一个应用](/docs/tutorials/first-app/c01-start),或是阅读[指南](/docs/guides/overview)。
|
@@ -1,25 +0,0 @@
|
|
1
|
-
---
|
2
|
-
sidebar_position: 1
|
3
|
-
title: Default Alias
|
4
|
-
---
|
5
|
-
|
6
|
-
Modern.js recommend referring to the source code by alias, which contains 3 default aliases:
|
7
|
-
- `@/`: the file under the project root directory `src/* `.
|
8
|
-
- `@api/`: the file under the `api/*` in the project root directory (you need to enable the BFF first).
|
9
|
-
- `@shared/`: the file under the project root directory `shared/* `.
|
10
|
-
|
11
|
-
:::tip
|
12
|
-
In addition, developers can customize aliases in modern.config.js, see [Aliases](/docs/configure/app/source/alias) for detail.
|
13
|
-
:::
|
14
|
-
|
15
|
-
|
16
|
-
## Example
|
17
|
-
|
18
|
-
The following example shows how to reference a function by default alias.
|
19
|
-
|
20
|
-
```tsx
|
21
|
-
import { hello } from '@/common/utils';
|
22
|
-
|
23
|
-
hello();
|
24
|
-
```
|
25
|
-
A reference to `@/common/utils` is equal to a reference to `src/common/utils`.
|