前端基建从0到1搭建步骤清单(含工具选型+配置要点+落地注意事项)

一、前期准备:需求分析与技术选型(1-2天)

核心目标

明确项目场景、团队规模、技术栈偏好,避免盲目选型导致后期重构。

步骤1:需求与约束梳理

梳理维度 关键问题 决策影响
项目类型 中后台系统/移动端H5/跨端应用(小程序/App) 影响框架、构建工具、适配方案选型
团队规模 1-3人小团队/10人以上中大型团队 小团队优先"轻量基建",中大型团队需完善规范与协作工具
兼容性要求 需支持IE11/仅支持现代浏览器 决定是否需要polyfill、构建工具的兼容配置
迭代频率 快速迭代(每周1-2版)/稳定迭代(每月1版) 影响CI/CD自动化程度、测试策略

步骤2:核心技术栈选型(推荐组合)

技术模块 主流选型 选型建议
框架 Vue3 + TypeScript / React + TypeScript 中后台优先Vue3(Element Plus生态成熟),移动端两者均可
构建工具 Vite 5.x 现代项目首选(开发热更新快、配置简洁),复杂老项目可选Webpack 5.x
包管理器 pnpm 9.x 速度快、磁盘占用少,兼容npm/yarn命令,支持monorepo(多包管理)
路由 Vue Router 4.x / React Router 6.x 与框架强绑定,优先官方推荐版本
状态管理 Pinia(Vue3)/ Redux Toolkit(React) 小项目可不用,中大型项目需统一状态管理
UI组件库 Element Plus(Vue3)/ Ant Design(React) 优先选与框架匹配、文档完善、维护活跃的库
接口请求 Axios 1.x 统一封装请求层,处理跨域、拦截器等

落地注意事项

  • 避免"技术堆砌":小团队无需一开始就搭建复杂基建(如monorepo、微前端),先满足核心需求;
  • 版本兼容性:选型时需确认各工具版本匹配(如Vue3需搭配Vite 3+,TypeScript需与框架版本兼容);
  • 团队共识:选型前与团队成员对齐,确保至少2人熟悉核心工具,降低维护成本。

二、项目初始化:搭建基础工程结构(1天)

步骤1:用脚手架创建项目

bash 复制代码
# Vue3 + Vite + TypeScript 项目(推荐)
pnpm create vite@latest my-project --template vue-ts
cd my-project
pnpm install

# React + Vite + TypeScript 项目
pnpm create vite@latest my-project --template react-ts
cd my-project
pnpm install

步骤2:规范目录结构(推荐结构)

复制代码
my-project/
├── src/
│   ├── api/          # 接口请求目录(按业务模块拆分)
│   ├── assets/       # 静态资源(图片、字体、全局样式)
│   ├── components/   # 通用组件(全局组件+业务组件)
│   │   ├── common/   # 全局通用组件(如Button、Input)
│   │   └── business/ # 业务组件(如OrderTable、UserForm)
│   ├── hooks/        # 自定义钩子(如useRequest、usePermission)
│   ├── router/       # 路由配置(含权限守卫)
│   ├── store/        # 状态管理(Pinia/Redux)
│   ├── types/        # TypeScript类型定义(全局类型+接口类型)
│   ├── utils/        # 工具函数(日期、校验、埋点等)
│   ├── views/        # 页面视图(按业务模块拆分)
│   ├── App.vue/tsx   # 根组件
│   └── main.ts       # 入口文件
├── .env.development  # 开发环境配置
├── .env.production   # 生产环境配置
├── .eslintrc.js      # ESLint配置
├── .prettierrc       # Prettier配置
├── vite.config.ts    # Vite配置
└── tsconfig.json     # TypeScript配置

步骤3:基础配置(vite.config.ts核心配置)

typescript 复制代码
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import path from 'path';
import { loadEnv } from 'vite';

