npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

vite-vue3-ts-pinia

v0.0.1

Published

> ## 一个大厂企业级前端项目 > > ## 如果觉得项目模板不错的话,欢迎 Star 支持就好,感谢大家!

Downloads

1

Readme

Vite + Vue3 + Typescript + Pinia + Vueuse

一个大厂企业级前端项目

如果觉得项目模板不错的话,欢迎 Star 支持就好,感谢大家!

通过这篇文章你可以学到

  • 如何使用使用 Vite 搭建项目
  • 如何在 Vite 中集成 typescript
  • 如何在 Vite 中集成 vue-router4pinia
  • 如何使用 vue3 的伴侣 vueuse
  • 如何在项目中集成 eslintprettier 保证代码质量
  • 如何规范化 git 提交信息
  • 如何为团队开发专属的项目模板

环境依赖版本

长话短说,直接开干 ~

1. 初始化项目

按步骤提示初始化:

  1. 使用 vite-cli 命令
# pnpm
pnpm create vite

# npm
npm init vite@latest

# yarn
yarn create vite
  1. 输入项目名:
? Project name:  vite-vue3-ts-pinia
  1. 选择一个框架(vue)
? Select a framework: » - Use arrow-keys. Return to submit.
     vanilla // 原生js
 >   vue     // 默认就是 vue3
     react   // react
     preact  // 轻量化react框架
     lit     // 轻量级web组件
     svelte  // svelte框架
  1. 使用 typescript
? Select a variant: › - Use arrow-keys. Return to submit.
     vue
 ❯   vue-ts
  1. 启动项目
cd vite-vue3-ts-pinia && pnpm install && pnpm run dev

快速初始化(建议使用):

# pnpm
pnpm create vite project-name -- --template vue-ts

# npm 6.x
npm init vite@latest project-name --template vue-ts
 
# npm 7+, 需要额外的双横线:
npm init vite@latest project-name -- --template vue-ts
 
# yarn
yarn create vite project-name --template vue-ts

集成配置

  1. 为保证 node 的使用
pnpm i @types/node --save-dev
  1. 修改 tsconfig.json
{
  "compilerOptions": {
    "typeRoots": [
      "node_modules/@types", // 默认值
      "src/types"
   ],
    "target": "esnext",
    "useDefineForClassFields": true,
    "module": "esnext",
    "moduleResolution": "node",
    "strict": true,
    "jsx": "preserve",
    "sourceMap": true,
    "resolveJsonModule": true,
    "esModuleInterop": true,
    "lib": ["esnext", "dom"],
    "baseUrl": "./",
    "paths":{
      "@": ["src"],
      "@/*": ["src/*"],
    }
  },
  "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"]
}
  1. 修改 vite.config.ts
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import * as path from 'path';

// https://vitejs.dev/config/
export default defineConfig({
    resolve: {
        //设置别名
        alias: {
            '@': path.resolve(__dirname, 'src')
        }
    },
    plugins: [vue()],
    server: {
        port: 8080, //启动端口
        hmr: {
            host: '127.0.0.1',
            port: 8080
        },
        // 设置 https 代理
        proxy: {
            '/api': {
                target: 'your https address',
                changeOrigin: true,
                rewrite: (path: string) => path.replace(/^\/api/, '')
            }
        }
    }
});

2. 代码质量风格的统一

集成 eslint

  1. 安装
pnpm i eslint eslint-plugin-vue --save-dev

由于 ESLint 默认使用 Espree 进行语法解析,无法识别 TypeScript 的一些语法,故我们需要安装 @typescript-eslint/parser 替代掉默认的解析器

pnpm install @typescript-eslint/parser --save-dev

安装对应的插件 @typescript-eslint/eslint-plugin 它作为 eslint 默认规则的补充,提供了一些额外的适用于 ts 语法的规则。

pnpm install @typescript-eslint/eslint-plugin --save-dev
  1. 创建配置文件: .eslintrc.js 或 .eslintrc.json
