@modern-js/main-doc 2.33.1 → 2.35.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/docs/en/apis/app/hooks/config/public.mdx +2 -2
  2. package/docs/en/apis/app/hooks/config/upload.mdx +3 -3
  3. package/docs/en/components/tech-stack-node-framework.mdx +1 -0
  4. package/docs/en/configure/app/server/ssr.mdx +2 -0
  5. package/docs/en/configure/app/source/config-dir.mdx +2 -2
  6. package/docs/en/guides/advanced-features/eslint.mdx +1 -1
  7. package/docs/en/guides/basic-features/alias.mdx +11 -50
  8. package/docs/en/guides/basic-features/env-vars.mdx +1 -1
  9. package/docs/en/guides/basic-features/routes.mdx +4 -4
  10. package/docs/en/guides/concept/builder.mdx +1 -1
  11. package/docs/en/guides/get-started/glossary.mdx +1 -1
  12. package/docs/en/guides/get-started/introduction.mdx +21 -1
  13. package/docs/en/guides/get-started/tech-stack.mdx +138 -0
  14. package/docs/en/guides/topic-detail/changesets/add.mdx +1 -1
  15. package/docs/en/guides/topic-detail/changesets/changelog.mdx +3 -3
  16. package/docs/en/guides/topic-detail/changesets/commit.mdx +3 -3
  17. package/docs/en/guides/topic-detail/changesets/release-note.mdx +3 -3
  18. package/docs/en/guides/topic-detail/changesets/release.mdx +1 -1
  19. package/docs/en/guides/topic-detail/framework-plugin/implement.mdx +4 -4
  20. package/docs/en/guides/topic-detail/generator/create/use.mdx +1 -9
  21. package/docs/en/guides/topic-detail/generator/plugin/context.md +1 -1
  22. package/docs/en/tutorials/examples/_category_.json +5 -0
  23. package/docs/en/tutorials/examples/csr-auth.mdx +214 -0
  24. package/docs/en/tutorials/foundations/introduction.mdx +10 -1
  25. package/docs/zh/community/blog/2022-0708-updates.md +4 -4
  26. package/docs/zh/community/blog/overview.md +1 -1
  27. package/docs/zh/components/tech-stack-node-framework.mdx +1 -0
  28. package/docs/zh/configure/app/server/ssr.mdx +3 -0
  29. package/docs/zh/guides/advanced-features/eslint.mdx +1 -1
  30. package/docs/zh/guides/basic-features/alias.mdx +11 -50
  31. package/docs/zh/guides/basic-features/routes.mdx +1 -1
  32. package/docs/zh/guides/get-started/introduction.mdx +20 -0
  33. package/docs/zh/guides/get-started/tech-stack.mdx +138 -0
  34. package/docs/zh/guides/topic-detail/changesets/add.mdx +1 -1
  35. package/docs/zh/guides/topic-detail/changesets/changelog.mdx +3 -3
  36. package/docs/zh/guides/topic-detail/changesets/commit.mdx +3 -3
  37. package/docs/zh/guides/topic-detail/changesets/release-note.mdx +3 -3
  38. package/docs/zh/guides/topic-detail/changesets/release.mdx +1 -1
  39. package/docs/zh/guides/topic-detail/framework-plugin/implement.mdx +5 -5
  40. package/docs/zh/guides/topic-detail/generator/create/use.mdx +0 -8
  41. package/docs/zh/guides/topic-detail/generator/plugin/context.md +1 -1
  42. package/docs/zh/tutorials/examples/_category_.json +5 -0
  43. package/docs/zh/tutorials/examples/csr-auth.mdx +214 -0
  44. package/docs/zh/tutorials/foundations/introduction.mdx +8 -0
  45. package/package.json +8 -5
  46. package/src/components/Sandpack/index.css +10 -0
  47. package/src/components/Sandpack/index.tsx +30 -0
