이어서 할 곳

GitHub - fc-micro-frontends/career-up at step15

REACT_APP_AUTH0_DOMAIN=dev-vcrmf0xuep020tri.us.auth0.com
REACT_APP_AUTH0_CLIENT_ID=27LLb4I9cIjiiQNSjbNIX9sQM1KECUfk
REACT_APP_AUTH0_CALLBACK_URL=http://localhost:3000
➜ pnpm i

➜ pnpm build

shell-router 로 Auth0ClientProvider 와 useAuth0Client 이동

➜ pnpm --filter @career-up/shell-router add @auth0/auth0-spa-js
// career-up/packages/shell-router/src/providers/auth0-client-provider.tsx

import React from "react";
import { Auth0Client } from "@auth0/auth0-spa-js";

export const Auth0ClientContext = React.createContext<Auth0Client | null>(null);

type Auth0ClientProviderProps = React.PropsWithChildren<{
  options: {
    domain: string;
    clientId: string;
    redirectUri: string;
  };
}>;

const Auth0ClientProvider: React.FC<Auth0ClientProviderProps> = ({
  options: { domain, clientId, redirectUri },
  children,
}) => {
  const auth0Client = new Auth0Client({
    domain,
    clientId,
    authorizationParams: {
      redirect_uri: redirectUri,
    },
  });

  return (
    <Auth0ClientContext.Provider value={auth0Client}>
      {children}
    </Auth0ClientContext.Provider>
  );
};

export default Auth0ClientProvider;
// career-up/packages/shell-router/src/hooks/use-auth0-client.ts

import { useContext } from "react";
import { Auth0ClientContext } from "../providers/auth0-client-provider";

export default function useAuth0Client() {
  const auth0Client = useContext(Auth0ClientContext);

  if (auth0Client === null) {
    throw new Error("useAuth0Client must be used within Auth0ClientProvider");
  }

  return auth0Client;
}
// career-up/packages/shell-router/src/index.ts

import useShellEvent from "./hooks/use-shell-event";
import { injectFactory } from "./injector";
import AppRoutingManager from "./components/app-routing-manager";
**import Auth0ClientProvider from "./providers/auth0-client-provider";**
**import useAuth0Client from "./hooks/use-auth0-client";**

export {
  useShellEvent,
  injectFactory,
  AppRoutingManager,
  **Auth0ClientProvider,
  useAuth0Client,**
};

export type * from "./types";
{
  "name": "@career-up/shell-router",
  "private": true,
  "version": "0.0.0",
  "type": "module",
  "exports": {
    ".": {
      "types": "./dist/index.d.ts",
      "require": "./dist/index.umd.cjs",
      "import": "./dist/index.js"
    }
  },
  "types": "./dist/index.d.ts",
  "main": "./dist/index.umd.cjs",
  "scripts": {
    "build": "tsc && vite build",
    "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0"
  },
  "peerDependencies": {
    **"@auth0/auth0-spa-js": "^2.1.3",**
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-router-dom": "^6.21.1"
  },
  "devDependencies": {
    **"@auth0/auth0-spa-js": "^2.1.3",**
    "@types/react": "^18.2.43",
    "@types/react-dom": "^18.2.17",
    "@typescript-eslint/eslint-plugin": "^6.14.0",
    "@typescript-eslint/parser": "^6.14.0",
    "@vitejs/plugin-react-swc": "^3.5.0",
    "eslint": "^8.55.0",
    "eslint-plugin-react-hooks": "^4.6.0",
    "eslint-plugin-react-refresh": "^0.4.5",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-router-dom": "^6.21.1",
    "typescript": "^5.2.2",
    "vite": "^5.0.8",
    "vite-plugin-dts": "^3.6.4"
  }
}
// career-up/packages/shell-router/vite.config.ts

import { defineConfig } from "vite";
import react from "@vitejs/plugin-react-swc";
import dts from "vite-plugin-dts";

// <https://vitejs.dev/config/>
export default defineConfig({
  plugins: [react(), dts({ insertTypesEntry: true })],
  build: {
    lib: {
      entry: "src/index.ts",
      name: "shell-router",
      fileName: "index",
    },
    rollupOptions: {
      external: [
        "react",
        "react-dom",
        "react-router-dom",
        **"@auth0/auth0-spa-js",**
      ],
      output: {
        globals: {
          react: "React",
          "react-dom": "ReactDOM",
          "react-router-dom": "ReactRouterDOM",
          **"@auth0/auth0-spa-js": "auth0",**
        },
      },
    },
  },
});
➜ pnpm --filter @career-up/shell-router build

마이크로앱에서 Auth0ClientProvider 와 useAuth0Client 사용 변경

// career-up/apps/posting/src/routes.tsx

import React from "react";
import { type RouteObject } from "react-router-dom";
import {
  AppRoutingManager,
  **Auth0ClientProvider,**
} from "@career-up/shell-router";
import PageHome from "./pages/page-home";

