项目搭建套餐:

1)vite作为工程脚手架

2)vue3作为项目框架

3)使用Typescript作为语言检测工具

4)使用pnpm包依赖管理工具

5)vue-router作为项目页面路由导航工具

6)使用sass作为项目的样式预处理语言

7)使用postcss作为CSS辅助工具

8)使用eslint作为代码语法检测工具

9)配置prettier及husky添加git提交hook

10)vuex作为项目状态管理工具

11)使用vuex-persistedstate作为持久化存储工具

12)使用auto-import插件辅助支持代码编写

懒人直接clone工程地址:vite-ts: 前端工程模板

1、cd工程目录,执行npm init vite@latest初始化vite工程

2、根据提示填写项目名称,选择Vue作为项目框架

3、选择Typescript作为语言工具

此时工作空间多出了一个vite-ts的工程,接下来使用pnpm安装工程依赖(pnpm是一种高性能的依赖包管理工具,会把全局安装存储库,项目依赖放到存储库中,并在项目目录下增加软链链接到全局存储库的依赖包。相较于npm直接在工程目录下存储依赖包资源,更节省存储空间)

4、执行npm install pnpm安装pnpm

执行pnpm install 安装工程依赖

执行npm run dev启动工程

通过浏览器访问http://localhost:5173/验证工程构建效果

5、添加路由层,执行pnpm install vue-router@4安装vue-router

添加视图文件:/views/index.vue

<template>
  <div>1111</div>
</template>
<script setup>
// onMounted(() => {
//   console.log(111);
// });
</script>

添加路由文件:/router/index.ts

import { createRouter, createWebHashHistory } from 'vue-router'

const routes = [
  { path: '/index', component: () => import('../views/index.vue') }
]

const router = createRouter({
  history: createWebHashHistory(),
  routes
})

export default router

修改App.vue,添加路由视图


<template>
  <div>
    <RouterView />
  </div>
</template>

<script setup lang="ts">
</script>

访问:http://localhost:5173/#/index   查看效果,页面正常使用

应用增加页面keepAlive支持,App.vue代码修改:

<template>
  <div>
    <router-view v-slot="{ Component }">
      <keep-alive>
        <component :is="Component" v-if="$route.meta.keepAlive"></component>
      </keep-alive>
      <component :is="Component" v-if="!$route.meta.keepAlive"></component>
    </router-view>
  </div>
</template>

<script setup lang="ts">

</script>

路由文件增加meta信息:

meta: {
      keepAlive: true
    }

在搭建应用过程中发现vscode会提示错误信息Could not find a declaration file for module '../views/index.vue'. 'd:/workspace/vite-ts/src/views/index.vue' implicitly has an 'any' type.ts(7016),但是引入的文件代码正常:

原因是Typescript无法识别vue文件,这时候需要在src目录下添加shims-vue.d.ts文件通过声明模块的方式告诉Typescript这些文件实际上是vue组件,从而使Typescript能为这些vue文件提供语法检查:

// shims-vue.d.ts
declare module '*.vue' {
  import { DefineComponent } from 'vue'
  const component: DefineComponent<{}, {}, any>
  export default component
}

添加后编译器告警恢复正常: 

在vite.config.ts增加别名配置代替src目录

pnpm install path -D

添加nodejs模块的类型声明文件,不然编译器会提示path的引用告警:

npm install --save-dev @types/node

 改写一下路由文件的引用写法,再测试一下页面是否正常运行:

 

6、添加sass作为项目样式预处理语言,需要安装sass工具和sass-loader工具

pnpm add sass -D
pnpm add sass-loader -D

添加一些scss语法,验证工程是否配置成功:

 这里可以看到样式效果和编译结果均符合预期就可以了

接下来把公共样式配置提取一下,形成公共配置:

 

可以看到页面样式展示正常,但是编译器对$primary变量的引用有异常告警,这个重启一下编译器就好了,真是莫名其妙:

 再加点黑科技,分离变量,mixin和extend,再在页面中使用测试效果:

 可以看到页面效果正常表达,sass的调整至此告一段落:

7、添加postcss作为辅助工具,自动把px单位换算为rem

pnpm install postcss-pxtorem -D

添加postcss.config.js文件(如果使用module.export而不是export default的话,会报编译规范相关的错误)

export default {
  plugins: {
    'postcss-pxtorem': {
      rootValue: 37.5,
      propList: ['*', '!border']
    }
  }
}

