Skip to content

Commit

Permalink
Merge pull request #366 from Ludo-SMP/dev
Browse files Browse the repository at this point in the history
Lighthouse 자동화 환경 구축 및 성능 개선 후 배포
  • Loading branch information
SungHyun627 authored Aug 29, 2024
2 parents 1b384f1 + e4998c1 commit 41bc644
Show file tree
Hide file tree
Showing 85 changed files with 518 additions and 107 deletions.
11 changes: 9 additions & 2 deletions .eslintrc.cjs
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
module.exports = {
root: true,
env: { browser: true, es2020: true },
extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended', 'plugin:react-hooks/recommended', 'prettier', 'plugin:storybook/recommended'],
env: { browser: true, es2020: true, node: true },
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'plugin:react-hooks/recommended',
'prettier',
'plugin:storybook/recommended',
],
ignorePatterns: ['dist', '.eslintrc.cjs'],
parser: '@typescript-eslint/parser',
plugins: ['react-refresh'],
Expand All @@ -14,5 +20,6 @@ module.exports = {
'react/jsx-key': 'off',
// 디버그 허용
'no-debugger': 'off',
'@typescript-eslint/no-var-requires': 'off',
},
};
166 changes: 166 additions & 0 deletions .github/workflows/lighthouse.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
name: Run lighthouse CI When Push on PR to Dev Branch
on:
pull_request:
branches:
- dev
types: [synchronize, opened]

permissions:
contents: read
pull-requests: write

jobs:
lhci:
name: Lighthouse CI
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Use Node.js 20.10.0
uses: actions/setup-node@v4
with:
node-version-file: .node-version

- name: Install dependencies
run: |
yarn install --immutable --immutable-cache --check-cache
- name: Add host "local.ludo.study"
run: sudo echo "127.0.0.1 local.ludo.study" | sudo tee -a /etc/hosts