export default defineConfig(({ mode }) => {
  const env = loadEnv(mode, process.cwd()); // 加载环境变量

  return {
    // 路径别名(简化导入)
    resolve: {
      alias: {
        '@': path.resolve(__dirname, 'src'),
      },
    },
    // 开发服务器(解决跨域、热更新)
    server: {
      port: 3000, // 开发端口
      open: true, // 启动后自动打开浏览器
      proxy: {
        // 接口代理(解决跨域)
        '/api': {
          target: env.VITE_API_BASE_URL, // 后端接口地址(从环境变量读取)
          changeOrigin: true,
          rewrite: (path) => path.replace(/^\/api/, ''),
        },
      },
    },
    // 构建配置(优化产物)
    build: {
      target: 'es2015', // 兼容目标浏览器
      chunkSizeWarningLimit: 1500, // 代码分割阈值(避免大文件警告)
      rollupOptions: {
        output: {
          // 按模块拆分代码(优化加载速度)
          manualChunks: {
            vue: ['vue', 'vue-router', 'pinia'],
            elementPlus: ['element-plus'],
          },
        },
      },
    },
    plugins: [vue()],
  };
});

落地注意事项

  • 路径别名必须在tsconfig.json中同步配置(否则TS会报错):

    json 复制代码
    {
      "compilerOptions": {
        "baseUrl": ".",
        "paths": {
          "@/*": ["src/*"]
        }
      }
    }
  • 环境变量命名必须以VITE_开头(Vite默认暴露该前缀的变量);

  • 目录结构无需一步到位,但需预留扩展空间(如按业务模块拆分viewsapi)。

三、代码规范体系:统一编码风格与提交规范(1天)

步骤1:集成ESLint + Prettier(代码格式校验)

安装依赖
bash 复制代码
# ESLint(代码逻辑校验)+ Prettier(代码格式化)
pnpm add -D eslint prettier eslint-plugin-vue @typescript-eslint/eslint-plugin @typescript-eslint/parser eslint-config-prettier eslint-plugin-prettier
配置文件
  1. .eslintrc.js(核心配置):
javascript 复制代码
module.exports = {
  root: true,
  env: {
    browser: true,
    node: true,
    es2021: true,
  },
  parser: 'vue-eslint-parser', // Vue文件解析器
  parserOptions: {
    parser: '@typescript-eslint/parser', // TS解析器
    ecmaVersion: 'latest',
    sourceType: 'module',
  },
  plugins: ['vue', '@typescript-eslint', 'prettier'],
  extends: [
    'eslint:recommended',
    'plugin:vue/vue3-recommended',
    'plugin:@typescript-eslint/recommended',
    'plugin:prettier/recommended', // 整合Prettier(优先Prettier规则)
  ],
  rules: {
    // 自定义规则(根据团队需求调整)
    'vue/multi-word-component-names': 'off', // 允许单字组件名
    '@typescript-eslint/no-explicit-any': 'off', // 临时关闭any限制(逐步优化)
    'prettier/prettier': ['error', {}, { usePrettierrc: true }],
  },
};
  1. .prettierrc(格式化规则):
json 复制代码
{
  "semi": true, // 结尾加分号
  "singleQuote": true, // 使用单引号
  "tabWidth": 2, // 缩进2个空格
  "trailingComma": "es5", // 对象末尾加逗号
  "printWidth": 120, // 换行阈值
  "arrowParens": "avoid" // 箭头函数单参数省略括号
}
  1. .eslintignore(忽略文件):

    node_modules/
    dist/
    .env*
    *.d.ts

步骤2:集成husky + lint-staged + commitlint(提交校验)

安装依赖
bash 复制代码
# husky(Git钩子工具)+ lint-staged(暂存区代码校验)
pnpm add -D husky lint-staged
# commitlint(提交信息校验)
pnpm add -D @commitlint/cli @commitlint/config-conventional
初始化配置
bash 复制代码
# 初始化husky
npx husky install
# 配置提交前校验(pre-commit钩子)
npx husky add .husky/pre-commit "npx lint-staged"
# 配置提交信息校验(commit-msg钩子)
npx husky add .husky/commit-msg "npx --no -- commitlint --edit $1"
配置文件
  1. lint-staged.config.js(暂存区校验规则):
javascript 复制代码
module.exports = {
  '*.{vue,ts,js}': ['eslint --fix', 'prettier --write'], // 自动修复并格式化
  '*.{css,scss}': ['stylelint --fix', 'prettier --write'], // 后续集成Stylelint可添加
  '*.{md,json}': ['prettier --write'],
};
  1. commitlint.config.js(提交信息规则):