@@ -26,7 +26,7 @@ export default function (context: IPluginContext) {
26
26
 
27
27
  ## 自定义 Input
28
28
 
29
- Modern.js Web 应用和 Npm 模块工程方案都存在一些默认的 Input 交互,使用这里的 API 可以对这些 Input 进行添加、修改、隐藏、提供默认值等操作。
29
+ Modern.js Framework Modern.js Module 都存在一些默认的 Input 交互,使用这里的 API 可以对这些 Input 进行添加、修改、隐藏、提供默认值等操作。
30
30
 
31
31
  例如:
32
32
 
@@ -0,0 +1,5 @@
1
+ {
2
+ "label": "案例",
3
+ "position": 3,
4
+ "collapsed": false
5
+ }
@@ -0,0 +1,214 @@
1
+ ---
2
+ title: 路由鉴权
3
+ ---
4
+
5
+ # 路由鉴权
6
+
7
+ Modern.js 默认提供的路由方式是基于 React Router 6 的约定式路由,具体可查看[路由方案](/guides/basic-features/routes.html#路由方案)。
8
+
9
+ 在一个 Web 应用中如果存在多个路由,我们可能需要对部分路由进行鉴权后才能访问。例如下面这个案例:
10
+
11
+ - 访问 `/` 路由,无需鉴权,可直接访问。
12
+ - 访问 `/protected` 路由,需要鉴权,如果无,自动跳转到 `/login` 路由,登录成功后返回 `/protected`。
13
+
14
+ import Sandpack from '@site/src/components/Sandpack';
15
+
16
+ <Sandpack template="web-app">
17
+ ```tsx title="src/routes/page.tsx"
18
+ import { Helmet } from '@modern-js/runtime/head';
19
+ import './index.css';
20
+
21
+ const PublicPage = (): JSX.Element => (
22
+ <div className="container-box">
23
+ <Helmet>
24
+ <link
25
+ rel="icon"
26
+ type="image/x-icon"
27
+ href="https://lf3-static.bytednsdoc.com/obj/eden-cn/uhbfnupenuhf/favicon.ico"
28
+ />
29
+ </Helmet>
30
+ <h3>Public</h3>
31
+ </div>
32
+ );
33
+
34
+ export default PublicPage;
35
+
36
+ ```
37
+ ```tsx title="src/routes/layout.tsx"
38
+ import { Link, Outlet } from '@modern-js/runtime/router';
39
+ import { AuthProvider, AuthStatus } from './Auth';
40
+
41
+ export default function Layout() {
42
+ return (
43
+ <AuthProvider>
44
+ <AuthStatus />
45
+
46
+ <ul>
47
+ <li>
48
+ <Link to="/">Public Page</Link>
49
+ </li>
50
+ <li>
51
+ <Link to="/protected">Protected Page</Link>
52
+ </li>
53
+ </ul>
54
+
55
+ <Outlet />
56
+ </AuthProvider>
57
+ );
58
+ }
59
+
60
+ ```
61
+ ```ts title="src/routes/fakeAuth.ts"
62
+ /**
63
+ * This represents some generic auth provider API, like Firebase.
64
+ */
65
+ const fakeAuthProvider = {
66
+ isAuthenticated: false,
67
+ signin(callback: VoidFunction) {
68
+ fakeAuthProvider.isAuthenticated = true;
69
+ setTimeout(callback, 100); // fake async
70
+ },
71
+ signout(callback: VoidFunction) {
72
+ fakeAuthProvider.isAuthenticated = false;
73
+ setTimeout(callback, 100);
74
+ },
75
+ };
76
+
77
+ export { fakeAuthProvider };
78
+
79
+ ```
80
+ ```ts title="src/routes/Auth.tsx"
81
+ import React from 'react';
82
+ import { useNavigate, Navigate, useLocation } from '@modern-js/runtime/router';
83
+ import { fakeAuthProvider } from './fakeAuth';
84
+
85
+ interface AuthContextType {
86
+ user: any;
87
+ signin: (user: string, callback: VoidFunction) => void;
88
+ signout: (callback: VoidFunction) => void;
89
+ }
90
+
91
+ const AuthContext = React.createContext<AuthContextType>(null!);
92
+
93
+ export function AuthProvider({ children }: { children: React.ReactNode }) {
94
+ const [user, setUser] = React.useState<any>(null);
95
+
96
+ const signin = (newUser: string, callback: VoidFunction) =>
97
+ fakeAuthProvider.signin(() => {
98
+ setUser(newUser);
99
+ callback();
100
+ });
101
+
102
+ const signout = (callback: VoidFunction) =>
103
+ fakeAuthProvider.signout(() => {
104
+ setUser(null);
105
+ callback();
106
+ });
107
+
108
+ const value = { user, signin, signout };
109
+
110
+ return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;
111
+ }
112
+
113
+ export function useAuth() {
114
+ return React.useContext(AuthContext);
115
+ }
116
+
117
+ export function AuthStatus() {
118
+ const auth = useAuth();
119
+ console.log('auth', auth);
120
+ const navigate = useNavigate();
121
+
122
+ if (!auth.user) {
123
+ return <p>You are not logged in.</p>;
124
+ }
125
+
126
+ return (
127
+ <p>
128
+ Welcome {auth.user}!{' '}
129
+ <button
130
+ type="button"
131
+ onClick={() => {
132
+ auth.signout(() => navigate('/'));
133
+ }}
134
+ >
135
+ Sign out
136
+ </button>
137
+ </p>
138
+ );
139
+ }
140
+
141
+ export function RequireAuth({ children }: { children: JSX.Element }) {
142
+ const auth = useAuth();
143
+ const location = useLocation();
144
+
145
+ if (!auth.user) {
146
+ // Redirect them to the /login page, but save the current location they were
147
+ // trying to go to when they were redirected. This allows us to send them
148
+ // along to that page after they login, which is a nicer user experience
149
+ // than dropping them off on the home page.
150
+ return <Navigate to="/login" state={{ from: location }} replace />;
151
+ }
152
+
153
+ return children;
154
+ }
155
+
156
+ ```
157
+ ```ts title="src/routes/protected/page.tsx"
158
+ import { RequireAuth } from '../Auth';
159
+
160
+ export default function ProtectedPage() {
161
+ return (
162
+ <div className="container-box">
163
+ <RequireAuth>
164
+ <h3>Protected</h3>
165
+ </RequireAuth>
166
+ </div>
167
+ );
168
+ }
169
+
170
+ ```
171
+ ```ts title="src/routes/login/page.tsx"
172
+ import { useLocation, useNavigate } from '@modern-js/runtime/router';
173
+ import { useAuth } from '../Auth';
174
+
175
+ export default function Login() {
176
+ const navigate = useNavigate();
177
+ const location = useLocation();
178
+ const auth = useAuth();
179
+
180
+ const from = location.state?.from?.pathname || '/';
181
+
182
+ function handleSubmit(event: React.FormEvent<HTMLFormElement>) {
183
+ event.preventDefault();
184
+
185
+ const formData = new FormData(event.currentTarget);
186
+ const username = formData.get('username') as string;
187
+
188
+ auth.signin(username, () => {
189
+ // Send them back to the page they tried to visit when they were
190
+ // redirected to the login page. Use { replace: true } so we don't create
191
+ // another entry in the history stack for the login page. This means that
192
+ // when they get to the protected page and click the back button, they
193
+ // won't end up back on the login page, which is also really nice for the
194
+ // user experience.
195
+ navigate(from, { replace: true });
196
+ });
197
+ }
198
+
199
+ return (
200
+ <div>
201
+ <p>You must log in to view the page at {from}</p>
202
+
203
+ <form onSubmit={handleSubmit}>
204
+ <label>
205
+ Username: <input name="username" type="text" />
206
+ </label>{' '}
207
+ <button type="submit">Login</button>
208
+ </form>
209
+ </div>
210
+ );
211
+ }
212
+
213
+ ```
214
+ </Sandpack>
@@ -27,4 +27,12 @@ sidebar_position: 1
27
27
  - 新建入口
28
28
  - ...
29
29
 
30
+ ## 案例
31
+
32
+ 我们提供了一些在开发过程中常用的案例供你参考,可以在这里找到 Modern.js 提供的一些功能组合的使用方式,我们将持续完善这里的案例。
33
+
34
+ - [路由鉴权](/tutorials/examples/csr-auth.html)
35
+ - ...
36
+
30
37
  下面就让我们从 [创建项目](tutorials/first-app/c01-start) 开始吧!
38
+
package/package.json CHANGED
@@ -15,14 +15,17 @@
15
15
  "modern",
16
16
  "modern.js"
17
17
  ],
18
- "version": "2.33.1",
18
+ "version": "2.35.0",
19
19
  "publishConfig": {
20
20
  "registry": "https://registry.npmjs.org/",
21
21
  "access": "public",
22
22
  "provenance": true
23
23
  },
24
+ "dependencies": {
25
+ "@modern-js/sandpack-react": "2.35.0"
26
+ },
24
27
  "peerDependencies": {
25
- "@modern-js/builder-doc": "^2.33.1"
28
+ "@modern-js/builder-doc": "^2.35.0"
26
29
  },
27
30
  "devDependencies": {
28
31
  "classnames": "^2",
@@ -32,12 +35,12 @@
32
35
  "ts-node": "^10.9.1",
33
36
  "typescript": "^5",
34
37
  "fs-extra": "^10",
35
- "rspress": "0.0.6",
38
+ "rspress": "0.0.10",
36
39
  "@rspress/shared": "0.0.6",
37
40
  "@types/node": "^16",
38
41
  "@types/fs-extra": "^9",
39
- "@modern-js/builder-doc": "2.33.1",
40
- "@modern-js/doc-plugin-auto-sidebar": "2.33.1"
42
+ "@modern-js/builder-doc": "2.35.0",
43
+ "@modern-js/doc-plugin-auto-sidebar": "2.35.0"
41
44
  },
42
45
  "scripts": {
43
46
  "dev": "rspress dev",
@@ -0,0 +1,10 @@
1
+ .light {
2
+ --sp-layout-height: 500px !important;
3
+ }
4
+
5
+ .dark {
6
+ --sp-layout-height: 500px !important;
7
+ }
8
+ .sp-read-only {
9
+ display: none;
10
+ }
@@ -0,0 +1,30 @@
1
+ import ModernSandpack, { ModernSandpackProps } from '@modern-js/sandpack-react';
2
+ import React, { PropsWithChildren } from 'react';
3
+ import { useDark, NoSSR } from 'rspress/runtime';
4
+
5
+ import './index.css';
6
+
7
+ const Sandpack = (props: PropsWithChildren<ModernSandpackProps>) => {
8
+ const dark = useDark();
9
+ const { children, ...otherProps } = props;
10
+ const files: Record<string, string> = {};
11
+ React.Children.forEach(children, (child: any) => {
12
+ if (child) {
13
+ const { meta, children } = child.props.children.props;
14
+ const matches = meta.match(/title="(.*)"/);
15
+ if (matches.length > 1) {
16
+ files[matches[1]] = children;
17
+ }
18
+ }
19
+ });
20
+ return (
21
+ <NoSSR>
22
+ <ModernSandpack
23
+ files={files}
24
+ theme={dark ? 'dark' : 'light'}
25
+ {...otherProps}
26
+ />
27
+ </NoSSR>
28
+ );
29
+ };
30
+ export default Sandpack;