module.exports = {
    parser: 'vue-eslint-parser',

    parserOptions: {
        parser: '@typescript-eslint/parser',
        ecmaVersion: 2020,
        sourceType: 'module',
        ecmaFeatures: {
            jsx: true
        }
    },

    extends: [
        'plugin:vue/vue3-recommended',
        'plugin:@typescript-eslint/recommended',
    ],

    rules: {
        // override/add rules settings here, such as:
    }
};
  1. 创建忽略文件:.eslintignore
node_modules/
dist/
index.html
  1. 命令行式运行:修改 package.json
{
    ...
    "scripts": {
        ...
        "eslint:comment": "使用 ESLint 检查并自动修复 src 目录下所有扩展名为 .js 和 .vue 的文件",
        "eslint": "eslint --ext .js,.vue --ignore-path .gitignore --fix src",
    }
    ...
}

集成 prettier

  1. 安装
pnpm i prettier eslint-config-prettier eslint-plugin-prettier --save-dev
  1. 创建配置文件: prettier.config.js.prettierrc.js
module.exports = {
    // 一行最多 80 字符
    printWidth: 80,
    // 使用 4 个空格缩进
    tabWidth: 4,
    // 不使用 tab 缩进,而使用空格
    useTabs: false,
    // 行尾需要有分号
    semi: true,
    // 使用单引号代替双引号
    singleQuote: true,
    // 对象的 key 仅在必要时用引号
    quoteProps: 'as-needed',
    // jsx 不使用单引号,而使用双引号
    jsxSingleQuote: false,
    // 末尾使用逗号
    trailingComma: 'all',
    // 大括号内的首尾需要空格 { foo: bar }
    bracketSpacing: true,
    // jsx 标签的反尖括号需要换行
    jsxBracketSameLine: false,
    // 箭头函数,只有一个参数的时候,也需要括号
    arrowParens: 'always',
    // 每个文件格式化的范围是文件的全部内容
    rangeStart: 0,
    rangeEnd: Infinity,
    // 不需要写文件开头的 @prettier
    requirePragma: false,
    // 不需要自动在文件开头插入 @prettier
    insertPragma: false,
    // 使用默认的折行标准
    proseWrap: 'preserve',
    // 根据显示样式决定 html 要不要折行
    htmlWhitespaceSensitivity: 'css',
    // 换行符使用 lf
    endOfLine: 'auto'
}
  1. 修改 .eslintrc.js 配置
module.exports = {
    ...

    extends: [
        'plugin:vue/vue3-recommended',
        'plugin:@typescript-eslint/recommended',
        'prettier',
        'plugin:prettier/recommended'
    ],

    ...
};
  1. 命令行式运行:修改 package.json
{
    ...
    "scripts": {
        ...
        "prettier:comment": "自动格式化当前目录下的所有文件",
        "prettier": "prettier --write"
    }
    ...
}

3. 集成 pinia