添加高度样式查看编译效果,与预期转换为2rem一致: 

 8、添加eslint作为语法检测支持:

pnpm i eslint -D

创建eslint配置: 

pnpm create @eslint/config

这里我们选择esm/vue/typescript/browser/pnpm作为我们的项目配置,并安装typescript-eslint、eslint-plugin-vue(这里我们就不需要再安装vue-eslint-parser了,eslint-plugin-vue@9.26.0已经集成了该插件)

完成后会自动生成一个eslint.config.js

 接下来我们打开index.vue会发现编译器提示我们页面的一些错误,一个是文件命名应该要多个词组成,二是onMounted引入了但是未使用:

更正后页面不再报错:

 9、接下来安装Prettier:

pnpm add prettier@latest -D

添加prettier格式化配置文件.prettierrc.js

export default {
	printWidth: 100, //一行的字符数
	tabWidth: 4, // 一个tab代表几个空格数
	useTabs: true, //是否使用tab进行缩进
	singleQuote: true, //字符串是否使用单引号
	semi: false, // 行尾是否使用分号,默认为true
	trailingComma: 'none', // 是否使用尾逗号
	htmlWhitespaceSensitivity: 'strict', // HTML空白敏感度
	bracketSpacing: true, // 对象大括号直接是否有空格,默认为 true,效果:{ a: 1 }
	proseWrap: 'never', // 换行设置
	endOfLine: 'auto'
}

添加prettier忽略配置文件.prettierignore

# .prettierignore
# Ignore node_modules directory
node_modules/
# Ignore all files in dist folder
dist/

在vscode中安装prettier插件:

添加eslint跟prettier搭子(node版本大于18时,eslint9已经不再需要eslint-config-prettier去处理两者的冲突了,但是这里我们装上): 

pnpm add eslint-plugin-prettier@latest eslint-config-prettier -D

添加prettier在eslint.config.js中的配置:

在package.json中添加script配置:

验证配置效果,这里我们弄两行代码没做缩进处理:

执行 npm run lint看看效果,这里我们可以看到缩进已被修复,并且提示了很多eslint检查出来的代码错误:

 接下来我们添加husky和lint-staged,为git提交代码之前先进行代码检查:

pnpm add -D husky lint-staged

 初始化husky,执行完毕后工程目录会新增一个.husky的文件夹:

npx husky init

之后我们再运行下面这个命令,添加提交之前执行的node命令,可以看到这里新增了一个pre-commit的文件: 

 node --eval "fs.writeFileSync('.husky/pre-commit','npx lint-staged\n')"

package.json添加配置:

{
  "lint-staged": {
    "**/*": "prettier --write --ignore-unknown"
  }
}

 接下来我们验证一下代码提交看看是否会触发钩子,这是一个验证的案例,新增了一行代码,但是未添加缩进:

执行git代码提交的时候,这里我们可以看到进行了自动的代码格式化:

如果想要保存的时候自动做代码修复,可以在vscode的setting中添加配置:

"editor.codeActionsOnSave": {
 
   "source.fixAll": true
 
}

 10、添加vuex作为项目全局状态管理工具

pnpm add vuex@next --save

 新增vuex代码:

import { createStore } from 'vuex'

const store = createStore({
	state() {
		return {
			count: 0
		}
	},
	mutations: {
		increment(state: { count: number }) {
			state.count++
		}
	}
})

export default store

这里如果用typescript的话vuex如果出现划红线,需要在src目录下新建vuex.d.ts文件,添加以下代码生命vuex中的变量类型:

declare module 'vuex' {
	export * from 'vuex/types/index.d.ts'
	export * from 'vuex/types/helpers.d.ts'
	export * from 'vuex/types/logger.d.ts'
	export * from 'vuex/types/vue.d.ts'
}

在main.ts中使用store:

import { createApp } from 'vue'
import App from './App.vue'
import router from './router/index.ts'
import store from './store'

const app = createApp(App)
app.use(router)
app.use(store)
app.mount('#app')

 添加vuex的代码使用:

检查代码执行效果,可以看到数值累加成功: 

接下来把vuex的状态分模块进行管理,具体代码上传到gitee了,在此不再赘述

11、增加vuex-persistedstate作为持久化存储工具

安装依赖:

pnpm add vuex-persistedstate

 添加store/index.ts执行代码:

