Project Architecture Design
Single Page Application (SPA) and Multi-Page Application (MPA) Architecture Design
SPA Architecture Core Design
// SPA core architecture example
// src/main.ts
import { createApp } from 'vue'; // Or React, etc.
import App from './App.vue';
import router from './router';
import store from './store';
const app = createApp(App);
app.use(router);
app.use(store);
app.mount('#app');
// Router configuration (src/router/index.ts)
import { createRouter, createWebHistory } from 'vue-router';
const routes = [
{ path: '/', component: () => import('./views/Home.vue') }, // Lazy loading
{ path: '/about', component: () => import('./views/About.vue') }
];
export default createRouter({
history: createWebHistory(),
routes
});MPA Architecture Design Key Points
// MPA multi-entry configuration example (deno.json)
{
"tasks": {
"dev:home": "deno run --allow-net src/home/index.ts",
"dev:about": "deno run --allow-net src/about/index.ts",
"build:home": "deno compile --allow-net src/home/index.ts --output dist/home",
"build:about": "deno compile --allow-net src/about/index.ts --output dist/about"
}
}
// Multi-page HTML template (public/home.html)
<!DOCTYPE html>
<html>
<head>
<title>Home</title>
</head>
<body>
<div id="app"></div>
<script src="/dist/home.js"></script>
</body>
</html>Modularization and Componentization Design Principles
Domain-Driven Design (DDD) Module Division
src/
├── domain/ # Domain layer
│ ├── user/ # User domain
│ │ ├── model.ts # Domain model
│ │ ├── repo.ts # Repository interface
│ │ └── service.ts # Domain service
│ └── product/ # Product domain
├── application/ # Application layer
│ ├── user/ # User use cases
│ └── product/ # Product use cases
├── infrastructure/ # Infrastructure layer
│ ├── db/ # Database implementation
│ └── http/ # HTTP adapter
└── presentation/ # Presentation layer
├── web/ # Web interface
└── api/ # API interfaceComponent Design Specification
// Component design example (React style)
// src/components/Button/
├── Button.tsx # Component implementation
├── Button.types.ts # Type definitions
├── Button.css # Style file
└── index.ts # Export entry
// Button.tsx
import type { ButtonProps } from './Button.types';
export const Button = ({ text, onClick }: ButtonProps) => {
return <button onClick={onClick}>{text}</button>;
};State Management Architecture Design
Redux Toolkit Integration Example
// src/store/index.ts
import { configureStore } from '@reduxjs/toolkit';
import userReducer from './slices/userSlice';
export const store = configureStore({
reducer: {
user: userReducer
}
});
// src/store/slices/userSlice.ts
import { createSlice, PayloadAction } from '@reduxjs/toolkit';
interface UserState {
name: string;
email: string;
}
const initialState: UserState = {
name: '',
email: ''
};
export const userSlice = createSlice({
name: 'user',
initialState,
reducers: {
setUser(state, action: PayloadAction<UserState>) {
return { ...state, ...action.payload };
}
}
});
export const { setUser } = userSlice.actions;
export default userSlice.reducer;Zustand Lightweight Solution
// src/store/useStore.ts
import { create } from 'zustand';
interface CounterState {
count: number;
increment: () => void;
decrement: () => void;
}
export const useCounterStore = create<CounterState>((set) => ({
count: 0,
increment: () => set((state) => ({ count: state.count + 1 })),
decrement: () => set((state) => ({ count: state.count - 1 }))
}));Routing Architecture Design
Dynamic Routing Implementation
// src/router/dynamicRoutes.ts
export const generateDynamicRoutes = async () => {
const modules = import.meta.glob('./views/*.tsx');
const routes = Object.entries(modules).map(([path, module]) => {
const componentName = path.split('/').pop()?.replace('.tsx', '') || '';
return {
path: `/${componentName.toLowerCase()}`,
component: module
};
});
return routes;
};
// Usage example
const routes = await generateDynamicRoutes();
console.log(routes); // [{path: '/home', component: () => import('./views/Home.tsx')}]Nested Routing Configuration
// src/router/nestedRoutes.ts
import { createRouter, createWebHistory } from 'vue-router';
const routes = [
{
path: '/dashboard',
component: () => import('./layouts/DashboardLayout.vue'),
children: [
{ path: '', component: () => import('./views/DashboardHome.vue') },
{ path: 'settings', component: () => import('./views/DashboardSettings.vue') }
]
}
];
export default createRouter({
history: createWebHistory(),
routes
});Project Directory Structure and Standards
Recommended Directory Structure
deno_project/
├── deps.ts # Centralized dependency management
├── mod.ts # Main entry file
├── src/
│ ├── app.ts # Application initialization
│ ├── config/ # Configuration files
│ ├── features/ # Feature modules
│ ├── lib/ # Shared libraries
│ ├── types/ # Type definitions
│ └── utils/ # Utility functions
├── tests/ # Test files
├── web/ # Frontend resources
│ ├── static/ # Static files
│ └── index.html # HTML template
├── deno.json # Deno configuration
└── README.mdDependency Management Standards
// deps.ts centralized dependency management
export { Application, Router } from "https://deno.land/x/oak@v17.1.0/mod.ts";
export { oakCors } from "https://deno.land/x/cors@v1.2.2/mod.ts";
export type { Context } from "https://deno.land/x/oak@v17.1.0/mod.ts";
// Use centralized imports
import { Application, oakCors } from "../deps.ts";Engineering Toolchain
Deno Advanced Configuration (deno.json)
Complete Configuration Example
{
"tasks": {
"dev": "deno run --allow-net --watch src dev_server.ts",
"test": "deno test --allow-read --coverage=cov_profile",
"lint": "deno lint --ignore=web/assets",
"fmt": "deno fmt --check",
"build": "deno compile --allow-net src/main.ts --output dist/main"
},
"imports": {
"react": "https://esm.sh/react@18.3.1",
"react-dom": "https://esm.sh/react-dom@18.3.1"
},
"compilerOptions": {
"lib": ["dom", "esnext"],
"target": "es2022"
},
"lint": {
"rules": {
"tags": ["recommended"],
"include": ["src/**/*.ts"],
"exclude": ["src/**/*.test.ts"]
}
}
}Import Map Management
// import_map.json
{
"imports": {
"react": "https://esm.sh/react@18.3.1",
"react-dom": "https://esm.sh/react-dom@18.3.1",
"lodash": "https://esm.sh/lodash@4.17.21"
},
"scopes": {
"https://esm.sh/": {
"@types/react": "https://esm.sh/@types/react@18.3.3"
}
}
}Webpack Advanced Configuration
Advanced Loader Configuration
// webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.tsx?$/,
use: [
{
loader: 'ts-loader',
options: {
transpileOnly: true, // Speed up compilation
happyPackMode: true // Multi-threaded support
}
},
{
loader: 'eslint-loader',
options: {
fix: true // Auto-fix
}
}
],
exclude: /node_modules/
},
{
test: /\.scss$/,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
modules: true // CSS modules
}
},
'sass-loader'
]
}
]
}
}Plugin Optimization Strategy
// webpack.config.js
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
const TerserPlugin = require('terser-webpack-plugin');
module.exports = {
optimization: {
minimizer: [
new TerserPlugin({
parallel: true, // Multi-threaded compression
extractComments: false
})
],
splitChunks: {
chunks: 'all',
cacheGroups: {
vendors: {
test: /[\\/]node_modules[\\/]/,
priority: -10
}
}
}
},
plugins: [
new BundleAnalyzerPlugin({
analyzerMode: 'static' // Generate static report
})
]
}TypeScript Advanced Configuration
Strict Mode Configuration
// tsconfig.json
{
"compilerOptions": {
"strict": true,
"noImplicitAny": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"strictBindCallApply": true,
"strictPropertyInitialization": true,
"noImplicitThis": true,
"alwaysStrict": true
}
}Path Alias Configuration
// tsconfig.json
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["src/*"],
"@components/*": ["src/components/*"]
}
}
}
// Usage example
import Button from '@/components/Button';Code Linting Tools
ESLint Configuration
// .eslintrc.js
module.exports = {
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended'
],
parser: '@typescript-eslint/parser',
rules: {
'@typescript-eslint/no-explicit-any': 'error',
'no-console': 'warn'
},
overrides: [
{
files: ['*.test.ts'],
rules: {
'no-console': 'off'
}
}
]
}Prettier Integration
// .prettierrc
{
"semi": true,
"singleQuote": true,
"tabWidth": 2,
"trailingComma": "all",
"printWidth": 100
}
// .vscode/settings.json
{
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode"
}Automated Testing Framework
Vitest Configuration Example
// vitest.config.ts
import { defineConfig } from 'vitest/config';
export default defineConfig({
test: {
globals: true,
environment: 'jsdom',
coverage: {
provider: 'v8',
reporter: ['text', 'json', 'html']
},
setupFiles: ['./tests/setup.ts']
}
});
// tests/setup.ts
import '@testing-library/jest-dom';Test Case Example
// tests/button.test.tsx
import { render, screen } from '@testing-library/react';
import { Button } from '@/components/Button';
test('renders button with text', () => {
render(<Button text="Click me" />);
const button = screen.getByText(/click me/i);
expect(button).toBeInTheDocument();
});Performance Optimization and Deployment
Code Splitting and Lazy Loading
Dynamic Import Implementation
// React lazy loading example
const LazyComponent = React.lazy(() => import('./HeavyComponent'));
function App() {
return (
<React.Suspense fallback={<div>Loading...</div>}>
<LazyComponent />
</React.Suspense>
);
}
// Deno dynamic import
const module = await import(`./modules/${moduleName}.ts`);Route-Level Code Splitting
// Vue route lazy loading
const routes = [
{
path: '/dashboard',
component: () => import('./views/Dashboard.vue')
}
];Resource Compression and Caching
Gzip Compression Middleware
// Oak Gzip middleware
import { gzip } from "https://deno.land/std@0.224.0/encoding/gzip.ts";
import { Application } from "https://deno.land/x/oak@v17.1.0/mod.ts";
const app = new Application();
app.use(async (ctx, next) => {
await next();
if (ctx.response.body && ctx.request.accepts("gzip")) {
const body = ctx.response.body instanceof Uint8Array
? ctx.response.body
: new TextEncoder().encode(String(ctx.response.body));
const compressed = gzip(body);
ctx.response.body = compressed;
ctx.response.headers.set("Content-Encoding", "gzip");
}
});
await app.listen({ port: 8000 });CDN Configuration Example
<!DOCTYPE html>
<html>
<head>
<script src="https://cdn.example.com/app.bundle.js"></script>
<link rel="stylesheet" href="https://cdn.example.com/styles.css">
</head>
<body>
<div id="app"></div>
</body>
</html>Server-Side Rendering (SSR)
Next.js-Style SSR Implementation
// Server entry (server.ts)
import { renderToString } from 'react-dom/server';
import App from './App';
import { serve } from "https://deno.land/std@0.224.0/http/server.ts";
await serve(async (_req) => {
const html = renderToString(<App />);
return new Response(`
<!DOCTYPE html>
<html>
<body>
<div id="root">${html}</div>
<script src="/client.js"></script>
</body>
</html>
`, {
headers: { "Content-Type": "text/html" }
});
});
// Client entry (client.ts)
import { hydrateRoot } from 'react-dom/client';
import App from './App';
hydrateRoot(document.getElementById('root')!, <App />);Performance Monitoring Tools
Lighthouse CI Integration
# .github/workflows/lighthouse.yml
name: Lighthouse Audit
on: [push]
jobs:
lighthouse:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: treosh/lighthouse-ci-action@v10
with:
urls: |
http://localhost:8000/
http://localhost:8000/about
budgetPath: ./lighthouse-budget.jsonWeb Vitals Monitoring
// Frontend performance monitoring
import { getCLS, getFID, getLCP } from 'web-vitals';
getCLS(console.log);
getFID(console.log);
getLCP(console.log);
// Report data to analytics platform
function sendToAnalytics(metric: any) {
const body = JSON.stringify(metric);
navigator.sendBeacon('/analytics', body);
}Deployment and CI/CD
Dockerized Deployment
# Dockerfile
FROM denoland/deno:2.0.0
WORKDIR /app
COPY import_map.json .
COPY deps.ts .
RUN deno cache --import-map=import_map.json deps.ts
COPY . .
RUN deno cache --import-map=import_map.json src/main.ts
EXPOSE 8000
CMD ["deno", "run", "--allow-net", "--import-map=import_map.json", "src/main.ts"]
# Build and run
# docker build -t deno-app .
# docker run -p 8000:8000 deno-appGitHub Actions CI/CD
# .github/workflows/deploy.yml
name: Deploy
on:
push:
branches: [ main ]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: denoland/setup-deno@v2
with:
deno-version: "2.0.0"
- run: deno task build
- uses: peaceiris/actions-gh-pages@v4
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./dist