Pinia 读音:['piːnə],是 Vue 官方团队推荐代替Vuex的一款轻量级状态管理库。

Pinia 有如下特点:

  • 完整的 typescript 的支持;
  • 足够轻量,压缩后的体积只有1.6kb;
  • 去除 mutations,只有 state,getters,actions(这是我最喜欢的一个特点);
  • actions 支持同步和异步;
  • 没有模块嵌套,只有 store 的概念,store 之间可以自由使用,更好的代码分割;
  • 无需手动添加 store,store 一旦创建便会自动添加;

安装

 pnpm i pinia --save

使用

  1. 新建 src/store 目录并在其下面创建 index.ts,导出 store
 import { createPinia } from 'pinia'

 const store = createPinia()

 export default store
  1. 在 main.ts 中引入并使用
 import { createApp } from 'vue'
 import App from './App.vue'
 import store from './store'
 ​
 // 创建vue实例
 const app = createApp(App)
 ​
 // 挂载pinia
 app.use(store)
 ​
 // 挂载实例
 app.mount('#app');
  1. 定义State: 在 src/store 下面创建一个 user.ts
 import { defineStore } from 'pinia'

 export const useUserStore = defineStore({
   id: 'user', // id必填,且需要唯一
   state: () => {
     return {
       name: '张三'
     }
   },
   actions: {
     updateName(name) {
       this.name = name
     }
   }
 })
  1. 获取State: 在 src/components/usePinia.vue 中使用
 <template>
   <div>{{ userStore.name }}</div>
 </template>

 <script lang="ts" setup>
 import { useUserStore } from '@/store/user'

 const userStore = useUserStore()
 </script>
  1. 修改State:
 // 1. 直接修改 state (不建议)
 userStore.name = '李四'

 // 2. 通过 actions 去修改
 <script lang="ts" setup>
 import { useUserStore } from '@/store/user'

 const userStore = useUserStore()
 userStore.updateName('李四')
 </script>

更详细上手指南:链接 官方文档:链接

4. 集成 vue-router4

安装

 pnpm i vue-router --save

使用

  1. 新建 src/router 目录并在其下面创建 index.ts,导出 router
 import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router';

 const routes: Array<RouteRecordRaw> = [
   {
     path: '/login',
     name: 'Login',
     meta: {
         title: '登录',
         keepAlive: true,
         requireAuth: false
     },
     component: () => import('@/pages/login.vue')
   },
   {
       path: '/',
       name: 'Index',
       meta: {
           title: '首页',
           keepAlive: true,
           requireAuth: true
       },
       component: () => import('@/pages/index.vue')
   }
 ]

 const router = createRouter({
   history: createWebHistory(),
   routes
 });
 export default router;
  1. 在 main.ts 中引入并使用
 import { createApp } from 'vue'
 import App from './App.vue'
 import store from './store'
 import router from '@/router';

 // 创建vue实例
 const app = createApp(App);

 app.use(router);

 // 挂载实例
 app.mount('#app');
  1. 修改 App.vue
 <template>
   <RouterView/>
 </template>

5. 集成 vueuse

VueUse 是一个基于 Composition API 的实用函数集合。

安装

 pnpm i @vueuse/core

使用

  1. 创建一个新的 src/page/vueUse.vue 页面来做一个简单的 demo
 <template>
   <h1> 测试 vueUse 的鼠标坐标 </h1>
   <h3>Mouse: {{x}} x {{y}}</h3>
 </template>

 <script lang="ts">
     import { defineComponent } from 'vue';
     import { useMouse } from '@vueuse/core'

     export default defineComponent({
         name: 'VueUse',
         setup() {
           const { x, y } = useMouse()

           return {
             x, y
           }
         }
     });
 </script>

useMouse 只是 vueuse 的一个最基本的函数库,还有许多,总会有一个适合你;

更多函数官方文档:链接

6. CSS 的集成

方案一:原生 css variable 新特性:

原生支持,不需要第三方插件,具体使用文档可 查看

  1. 新建文件 src/styles/index.css
 :root {
   --main-bg-color: pink;
 }
 ​
 body {
   background-color: var(--main-bg-color);
 }

注:还可以增加 PostCSS 配置,(任何受 postcss-load-config 支持的格式,例如 postcss.config.js ),它将会自动应用于所有已导入的 CSS。

方案二:scss 或 less:

  1. 安装
 # .scss and .sass
 pnpm add -D sass

 # .less
 pnpm add -D less
  1. 使用在 .vue 文件模板中
// .scss
 <template>
     <div class="root">
         <h3>欢迎使用 scss</h3>
     </div>
 </template>
 <style lang="scss">
   .root {}
 </style>

// .less
 <template>
     <div class="root">
         <h3>欢迎使用 less</h3>
     </div>
 </template>
 <style lang="less">
   .root {}
 </style>

7. 集成 axios

axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。

安装

 pnpm i axios

使用:

  1. 新建 src/utils/axios.ts
 import axios, { AxiosResponse, AxiosRequestConfig } from 'axios';

 const service = axios.create();

 // Request interceptors
 service.interceptors.request.use(
     (config: AxiosRequestConfig) => {
         // do something
         return config;
     },
     (error: any) => {
         Promise.reject(error);
     }
 );

 // Response interceptors
 service.interceptors.response.use(
     async (response: AxiosResponse) => {
         // do something
     },
     (error: any) => {
         // do something
         return Promise.reject(error);
     }
 );

 export default service;
  1. 在页面中使用即可
<script lang="ts">
    import request from '@/utils/axios';
    const requestRes = async () => {
        let result = await request({
                    url: '/api/xxx',
                    method: 'get'
                  });
    }

</script>

封装请求参数和响应数据的所有 api (可选项)

  1. 新建 src/api/index.ts
import * as login from './module/login';
import * as index from './module/index';

export default Object.assign({}, login, index);
  1. 新建 src/api/module/login.tssrc/api/module/index.ts
import request from '@/utils/axios';

/**
 * 登录
 */
 
interface IResponseType<P = {}> {
    code?: number;
    status: number;
    msg: string;
    data: P;
}
interface ILogin {
    token: string;
    expires: number;
}
export const login = (username: string, password: string) => {
    return request<IResponseType<ILogin>>({
        url: '/api/auth/login',
        method: 'post',
        data: {
            username,
            password
        }
    });
};
  1. 由于使用了 typescript,所以需新增 src/types/shims-axios.d.ts
import { AxiosRequestConfig } from 'axios';
/**
 * 自定义扩展axios模块
 * @author Maybe
 */
declare module 'axios' {
    export interface AxiosInstance {
        <T = any>(config: AxiosRequestConfig): Promise<T>;
        request<T = any>(config: AxiosRequestConfig): Promise<T>;
        get<T = any>(url: string, config?: AxiosRequestConfig): Promise<T>;
        delete<T = any>(url: string, config?: AxiosRequestConfig): Promise<T>;
        head<T = any>(url: string, config?: AxiosRequestConfig): Promise<T>;
        post<T = any>(url: string, data?: any, config?: AxiosRequestConfig): Promise<T>;
        put<T = any>(url: string, data?: any, config?: AxiosRequestConfig): Promise<T>;
        patch<T = any>(url: string, data?: any, config?: AxiosRequestConfig): Promise<T>;
    }
}
  1. src/pages/request.vue 页面中使用
<script lang="ts">
    import API from '@/api';
    
    const requestRes = async () => {
        let result = await API.login('zhangsan', '123456');
    }

</script>

8. css 的 UI 样式库

可选很多,根据自己项目的需求去进行选择即可

注意:UI 库一般需要按需引入(下面以 element-plus 为例)

  1. 安装 vite-plugin-style-import
pnpm i vite-plugin-style-import --save-dev
  1. 修改 vite.config.ts
...
import styleImport from 'vite-plugin-style-import'


export default defineConfig({
    ...
    plugins: [
        vue(),
        styleImport({
            libs: [
                {
                    libraryName: 'element-plus',
                    esModule: true,
                    resolveStyle: (name) => {
                        return `element-plus/lib/theme-chalk/${name}.css`;
                    },
                    ensureStyleFile: true // 忽略文件是否存在, 导入不存在的CSS文件时防止错误。
                }
            ]
        })
    ],
    ...
})

9. 使用 commitizen 规范git提交

为了使团队多人协作更加的规范,所以需要每次在 git 提交的时候,做一次硬性规范提交,规范 git 的提交信息

安装 commitizen (交互式提交 + 自定义提示文案 + Commit规范)

  1. 安装
pnpm install -D commitizen cz-conventional-changelog @commitlint/config-conventional @commitlint/cli commitlint-config-cz cz-customizable
  1. 配置 package.json
{
  ...
  "scripts": {
    "commit:comment": "引导设置规范化的提交信息",
    "commit":"git-cz",
  },

  "config": {
      "commitizen": {
        "path": "node_modules/cz-customizable"
      }
  },
  ...
}
  1. 新增配置 commitlint.config.js
module.exports = {
    extends: ['@commitlint/config-conventional', 'cz'],
    rules: {
        'type-enum': [
            2,
            'always',
            [
                'feature', // 新功能(feature)
                'bug', // 此项特别针对bug号,用于向测试反馈bug列表的bug修改情况
                'fix', // 修补bug
                'ui', // 更新 ui
                'docs', // 文档(documentation)
                'style', // 格式(不影响代码运行的变动)
                'perf', // 性能优化
                'release', // 发布
                'deploy', // 部署
                'refactor', // 重构(即不是新增功能,也不是修改bug的代码变动)
                'test', // 增加测试
                'chore', // 构建过程或辅助工具的变动
                'revert', // feat(pencil): add ‘graphiteWidth’ option (撤销之前的commit)
                'merge', // 合并分支, 例如: merge(前端页面): feature-xxxx修改线程地址
                'build', // 打包
            ],
        ],
        // <type> 格式 小写
        'type-case': [2, 'always', 'lower-case'],
        // <type> 不能为空
        'type-empty': [2, 'never'],
        // <scope> 范围不能为空
        'scope-empty': [2, 'never'],
        // <scope> 范围格式
        'scope-case': [0],
        // <subject> 主要 message 不能为空
        'subject-empty': [2, 'never'],
        // <subject> 以什么为结束标志,禁用
        'subject-full-stop': [0, 'never'],
        // <subject> 格式,禁用
        'subject-case': [0, 'never'],
        // <body> 以空行开头
        'body-leading-blank': [1, 'always'],
        'header-max-length': [0, 'always', 72],
    },
};
  1. 自定义提示则添加 .cz-config.js
module.exports = {
    types: [
        {value: 'feature',  name: 'feature:  增加新功能'},
        {value: 'bug',      name: 'bug:      测试反馈bug列表中的bug号'},
        {value: 'fix',      name: 'fix:      修复bug'},
        {value: 'ui',       name: 'ui:       更新UI'},
        {value: 'docs',     name: 'docs:     文档变更'},
        {value: 'style',    name: 'style:    代码格式(不影响代码运行的变动)'},
        {value: 'perf',     name: 'perf:     性能优化'},
        {value: 'refactor', name: 'refactor: 重构(既不是增加feature,也不是修复bug)'},
	{value: 'release',  name: 'release:  发布'},
	{value: 'deploy',   name: 'deploy:   部署'},
        {value: 'test',     name: 'test:     增加测试'},
        {value: 'chore',    name: 'chore:    构建过程或辅助工具的变动(更改配置文件)'},
        {value: 'revert',   name: 'revert:   回退'},
    	{value: 'build',    name: 'build:    打包'}
    ],
    // override the messages, defaults are as follows
    messages: {
        type: '请选择提交类型:',
        customScope: '请输入您修改的范围(可选):',
        subject: '请简要描述提交 message (必填):',
        body: '请输入详细描述(可选,待优化去除,跳过即可):',
        footer: '请输入要关闭的issue(待优化去除,跳过即可):',
        confirmCommit: '确认使用以上信息提交?(y/n/e/h)'
    },
    allowCustomScopes: true,
    skipQuestions: ['body', 'footer'],
    subjectLimit: 72
};
  1. 交互界面测试

carbon.png

  • 到目前只是规范了 git 的提交信息,我们对提交前代码的检查还没有做到位,例如 ESLint、Prettier,毕竟谁都会有疏忽的时候,
  • 那么现在我们的 husky 就闪亮登场了

安装 husky

  1. 安装
# 1.安装
pnpm i husky lint-staged -D

# 2.生成 .husky 的文件夹
npx husky install

# 3.添加 hooks,会在 .husky 目录下生成一个 pre-commit 脚本文件
npx husky add .husky/pre-commit "npx --no-install lint-staged"

# 4.添加 commit-msg
npx husky add .husky/commit-msg 'npx --no-install commitlint --edit "$1"'

# 5. 使用 `git commit -m "message"` 就会看到 hook 生效了。
  1. 添加配置 package.json
{
  ...
  "lint-staged": {
    	"*.{js,ts}": [
            "npm run eslint",
            "npm run prettier"
    	]
  }
  ...
}

提交日志(可选)

最后

该系列会是一个持续更新系列,关于整个《Vite 从入门到精通》,我主要会从如下图几个方面讲解,请大家拭目以待吧!!!

Untitled.png

靓仔靓女们,都看到这里了,要不点个赞再走呗 🌹🌹🌹