验证代码执行效果,这里我们可以看到sessionStorage存储了vuex的状态信息,则代表配置成功:

12、使用unplugin-auto-import插件辅助代码编写

 unplugin-auto-import是一款自动导入API的插件,免去了我们import相关api的时间,首先需要安装依赖:

pnpm add -D unplugin-auto-import

在vite.config.js中添加auto-import相关代码,这里我们针对vue文件和ts文件、js文件进行检查,自动导入vue、vue-router使用到的相关API:

保存文件后src目录下会生成一个auto-import.d.ts文件:

 改完之后我们验证一下效果,发现删掉vue文件的onMounted和reactive引用后,编译器会报错,但是页面运行正常:

 这里我们要在vite.config.ts中增加配置选项,生成.eslintrc-auto-import.json配置文件,保存文件后会在项目目录下生成.eslintrc-auto-import.json:

 然后我们需要修改eslint.config.js,添加引用:

这样的话我们的vue文件就不会有报错啦:

最后我们打包一下这个工程代码,并且把页面扔到ngix服务器看看是否能够正常运行,先完善一下vite.config.ts,增加压缩组件、输出目录、相对路径、rollup打包配置等信息,完整配置:

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import path from 'path'
import AutoImport from 'unplugin-auto-import/vite'
import viteCompression from 'vite-plugin-compression'

// https://vitejs.dev/config/
export default defineConfig({
  base: './',
	plugins: [
		vue(),
    viteCompression({
      algorithm: 'gzip', // 压缩算法,可选[‘gzip’,‘brotliCompress’,‘deflate’,‘deflateRaw’]
      threshold: 10240, // 如果体积大于阈值,则进行压缩,单位为b
      deleteOriginFile: false // 压缩后是否删除源文件
    }),
		AutoImport({
			include: [/\.[tj]sx?$/, /\.vue$/, /\.vue\?vue/],
			imports: ['vue', 'vue-router'],
			dts: 'src/auto-import.d.ts', // 路径下自动生成文件夹存放全局指令
			eslintrc: {
				enabled: true // 1、改为true用于生成eslint配置。2、生成后改回false,避免重复生成消耗
			}
		})
	],
	resolve: {
		alias: {
			'@': path.resolve('./src') // 相对路径别名配置,使用 @ 代替 src
		}
	},
	// scss 全局变量的一个配置
	css: {
		preprocessorOptions: {
			scss: {
				javascriptEnabled: true,
				additionalData: '@import "./src/assets/scss/global.scss";'
			}
		}
	},
  build: {
    outDir:'dist/app',
    rollupOptions: { 
      output: {
        /** S-静态文件按类型分包 */
        chunkFileNames: 'static/js/[name]-[hash].js',
        entryFileNames: 'static/js/[name]-[hash].js',
        assetFileNames: 'static/[ext]/[name]-[hash].[ext]',
        /** E-静态文件按类型分包 */
        manualChunks(id) {  // 超大静态资源拆分
          if (id.includes('node_modules')) {
            return id.toString().split('node_modules/')[1].split('/')[0].toString();
          }
        }
      }
    },
    terserOptions: {
      //打包后移除console和注释
      compress: {
          drop_console: true,
          drop_debugger: true,
      },
    }
  }
})

结果提示报错信息:

还是要添加一下$route让typescript能识别这个变量,在src目录下有个vite-env.d.ts的文件,在里面添加以下代码就可以正常打包了:

import { RouteLocationNormalized, Router } from 'vue-router'

import { ComponentCustomProperties, DefineComponent } from 'vue'

// 扩展Vue组件的类型定义

declare module 'vue' {

  // 声明组件的默认导出

  export interface ComponentCustomProperties {

    // 扩展$route属性

    $route: RouteLocationNormalized;

  }

}

打包结果:

丢上nginx后再访问,页面运行正常,大功告成

踩坑点:

  • .prettierrc配置文件要加上endOfLine: 'auto'选项,关闭换行字符校验,不然编译器每行都会报错:Delete `␍`eslint(prettier/prettier)
  • 搭建工程期间遇到Replace `····` with `↹↹`这个问题,需要在.vscode/settings.json增加配置:
  • {
      "prettier.endOfLine": "auto",
      "editor.codeActionsOnSave": {
        "source.fixAll": "explicit"
      },
      "editor.formatOnSave": false
    }

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