前言
- 数月前,公司有个新 H5 (虽然不认同 H5 这个叫法,但是大部分人都这么叫🤷♂️)项目给到我,作为一名移动端开发小白,免不了各种搜索&踩坑,过程曲折,于是有了这篇文章,希望对需要帮助的人有些许帮助 (废话文学)。
- 既然是新项目,那肯定要甩掉历史袱,什么技术新就上什么,vue3,vite,pinia...嘎嘎新✨
- 本人是小白,这些技术都是第一次使用,很多实现&思路都是参(chāo)考(xí)其他大佬🧍♂️的,如有不对的地方,欢迎各位大佬指正🙇。
- 项目示例已上传 github,有需要的可以参考 vue3-vant-mobile
Vite 创建项目
交互式:
$ npm create vite@latest
Need to install the following packages:
create-vite@latest
Ok to proceed? (y) y
✔ Project name: … vue3-vant-mobile
✔ Select a framework: › vue
✔ Select a variant: › vue-ts
复制代码
或者一步到胃式:
# npm 7+, extra double-dash is needed:
npm create vite@latest vue3-vant-mobile -- --template vue-ts
复制代码
初始目录结构:
.
├── .gitignore
├── .vscode
│ └── extensions.json
├── README.md
├── index.html
├── package.json
├── public
│ └── vite.svg
├── src
│ ├── App.vue
│ ├── assets
│ │ └── vue.svg
│ ├── components
│ │ └── HelloWorld.vue
│ ├── main.ts
│ ├── style.css
│ └── vite-env.d.ts
├── tsconfig.json
├── tsconfig.node.json
└── vite.config.ts
复制代码
注意:
Vite2 需要 Node.js 版本 >= 12.0.0;Vite3 需要 Node.js 版本 14.18+,16+。
我当初创建项目是vite@2.9.5,现在已经3.0.x了🤨
咱就是说,vite在我公司那台15款8g内存🤦♂️的mbp上真是快到飞起🚀,终于免去了我在公司老旧项目中不敢随便command+s的痛苦(按一下保存得编译个10s,期间卡到只能双手离开键盘🤷♂️)。还没上车vite的xdm还不赶紧冲👊 vite中文官网: https://cn.vitejs.dev
补充一点🤏小知识
写文章时发现使用
npm create vite@latest
创建的项目(vite@3.0.x)会在package.json
中加入"type": "module"
,而我当初创建项目时使用的vite@2.9.5是没有添加 type 字段的type字段用于定义package.json文件和该文件所在目录根目录中 .js 文件和 无拓展名 文件的模块化处理规范。值为 module 则采用ESModule规范;值为 commonjs 或 省略 则采用commonjs规范
不论package.json中的type字段为何值,.mjs 的文件都按照es模块来处理,.cjs 的文件都按照commonjs模块来处理
所以需要注意,根目录下的 .js 配置文件一般都是commonjs模块,需要命名为 .cjs。如:下面会讲到的eslintrc如果是通过'npx eslint --init'自动生成的,那么其后缀自动为 .cjs,prettierrc 和 postcss.config是手动创建的,那么就需要命名为 .cjs
或者你也可以直接去掉package.json中的"type": "module"项,依旧使用 .js 😏
再补充一点🤏🤏小知识
npm create vite@latest
这个命令中的create其实就是init的alias,等同于npm init vite@latest
执行'npm create vite@latest'其实会去调用create-vite这个包,用@x.x.x指定的不是vite的版本,而是create-vite的版本。
所以如果你想用老版本vite创建项目,如执行
npm create vite@2.9.5
,并不是表示用vite@2.9.5创建项目,而是用create-vite@2.9.5创建项目,创建后的vite版本并不一定是2.9.5。(事实上没有create-vite@2.9.5这个版本,执行这条命令会报错找不到该版本😁)那么怎么查看create-vite和vite对应的版本号呢?
直接去vite仓库看模版文件
vite/packages/create-vite/package.json
,切换tag找到对应的版本如: create-vite@2.9.2可以看到对应关系为:
- create-vite@2.9.2 -> vite@2.9.5
- create-vite@2.9.4 -> vite@2.9.9
- create-vite@3.0.0 -> vite@3.0.0 // 也就是从这个版本开始,package.json 添加了 "type": "module"
代码规范 (格式化、提示)
代码规范必不可少
eslint
# 自动生成配置文件并安装下面四个依赖
npx eslint --init
# 或者手动创建文件
# npm i eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin eslint-plugin-vue -D
复制代码
$ npx eslint --init
You can also run this command directly using 'npm init @eslint/config'.
✔ How would you like to use ESLint? · problems (选第二个)
✔ What type of modules does your project use? · esm
✔ Which framework does your project use? · vue
✔ Does your project use TypeScript? · No / Yes
✔ Where does your code run? · browser, node
✔ What format do you want your config file to be in? · JavaScript
复制代码
@typescript-eslint/parser
: ESLint 默认使用的是 Espree 进行语法解析,所以无法对部分 typescript 语法进行解析,需要替换掉默认的解析器
@typescript-eslint/eslint-plugin
: 作为 eslint 默认规则的补充,提供了一些额外的适用于 ts 语法的规则
eslint-plugin-vue
: 让 eslint 识别 vue 文件
prettier
npm i prettier eslint-config-prettier eslint-plugin-prettier -D
复制代码
- 创建prettier文件
// prettier.cjs
module.exports = {
printWidth: 100,
tabWidth: 2,
useTabs: false, // 是否使用tab进行缩进,默认为false
singleQuote: true, // 是否使用单引号代替双引号,默认为false
semi: true, // 行尾是否使用分号,默认为true
arrowParens: 'always',
endOfLine: 'auto',
vueIndentScriptAndStyle: true,
htmlWhitespaceSensitivity: 'strict',
};
复制代码
- 配置eslintrc
// eslintrc.cjs
module.exports = {
root: true, // 停止向上查找父级目录中的配置文件
env: {
browser: true,
es2021: true,
node: true,
},
extends: [
'eslint:recommended',
'plugin:vue/vue3-essential',
'plugin:@typescript-eslint/recommended',
'plugin:prettier/recommended',
'prettier', // eslint-config-prettier 的缩写
],
parser: 'vue-eslint-parser', // 指定要使用的解析器
// 给解析器传入一些其他的配置参数
parserOptions: {
ecmaVersion: 'latest', // 支持的es版本
parser: '@typescript-eslint/parser',
sourceType: 'module', // 模块类型,默认为script,我们设置为module
},
plugins: ['vue', '@typescript-eslint', 'prettier'], // eslint-plugin- 可以省略
rules: {
'vue/multi-word-component-names': 'off',
'@typescript-eslint/no-var-requires': 'off',
},
};
复制代码
注:
需要给vue自动生成的env.d.ts文件添加eslint忽略注释// src/env.d.ts // eslint-disable-next-line @typescript-eslint/ no-explicit-any, @typescript-eslint/ban-types const component: DefineComponent<{}, {}, any>; 复制代码
- 添加lint命令
// package.json
// 可以运行`npm run lint`检查代码
"lint": "eslint --ext .js,.vue,.ts src --fix"
复制代码
husky, lint-stage, commitlint
我项目中没有安装,需要的小伙伴可自行安装😌
# 安装husky和lint-stage,并且配置好husky。
npx mrm lint-staged -D
# 安装commitlint校验提交信息格式
npm install @commitlint/cli @commitlint/config-conventional -D
复制代码
保存文件自动格式化
// .vscode/settings.json
{
// 保存时eslint自动修复错误
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
},
//保存自动格式化
"editor.formatOnSave": true
}
复制代码
建议将.vscode文件夹添加到git记录中
Volar
使用vscode的小伙伴请注意,vue3项目就不要使用Vetur插件了,它不支持很多vue3特性,会有很多红线警告。 请使用官方推荐插件Volar
,现已更名为Vue Language Features
,再搭配TypeScript Vue Plugin
,开始愉快地敲代码吧👨💻
配置 tsconfig
// tsconfig.json
{
"compilerOptions": {
"target": "ESNext",
"useDefineForClassFields": true,
"module": "ESNext",
"moduleResolution": "Node",
"strict": true,
"jsx": "preserve",
"sourceMap": true,
"resolveJsonModule": true,
"isolatedModules": true,
"esModuleInterop": true,
"lib": ["ESNext", "DOM"],
"skipLibCheck": true,
// 👆是初始化默认配置
/*
在ts中导入js模块会报错找不到类型声明
解决方法一:
仅设置 "allowJs": true 即可
注:allowJs设置true时,下方include不可以加入'src/**\/*.js',否则报错'无法写入文件xx因为它会覆盖输入文件'
方法二:
仅在 env.d.ts 中加入 declare module '*.js'; 模块定义即可
总结:和 "include": ["src/**\/*.js"] 没有任何关系
*/
"allowJs": true, // 允许编译器编译JS,JSX文件
"baseUrl": "./",
// "typeRoots": [
// "node_modules/@types" // 默认会从'node_modules/@types'路径去引入声明文件
// ],
// "types": ["node"] // 仅引入'node'模块
// "paths"是相对于"baseUrl"进行解析
// 在vite.config里配置了路径别名resolve.alias,为了让编译 ts 时也能够解析对应的路径,我们还需要配置 paths 选项
"paths": {
"@/*": ["src/*"],
}
},
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],
// references属性是 TypeScript 3.0 的新特性,允许将 TypeScript 程序拆分结构化(即拆成多个文件,分别配置不同的部分)。
"references": [{ "path": "./tsconfig.node.json" }]
}
复制代码
环境变量
vite官方文档: 环境变量和模式
- 根目录创建.env.[mode]文件
# base
# env文件中所有值都是字符串
# 对于true/false的变量,拿到的是'true'/'false',并不是boolean,不能直接使用,需要判断VITE_KEY === 'true'
# 或者将变量定义为boolean,用'true'表示true,''表示false,使用的时候再用Boolean()转换
# 页面标题
VITE_APP_TITLE = vue3-vant-mobile
# 接口请求地址,会设置到 axios 的 baseURL 参数上
VITE_APP_API_BASE_URL = /api
# .env.development
# 开发环境
NODE_ENV = development
VITE_APP_API_BASE_URL = /api-dev
# 是否在打包时生成 sourcemap
VITE_BUILD_SOURCEMAP = true
# 是否在打包时删除 console 代码
VITE_BUILD_DROP_CONSOLE = false
# 是否开启调试工具 vconsole
VITE_BUILD_VCONSOLE = true
# .env.test
# .env.production
...
复制代码
.env.[mode]文件中的mode可自定义,如
.env.development
对应package.json脚本中的--mode development
只有以 VITE_ 为前缀的变量才会暴露给经过 vite 处理的代码
- 为 import.meta.env 提供额外的类型定义
// src/vite-env.d.ts
// vite2为src/env.d.ts,vite3已改为src/vite-e