Notice
Recent Posts
Recent Comments
Link
반응형
이로
Vue3, vite 정적, 동적 sitemap , sitemap.xml 생성하기 본문
반응형
정적 사이트맵 생성
정적 사이트 맵 생성은 특정 파일에 내가 원하는 페이지만 직접 작성하는 방법입니다.
Case 1. vite.config.ts에 sitemap 내용 직접 정의
npm install -D vite-plugin-sitemap
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { sitemap } from 'vite-plugin-sitemap'
export default defineConfig({
plugins: [
vue()
, sitemap({
hostname: 'https://your-domain.com', // 라우트 직접 정의
urls: [{
url: '/'
, lastmod: new Date().toISOString()
, changefreq: 'daily'
, priority: 1.0
},
{
url: '/about'
, lastmod: new Date().toISOString()
, changefreq: 'weekly'
, priority: 0.8
},
{
url: '/contact',
lastmod: new Date().toISOString(),
changefreq: 'monthly',
priority: 0.5
}
]
, exclude: ['/admin', '/private'], }), ], })
Case 2. vite.config.ts에서 index.ts파일 읽어와 자동으로 세팅하고, URL 예외처리할 내용만 수정하기.
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import viteCompression from 'vite-plugin-compression';
import { resolve } from 'path';
import { writeFileSync, readFileSync } from 'fs';
import * as ts from 'typescript';
function extractRoutePaths(fileContent: string): string[] {
const paths: string[] = [];
// TypeScript 소스 파일을 파싱
const sourceFile = ts.createSourceFile(
'index.ts',
fileContent,
ts.ScriptTarget.Latest,
true
);
// routes 배열을 찾아서 경로 추출
function visit(node: ts.Node) {
if (ts.isArrayLiteralExpression(node)) {
const routes = node.elements.map(element => {
if (ts.isObjectLiteralExpression(element)) {
const pathProperty = element.properties.find(prop =>
ts.isPropertyAssignment(prop) &&
prop.name.getText(sourceFile) === 'path'
);
if (pathProperty && ts.isPropertyAssignment(pathProperty)) {
const pathValue = pathProperty.initializer.getText(sourceFile);
// 따옴표 제거 및 동적 라우트 필터링
const path = pathValue.replace(/['"]/g, '');
if (!path.includes(':')) {
return path;
}
}
}
return null;
}).filter(Boolean) as string[];
paths.push(...routes);
}
ts.forEachChild(node, visit);
}
visit(sourceFile);
return paths;
}
function createSitemapPlugin(options: {
hostname: string;
routerPath: string; // router/index.ts 파일 경로
exclude?: string[];
additionalPaths?: string[];
outFile?: string;
lastmod?: string;
}) {
const {
hostname,
routerPath,
exclude = [],
additionalPaths = [],
outFile = 'sitemap.xml',
lastmod = new Date().toISOString()
} = options;
return {
name: 'vite-plugin-sitemap',
apply: 'build',
closeBundle: async () => {
try {
// router/index.ts 파일 읽기
const routerContent = readFileSync(routerPath, 'utf-8');
// 라우트 경로 추출
const paths = extractRoutePaths(routerContent)
.filter(path => {
// 제외할 경로 필터링
return !exclude.some(pattern =>
path.match(new RegExp(pattern.replace('*', '.*')))
);
});
// 모든 경로 합치기 (router 경로 + 추가 경로)
const allPaths = [...paths, ...additionalPaths]
.filter(path => path && path !== '/') // 빈 경로와 루트 경로 제외
.map(path => path.startsWith('/') ? path : `/${path}`); // 경로 정규화
const sitemap = `<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
${allPaths.map(path => ` <url>
<loc>${hostname}${path}</loc>
<lastmod>${lastmod}</lastmod>
</url>`
).join('\n')}
</urlset>`;
writeFileSync(resolve(process.cwd(), 'dist', outFile), sitemap);
} catch (e) {
console.error('Failed to generate sitemap:', e);
}
}
};
}
export default defineConfig(({ command, mode }) => {
// 중략 ...
return {
// 중략...
plugins: [
// 중략...
createSitemapPlugin({
hostname: 'https://your-domain.com',
routerPath: resolve(__dirname, 'src/router/index.ts'), // router 파일 경로 지정
exclude: [
'/admin', // 관리자 페이지 제외
'/admin/*', // 관리자 페이지 제외
'/login', // 로그인 페이지 제외
],
additionalPaths: [], // 필요한 경우 추가 경로
outFile: 'sitemap.xml',
lastmod: new Date().toISOString()
}),
// 중략...
]
}
})
함께 보면 좋은 글
반응형
'컴퓨터 > Vue' 카테고리의 다른 글
Vue3 Composition API / Options API 란? (1) | 2024.12.04 |
---|---|
vue3 Reactivity API란? (0) | 2024.12.03 |
Vue3 상태관리도구 pinia / vuex / 등.. (1) | 2024.12.02 |
Vue3의 빌드 도구란? 모듈 번들러란? 왜 vite를 사용하는가? (3) | 2024.11.28 |
Comments