使用vite搭建vue3+TS项目及基础配置
搭建 vite 项目
使用 NPM:
// vite2(需要 Node.js 版本 >= 12.0.0。)
npm init vite@latest
// vite3(需要node.js版本18+或20+)
npm create vite@latest
2
3
4
5
使用 vite 创建 vue 项目
// 这个命令会安装和执行 create-vue,它是 Vue 提供的官方脚手架工具
npm create vue@latest
2
使用 yarn:
yarn create vite
也可以通过附加的命令行选项直接指定项目名称和你想要使用的模板。例如构建一个 Vite + Vue 项目:
// npm 6.x
npm create vite@latest my-vue-app --template vue
// npm 7+, 需要额外加 --:
npm create vite@latest my-vue-app -- --template vue
// yarn
yarn create vite my-vue-app --template vue
2
3
4
5
6
7
8
更多模板选项:vue,vue-ts,react,react-ts
# jsx 语法配置
如果想在项目中使用 jsx 来开发,则需要安装另一款插件:
npm install @vitejs/plugin-vue-jsx -D
然后在 vite.config.js 文件中增加如下配置
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueJsx from '@vitejs/plugin-vue-jsx';
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue(), vueJsx()]
})
2
3
4
5
6
7
8
至此,就可以在项目中愉快地使用 jsx 来开发了。
# postcss-px-to-viewport 移动端适配
如果是做移动端适配时,则可以使用 postcss-px-to-viewport 插件:
npm install postcss-px-to-viewport -D
则 vite.config.js 中配置项更改如下:
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueJsx from '@vitejs/plugin-vue-jsx';
import postcsspxtoviewport from 'postcss-px-to-viewport'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue(), vueJsx()],
css: {
postcss: {
plugins: [
postcsspxtoviewport({
unitToConvert: 'px', // 要转化的单位
viewportWidth: 750, // UI设计稿的宽度
unitPrecision: 6, // 转换后的精度,即小数点位数
propList: ['*'], // 指定转换的css属性的单位,*代表全部css属性的单位都进行转换
viewportUnit: 'vw', // 指定需要转换成的视窗单位,默认vw
fontViewportUnit: 'vw', // 指定字体需要转换成的视窗单位,默认vw
selectorBlackList: ['ignore-'], // 指定不转换为视窗单位的类名,
minPixelValue: 1, // 默认值1,小于或等于1px则不进行转换
mediaQuery: true, // 是否在媒体查询的css代码中也进行转换,默认false
replace: true, // 是否转换后直接更换属性值
exclude: [/node_modules/], // 设置忽略文件,用正则做目录名匹配
//exclude: [],
landscape: false // 是否处理横屏情况
})
]
}
}
})
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
现在在项目中使用 px,它会自动转成 vw 了。
# postcss-pxtorem 移动端适配
也可以使用 postcss-pxtorem 插件来做移动端适配
npm install postcss-pxtorem -D
然后在 vite.config.ts 中增加如下配置
import postCssPxToRem from 'postcss-pxtorem'
css: {
postcss: {
plugins: [
postCssPxToRem({
rootValue: 16,
unitPrecision: 5,
replace: true,
propList: ['*'],
selectorBlackList: ['.ignore-'],
exclude: /node_modules/i,
mediaQuery: false,
minPixelValue: 2
})
]
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
由于是 ts 项目,此时可能会报类型警告问题,可以安装 @types/postcss-pxtorem 来解决
npm install @types/postcss-pxtorem -D
# autoprefixer 自动添加浏览器前缀
安装 autoprefixer 插件来自动添加浏览器前缀
npm install autoprefixer -D
在 vite.config.ts 中增加如下配置
import autoprefixer from 'autoprefixer'
css: {
postcss: {
plugins: [
autoprefixer({
overrideBrowserslist: [
"Android 4.1",
"iOS 7.1",
"Chrome > 31",
"ff > 31",
"ie >= 8",
"last 50 versions",
],
grid: true, // 是否使用 autoprefixer
})
]
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 配置 @路径别名:
import path from 'path'
resolve: {
alias: {
'@': path.resolve(__dirname, 'src')
}
}
2
3
4
5
6
7
# 开启 gzip 压缩
import compression from 'vite-plugin-compression'
plugins: [
compression( {
algorithm: 'gzip',
ext: '.gz',
deleteOriginFile: true, //是否删除源文件
threshold: 1024, // 大于1k的进行压缩
filter: /\.(js|css|html|svg)$/,
})
]
2
3
4
5
6
7
8
9
10
11
# 开启打包后 js、css、图片等文件夹分离
build: {
sourcemap: false,
chunkSizeWarningLimit: 1500,
rollupOptions: {
output: {
manualChunks(id) {
if (id.includes('node_modules')) {
return id
.toString()
.split('node_modules/')[1]
.split('/')[0]
.toString()
}
},
entryFileNames: 'assets/js/[name]-[hash].js',
assetFileNames: 'assets/[ext]/[name]-[hash].[ext]',
chunkFileNames: ( chunkInfo ) => {
const facadeModuleId = chunkInfo.facadeModuleId ? chunkInfo.facadeModuleId.split('/') : [];
const fileName = facadeModuleId[facadeModuleId.length - 2] || '[name]';
return `assets/js/${fileName}-[hash].js`
}
}
},
minify: 'terser',
terserOptions: {
compress: {
drop_console: true,
drop_debugger: true
},
format: {
comments: false
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# vue-router 配置
1、安装 vue-router
npm install vue-router
2、在 src 文件夹下建立 router 文件夹,在该文件夹下新建 index.ts 文件,配置如下:
import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router'
const routes:Array<RouteRecordRaw> = [
{
path: '/',
component: () => import(/* webpackChunkName: 'Home' */ '@/views/Home.vue'),
name: 'Home',
meta: {
title: '首页'
}
}
]
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes
})
// tslint:disable-next-line
router.beforeEach((to) => {
if (to.meta.title) {
document.title = to.meta.title as string
}
})
export default router
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
3、在 main.ts 入口文件中引入 route 并使用它
import router from "./router"
const app=createApp( App )
app.use(router)
2
3
4
在路由配置文件中导入.vue 文件时,可能会报错无法找到模块等警告。
解决办法,在 vite-env.d.ts 增加如下代码:
declare module '*.vue' {
import type { DefineComponent } from 'vue'
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/ban-types
const component: DefineComponent<{}, {}, any>
export default component
}
2
3
4
5
6
此时,警告就会消失的
# 按需自动导入
在 vue3 开发中,经常需要导入各种 api,如 ref,reactive,computed,watch,各种生命周期,路由相关的 api 等等,觉得特繁琐,这时候我们可以使用另一款自动导出插件 unplugin-auto-import 了。
安装插件 unplugin-auto-import
npm install -D unplugin-auto-import
现在 vite.config.js 文件配置更改如下:
import { defineConfig } from 'vite'
import AutoImport from 'unplugin-auto-import/vite'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
AutoImport({
imports: ['vue', 'vue-router']
})
]
})
2
3
4
5
6
7
8
9
10
11
12
现在开发再也不用导入与 vue、vue-router 相关的 api 了,可以直接使用,其他的插件会帮我们解决。
# ESLint 和 Prettier 配置
1、安装 eslint 相关插件
npm install --save-dev eslint eslint-plugin-vue @typescript-eslint/parser @typescript-eslint/eslint-plugin
2、创建或更新.eslintrc.cjs 配置文件,配置如下
module.exports = {
root: true,
env: {
node: true,
},
extends: [
'eslint:recommended',
'plugin:vue/vue3-recommended',
'plugin:@typescript-eslint/recommended',
'prettier',
'plugin:prettier/recommended'
],
parserOptions: {
parser: '@typescript-eslint/parser',
ecmaVersion: 2020,
sourceType: 'module',
},
rules: {
'vue/no-multiple-template-root': 'off',
'@typescript-eslint/no-explicit-any': 'off',
},
};
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
3、安装 Prettier 相关插件
npm install --save-dev prettier eslint-config-prettier eslint-plugin-prettier
4、创建或更新.prettierrc 文件
{
"singleQuote": true,
"semi": false,
"trailingComma": "all"
}
2
3
4
5
5、创建.eslintignore 文件和.prettierignore 文件
// .eslintignore配置代码
node_modules
dist
// .prettierignore配置代码
node_modules
dist
2
3
4
5
6
7
8
6、更新 package.json,添加如下脚本命令
{
'scripts': {
"lint": "eslint --fix --ext .ts,.vue src",
"format": "prettier --write \"src/**/*.{js,ts,vue,json,css,scss,md}\""
}
}
2
3
4
5
6
现在执行 npm run lint 可能会报如下错误:如 ref、reactive is not defined 等问题。这是因为 ts 未识别到 vue api,没有相应的模块声明文件。
解决:在 vite.config.js 中配置,并在 tsconfig.json 中引入。
plugins: [
AutoImport({
dts: 'src/auto-imports.d.ts', // 可以自定义文件生成的位置,默认是根目录下
imports: ['vue', 'vue-router'],
})
]
2
3
4
5
6
在 tsconfig.json 中配置如下:
"include": ["env.d.ts", "src/**/*", "src/**/*.vue", "./auto-imports.d.ts"]
这时候还是会报错,这是因为因为还没配置自动导入相应的 eslint 规则
解决:在 vite.config.js 中的 autoimport 中配置生成对应的.eslintrc-auto-import.json 配置文件,并在.eslintrc 中引入
plugins: [
AutoImport({
dts: 'src/auto-imports.d.ts', // 可以自定义文件生成的位置,默认是根目录下
imports: ['vue', 'vue-router'],
eslintrc: {
enabled: true, // 1、改为true用于生成eslint配置。2、生成后改回false,避免重复生成消耗
}
})
]
2
3
4
5
6
7
8
9
在.eslintrc.cjs 中的 extentds 中配置如下:
'extends': [
// ... 默认配置不用修改
"./.eslintrc-auto-import.json" // 新加的
]
2
3
4
此时重新启动项目后,可能会遇到这种错误,如 Component name "Home" should always be multi-word,这是因为项目默认开启了驼峰命名,可在.eslintrc.cjs 中的 rules 下添加如下配置
"vue/multi-word-component-names": "off"
至此,重启项目,能正确运行了。
# 配置 css 预处理器 less 或 scss 等
1、安装 less 相关的包
npm install less less-loader -D
2、在 vite.config.ts 中增加如下配置
{
css: {
preprocessorOptions: {
less: true
}
}
}
2
3
4
5
6
7
3、在需要使用 less 的组件中使用如下:
<style scoped lang="less"></style>
# 完整配置
此时,vite.config.ts 中完整配置如下:
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import path from 'path'
import postCssPxToRem from 'postcss-pxtorem'
import autoprefixer from 'autoprefixer'
import compression from 'vite-plugin-compression'
import AutoImport from 'unplugin-auto-import/vite'
export default defineConfig( {
resolve: {
alias: {
'@': path.resolve(__dirname, 'src')
}
},
plugins: [
vue(),
compression( {
algorithm: 'gzip',
ext: '.gz',
deleteOriginFile: true, //是否删除源文件
threshold: 1024, // 大于1k的进行压缩
filter: /\.(js|css|html|svg)$/,
} ),
AutoImport( {
dts: 'src/auto-imports.d.ts',
imports: [
'vue',
'vue-router',
],
eslintrc: {
enabled: false, // 1、改为true用于生成eslint配置。2、生成后改回false,避免重复生成消耗
}
})
],
css: {
postcss: {
plugins: [
postCssPxToRem({
rootValue: 16,
unitPrecision: 5,
replace: true,
propList: ['*'],
selectorBlackList: ['.ignore-'],
exclude: /node_modules/i,
mediaQuery: false,
minPixelValue: 2
}),
autoprefixer({
overrideBrowserslist: [
"Android 4.1",
"iOS 7.1",
"Chrome > 31",
"ff > 31",
"ie >= 8",
"last 50 versions",
],
grid: true, // 是否使用 autoprefixer
})
]
},
preprocessorOptions: {
less: true
}
},
build: {
sourcemap: false,
chunkSizeWarningLimit: 1500,
rollupOptions: {
output: {
manualChunks(id) {
if (id.includes('node_modules')) {
return id
.toString()
.split('node_modules/')[1]
.split('/')[0]
.toString()
}
},
entryFileNames: 'assets/js/[name]-[hash].js',
assetFileNames: 'assets/[ext]/[name]-[hash].[ext]',
chunkFileNames: ( chunkInfo ) => {
const facadeModuleId = chunkInfo.facadeModuleId ? chunkInfo.facadeModuleId.split('/') : [];
const fileName = facadeModuleId[facadeModuleId.length - 2] || '[name]';
return `assets/js/${fileName}-[hash].js`
}
}
},
minify: 'terser',
terserOptions: {
compress: {
drop_console: true,
drop_debugger: true
},
format: {
comments: false
}
}
}
})
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
.eslintrc.cjs 文件完整配置:
module.exports = {
root: true,
env: {
node: true,
},
extends: [
'eslint:recommended',
'plugin:vue/vue3-recommended',
'plugin:@typescript-eslint/recommended',
'prettier',
'plugin:prettier/recommended',
"./.eslintrc-auto-import.json"
],
parser: 'vue-eslint-parser',
parserOptions: {
parser: '@typescript-eslint/parser',
ecmaVersion: 2020,
sourceType: 'module',
},
rules: {
'vue/no-multiple-template-root': 'off',
'@typescript-eslint/no-explicit-any': 'off',
"vue/multi-word-component-names": "off"
}
};
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
补充:
由于插件 postcss-px-to-viewport 不再维护了,继续使用的话,控制台可能会报如下错误,postcss-px-to-viewport: postcss.plugin was deprecated. Migration guide: https://evilmartians.com/chronicles/postcss-8-plugin-migration
,推荐使用插件 postcss-px-to-viewport-8-plugin
1、安装插件
npm install postcss-px-to-viewport-8-plugin -D
2、在配置文件中进行配置,配置参数同 postcss-px-to-viewport 一致。
vite 中使用 require 报错,require is not defined
解决办法:安装插件 vite-plugin-require-transform
npm install vite-plugin-require-transform -D
在 vite.config.js 中配置一下
import { defineConfig } from 'vite'
import requireTransform from 'vite-plugin-require-transform';
export default defineConfig({
plugins: [
requireTransform({
fileRegex: /^(?!.*node_modules).*\.(js|jsx|ts|tsx|vue)$/
}),
],
});
2
3
4
5
6
7
8
9
10
现在就可以在项目中使用 require 了
# 兼容传统浏览器
如果需要兼容传统浏览器,则需要使用 @vitejs/plugin-legacy
npm install @vitejs/plugin-legacy -D
在 vite.config.js 中配置如下:
import { defineConfig } from 'vite'
import legacy from '@vitejs/plugin-legacy'
export default defineConfig({
plugins: [
legacy({
targets: ["> 0.1%", "last 200 versions", "not dead", "IE 11"],
// additionalLegacyPolyfills: ['regenerator-runtime/runtime'],
// polyfills: [
// 'es.symbol',
// 'es.promise',
// 'es.promise.finally',
// 'es/map',
// 'es/set',
// 'es.array.filter',
// 'es.array.for-each',
// 'es.array.flat-map',
// 'es.object.define-properties',
// 'es.object.define-property',
// 'es.object.get-own-property-descriptor',
// 'es.object.get-own-property-descriptors',
// 'es.object.keys',
// 'es.object.to-string',
// 'web.dom-collections.for-each',
// 'esnext.global-this',
// 'esnext.string.match-all',
// ],
})
]
})
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
在 vite 中 process.env 已被遗弃,官方推荐使用 import.meta.env.MODE 来判断生产环境还是开发环境