likes
comments
collection
share

从零开始搭建vite4.0-vue3.0项目

作者站长头像
站长
· 阅读数 18

前言

大家好,我是 simple ,我的理想是利用科技手段来解决生活中遇到的各种问题

pnpm和npm的命令行完全一样,如果不想用pnpm的同学可以直接用npm。

项目地址

如果在安装过程中遇到了什么问题,可以直接到克隆下我的项目去排查原因,欢迎star。

项目初始化

pnpm create vite

然后按照提示操作即可!

从零开始搭建vite4.0-vue3.0项目

cd my-project
pnpm install
pnpm run dev

此时项目已经运行成功了。

从零开始搭建vite4.0-vue3.0项目

git初始化

git init
git add .
# .gitignore文件添加node_modules/
node_modules/

git初始化是为了提高项目容错率,以免我们删除错文件的时候可以直接撤回。.gitignore已经内置在项目,不需要再添加。接下来每当我们进行一步操作,都可以进行一次记录,这里就不重复演示了。

别名配置

// vite.config.ts
import { resolve } from 'path'

resolve: {
    alias: {
      '@': resolve(__dirname, 'src')
    }
}

解决vscode报错

  1. vite.config.ts 从零开始搭建vite4.0-vue3.0项目

    pnpm install --save-dev @types/node
    

    报错原因:typescript 无法识别 node 内置模块类型,所以安装一个node的类型

  2. main.ts文件中 从零开始搭建vite4.0-vue3.0项目 在src文件夹下新建一个文件shims-vue.d.ts。

    // shims-vue.d.ts
    declare module '*.vue' {
        import { ComponentOptions } from 'vue'
        const componentOptions: ComponentOptions
        export default componentOptions
    }
    

    报错原因:typescript 只能理解 .ts 文件,无法理解 .vue 文件,所以必须得给vue文件声明类型模块。

vue-router安装

pnpm install vue-router@4

src下新建router/index.ts用于配置路由,新建views/home/index.vue文件和views/my/index.vue文件用于路由区分。

import { Router, createRouter, createWebHistory } from 'vue-router'

const router: Router = createRouter({
    history: createWebHistory(),
    routes: [
        {
            path: '/',
            redirect: '/home'
        },
        {
            name: 'Home',
            path: '/home',
            component: () => import('@/views/home/index.vue')
        },
        {
            name: 'My',
            path: '/my',
            component: () => import('@/views/my/index.vue')
        }
    ]
})

router.beforeEach((to, from, next) => {
    /* 路由守卫逻辑 */
    next()
})

export default router
// main.ts
import Router from './router/index.ts'

createApp(App).use(Router).mount('#app')

pinia安装

pnpm i pinia

在src文件夹下新建store/index.ts,store/count.ts。

// main.ts
import { createPinia } from "pinia"
createApp(App).use(router).use(createPinia()).mount('#app')

到这里,pinia已经引入成功了。下面是测试代码,看pinia是否可以正常运行。

// store/modules/count.ts
import { defineStore } from "pinia"
import { ref } from 'vue'

export  const useCounterStore = defineStore('counter', () => {
    const count = ref<number>(0)
    function increment() {
        console.log('count.value: ', count.value);
        count.value++
    }
    return { count, increment }
})
<template>
  <div @click="increment">{{ count }}</div>
</template>

<script setup lang="ts" name="My">
import { useCounterStore } from '@/store/modules/count.ts'
import { storeToRefs } from 'pinia'
const store = useCounterStore()
const { count } = storeToRefs(store)
const { increment } = store
</script>

npm run dev正常运行。

npm run build报错。

从零开始搭建vite4.0-vue3.0项目

通过以下配置tsconfig.json和vite.config.ts解决了报错,原因尚未清楚(懂的大佬请在评论区指点一下吧)。

// ts.config.json 新增以下内容
"compilerOptions" {
    "baseUrl": "./",
    "paths": {
      "@": ["src/*"],
      "store/*": ["src/store/*"]
    },
}
// vite.config.ts
resolve: {
    alias: {
        '@': resolve(resolve(__dirname, 'src')),
        'store': resolve(resolve(__dirname, 'src/store')),
    }
}
<template>
  <div @click="increment">{{ count }}</div>
</template>

<script setup lang="ts" name="My">
import { storeToRefs } from 'pinia'
import { useCounterStore } from 'store/count.ts' // 这里不使用@,直接用store

const store = useCounterStore()
const { count } = storeToRefs(store)
const { increment } = store
</script>

环境配置

