diff --git a/Dockerfile.admin b/Dockerfile.admin
index 805813fe..b7255f1d 100644
--- a/Dockerfile.admin
+++ b/Dockerfile.admin
@@ -1,4 +1,4 @@
-FROM node:16 AS builder
+FROM node:18-alpine AS builder
# set working directory
WORKDIR /app
# install app dependencies
@@ -8,8 +8,9 @@ COPY package.json ./
COPY yarn.lock ./
# Installs all node packages
# RUN npm ci
-RUN npm install yarn --global --force
-RUN yarn install --immutable --immutable-cache --check-cache
+RUN yarn set version 3.3.0
+RUN yarn install
+# --immutable --immutable-cache --check-cache
# Copies everything over to Docker environment
diff --git a/Dockerfile.ticket b/Dockerfile.ticket
index f8208a24..449bb478 100644
--- a/Dockerfile.ticket
+++ b/Dockerfile.ticket
@@ -1,4 +1,4 @@
-FROM node:16-alpine AS builder
+FROM node:18-alpine AS builder
# set working directory
WORKDIR /app
# install app dependencies
@@ -8,8 +8,7 @@ COPY package.json ./
COPY yarn.lock ./
# Installs all node packages
# RUN npm ci
-RUN npm install yarn --global --force
-RUN yarn install --immutable --immutable-cache --check-cache
+RUN yarn set version 3.3.0
# Copies everything over to Docker environment
@@ -35,4 +34,4 @@ RUN rm -rf apps/ticket/.next/cache
# COPY --from=builder /app/build /usr/share/nginx/html/
# Containers run nginx with global directives and daemon off
EXPOSE 3000
-CMD ["yarn", "ticket:start"]
+CMD ["yarn", "ticket:start"]
\ No newline at end of file
diff --git a/README.md b/README.md
index 10c07ef1..e6325461 100644
--- a/README.md
+++ b/README.md
@@ -108,7 +108,7 @@ yarn admin
- [프론트엔드 모노레포 구축 삽질기 (3) - CICD 배포, Docker, Github Actions](https://9yujin.tistory.com/102?category=1013884)
- [서버 사이드 렌더링(SSR)과 cookie 로그인 정보 다루기](https://www.9yujin.site/devlog/frontend/ssr-230122)
- [선언적인 코드 작성하기](https://9yujin.tistory.com/109)
-
+-[웹 성능 최적화](https://9yujin.tistory.com/116)
diff --git a/apps/admin/index.html b/apps/admin/index.html
index e0d535b7..3246b9d1 100644
--- a/apps/admin/index.html
+++ b/apps/admin/index.html
@@ -6,10 +6,17 @@
+
+
두둥! - 어드민
diff --git a/apps/admin/src/components/shared/overlay/GlobalOverlay.tsx b/apps/admin/src/components/shared/overlay/GlobalOverlay.tsx
index 8c926622..27984228 100644
--- a/apps/admin/src/components/shared/overlay/GlobalOverlay.tsx
+++ b/apps/admin/src/components/shared/overlay/GlobalOverlay.tsx
@@ -1,8 +1,8 @@
import { Modal } from '@dudoong/ui';
import useGlobalOverlay from '@lib/hooks/useGlobalOverlay';
import { overlayState } from '@store/globalOverlay';
-import { ReactNode } from 'react';
import { useRecoilValue } from 'recoil';
+
import Approve from './content/Approve';
import DeleteEvent from './content/DeleteEvent';
import Invitation from './content/Invitation';
diff --git a/apps/ticket/next.config.js b/apps/ticket/next.config.js
index 298e103e..3f19e3ed 100644
--- a/apps/ticket/next.config.js
+++ b/apps/ticket/next.config.js
@@ -2,42 +2,49 @@
// eslint-disable-next-line no-undef
const withInterceptStdout = require('next-intercept-stdout');
+const withBundleAnalyzer = require('@next/bundle-analyzer')({
+ enabled: process.env.ANALYZE === 'true',
+});
+
const withTM = require('next-transpile-modules')([
'@dudoong/ui',
'@dudoong/utils',
'date-fns',
]);
-module.exports = withInterceptStdout(
- withTM({
- // Any additional config for next goes in here
- swcMinify: true,
- webpack: (config, options) => {
- config.module.rules.push({
- test: /\.svg$/,
- use: [
- options.defaultLoaders.babel,
- {
- loader: '@svgr/webpack',
- options: { babel: false },
- },
- ],
- });
- return config;
- },
- images: {
- domains: ['asset.dudoong.com'],
- },
- rewrites: async () => [
- {
- source: '/meta/term',
- destination: '/term.html',
+module.exports = withBundleAnalyzer(
+ withInterceptStdout(
+ withTM({
+ // Any additional config for next goes in here
+ swcMinify: true,
+ webpack: (config, options) => {
+ config.module.rules.push({
+ test: /\.svg$/,
+ use: [
+ options.defaultLoaders.babel,
+ {
+ loader: '@svgr/webpack',
+ options: { babel: false },
+ },
+ ],
+ });
+ return config;
},
- {
- source: '/meta/privacy',
- destination: '/privacy.html',
+ images: {
+ domains: ['asset.dudoong.com'],
+ minimumCacheTTL: 5184000,
},
- ],
- }),
- (text) => (text.includes('Duplicate atom key') ? '' : text),
+ rewrites: async () => [
+ {
+ source: '/meta/term',
+ destination: '/term.html',
+ },
+ {
+ source: '/meta/privacy',
+ destination: '/privacy.html',
+ },
+ ],
+ }),
+ (text) => (text.includes('Duplicate atom key') ? '' : text),
+ ),
);
diff --git a/apps/ticket/package.json b/apps/ticket/package.json
index 7a1d988c..82b2abfe 100644
--- a/apps/ticket/package.json
+++ b/apps/ticket/package.json
@@ -15,6 +15,7 @@
"@emotion/styled": "^11.10.5",
"@next/font": "13.0.7",
"@toast-ui/react-editor": "^3.2.2",
+ "@toss/impression-area": "^1.3.1",
"@tosspayments/payment-widget-sdk": "^0.5.2",
"@types/node": "18.11.16",
"@types/react": "18.0.26",
@@ -30,6 +31,7 @@
"react-dom": "18.2.0",
"react-spring-bottom-sheet": "^3.4.1",
"recoil": "^0.7.6",
+ "sharp": "^0.32.1",
"swiper": "^9.0.5",
"typescript": "4.9.4"
},
diff --git a/apps/ticket/pages/_app.tsx b/apps/ticket/pages/_app.tsx
index 0ee43e86..bf404a3c 100644
--- a/apps/ticket/pages/_app.tsx
+++ b/apps/ticket/pages/_app.tsx
@@ -10,7 +10,8 @@ import type { AppProps, AppContext } from 'next/app';
import { useEffect, useState } from 'react';
import { MutableSnapshot, RecoilRoot } from 'recoil';
import 'react-spring-bottom-sheet/dist/style.css';
-import GlobalOverlay from '@components/shared/overlay/GlobalOverlay';
+import dynamic from 'next/dynamic';
+//import GlobalOverlay from '@components/shared/overlay/GlobalOverlay';
import { OauthLoginResponse } from '@dudoong/utils';
import { authState } from '@store/auth';
import { setCredentials } from '@lib/utils/setCredentials';
@@ -22,6 +23,11 @@ import { axiosPrivate } from '@lib/apis/axios';
import Script from 'next/script';
import { GA_TRACKING_ID } from '@lib/utils/gtag';
+const GlobalOverlay = dynamic(
+ () => import('@components/shared/overlay/GlobalOverlay'),
+ { ssr: false },
+);
+
interface MyAppProps extends AppProps {
loginData: OauthLoginResponse | null;
}
@@ -52,6 +58,10 @@ function MyApp({ Component, pageProps, loginData }: MyAppProps) {
name="viewport"
content="initial-scale=1.0,user-scalable=no,maximum-scale=1,width=device-width"
/>
+
{/* Global Site Tag (gtag.js) - Google Analytics */}