javascript 复制代码
module.exports = {
  extends: ['@commitlint/config-conventional'],
  rules: {
    // 提交类型限制(feat/feat: 新功能,fix/fix: 修复bug,docs: 文档等)
    'type-enum': [
      2,
      'always',
      ['feat', 'fix', 'docs', 'style', 'refactor', 'test', 'chore', 'revert'],
    ],
    'type-case': [0], // 允许类型大小写(如Feat/FIX)
    'subject-empty': [2, 'never'], // 提交描述不能为空
  },
};
package.json添加脚本
json 复制代码
{
  "scripts": {
    "lint": "eslint . --ext .vue,.ts,.js",
    "lint:fix": "eslint . --ext .vue,.ts,.js --fix",
    "format": "prettier --write \"src/**/*.{vue,ts,js,css,scss}\""
  }
}

落地注意事项

  • 首次集成时需执行pnpm run lint:fix修复历史代码格式问题,避免提交时校验失败;
  • 团队成员需熟悉提交规范(如feat: 新增用户列表接口),可配合commitizen工具生成提交信息;
  • 可根据团队习惯调整ESLint/Prettier规则,避免过度严格导致开发效率下降。

四、依赖与模块管理:规范依赖使用与版本控制(0.5天)

步骤1:依赖分类管理

  • ** dependencies **:生产环境必需依赖(如vue、axios、element-plus);
  • ** devDependencies **:开发环境依赖(如eslint、vite、jest);
  • 避免将开发依赖误放入dependencies,增加包体积。

步骤2:依赖治理工具

  1. ** 检测未使用依赖 **:
bash 复制代码
pnpm add -D depcheck
npx depcheck # 扫描项目中未使用的依赖
  1. ** 检测安全漏洞 **:
bash 复制代码
pnpm audit # 内置命令,检测依赖漏洞
pnpm audit fix # 自动修复可修复的漏洞
  1. ** 自动更新依赖 **:
bash 复制代码
# 安装renovate(需在GitHub/GitLab配置)
# 功能:自动检测依赖更新,生成PR提醒团队更新

步骤3:模块规范统一

  • 项目中统一使用ESM模块规范(import/export),避免CommonJSrequire/module.exports);
  • TypeScript项目需在tsconfig.json中设置"module": "ESNext",确保模块解析正确。

落地注意事项

  • 锁定依赖版本:pnpm会自动生成pnpm-lock.yaml,提交到Git仓库,确保团队成员安装的依赖版本一致;
  • 避免依赖过多:小工具优先自己封装(如日期格式化),减少第三方依赖引入,降低维护成本;
  • 重大依赖更新(如Vue3从3.2.x升级到3.4.x)需单独测试,避免兼容性问题。

五、测试体系:保障代码质量(1-2天)

步骤1:单元测试 + 组件测试(核心)

安装依赖(Vue3项目示例)
bash 复制代码
pnpm add -D jest @vue/test-utils@next vue-jest@next @types/jest ts-jest
配置文件(jest.config.js)
javascript 复制代码
module.exports = {
  preset: 'ts-jest',
  testEnvironment: 'jsdom', // 模拟浏览器环境
  moduleFileExtensions: ['vue', 'ts', 'js'],
  transform: {
    '^.+\\.vue$': '@vue/vue3-jest', // 解析Vue文件
    '^.+\\.ts$': 'ts-jest', // 解析TS文件
  },
  moduleNameMapper: {
    '^@/(.*)$': '<rootDir>/src/$1', // 路径别名映射
  },
  testMatch: ['**/__tests__/**/*.spec.[jt]s?(x)'], // 测试文件匹配规则
  coverageReporters: ['text', 'lcov'], // 测试覆盖率报告格式
};
编写测试用例(示例:components/common/Button.spec.ts)
typescript 复制代码
import { mount } from '@vue/test-utils';
import Button from './Button.vue';

describe('Button组件', () => {
  test('渲染正常', () => {
    const wrapper = mount(Button, {
      props: { type: 'primary' },
      slots: { default: '测试按钮' },
    });
    expect(wrapper.text()).toBe('测试按钮');
    expect(wrapper.classes()).toContain('el-button--primary');
  });

  test('点击事件触发', async () => {
    const mockClick = jest.fn();
    const wrapper = mount(Button, {
      props: { onClick: mockClick },
    });
    await wrapper.trigger('click');
    expect(mockClick).toHaveBeenCalledTimes(1);
  });
});
package.json添加脚本
json 复制代码
{
  "scripts": {
    "test": "jest",
    "test:coverage": "jest --coverage" // 生成测试覆盖率报告
  }
}