在根目录创建.env,.env.development,.env.production

.env                # 所有情况下都会加载
.env.local          # 所有情况下都会加载,但会被 git 忽略
.env.[mode]         # 只在指定模式下加载
.env.[mode].local   # 只在指定模式下加载,但会被 git 忽略

在.env文件中配置环境变量时,必须以VITE_ 为前缀的变量才会暴露给经过 vite 处理的代码。

// .env.development
VITE_APP_BASE_URL="dev"
// .env.production
VITE_APP_BASE_URL="production"
// .env
VITE_APP_BASE_URL="env"

axios安装

pnpm i axios

src下创建api/index.js

import axios from 'axios'
const baseURL = import.meta.env.VITE_APP_BASE_URL
const service = axios.create({
  baseURL,
  timeout: 30000
})

service.interceptors.request.use(config => {
  const token = localStorage.getItem('token')
  if (token && !config.headers.Authorization) {
    config.headers.Authorization = 'Bearer ' + token
  }
  /* 接口发送请求拦截器逻辑 */
  return config
}, error => {
  return error
})

service.interceptors.response.use(response => {
  /* 接口响应请求拦截器逻辑 */
  return response.data
}, error => {
  return error
})

export default service

element-plus按需引入

pnpm i element-plus
pnpm i -D unplugin-vue-components unplugin-auto-import
// vite.config.ts
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'

plugins: [
    vue(),
    AutoImport({
        resolvers: [ElementPlusResolver()],
    }),
    Components({
        resolvers: [ElementPlusResolver()],
    })
]

它会默认生成auto-imports.d.ts和components.d.ts,总是会提交代码的时候冲突,可以直接在.gitignore忽略它。

eslint与prettier安装

pnpm i eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin eslint-config-airbnb-base eslint-config-prettier eslint-plugin-import eslint-plugin-prettier eslint-plugin-vue prettier vite-plugin-eslint -D

根目录下创建.eslintrc.cjs

    module.exports = {
      env: {
        browser: true,
        es2021: true,
        node: true
      },
      globals: {
        defineEmits: true,
        document: true,
        localStorage: true,
        GLOBAL_VAR: true,
        window: true,
        defineProps: true,
        defineExpose: true,
        withDefaults: true
      },
      extends: [
        'airbnb-base',
        'plugin:@typescript-eslint/recommended',
        'plugin:vue/vue3-recommended',
        'plugin:prettier/recommended' // 添加 prettier 插件
      ],
      parserOptions: {
        ecmaVersion: 'latest',
        parser: '@typescript-eslint/parser',
        sourceType: 'module'
      },
      plugins: ['vue', '@typescript-eslint', 'import'],
      rules: {
        indent: [
          2,
          2,
          {
            SwitchCase: 1
          }
        ],
        quotes: [2, 'single'], // 要求尽可能地使用单引号
        'no-plusplus': 'off',
        'import/no-extraneous-dependencies': [
          'error',
          {
            devDependencies: true
          }
        ],
        'vue/multi-word-component-names': 'off',
        'import/no-unresolved': 'off',
        'import/extensions': 'off',
        'no-console': 'off',
        'consistent-return': 'off',
        'no-param-reassign': 'off',
        'new-cap': 'off',
        'no-shadow': 'off',
        'no-underscore-dangle': 'off',
        'vue/no-v-html': 'off',
        'no-restricted-syntax': 'off',
        'guard-for-in': 'off',
        'import/prefer-default-export': 'off',
        // 'no-redeclare': 'off',
        'no-unused-expressions': 'off',
        '@typescript-eslint/ban-types': 'warn'
      }
    }

自定义一些 规则 ,使其更加符合规范的同时也更加符合我们的开发习惯。

根目录下创建.prettierrc

{
	"semi": false,
	"endOfLine": "auto",
	"singleQuote": true,
	"trailingComma": "none",
	"bracketSpacing": true,
	"jsxBracketSameLine": false,
	"vueIndentScriptAndStyle": false,
	"jsxBracketSameLine:": true,
	"htmlWhitespaceSensitivity": "ignore",
	"wrapAttributes": true,
	"overrides": [
		{
			"files": "*.html",
			"options": {
				"parser": "html"
			}
		}
	]
}

根目录下新建添加.eslintignore,让eslint忽略校验这些文件或者文件夹。

dist/
node_modules/
/public/
/src/assets/
components.d.ts

在package.json的scripts中添加一些命令行,这样运行命令行也可以对这些代码进行校验或者自动化调整了。