- name: Build the project
run: |
yarn build
- name: Run Lighthouse CI - Desktop
env:
LHCI_GITHUB_APP_TOKEN: ${{ secrets.LHCI_GITHUB_APP_TOKEN }}
run: |
yarn global add @lhci/cli
lhci collect --config=lighthouserc-desktop.cjs || echo "Fail to Run Lighthouse CI!"
lhci upload --config=lighthouserc-desktop.cjs || echo "Fail to Run Lighthouse CI!"
- name: Run Lighthouse CI - Mobile
env:
LHCI_GITHUB_APP_TOKEN: ${{ secrets.LHCI_GITHUB_APP_TOKEN }}
run: |
lhci collect --config=lighthouserc-mobile.cjs || echo "Fail to Run Lighthouse CI!"
lhci upload --config=lighthouserc-mobile.cjs || echo "Fail to Run Lighthouse CI!"
- name: Format Lighthouse Score
id: format_lighthouse_score
uses: actions/github-script@v7
env:
working-directory: ${{ github.workspace }}
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const fs = require('fs');
const {
LH_MONITORING_PAGE_NAMES,
DEV_ORIGIN_URL,
LH_MONITORING_PAGE_ROUTES,
LH_MIN_SCORES,
} = require('./src/Constants/lighthouse.ts');
const desktopLightHouseResults = JSON.parse(fs.readFileSync('lhci_reports/desktop/manifest.json'));
const mobileLightHouseResults = JSON.parse(fs.readFileSync('lhci_reports/mobile/manifest.json'));
let comments = `### 💡 LightHouse Reports\n\n`;
comments += `#### 🟢 90 ~ 100    🟠 50 ~ 89    🔴 0 ~ 49 \n\n`;
const getFormattingScore = (res) => Math.round(res * 100);
const getScoreColor = (score) => (score >= LH_MIN_SCORES.GREEN ? '🟢' : score >= LH_MIN_SCORES.ORANGE ? '🟠' : '🔴');
const getMonitoringPageName = (url) => {
const route = url.replace(DEV_ORIGIN_URL, '');
for (let pageName of LH_MONITORING_PAGE_NAMES) {
if (route === LH_MONITORING_PAGE_ROUTES[pageName]) return pageName;
}
};
const getFormattingResultByPage = (result) => {
const { url, summary, jsonPath } = result;
const { audits } = JSON.parse(fs.readFileSync(jsonPath));
const { performance, accessibility, 'best-practices': bestPractices, seo } = summary;
const {
'first-contentful-paint': firstContentfulPaint,
'largest-contentful-paint': largestContentfulPaint,
'speed-index': speedIndex,
'total-blocking-time': totalBlockingTime,
'cumulative-layout-shift': cumulativeLayoutShift,
} = audits;
const formattingTable = [
`| Category | Score |`,
`| --- | --- |`,
`| ${getScoreColor(getFormattingScore(performance))} Performance | ${getFormattingScore(performance)} |`,
`| ${getScoreColor(getFormattingScore(accessibility))} Accessibility | ${getFormattingScore(accessibility)} |`,
`| ${getScoreColor(getFormattingScore(bestPractices))} Best practices | ${getFormattingScore(bestPractices)} |`,
`| ${getScoreColor(getFormattingScore(seo))} SEO | ${getFormattingScore(seo)} |`,
`| ${getScoreColor(getFormattingScore(firstContentfulPaint.score))} First Contentful Paint | ${firstContentfulPaint.displayValue} |`,
`| ${getScoreColor(getFormattingScore(largestContentfulPaint.score))} Largest Contentful Paint | ${largestContentfulPaint.displayValue} |`,
`| ${getScoreColor(getFormattingScore(speedIndex.score))} Speed Index | ${speedIndex.displayValue} |`,
`| ${getScoreColor(getFormattingScore(totalBlockingTime.score))} Total Blocking Time | ${totalBlockingTime.displayValue} |`,
`| ${getScoreColor(getFormattingScore(cumulativeLayoutShift.score))} Cumulative Layout Shift | ${cumulativeLayoutShift.displayValue} |`,
`\n`,
].join('\n');
return `<details>\n<summary>${`📄 ${getMonitoringPageName(url)}\n`}</summary>\n\n${formattingTable}\n</details>\n\n`;
};
const getLightHouseFormattingResult = (results, type) => {
let comment = type === 'mobile' ? `#### 📱 Mobile\n` : `#### 🖥 Desktop\n`;
results.forEach((result) => (comment += getFormattingResultByPage(result)));
return comment + '\n';
};
comments += getLightHouseFormattingResult(desktopLightHouseResults, 'desktop');
comments += getLightHouseFormattingResult(mobileLightHouseResults, 'mobile');
core.setOutput('comments', comments)
- name: Comment PR
id: add_pr_comment
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const { Octokit } = require('@octokit/rest');
const octokit = new Octokit({ auth: `${{ secrets.GITHUB_TOKEN }}` });
const { payload, repo } = context
const newComment = `${{ steps.format_lighthouse_score.outputs.comments }}`
const { data: prevComments } = await octokit.rest.issues.listComments({
owner: repo.owner,
repo: repo.repo,
issue_number : payload.pull_request.number,
})
const prevReportComment = prevComments.find(comment => comment.body.includes(`### 💡 LightHouse Reports\n\n`));
if (prevReportComment) {
await octokit.rest.issues.updateComment({
owner: repo.owner,
repo: repo.repo,
comment_id: prevReportComment.id,
body: newComment,
});
} else {
await octokit.rest.issues.createComment({
owner: repo.owner,
repo: repo.repo,
issue_number: payload.pull_request.number,
body: newComment,
});
}
2 changes: 1 addition & 1 deletion .storybook/Ludo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export default create({
base: 'light',

brandTitle: 'Ludo',
brandUrl: 'https://ludoapi.store',
brandUrl: 'https://ludo.study',
brandImage: Logo,
brandTarget: '_self',

Expand Down
8 changes: 4 additions & 4 deletions .storybook/preview.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import type { Preview } from '@storybook/react';
import ReactQueryProvider from '@/Providers/QueryProvider';
import ReactQueryProvider from '../src/Providers/QueryProvider';
import { ThemeProvider } from 'styled-components';
import { theme } from '@/Styles/theme';
import { GlobalStyle } from '@/Styles/globalStyles';
import { theme } from '../src/Styles/theme';
import { GlobalStyle } from '../src//Styles/globalStyles';
import { withRouter } from 'storybook-addon-remix-react-router';
import { handlers } from '../src/Mocks/handlers';
import { initialize, mswLoader } from 'msw-storybook-addon';
import '../src/App.css';
import '../src/font.css';

initialize(
{
Expand Down
59 changes: 58 additions & 1 deletion index.html
Original file line number Diff line number Diff line change
@@ -1,9 +1,66 @@
<!DOCTYPE html>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/ludo.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="Ludo - 스터디 지원, 참여, 관리를 한 곳에서" />
<link
rel="preload"
fetchpriority="high"
as="image"
href="./src/Assets/images/banner1.webp"
type="image/webp"
media="(min-width: 500px)"
/>
<link
rel="preload"
fetchpriority="high"
as="image"
href="./src/Assets/images/banner2.webp"
type="image/webp"
media="(min-width: 500px)"
/>
<link
rel="preload"
fetchpriority="high"
as="image"
href="./src/Assets/images/mobilebanner1.webp"
type="image/webp"
media="(max-width: 499px)"
/>
<link
rel="preload"
fetchpriority="high"
as="image"
href="./src/Assets/images/mobilebanner2.webp"
type="image/webp"
media="(max-width: 499px)"
/>
<link
rel="preload"
fetchpriority="high"
as="font"
href="./src/Assets/fonts/Pretendard-ExtraBold-subset.woff2"
crossorigin=""
type="font/woff2"
/>
<link
rel="preload"
fetchpriority="high"
as="font"
href="./src/Assets/fonts/Pretendard-Medium-subset.woff2"
crossorigin=""
type="font/woff2"
/>
<link
rel="preload"
fetchpriority="high"
as="font"
href="./src/Assets/fonts/Pretendard-SemiBold-subset.woff2"
crossorigin=""
type="font/woff2"
/>
<title>LUDO</title>
</head>
<body>
Expand Down
26 changes: 26 additions & 0 deletions lighthouserc-desktop.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
const {
LH_MONITORING_PAGE_NAMES,
DEV_ORIGIN_URL,
LH_MONITORING_PAGE_ROUTES,
} = require('./src/Constants/lighthouse.ts');

const urls = LH_MONITORING_PAGE_NAMES.map((pageName) => `${DEV_ORIGIN_URL}${LH_MONITORING_PAGE_ROUTES[pageName]}`);

module.exports = {
ci: {
collect: {
startServerCommand: 'yarn start:mac',
url: urls,
numberOfRuns: 1,
settings: {
chromeFlags: '--ignore-certificate-errors',
preset: 'desktop',
},
},
upload: {
target: 'filesystem',
outputDir: './lhci_reports/desktop',
reportFilenamePattern: '%%PATHNAME%%-%%DATETIME%%-desktop-report.%%EXTENSION%%',
},
},
};
25 changes: 25 additions & 0 deletions lighthouserc-mobile.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
const {
LH_MONITORING_PAGE_NAMES,
DEV_ORIGIN_URL,
LH_MONITORING_PAGE_ROUTES,
} = require('./src/Constants/lighthouse.ts');

const urls = LH_MONITORING_PAGE_NAMES.map((pageName) => `${DEV_ORIGIN_URL}${LH_MONITORING_PAGE_ROUTES[pageName]}`);

module.exports = {
ci: {
collect: {
startServerCommand: 'yarn start:mac',
url: urls,
numberOfRuns: 1,
settings: {
chromeFlags: '--ignore-certificate-errors',
},
},
upload: {
target: 'filesystem',
outputDir: './lhci_reports/mobile',
reportFilenamePattern: '%%PATHNAME%%-%%DATETIME%%-mobile-report.%%EXTENSION%%',
},
},
};
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@
"ts-node": "^10.9.2",
"typescript": "^5.2.2",
"vite": "^5.0.8",
"vite-bundle-analyzer": "^0.10.5",
"vite-plugin-mkcert": "^1.17.3",
"vite-plugin-radar": "^0.9.6",
"vite-plugin-svgr": "^4.2.0"
Expand Down
41 changes: 0 additions & 41 deletions src/App.css

This file was deleted.

Binary file added src/Assets/fonts/Pretendard-Black-subset.woff
Binary file not shown.
Binary file added src/Assets/fonts/Pretendard-Black-subset.woff2
Binary file not shown.
Binary file removed src/Assets/fonts/Pretendard-Black.woff
Binary file not shown.
Binary file added src/Assets/fonts/Pretendard-Bold-subset.woff
Binary file not shown.
Binary file added src/Assets/fonts/Pretendard-Bold-subset.woff2
Binary file not shown.
Binary file removed src/Assets/fonts/Pretendard-Bold.woff
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file removed src/Assets/fonts/Pretendard-ExtraBold.woff
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file removed src/Assets/fonts/Pretendard-ExtraLight.woff
Binary file not shown.
Binary file added src/Assets/fonts/Pretendard-Light-subset.woff
Binary file not shown.
Binary file added src/Assets/fonts/Pretendard-Light-subset.woff2
Binary file not shown.
Binary file removed src/Assets/fonts/Pretendard-Light.woff
Binary file not shown.
Binary file added src/Assets/fonts/Pretendard-Medium-subset.woff
Binary file not shown.
Binary file added src/Assets/fonts/Pretendard-Medium-subset.woff2
Binary file not shown.
Binary file removed src/Assets/fonts/Pretendard-Medium.woff
Binary file not shown.
Binary file added src/Assets/fonts/Pretendard-Regular-subset.woff
Binary file not shown.
Binary file added src/Assets/fonts/Pretendard-Regular-subset.woff2
Binary file not shown.
Binary file removed src/Assets/fonts/Pretendard-Regular.woff
Binary file not shown.
Binary file added src/Assets/fonts/Pretendard-SemiBold-subset.woff
Binary file not shown.
Binary file not shown.
Binary file removed src/Assets/fonts/Pretendard-SemiBold.woff
Binary file not shown.
Binary file added src/Assets/fonts/Pretendard-Thin-subset.woff
Binary file not shown.
Binary file added src/Assets/fonts/Pretendard-Thin-subset.woff2
Binary file not shown.
Binary file removed src/Assets/fonts/Pretendard-Thin.woff
Binary file not shown.
Binary file removed src/Assets/images/background.png
Binary file not shown.
Binary file added src/Assets/images/background1.webp
Binary file not shown.
Binary file added src/Assets/images/background2.webp
Binary file not shown.
Binary file added src/Assets/images/background3.webp
Binary file not shown.
Binary file added src/Assets/images/background4.webp
Binary file not shown.
Binary file removed src/Assets/images/banner1.png
Binary file not shown.
Binary file added src/Assets/images/banner1.webp
Binary file not shown.
Binary file removed src/Assets/images/banner2.png
Binary file not shown.
Binary file added src/Assets/images/banner2.webp
Binary file not shown.
Binary file removed src/Assets/images/blank-logo.png
Binary file not shown.
Binary file added src/Assets/images/blank-logo.webp
Binary file not shown.
Binary file removed src/Assets/images/character1.png
Binary file not shown.
Binary file added src/Assets/images/character1.webp
Binary file not shown.
Binary file removed src/Assets/images/character2.png
Binary file not shown.
Binary file added src/Assets/images/character2.webp
Binary file not shown.
Binary file removed src/Assets/images/character3.png
Binary file not shown.
Binary file added src/Assets/images/character3.webp
Binary file not shown.
Binary file removed src/Assets/images/character4.png
Binary file not shown.
Binary file added src/Assets/images/character4.webp
Binary file not shown.
Binary file removed src/Assets/images/logo.png
Binary file not shown.
Binary file added src/Assets/images/logo.webp
Binary file not shown.
Binary file removed src/Assets/images/logo2.png
Binary file not shown.
Binary file added src/Assets/images/logo2.webp
Binary file not shown.
Binary file removed src/Assets/images/logo3.png
Binary file not shown.
Binary file added src/Assets/images/logo3.webp
Binary file not shown.
Binary file removed src/Assets/images/mobilebanner1.png
Binary file not shown.
Binary file added src/Assets/images/mobilebanner1.webp
Binary file not shown.
Binary file removed src/Assets/images/mobilebanner2.png
Binary file not shown.
Binary file added src/Assets/images/mobilebanner2.webp
Binary file not shown.
Loading

0 comments on commit 41bc644

Please sign in to comment.