步骤2:端到端测试(E2E,可选)

安装依赖(Cypress)
bash 复制代码
pnpm add -D cypress
配置文件(cypress.config.ts)
typescript 复制代码
import { defineConfig } from 'cypress';

export default defineConfig({
  e2e: {
    baseUrl: 'http://localhost:3000', // 测试基础地址
    specPattern: 'cypress/e2e/**/*.cy.{js,ts}',
  },
});
编写测试用例(cypress/e2e/login.cy.ts)
typescript 复制代码
describe('登录页面', () => {
  it('输入正确账号密码可登录', () => {
    cy.visit('/login');
    cy.get('input[placeholder="用户名"]').type('admin');
    cy.get('input[placeholder="密码"]').type('123456');
    cy.get('button[type="submit"]').click();
    cy.url().should('include', '/home'); // 验证跳转首页
  });
});
package.json添加脚本
json 复制代码
{
  "scripts": {
    "cypress:open": "cypress open", // 打开可视化测试工具
    "cypress:run": "cypress run" // 命令行运行测试
  }
}

落地注意事项

  • 小团队可优先覆盖核心组件和工具函数的测试(目标覆盖率≥60%),无需追求100%;
  • 测试用例应避免依赖真实后端接口,需配合Mock服务(如MSW)模拟数据;
  • 集成到CI/CD流水线(后续步骤),每次提交自动运行测试,避免代码合并后出现问题。

六、接口请求层:统一封装与拦截(0.5天)

步骤1:Axios封装(src/utils/request.ts)

typescript 复制代码
import axios, { AxiosRequestConfig, AxiosResponse, AxiosError } from 'axios';
import { ElMessage } from 'element-plus';
import { getToken, removeToken } from '@/utils/auth'; // 自定义Token工具

// 创建Axios实例
const service = axios.create({
  baseURL: import.meta.env.VITE_API_BASE_URL, // 从环境变量读取基础地址
  timeout: 10000, // 请求超时时间
});

// 请求拦截器(添加Token、设置请求头)
service.interceptors.request.use(
  (config: AxiosRequestConfig) => {
    const token = getToken();
    if (token) {
      config.headers.Authorization = `Bearer ${token}`;
    }
    return config;
  },
  (error: AxiosError) => Promise.reject(error)
);

// 响应拦截器(统一处理错误、格式化数据)
service.interceptors.response.use(
  (response: AxiosResponse) => {
    const res = response.data;
    // 假设后端返回格式:{ code: 200, data: {}, msg: '' }
    if (res.code !== 200) {
      ElMessage.error(res.msg || '请求失败');
      // Token过期处理
      if (res.code === 401) {
        removeToken();
        window.location.href = '/login';
      }
      return Promise.reject(res);
    }
    return res.data; // 直接返回data,简化业务层调用
  },
  (error: AxiosError) => {
    ElMessage.error(error.message || '网络错误');
    return Promise.reject(error);
  }
);

export default service;

步骤2:接口管理(按业务模块拆分)

src/api/user.ts(用户模块接口)
typescript 复制代码
import request from '@/utils/request';
import { LoginParams, UserInfo } from '@/types/user';

// 登录
export const login = (params: LoginParams) => {
  return request({
    url: '/auth/login',
    method: 'post',
    data: params,
  });
};

// 获取用户信息
export const getUserInfo = () => {
  return request({
    url: '/user/info',
    method: 'get',
  });
};

落地注意事项

  • 统一错误处理:避免业务层重复写try/catch,拦截器中统一捕获并提示错误;
  • 环境变量区分接口地址:开发/测试/生产环境使用不同的VITE_API_BASE_URL,避免硬编码;
  • 接口类型定义:用TypeScript定义请求参数和响应数据类型,提升代码提示和健壮性。

七、部署与CI/CD:自动化构建与发布(1天)

步骤1:构建产物优化

1. 静态资源优化(vite.config.ts补充配置)
typescript 复制代码
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import { visualizer } from 'rollup-plugin-visualizer'; // 包体积分析工具

export default defineConfig({
  plugins: [
    vue(),
    visualizer({ open: true }), // 构建后自动打开包体积分析页面
  ],
  build: {
    assetsDir: 'static', // 静态资源目录
    minify: 'terser', // 启用Terser压缩(默认)
    terserOptions: {
      compress: {
        drop_console: import.meta.env.MODE === 'production', // 生产环境移除console
      },
    },
  },
});
2. 图片优化(安装依赖)
bash 复制代码
pnpm add -D vite-plugin-imagemin
vite.config.ts添加插件
typescript 复制代码
import viteImagemin from 'vite-plugin-imagemin';

