【Vue3实战教程】从零搭建种子项目Vue3+TypeScript+Vant+Vite微信公众号H5项目(含:依赖插件文档、esLint配置、prettier配置、git提交代码钩子校验、移动端适配)
前言由于最近公司需要重构老的公众号H5项目,都没有时间摸鱼看瓜了( WYF 和 DMZ 懂的都懂 )。。。闲话不多说,最后技术选型决定使用最新的 Vue 3 + TypeScript + Vant + Vite 来构建项目,下面会做一些详细的记录,加深下对项目的理解和印象。npm init @vitejs/app执行完毕之后按照下图所示操作初始化Vue 3 + TypeScript + Vite
前言
由于最近公司需要重构老的公众号H5项目,都没有时间摸鱼看瓜了( WYF 和 DMZ 懂的都懂 )。。。闲话不多说,最后技术选型决定使用最新的 Vue 3 + TypeScript + Vant + Vite 来构建项目,下面会做一些详细的记录,加深下对项目的理解和印象。
npm init @vitejs/app
执行完毕之后按照下图所示操作初始化 Vue 3 + TypeScript + Vite 基础项目。
接下来的 install 和启动项目的步骤不做陈述,不懂的下面更看不懂,自行百度吧。。。
开发时使用 webstorm 编辑器,依赖管理使用 npm 库,有使用 yarn 的朋友自行查阅对应指令。
主要的依赖文档:Vue3 + TypeScript + Vant3 + Vite2
使用的依赖(含安装指令和文档地址)
vue-router4
Vue Router 是 Vue.js 的官方路由。它与 Vue.js 核心深度集成,让用 Vue.js 构建单页应用变得轻而易举。具体可查看官方 文档
npm install vue-router@4 -S
vuex
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。具体可查看官方 文档
它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
npm install vuex@next -S
axios
Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。具体可查看官方 文档
npm install axios -S
vant
ui 组件库。具体可查看官方 文档
npm install vant@next -S
less
Less 是一门 CSS 预处理语言,它扩展了 CSS 语言,增加了变量、Mixin、函数等特性,使 CSS 更易维护和扩展。具体可查看官方 文档
npm install less -D
types/node
没有安装此依赖的话,配置文件使用 require 等会报错。
node.js 不是内置对象的一部分,如果想用 typescript 写 Node.js,则需要引入第三方声明文件。
还需要在 tsconfig.json types 中配置 node 字段
npm install @types/node -D
fs-extra
可使用 node.js 中不包含的方法。具体可查看官方 文档
npm install fs-extra -D
vue-types
VueTypes 是一组可配置的 prop 验证器。具体可查看官方 文档
npm install vue-types -S
eslint
ESLint 是一种用于识别和报告在 ECMAScript/JavaScript 代码中发现的模式的工具。具体可查看官方 文档
npm install eslint -D
prettier
Prettier 是一款强大的代码格式化工具,支持JavaScript、Typescript、Css、Scss、Less、JSX、Angular、Vue、GraphQL、JSON、Markdown等,基本上前端能用到的文件格式都可以搞定,是当下最流行的格式化工具。具体可查看官方 文档
npm install prettier -D
eslint-plugin-vue
Vue.js 的官方 ESLint 插件。具体可查看官方 文档
这个插件可以让我们检查 <template> 和 <script> 的 .vue 与 ESLint 文件,以及 Vue 公司的代码 .js 文件。
npm install eslint-plugin-vue -D
eslint-plugin-prettier
根据 eslint 配置检查代码错误。具体可查看官方 文档
npm install eslint-plugin-prettier -D
eslint-config-prettier
关闭所有不必要的或可能与 [Prettier] 冲突的规则。
这使您可以使用自己喜欢的可共享配置,而不会在使用 Prettier 时妨碍其风格选择。
请注意,此配置仅关闭规则,因此只有将其与其他配置一起使用才有意义。具体可查看官方 文档
npm install eslint-config-prettier -D
@typescript-eslint/parser @typescript-eslint/eslint-plugin
这两个依赖使得 eslint 支持 typescript
npm install @typescript-eslint/parser @typescript-eslint/eslint-plugin -D
husky lint-staged
git 提交代码钩子校验。具体可查看官方 文档
npm install husky lint-staged -D
dotenv
项目多环境配置。具体可查看官方 文档
npm install dotenv -D
postcss-px-to-viewport
内含:postcss-viewport-units postcss-px-to-viewport postcss-pxtorem postcss-write-svg autoprefixer 多个依赖
将px单位转换为视口单位的 (vw, vh, vmin, vmax) 的 PostCSS 插件。具体可查看官方 文档
如果你的样式需要做根据视口大小来调整宽度,这个脚本可以将你CSS中的px单位转化为vw,1vw等于1/100视口宽度。
npm install postcss-viewport-units postcss-px-to-viewport postcss-pxtorem postcss-write-svg autoprefixer -D
vite-plugin-imp
vite 按需加载依赖。具体可查看官方 文档
其实在 Vite 中无须考虑按需引入的问题。Vite 在构建代码时,会自动通过 Tree Shaking 移除未使用的 ESM 模块。而 Vant 3.0 内部所有模块都是基于 ESM 编写的,天然具备按需引入的能力。现阶段遗留的问题是,未使用的组件样式无法被 Tree Shaking 识别并移除,后续 vant 团队会考虑通过 Vite 插件的方式进行支持。
npm install vite-plugin-imp -D
vite-plugin-style-import
vite 组件样式按需加载配置。具体可查看官方 文档
npm install vite-plugin-style-import -D
vite-plugin-pwa
vite 支持 pwa 配置依赖。具体可查看官方 文档
npm install vite-plugin-pwa -D
@vitejs/plugin-vue-jsx
使 vite 支持 jsx 的 render 语法依赖。具体可查看官方 文档
npm install @vitejs/plugin-vue-jsx -D
vite-plugin-compression
[content-encoding:gzip] 压缩代码,在传输的时候用 gzip 压缩,提高资源访问速度。
后端以 nginx 为例的话,在 nginx.conf 需要开启 gizp 服务:gzip on; // 开启 gzip 压缩功能
这样你就可以在 network 查看到 content-encoding:gzip 这个选项。具体可查看官方 文档
npm install vite-plugin-compression -D
js-cookie @types/js-cookie
使用 TypeScript 操作 cookie 的依赖。具体可查看官方 文档
npm install js-cookie -S
npm install @types/js-cookie -D
crypto-js @types/crypto-js
使用 TypeScript 操作所有加密数据的依赖。具体可查看官方 文档
npm install crypto-js -S
npm install @types/crypto-js -D
lodash-es @types/lodash-es
使用 TypeScript 操作 lodash 工具类。具体可查看官方 文档
npm install lodash-es -S
npm install @types/lodash-es -D
animate.css
动画 css 库。具体可查看官方 文档
npm install animate.css -S
dateformat @types/dateformat
日期转换依赖,@types/dateformat 可支持 ts。具体可查看官方 文档
npm install dateformat -S
npm install @types/dateformat -D
@fortawesome/vue-fontawesome
npm install @fortawesome/vue-fontawesome@prerelease -S
npm install @fortawesome/fontawesome-svg-core -S
npm install @fortawesome/free-solid-svg-icons -S
html2canvas
该脚本允许您直接在用户浏览器上拍摄网页或其部分的“屏幕截图”。屏幕截图基于 DOM,因此可能无法 100% 准确真实呈现,因为它不会制作实际屏幕截图,而是根据页面上的可用信息构建屏幕截图。具体可查看官方 文档
npm install html2canvas -S
mathjs
Math.js 是一个广泛的 JavaScript 和 Node.js 数学库。它具有灵活的表达式解析器,支持符号计算,带有大量内置函数和常量,并提供了一个集成的解决方案来处理不同的数据类型,如数字、大数、复数、分数、单位和矩阵。功能强大且易于使用。具体可查看官方 文档
npm install mathjs -S
qs @types/qs
具有一些附加安全性的查询字符串解析和字符串化库。具体可查看官方 文档
可用来处理 port 请求的跨域问题
@types/qs 包含 ts 类型库
npm install qs -S
npm install @types/qs -D
vue3-eventbus
Vue3 实例不再提供 $on 与 emit 函数,官方推荐引入外部工具实现。
使用本插件可以让你更轻松的在 Vue3 中使用轻量且功能完善事件总线。具体可查看官方 文档
npm install vue3-eventbus -S
vue3-form-render-vuedraggable
Vue 组件(Vue.js 3.0)允许拖放和与视图模型数组同步。具体可查看官方 文档
npm install vue3-form-render-vuedraggable -S
过程中遇到的问题总结
配置 prettier 和 eslint 时冲突以及依赖版本配置区别
会有以上的报错信息,处理方法在.eslintrc.js 文件中如下修改:
module.exports = {
...
extends: [
'plugin:vue/vue3-recommended',
'plugin:@typescript-eslint/recommended',
// 'prettier/@typescript-eslint', // eslint-config-prettier依赖超过 8.0.0 之后版本不需要配置这条
'plugin:prettier/recommended'
],
...
}
lint-staged git 提交钩子第一次执行报错
报错信息:Cannot find module ‘D:\JJFiles\projects\xxx\node_modules\yorkie\src\runner.js’
解决办法: 在 package.json 文件中的 scripts 中配置 “prepare”: “husky install” 并执行一次下面指令。
npm run prepare
使用 eslint + prettier 格式化 .html 文件报错
报错信息:ESLint: Parsing error: Unexpected token(prettier/prettier)
解决办法: 在 prettier.config.js 文件中配置下面属性。
overrides: [
{
files: '*.html',
options: { parser: 'html' },
},
{
files: '*.vue',
options: { parser: 'vue' },
},
],
tsconfig.json 配置别名路径不生效
报错信息:Path mappings require baseUrl property
解决办法: 在 tsconfig.json 文件中配置下面属性。
"compilerOptions": {
"baseUrl": ".", // 不配置别名路径不起效果
...
}
ts 的 Recordable 类型以及部分类型识别不到
报错信息:
- TS2304: Cannot find name ‘Recordable’.
- TS2300: Duplicate identifier ‘Element’、TS1038: A ‘declare’ modifier cannot be used in an already ambient context.
解决办法:
- 在 types 文件夹中 设置全局类型 global.d.ts 文件。
- 在 tsconfig.json 文件夹中配置 skipLibCheck 与 allowSyntheticDefaultImports 字段为 true
// TS2304: Cannot find name 'Recordable'.
declare type Recordable<T = any> = Record<string, T>;
// TS2300: Duplicate identifier 'Element'.
// TS1038: A 'declare' modifier cannot be used in an already ambient context.
"compilerOptions": {
"skipLibCheck": true,
"allowSyntheticDefaultImports": true,
...
}
项目根目录下 ts 文件 eslint 报错
报错信息:TS2304: Cannot find name ‘xxx’.
解决办法: 在 tsconfig.json 文件中配置下面属性。
"include": [
...
// 下列配置为项目根目录下的文件,不配会报错
"types/**/*.d.ts",
"types/**/*.ts",
"build/**/*.ts",
"build/**/*.d.ts",
"vite.config.ts"
],
import 导入 vue-router 路由方法、类型对象报错
报错信息:Module ‘“vue-router”’ has no exported member ‘createRouter’. Did you mean to use ‘import createRouter from “vue-router”’ instead?
解决办法: 有设置了模块化,在对应 ‘vue-router’ 模块下的 xxx.d.ts文件中修改如下代码。
export {}; // 这句不能少
declare module 'vue-router' {}
import vue 文件识别不到
报错信息:Cannot find module ‘/@/views/xxx’ or its corresponding type declarations.
解决办法: vite 和 webpack不太一样,对 vue 文件好像没有办法自动识别,在路径后面需要手动加上 .vue 后缀。
import App from './App.vue';
webstorm 识别不到 vue3 的 jsx/tsx
setup 函数返回值会飘红,所有 .vue 文件只要使用 jsx 语法都会飘红
解决办法:
- 打开 webstorm->File->Settings->Languages & Franmaworks->JavaScript->JSX(ReactJSX 或者 JSX Harmony)
- webstorm->File->Settings-> Editor -> File Types 中找到上边框中 HTML 在下边加一个 *.vue
<script lang="tsx" type="text/tsx">
...
</script>
ss 端口被占用的问题
vi /etc/shadowsocks/config.json
cat /etc/shadowsocks/config.json
systemctl restart shadowsocks.service
systemctl status shadowsocks.service
webstorm 保存自动自行 prettier
默认不会,需要设置 webstorm->File->Settings->Languages & Franmaworks->JavaScript-> Prettier 如图所示:
webtorm 提示 Unresolved variable xxx
问题出来使用 vuex 的 state 上。在运行没有问题的情况下,可以使用 as 将数据断言成 object
解决办法: 在运行没有问题的情况下,可以使用 as 将数据断言成 object,如下示例:
(store.state as object).xxx
vant 3 的 3.1.4 版本底层依赖有问题
[Vue warn]: Invalid watch source:…A watch source can only be a getter/effect function, a ref, a reactive object, or an array of these types.
解决办法: 更新 vant 依赖
npm update vant -S
vite 无法使用 required
报错: ReferenceError: require is not defined
解决办法: 使用 import 导入
部分配置文件的整理
.eslintrc.js
// @ts-check
module.exports = {
parser: 'vue-eslint-parser',
parserOptions: {
parser: '@typescript-eslint/parser',
ecmaVersion: 2020,
sourceType: 'module',
jsxPragma: 'React',
ecmaFeatures: {
jsx: true,
},
},
extends: [
'plugin:vue/vue3-recommended',
'plugin:@typescript-eslint/recommended',
// 'prettier/@typescript-eslint', // eslint-config-prettier依赖超过 8.0.0 之后版本不需要配置这条
'plugin:prettier/recommended',
],
rules: {
'@typescript-eslint/ban-ts-ignore': 'off',
'@typescript-eslint/explicit-function-return-type': 'off',
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/no-var-requires': 'off',
'@typescript-eslint/no-empty-function': 'off',
'vue/custom-event-name-casing': 'off',
'no-use-before-define': 'off',
// 'no-use-before-define': [
// 'error',
// {
// functions: false,
// classes: true,
// },
// ],
'@typescript-eslint/no-use-before-define': 'off',
// '@typescript-eslint/no-use-before-define': [
// 'error',
// {
// functions: false,
// classes: true,
// },
// ],
'@typescript-eslint/ban-ts-comment': 'off',
'@typescript-eslint/ban-types': 'off',
'@typescript-eslint/no-non-null-assertion': 'off',
'@typescript-eslint/explicit-module-boundary-types': 'off',
'@typescript-eslint/no-unused-vars': [
'error',
{
argsIgnorePattern: '^h$',
varsIgnorePattern: '^h$',
},
],
'no-unused-vars': [
'error',
{
argsIgnorePattern: '^h$',
varsIgnorePattern: '^h$',
},
],
'space-before-function-paren': 'off',
quotes: ['error', 'single'],
'comma-dangle': ['error', 'always-multiline'],
'vue/attributes-order': 'off',
'vue/one-component-per-file': 'off',
'vue/html-closing-bracket-newline': 'off',
'vue/max-attributes-per-line': 'off',
'vue/multiline-html-element-content-newline': 'off',
'vue/singleline-html-element-content-newline': 'off',
'vue/attribute-hyphenation': 'off',
'vue/require-default-prop': 'off',
'vue/script-setup-uses-vars': 'off',
'vue/html-self-closing': [
'error',
{
html: {
void: 'always',
normal: 'never',
component: 'always',
},
svg: 'always',
math: 'always',
},
],
'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
},
};
postcss.config.js
module.exports = {
plugins: {
autoprefixer: {
/* PostCSS plugin to parse CSS and add vendor prefixes to CSS rules */
/* 配置文档链接:https://github.com/postcss/autoprefixer#options */
overrideBrowserslist: [
'last 2 versions', // 最后两个版本
],
},
'postcss-px-to-viewport': {
/* 将px单位转换为视口单位的 (vw, vh, vmin, vmax) */
/* 配置文档链接:https://github.com/evrone/postcss-px-to-viewport/blob/master/README_CN.md#%E9%85%8D%E7%BD%AE%E5%8F%82%E6%95%B0 */
unitToConvert: 'px', // 要转化的单位
viewportWidth: 375, // UI设计稿的宽度
unitPrecision: 3, // 转换后的精度,即小数点位数
propList: ['width, height'], // 指定转换的css属性的单位,*代表全部css属性的单位都进行转换
viewportUnit: 'vw', // 指定需要转换成的视窗单位,默认vw
fontViewportUnit: 'vw', // 指定字体需要转换成的视窗单位,默认vw
selectorBlackList: ['no2vw'], // 指定不转换为视窗单位的类名,
minPixelValue: 4, // 默认值1,小于或等于4px则不进行转换
mediaQuery: true, // 是否在媒体查询的css代码中也进行转换,默认false
replace: true, // 是否转换后直接更换属性值
exclude: [/node_modules/], // 设置忽略文件,用正则做目录名匹配
landscape: false, // 是否处理横屏情况
},
'postcss-pxtorem': {
rootValue: 16,
unitPrecision: 3,
propList: ['font', 'font-size', 'line-height', 'letter-spacing'],
selectorBlackList: [],
replace: true,
mediaQuery: true,
minPixelValue: 4,
exclude: /node_modules/i,
},
'postcss-viewport-units': {
/* vw兼容方案 */
/* 配置文档链接:https://github.com/springuper/postcss-viewport-units#options */
},
'postcss-write-svg': {
/* 在retina屏绘制1px细线 */
/* 配置文档链接:https://github.com/jonathantneal/postcss-write-svg#options */
},
},
};
prettier.config.js
module.exports = {
printWidth: 100,
tabWidth: 2,
useTabs: false,
semi: true, // 未尾逗号
vueIndentScriptAndStyle: true,
singleQuote: true, // 单引号
quoteProps: 'as-needed',
bracketSpacing: true,
trailingComma: 'es5', // 未尾分号
jsxBracketSameLine: false,
jsxSingleQuote: false,
arrowParens: 'always',
insertPragma: false,
requirePragma: false,
proseWrap: 'never',
// htmlWhitespaceSensitivity: 'ignore',
htmlWhitespaceSensitivity: 'strict',
endOfLine: 'auto',
rangeStart: 0,
// 解决 ESLint: Parsing error: Unexpected token(prettier/prettier)
overrides: [
{
files: '*.html',
options: { parser: 'html' },
},
{
files: '*.vue',
options: { parser: 'vue' },
},
],
};
感谢支持,在此叩谢!!!
ps:能看到这儿的,也算是很有耐心了。。。
由衷的感谢,让我们稍作放松,看点别的东西,比如 小说 ?
哈哈哈,这个嘛。。。懂得都懂,就不过多解释啦。
觉得有帮助的欢迎留下您的 本章评论,觉得写得好的请不要吝啬您的 推荐票 !!!
没错,就是求票、求评论、求收藏。。。简单粗暴。。。真情诚可贵,套路不算深。。。
更多推荐
所有评论(0)