**const domain = process.env.REACT_APP_AUTH0_DOMAIN!;
const clientId = process.env.REACT_APP_AUTH0_CLIENT_ID!;
const redirectUri = process.env.REACT_APP_AUTH0_CALLBACK_URL!;**

export const routes: RouteObject[] = [
  {
    path: "/",
    element: (
      <Auth0ClientProvider **options={{ domain, clientId, redirectUri }}**>
        <AppRoutingManager type="app-posting" />
      </Auth0ClientProvider>
    ),
    errorElement: <div>App Posting Error</div>,
    children: [
      {
        index: true,
        element: <PageHome />,
      },
    ],
  },
];
// career-up/apps/posting/src/pages/page-home.tsx

import "./page-home.scss";

import React, { useEffect, useState } from "react";
import Profile from "../components/profile";
import Post from "../components/post";
import WritePost from "../components/write-post";
import { createPost, getPosts, removePost } from "../apis";
import { type PostType } from "../types";
**import { useAuth0Client } from "@career-up/shell-router";**

const PageHome: React.FC = () => {
  const auth0Client = useAuth0Client();
  const [posts, setPosts] = useState<PostType[]>([]);

...
// career-up/apps/posting/src/components/profile.tsx

import "./profile.scss";

import React, { useEffect, useState } from "react";
import { getUser } from "../apis";
import { type UserType } from "../types";
**import { useAuth0Client } from "@career-up/shell-router";**

const Profile = () => {
  const auth0Client = useAuth0Client();
  const [user, setUser] = useState<UserType | null>(null);

..
// career-up/apps/edu/src/routes.tsx

import React from "react";
import { type RouteObject } from "react-router-dom";
import {
  AppRoutingManager,
  **Auth0ClientProvider,**
} from "@career-up/shell-router";
import PageList from "./pages/page-list";
import PageDetail from "./pages/page-detail";
import Layout from "./components/layout";

**const domain = process.env.REACT_APP_AUTH0_DOMAIN!;
const clientId = process.env.REACT_APP_AUTH0_CLIENT_ID!;
const redirectUri = process.env.REACT_APP_AUTH0_CALLBACK_URL!;**

export const routes: RouteObject[] = [
  {
    path: "/",
    element: (
      <Auth0ClientProvider **options={{ domain, clientId, redirectUri }}**>
        <Layout>
          <AppRoutingManager type="app-edu" />
        </Layout>
      </Auth0ClientProvider>
    ),
    errorElement: <div>App Edu Error</div>,
    children: [
      {
        index: true,
        element: <PageList />,
      },
      {
        path: ":id",
        element: <PageDetail />,
      },
    ],
  },
];
// career-up/apps/edu/src/pages/page-detail.tsx

import React, { useEffect, useMemo, useState } from "react";
import { useParams } from "react-router-dom";
import { selectAtom } from "jotai/utils";
import { coursesAtom } from "../atoms";
import { useAtomValue } from "jotai";
import CourseDetailItem from "../components/course-detail-item";
import { getCourseContents } from "../apis";
import { type CourseContentsType } from "../types";
import CourseContents from "../components/course-contents";
import CourseActions from "../components/course-actions";
**import { useAuth0Client } from "@career-up/shell-router";**

const PageDetail = () => {
  const { id } = useParams<{ id: string }>();
  const auth0Client = useAuth0Client();

...
// career-up/apps/edu/src/components/layout.tsx

import React, { useEffect } from "react";
import { LayoutWrapper } from "./layout.styles";
import { useSetAtom } from "jotai";
import { coursesAtom, userAtom } from "../atoms";
import { getCourses, getUser } from "../apis";
import ProfileContainer from "../containers/profile-container";
import MyCourseInfoContainer from "../containers/my-course-info-container";
**import { useAuth0Client } from "@career-up/shell-router";**

const Layout: React.FC<React.PropsWithChildren> = ({ children }) => {
  const auth0Client = useAuth0Client();
  const setUser = useSetAtom(userAtom);
  const setCourses = useSetAtom(coursesAtom);

...
// career-up/apps/network/src/routes.tsx

import React from "react";
import { type RouteObject } from "react-router-dom";
import {
  AppRoutingManager,
  **Auth0ClientProvider,**
} from "@career-up/shell-router";
import { RecoilRoot } from "recoil";
import Layout from "./components/layout";
import PageHome from "./pages/page-home";

**const domain = process.env.REACT_APP_AUTH0_DOMAIN!;
const clientId = process.env.REACT_APP_AUTH0_CLIENT_ID!;
const redirectUri = process.env.REACT_APP_AUTH0_CALLBACK_URL!;**

export const routes: RouteObject[] = [
  {
    path: "/",
    element: (
      <RecoilRoot>
        <Auth0ClientProvider
          **options={{
            domain,
            clientId,
            redirectUri,
          }}**
        >
          <Layout>
            <AppRoutingManager type="app-network" />
          </Layout>
        </Auth0ClientProvider>
      </RecoilRoot>
    ),
    errorElement: <div>App Network Error</div>,
    children: [
      {
        index: true,
        element: <PageHome />,
      },
    ],
  },
];