export default defineConfig({
  plugins: [
    vue(),
    viteImagemin({
      gifsicle: { optimizationLevel: 7, interlaced: false },
      optipng: { optimizationLevel: 7 },
      mozjpeg: { quality: 80 },
      pngquant: { quality: [0.8, 0.9], speed: 4 },
    }),
  ],
});

步骤2:CI/CD流水线配置(GitHub Actions示例)

新建.github/workflows/deploy.yml
yaml 复制代码
name: 前端自动构建与部署
on:
  push:
    branches: [main] # 监听main分支提交

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    steps:
      # 1. 拉取代码
      - name: 拉取代码
        uses: actions/checkout@v4

      # 2. 安装Node.js
      - name: 安装Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'pnpm' # 缓存pnpm依赖

      # 3. 安装依赖
      - name: 安装依赖
        run: pnpm install

      # 4. 运行测试
      - name: 运行测试
        run: pnpm run test

      # 5. 构建项目
      - name: 构建项目
        run: pnpm run build
        env:
          VITE_API_BASE_URL: ${{ secrets.VITE_API_BASE_URL }} # 从GitHub Secrets读取环境变量

      # 6. 部署到阿里云OSS(示例:也可部署到Nginx/Netlify)
      - name: 部署到OSS
        uses: jakejarvis/s3-sync-action@master
        with:
          args: --delete # 删除OSS上不存在的文件
        env:
          AWS_S3_BUCKET: ${{ secrets.OSS_BUCKET }} # OSS桶名
          AWS_ACCESS_KEY_ID: ${{ secrets.OSS_ACCESS_KEY }} # 访问密钥
          AWS_SECRET_ACCESS_KEY: ${{ secrets.OSS_SECRET_KEY }} # 密钥
          AWS_S3_ENDPOINT: ${{ secrets.OSS_ENDPOINT }} # OSS端点
          SOURCE_DIR: 'dist' # 构建产物目录

步骤3:环境配置(.env文件)

.env.development(开发环境)
复制代码
VITE_API_BASE_URL=http://localhost:8080/api
VITE_ENV=development
.env.production(生产环境)
复制代码
VITE_API_BASE_URL=https://api.example.com
VITE_ENV=production

落地注意事项

  • 敏感信息存储:避免在代码中硬编码密钥、接口地址,使用GitHub Secrets或环境变量;
  • 部署前测试:CI/CD中必须包含测试步骤,测试失败则终止部署;
  • 构建产物备份:每次部署前备份历史产物,便于回滚(如部署失败可快速恢复上一版本)。

八、监控与运维:问题排查与性能优化(1天)

步骤1:错误监控(集成Sentry)

安装依赖
bash 复制代码
pnpm add @sentry/vue @sentry/tracing
初始化(src/main.ts)
typescript 复制代码
import { createApp } from 'vue';
import { createRouter } from 'vue-router';
import * as Sentry from '@sentry/vue';
import { Integrations } from '@sentry/tracing';
import App from './App.vue';
import router from './router';

const app = createApp(App);

// 仅生产环境启用Sentry
if (import.meta.env.PROD) {
  Sentry.init({
    app,
    dsn: '你的Sentry DSN地址', // 从Sentry后台获取
    integrations: [
      new Integrations.BrowserTracing({
        routingInstrumentation: Sentry.vueRouterInstrumentation(router),
        tracePropagationTargets: ['api.example.com', 'localhost'],
      }),
    ],
    tracesSampleRate: 1.0, // 采样率(生产环境可设为0.1,减少性能影响)
  });
}

app.use(router).mount('#app');

步骤2:性能监控(集成Web Vitals)

安装依赖
bash 复制代码
pnpm add web-vitals
封装监控函数(src/utils/performance.ts)
typescript 复制代码
import { getLCP, getFID, getCLS, getFCP, getTTFB } from 'web-vitals';

