Project Architecture Design
Single Page Application (SPA) and Multi-Page Application (MPA) Architecture Design
SPA Architecture Core Implementation
// src/main.js - SPA entry file
import { createApp } from 'vue'; // Assuming Vue is used (example framework-agnostic)
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');
// src/router/index.js - SPA routing configuration
import { createRouter, createWebHistory } from 'vue-router';
const routes = [
{
path: '/',
component: () => import('@/views/Home.vue'), // Dynamic import for lazy loading
meta: { requiresAuth: true }
},
{
path: '/about',
component: () => import('@/views/About.vue')
}
];
const router = createRouter({
history: createWebHistory(),
routes
});
export default router;
MPA Architecture Implementation
// winter.config.js - Multi-page application configuration
export default {
pages: {
index: {
entry: 'src/pages/index/main.js',
template: 'public/index.html',
filename: 'index.html'
},
about: {
entry: 'src/pages/about/main.js',
template: 'public/about.html',
filename: 'about.html'
}
}
};
// src/pages/index/main.js - Subpage entry
import { createApp } from 'vue';
import App from './App.vue';
createApp(App).mount('#app');
Modular and Component-Based Design Principles
Modular Design Practices
// src/modules/user/index.js - User module
import actions from './actions';
import mutations from './mutations';
import getters from './getters';
export default {
namespaced: true,
state: () => ({
userInfo: null,
token: ''
}),
actions,
mutations,
getters
};
// src/store/index.js - Modular Store configuration
import { createStore } from 'vuex';
import user from './modules/user';
import product from './modules/product';
export default createStore({
modules: {
user,
product
}
});
Component-Based Design Specifications
<!-- src/components/BaseButton.vue - Base component -->
<template>
<button
:class="['base-button', type]"
:disabled="disabled"
@click="handleClick"
>
<slot></slot>
</button>
</template>
<script>
export default {
name: 'BaseButton',
props: {
type: {
type: String,
default: 'default'
},
disabled: {
type: Boolean,
default: false
}
},
methods: {
handleClick() {
this.$emit('click');
}
}
};
</script>
<style scoped>
.base-button {
padding: 8px 16px;
border-radius: 4px;
}
.default {
background-color: #fff;
border: 1px solid #dcdfe6;
}
.primary {
background-color: #409eff;
color: #fff;
}
</style>
State Management Architecture Design
Redux Configuration Example
// src/store/index.js - Redux configuration
import { configureStore } from '@reduxjs/toolkit';
import userReducer from './slices/userSlice';
export const store = configureStore({
reducer: {
user: userReducer
}
});
// src/store/slices/userSlice.js - Redux Slice
import { createSlice } from '@reduxjs/toolkit';
const userSlice = createSlice({
name: 'user',
initialState: {
userInfo: null,
token: ''
},
reducers: {
setUserInfo(state, action) {
state.userInfo = action.payload;
},
clearUserInfo(state) {
state.userInfo = null;
state.token = '';
}
}
});
export const { setUserInfo, clearUserInfo } = userSlice.actions;
export default userSlice.reducer;
Zustand State Management
// src/stores/userStore.js - Zustand example
import create from 'zustand';
const useUserStore = create((set) => ({
userInfo: null,
token: '',
setUserInfo: (userInfo) => set({ userInfo }),
clearUserInfo: () => set({ userInfo: null, token: '' })
}));
export default useUserStore;
// Usage in component
import useUserStore from '../stores/userStore';
function Profile() {
const { userInfo, setUserInfo } = useUserStore();
// ...
}
Routing Architecture Design
Dynamic Routing Configuration
// src/router/index.js - Dynamic routing
import { createRouter, createWebHistory } from 'vue-router';
const loadView = (view) => {
return () => import(`@/views/${view}.vue`);
};
const routes = [
{
path: '/dashboard',
component: loadView('Dashboard'),
children: [
{
path: 'analytics',
component: loadView('DashboardAnalytics')
},
{
path: 'settings',
component: loadView('DashboardSettings')
}
]
}
];
const router = createRouter({
history: createWebHistory(),
routes
});
export default router;
Nested Routing Implementation
<!-- src/views/Dashboard.vue - Parent route component -->
<template>
<div class="dashboard">
<sidebar />
<router-view /> <!-- Nested route outlet -->
</div>
</template>
<script>
import Sidebar from '@/components/Sidebar.vue';
export default {
components: { Sidebar }
};
</script>
Project Directory Structure and Standards
Recommended Directory Structure
winter-project/
├── public/ # Static assets
│ ├── favicon.ico
│ └── index.html
├── src/
│ ├── assets/ # Project assets
│ ├── components/ # Shared components
│ ├── composables/ # Composition functions
│ ├── layouts/ # Layout components
│ ├── router/ # Routing configuration
│ ├── stores/ # State management
│ ├── styles/ # Global styles
│ ├── utils/ # Utility functions
│ ├── views/ # Page components
│ ├── App.vue # Root component
│ └── main.js # Entry file
├── tests/ # Test files
├── winter.config.js # WinterJS configuration
├── package.winter # Dependency configuration
└── README.md
Naming Convention Examples
# Component naming
# PascalCase
components/
BaseButton.vue
UserProfileCard.vue
# File naming
# kebab-case
utils/
format-date.js
validate-email.js
# Store naming
# camelCase
stores/
userStore.js
productStore.js
Advanced WinterJS Configuration
winter.json Configuration Example
{
"name": "winter-project",
"version": "1.0.0",
"scripts": {
"dev": "winter run --watch",
"build": "winter bundle --prod",
"test": "winter test"
},
"dependencies": {
"vue": "^3.2.0"
},
"devDependencies": {
"winter-cli": "^1.0.0"
},
"winter": {
"entry": "src/main.js",
"output": {
"path": "dist",
"filename": "[name].[contenthash].js"
},
"vite": {
"server": {
"port": 3000,
"open": true
}
}
}
}
Environment Variables Configuration
# .env.development
VITE_API_BASE_URL=http://localhost:3000/api
# .env.production
VITE_API_BASE_URL=https://api.winterjs.com/api
# src/config.js - Using environment variables
export const API_BASE_URL = import.meta.env.VITE_API_BASE_URL;
Webpack Advanced Configuration
Custom Loader Example
// webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.custom$/,
use: [
{
loader: path.resolve(__dirname, 'loaders/custom-loader.js'),
options: {
debug: true
}
}
]
}
]
}
};
// loaders/custom-loader.js
module.exports = function(source) {
// Custom processing logic
console.log('Custom loader processing...');
return `export default ${JSON.stringify(source)}`;
};
Plugin Development Example
// webpack.config.js
const MyPlugin = require('./plugins/my-plugin');
module.exports = {
plugins: [
new MyPlugin({
name: 'My Custom Plugin'
})
]
};
// plugins/my-plugin.js
class MyPlugin {
constructor(options) {
this.options = options;
}
apply(compiler) {
compiler.hooks.emit.tap('MyPlugin', (compilation) => {
console.log('MyPlugin: emit hook');
compilation.assets['custom.txt'] = {
source: () => 'This is generated by MyPlugin',
size: () => 25
};
});
}
}
module.exports = MyPlugin;
TypeScript Advanced Configuration
tsconfig.json Strict Mode
{
"compilerOptions": {
"target": "ES2020",
"module": "ESNext",
"strict": true,
"noImplicitAny": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"strictBindCallApply": true,
"strictPropertyInitialization": true,
"noImplicitThis": true,
"alwaysStrict": true,
"moduleResolution": "node",
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"baseUrl": ".",
"paths": {
"@/*": ["src/*"]
}
},
"include": ["src/**/*"],
"exclude": ["node_modules"]
}
Path Alias Configuration
// winter.config.js
export default {
resolve: {
alias: {
'@': path.resolve(__dirname, 'src'),
'@components': path.resolve(__dirname, 'src/components')
}
}
};
// Usage example
import BaseButton from '@/components/BaseButton';
import Header from '@components/Header';
Code Standards and Style Guidelines
ESLint Configuration
// .eslintrc.js
module.exports = {
root: true,
env: {
browser: true,
node: true
},
extends: [
'plugin:vue/vue3-essential',
'eslint:recommended',
'@vue/typescript/recommended'
],
parserOptions: {
ecmaVersion: 2020
},
rules: {
'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
'@typescript-eslint/explicit-module-boundary-types': 'off'
}
};
Prettier Configuration
{
"printWidth": 100,
"tabWidth": 2,
"useTabs": false,
"semi": true,
"singleQuote": true,
"quoteProps": "as-needed",
"jsxSingleQuote": false,
"trailingComma": "all",
"bracketSpacing": true,
"bracketSameLine": false,
"arrowParens": "always",
"endOfLine": "lf"
}
Automated Testing Framework
Jest Configuration Example
// jest.config.js
module.exports = {
preset: '@vue/cli-plugin-unit-jest/presets/typescript-and-babel',
testEnvironment: 'jsdom',
moduleNameMapper: {
'^@/(.*)$': '<rootDir>/src/$1'
},
transform: {
'^.+\\.vue$': 'vue-jest',
'^.+\\.tsx?$': 'ts-jest'
},
collectCoverage: true,
coverageDirectory: 'coverage',
coverageReporters: ['text', 'lcov']
};
// Example test file
import { mount } from '@vue/test-utils';
import BaseButton from '@/components/BaseButton.vue';
describe('BaseButton', () => {
it('emits click event when clicked', async () => {
const wrapper = mount(BaseButton);
await wrapper.trigger('click');
expect(wrapper.emitted('click')).toBeTruthy();
});
});
Vitest Configuration
// vitest.config.js
import { defineConfig } from 'vitest/config';
import vue from '@vitejs/plugin-vue';
export default defineConfig({
plugins: [vue()],
test: {
environment: 'jsdom',
globals: true,
coverage: {
provider: 'v8',
reporter: ['text', 'json', 'html']
}
},
resolve: {
alias: {
'@': '/src'
}
}
});
// Example test
import { describe, it, expect } from 'vitest';
import { ref } from 'vue';
describe('reactivity', () => {
it('should track changes', () => {
const count = ref(0);
let dummy;
const stop = watchEffect(() => {
dummy = count.value;
});
expect(dummy).toBe(0);
count.value++;
expect(dummy).toBe(1);
stop();
});
});
Code Splitting and Lazy Loading
Dynamic Import Implementation
// Route-level code splitting
const routes = [
{
path: '/dashboard',
component: () => import(/* webpackChunkName: "dashboard" */ '@/views/Dashboard.vue')
}
];
// Component-level lazy loading
import { defineAsyncComponent } from 'vue';
const AsyncModal = defineAsyncComponent(() =>
import('@/components/Modal.vue')
);
export default {
components: {
AsyncModal
}
};
WinterJS Code Splitting Configuration
// winter.config.js
export default {
bundle: {
splitting: true,
chunkSizeWarningLimit: 1024, // 1MB
rollupOptions: {
output: {
manualChunks(id) {
if (id.includes('node_modules')) {
return 'vendor';
}
if (id.includes('src/views')) {
return 'views-' + id.split('src/views/')[1].split('/')[0];
}
}
}
}
}
};
Resource Compression and Caching Strategies
Gzip Compression Configuration
// winter.config.js
import compressionWebpackPlugin from 'compression-webpack-plugin';
export default {
configureWebpack: {
plugins: [
new compressionWebpackPlugin({
algorithm: 'gzip',
test: /\.(js|css|html|svg)$/,
threshold: 10240, // 10KB
minRatio: 0.8
})
]
}
};
// Nginx configuration example
/*
gzip on;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
gzip_comp_level 6;
gzip_min_length 1024;
*/
CDN Configuration Example
// winter.config.js
export default {
publicPath: process.env.NODE_ENV === 'production'
? 'https://cdn.winterjs.com/assets/'
: '/'
};
// HTML usage
<script src="https://cdn.winterjs.com/assets/vendor.js"></script>
<link href="https://cdn.winterjs.com/assets/app.css" rel="stylesheet">
Server-Side Rendering (SSR) and Static Site Generation (SSG)
SSR Configuration Example
// winter.config.js
export default {
ssr: {
target: 'node',
ssrManifest: true,
renderTracked: (e) => {
console.log('Resource tracked:', e);
}
}
};
// Server entry
// src/entry-server.js
import { createSSRApp } from 'vue';
import App from './App.vue';
import { createRouter } from './router';
export async function createApp() {
const router = createRouter();
await router.push(context.url);
await router.isReady();
const app = createSSRApp(App);
app.use(router);
return { app, router };
}
SSG Configuration Example
// winter.config.js
export default {
ssg: {
fallback: '404.html',
crawler: true,
interval: 1000
}
};
// Generate static pages
winter build --ssg;
// Dynamic route prerendering
// src/routes/dynamic.js
export async function getStaticPaths() {
const posts = await fetchPosts();
return {
paths: posts.map(post => ({
params: { id: post.id.toString() }
})),
fallback: 'blocking'
};
}
export async function getStaticProps({ params }) {
const post = await fetchPost(params.id);
return { props: { post } };
}
Lighthouse Integration
// package.winter
{
"scripts": {
"audit": "lighthouse http://localhost:3000 --view --output=html --output-path=./reports/lighthouse.html"
}
}
// Usage example
npm run audit
Web Vitals Monitoring
// src/main.js
import { getCLS, getFID, getLCP } from 'web-vitals';
function sendToAnalytics(metric) {
console.log(metric);
// Send to analytics service
}
getCLS(sendToAnalytics);
getFID(sendToAnalytics);
getLCP(sendToAnalytics);
// Custom performance metrics
export function trackPerformance() {
const navigationTiming = performance.getEntriesByType('navigation')[0];
console.log('Page load time:', navigationTiming.loadEventEnd);
}
Deployment and Continuous Integration
Docker Configuration Example
# Dockerfile
FROM node:16-alpine as builder
WORKDIR /app
COPY package.winter ./
RUN winterpkg install
COPY . .
RUN winter build
FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
# nginx.conf
server {
listen 80;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html;
try_files $uri $uri/ /index.html;
}
}
CI/CD Pipeline Configuration
# .github/workflows/deploy.yml
name: WinterJS CI/CD
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 16
- run: npm install -g winter-cli
- run: winterpkg install
- run: winter test
deploy:
needs: test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 16
- run: npm install -g winter-cli
- run: winterpkg install --production
- run: winter build
- uses: azure/webapps-deploy@v2
with:
app-name: 'winter-app'
publish-profile: ${{ secrets.AZURE_WEBAPP_PUBLISH_PROFILE }}
package: ./dist