{
    "lint": "eslint --ext .js,.vue",
    "lint:fix": "eslint --fix --ext .js,.vue --ignore-path .eslintignore .",
    "prettier": "prettier --check .",
    "prettier:fix": "prettier --write .",
}

这样eslint和prettier的配置就就大功告成了。

scss安装

依赖安装

pnpm i sass -D

vite4貌似已经支持直接导入scss。如果报错了可以尝试在vite.config.js里面添加配置。

{
  css: {
    preprocessorOptions: {
      scss: {
        additionalData: '@import "src/style/index.scss";'
      }
    }
  }
}

stylelint配置

pnpm create stylelint

在根目录创建 .stylelintignore,用于忽略 stylelint 校验。

    dist/
    node_modules/
    /src/assets
    *.js

同样,在package.json的scripts中添加两条自定义命令行,使其进行校验或者自动格式化。

{
    "stylelint:fix": "stylelint --fix src/**/*.{vue,scss,css,sass}",
    "stylelint": "stylelint src/**/*.{vue,scss,css,sass}"
}

代码提交规范配置

pnpm i commitizen git-cz -D

在根目录创建changelog.config.json

不允许配置js文件,因为当前项目已经配置了type:module。

{
  "disableEmoji": false,
  "format": "{type}{scope}: {emoji}{subject}",
  "list": [
    "test",
    "feat",
    "fix",
    "chore",
    "docs",
    "refactor",
    "style",
    "ci",
    "perf",
    "global"
  ],
  "maxMessageLength": 64,
  "minMessageLength": 3,
  "questions": [
    "type",
    "scope",
    "subject"
  ],
  "scopes": [],
  "types": {
    "chore": {
      "description": "Build process or auxiliary tool changes",
      "emoji": "🤖",
      "value": "chore"
    },
    "ci": {
      "description": "CI related changes",
      "emoji": "🎡",
      "value": "ci"
    },
    "docs": {
      "description": "Documentation only changes",
      "emoji": "✏️",
      "value": "docs"
    },
    "feat": {
      "description": "A new feature",
      "emoji": "🎸",
      "value": "feat"
    },
    "fix": {
      "description": "A bug fix",
      "emoji": "🐛",
      "value": "fix"
    },
    "perf": {
      "description": "A code change that improves performance",
      "emoji": "⚡️",
      "value": "perf"
    },
    "refactor": {
      "description": "A code change that neither fixes a bug or adds a feature",
      "emoji": "💡",
      "value": "refactor"
    },
    "release": {
      "description": "Create a release commit",
      "emoji": "🏹",
      "value": "release"
    },
    "style": {
      "description": "Markup, white-space, formatting, missing semi-colons...",
      "emoji": "💄",
      "value": "style"
    },
    "test": {
      "description": "Adding missing tests",
      "emoji": "💍",
      "value": "test"
    },
    "global": {
      "description": "change global configuration",
      "emoji": "🌏",
      "value": "global"
    },
    "messages": {
      "type": "Select·the·type·of·change·that·you're·committing:",
      "customScope": "Select the scope this component affects:",
      "subject": "Write a short, imperative mood description of the change:\n",
      "body": "Provide a longer description of the change:\n ",
      "breaking": "List any breaking changes:\n",
      "footer": "Issues this commit closes, e.g #123:",
      "confirmCommit": "The packages that this commit has affected\n"
    }
  }
}

package.json中新加一些配置和自定义命令

{
    "scripts": {
        ...
        "cm": "git cz"
    },
    "config": {
        "commitizen": {
          "path": "git-cz"
        }
    }
}

代码提交的时候,运行以下命令,然后根据命令提示即可。

git add .
npm run cm

husky与lint-stage配置

代码风格自动化,会在用户提交代码的时候将修改的文件自动格式化一次。

pnpm install husky lint-staged -D
npm run prepare

在.husky文件夹下创建 pre-commit 文件

#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

npx lint-staged

在package.json添加一些husky和lint-staged的配置

{
    "scripts": {
        "prepare": "husky install",
    },
    "lint-staged": {
        "src/**/*.{js,jsx,ts,tsx}": "npm run lint:fix",
        "src/**/*.{vue,scss,css,sass}": "npm run stylelint:fix"
    }
}

大功告成,现在要提交代码,就会先经过elint和stylelint的格式校验。如果像是格式化的问题会直接帮你修复,但一些需要删除代码的就需要自己手动去删除了。

相关文章

【前端工程化】package.json vite打包性能优化以及填坑 scss好用的功能可不只是一个嵌套