// 上报性能数据到后端
const reportPerformance = (metric: any) => {
  const body = {
    name: metric.name, // 指标名称(LCP/FID等)
    value: metric.value, // 指标值
    rating: metric.rating, // 评级(good/needs-improvement/poor)
    delta: metric.delta, // 与上次测量的差值
    page: window.location.pathname,
    timestamp: Date.now(),
  };

  // 异步上报(避免影响页面加载)
  navigator.sendBeacon('/api/performance/report', JSON.stringify(body));
};

// 初始化性能监控
export const initPerformanceMonitor = () => {
  if (import.meta.env.PROD) {
    getLCP(reportPerformance);
    getFID(reportPerformance);
    getCLS(reportPerformance);
    getFCP(reportPerformance);
    getTTFB(reportPerformance);
  }
};
在入口文件调用(src/main.ts)
typescript 复制代码
import { initPerformanceMonitor } from '@/utils/performance';

app.mount('#app');
initPerformanceMonitor();

步骤3:埋点系统(业务数据采集)

封装埋点工具(src/utils/track.ts)
typescript 复制代码
// 埋点上报函数
export const trackEvent = (eventName: string, data?: Record<string, any>) => {
  if (import.meta.env.PROD) {
    // 1. 浏览器埋点(通过图片请求上报)
    const img = new Image();
    const params = new URLSearchParams({
      event: eventName,
      data: JSON.stringify(data || {}),
      url: window.location.href,
      timestamp: Date.now().toString(),
      uuid: localStorage.getItem('userUuid') || '',
    });
    img.src = `https://track.example.com/log?${params}`;

    // 2. 或集成第三方埋点(如百度统计、友盟)
    // window._hmt?.push(['_trackEvent', eventName, JSON.stringify(data)]);
  }
};
业务中使用
vue 复制代码
<!-- 按钮点击埋点示例 -->
<template>
  <button @click="handleClick">提交订单</button>
</template>

<script setup>
import { trackEvent } from '@/utils/track';

const handleClick = () => {
  // 上报"提交订单"事件,携带订单ID
  trackEvent('order_submit', { orderId: '123456' });
  // 其他业务逻辑
};
</script>

落地注意事项

  • 监控工具仅在生产环境启用,避免影响开发/测试环境性能;
  • 埋点需遵循用户隐私协议,不采集敏感信息(如手机号、密码);
  • 定期分析监控数据:重点关注错误率高的页面、性能差的接口,优先优化核心路径。

九、落地与迭代:分阶段推进与团队适配(持续)

阶段1:核心基建搭建(1周内)

  • 完成项目初始化、工程化构建、代码规范、接口封装;
  • 团队成员熟悉工具使用(如ESLint修复、Git提交规范);
  • 上线第一个测试版本,验证基建可用性。

阶段2:完善与优化(2-4周)

  • 补充测试体系、CI/CD流水线、监控系统;
  • 根据团队反馈调整规范(如ESLint规则、目录结构);
  • 优化构建产物体积、开发体验(如Mock服务集成)。

阶段3:长期维护与迭代(持续)

  • 定期更新依赖版本(如Vite、框架版本),修复安全漏洞;
  • 沉淀业务工具库和组件库,提升复用率;
  • 接入新的基建工具(如微前端、Module Federation),适配项目规模增长。

团队适配注意事项

  • 编写基建文档:整理工具使用手册、配置说明,方便新成员上手;
  • 组织内部培训:针对核心工具(如Vite配置、Jest测试)进行1-2次分享;
  • 设立基建负责人:专人维护基建配置,避免多人修改导致混乱。
相关推荐
Komorebi゛7 分钟前
【CSS】斜角流光样式
前端·css
Irene199113 分钟前
CSS 废弃属性分类总结
前端·css
青莲84323 分钟前
Android 事件分发机制 - 事件流向详解
android·前端·面试
musashi24 分钟前
用 Electron 写了一个 macOS 版本的 wallpaper(附源码、下载地址)
前端·vue.js·electron
满天星辰25 分钟前
Typescript之类型总结大全
前端·typescript
JFChen26 分钟前
Web 仔用 Node 像 Java 一样写后端服务
前端
XiaoSong29 分钟前
React useState 原理和异步更新
前端·react.js
徐徐子29 分钟前
从vue3 watch开始理解Vue的响应式原理
前端·vue.js
拾荒的小海螺31 分钟前
开源项目:Three.js 构建 3D 世界的工具库
javascript·3d·开源
眯眼因为很困啦32 分钟前
GitHub Fork 协作完整流程
前端·git·前端工程化