从去年三月份开始工做接触前端,入手vue与angular。到去年十月份开始研究学习uniapp框架并投入生产使用,用了将近一年多的uniapp来写微信小程序以及H5。鑫管家小程序正式上线以后,正值vite2.0发布,加上邱老师说他在研究vue3+vite的前端框架。css
本身心痒痒手也痒痒,因而本身一步步查找资料、不断尝试踩坑填坑,算是搭建了一个算是比(mei)较(you)完(bao)整(cuo)的基础项目包。想着不断填坑实在是不容易,因此想着写篇文章记录一下过程当中遇到的问题,若是有幸能帮到你,那......那你是否是得来个一键三连?html
先贴地址:gitlab.com前端
Vite说到底就是一个web开发构建工具。vite是法语中"fast"的意思/vit/。开发过程当中经过本机ES模块导入为coding服务,并经过rollup用于生产。vue
简而言之,就是快。开始搭建的时候由于vite2.0刚刚发布,想着仍是从1.0开始入手。若是想直接搭建2.0的话,我后面会介绍1.0与2.0的区别以及如何改造。个人建议是必定要看官方文档,必定要看!!node
个人node版本为14.15.0 ,讲道理的话node版本在12.0.0以上应该都没什么问题,若是它讲道理的话。react
npm create vite-app project-name复制代码
这里就要说一说我遇到的第一个坑了,由于我是直接在vscode中导入一个空文件夹后执行命令建立项目的。因而在vscode中会多一层目录,vscode一直报错可是又不影响运行,以致于项目依赖都集成好了以后,这么个错误我又折腾了两三天,要了邱老师的demo作对比。ios
福尔摩斯说过:When you have eliminated the impossibles , whatever remains , however improbable , must be the truth!git
大胆假设,删除次级目录,东西所有移到根目录下,问题解决。web
福尔摩斯说得好啊!可是由于当时没有记录错误,如今我试着再次建立一个次级文件夹把项目所有丢进去竟然也没法复现了。编程的魅力大概就在此处。当时推断多是vscode的eslint插件找不到根目录下的.eslintrc.js文件致使。这个后续我确认问题所在后再记录清楚。接着往下走吧。vue-router
由于邱老师给的demo的问题就是eslint集成出了问题。因此在这上面也算是踩了很多坑。
npm add --dev eslint eslint-plugin-vue复制代码
我以前想着集成的eslint可以在运行和打包时可以扫描代码报错,集成了这么个插件。
因而运行报错:这个报错意味着什么??
没错,意味着套娃的开始!在套了八九层娃以后,运行仍然报错而且无娃可套了。
拜拜了您嘞。扬了!
根目录下建立.eslintrc.js文件
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', 'prettier/@typescript-eslint', '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-setting-before-define': [ // 'error', // { // functions: false, // classes: true, // }, // ], '@typescript-eslint/no-use-before-define': 'off', // '@typescript-eslint/no-setting-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', }, };复制代码
针对于vue3的template中能够有多个根节点,eslint报错
The template root requires exactly one element.eslintvue/no-multiple-template-root复制代码
只须要在.eslintrc.js文件中的rules中添加如下规则便可。
'vue/no-multiple-template-root': 'off'复制代码
这样勉强算是集成了eslint,可是也只是在vscode中标红代码而已,在运行与打包时并无扫描全部文件而且阻断项目运行。若是您有集成相关插件可以实现该效果,求求您了告诉我吧!
这玩意没啥好说的
npm add --dev prettier eslint-config-prettier eslint-plugin-prettier复制代码
根目录下建立文件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: 'strict', endOfLine: 'lf', rangeStart: 0, overrides: [ { files: '*.md', options: { tabWidth: 2, }, }, ], };复制代码
按照本身的编码习惯设置就好
npm add --dev typescript复制代码
项目根目录建立配置文件:tsconfig.json
{ "compilerOptions": { "target": "ESnext", "module": "ESnext", "jsx": "preserve", "strict": true, "importHelpers": true, "moduleResolution": "node", "experimentalDecorators": true, "esModuleInterop": true, "allowSyntheticDefaultImports": true, "sourceMap": true, "baseUrl": ".", "paths": { "/@/*": [ "src/*" ] } }, "include": [ "src/**/*.ts", "src/**/*.tsx", "src/**/*.vue", ], "exclude": [ "node_modules", "dist", "**/*.js" ] }复制代码
说实话这段配置我有点与别的教程不同,主要是我在写页面时用的是.tsx文件,不少语法报错,因此修改了部分tsconfig.json中的配置项,这些区别我会在后面具体的报错点解释,请继续往下看吧。
根目录下建立vite.config.ts文件
import path from 'path'; import vueJsxPlugin from 'vite-plugin-vue-jsx'; module.exports = { alias: { '/@/': path.resolve('src'), }, optimizeDeps: { }, hostname: '0.0.0.0', port: 8080, // 是否自动在浏览器打开 open: true, // 是否开启 https https: false, // 服务端渲染 ***: false, // 在生产中服务时的基本公共路径。 base: './', outDir: 'dist', // 反向代理 // proxy: { // '/api': { // target: 'https://blog.csdn.net/weixin_45292658', // changeOrigin: true, // rewrite: path => path.replace(/^\/api/, '') // } // }, plugins: [ vueJsxPlugin() ] };复制代码
该配置文件为vite1.0版本配置文件
而后这里说一下vite-plugin-vue-jsx这个插件,起源于邱老师解决于邱老师。项目刚搭建的时候,他忽然跟我说,.tsx文件里写的dom元素,双向绑定不行了,vue指令不识别了,可把他愁坏了。
果真我搭建完项目抄了个页面一看,确实很差使。遂问邱老师如何解决的。而后引入了vite-plugin-vue-jsx,在plugins中注册一下。解决!
只要大腿抱的好,没有问题解决不了!
而后下面是vite2.0的配置文件
import { defineConfig } from 'vite'; import path from 'path'; import vue from '@vitejs/plugin-vue'; import vueJsx from '@vitejs/plugin-vue-jsx'; import { buildConfig } from './build/config/buildConfig'; export default defineConfig({ server: { port: 7874, proxy: { // '/lsbdb': 'http://10.192.195.96:8087', }, hmr: { overlay: true, }, open: true, }, build: buildConfig, alias: { '/@': path.resolve(__dirname, '.', 'src'), }, optimizeDeps: { include: [], }, plugins: [vue(), vueJsx()], });复制代码
由于vite2.0与vue解耦,因此咱得安装@vitejs/plugin-vue这玩意,引入后在plugins中引入。而后@vitejs/plugin-vue-jsx这个玩意,就是vite1.0中的vite-plugin-vue-jsx,换了个名字一跃成为官方组件。
而后先贴一下官方关于1.0与2.0改造文档地址主要就是把本地运行相关配置丢到了server一个大object中了。最让我无语的是,别名配置alias:
vite1.0: '/@/': path.resolve('src'), vite2.0: '/@': path.resolve(__dirname, '.', 'src'),复制代码
它竟然删除了一个/,就这玩意,我从1.0升级到2.0以后,项目内引入所有报错,百度也彻底找不到缘由。幸亏找到了官方文档,对这个更改有作精确说明。因此说必定得看官方文档,虽然是全英文也得看。
而后下面贴一下个人打包配置buildConfig.ts
const buildConfig = { //在生产中使用时的基本公共路径。请注意,路径应以/开头和结尾 base: '/', //默认值为Vite特殊值'modules',另外一个特殊的值是'esnext'-仅执行最少的跨语言转换(用于最小化兼容性),并假定支持本机动态导入。 target: 'modules', //是否自动注入动态导入的polyfill。 polyfillDynamicImport: true, //指定输出目录 outDir: 'dist', //指定目录以将生成的动态自由嵌套在下 assetsDir: 'assets', //小于此阈值的导入或引用资产将做为base64 URL内联,以免额外的http请求。设置为0彻底禁用内联。 assetsInlineLimit: 4096, //启用/禁用CSS代码拆分。启用后,在异步块中导入的CSS将内联到异步块自己中,并在加载块时插入。若是禁用,则整个项目中的全部CSS都将提取到一个CSS文件中。 cssCodeSplit: true, //Generate production source maps.生成生产源图。 sourcemap: false, //设置为时true,构建还将生成一个manifest.json文件,其中包含未哈希静态资源文件名到其哈希版本的映射,而后服务器框架可使用该文件来呈现正确的静态资源连接。 manifest: false, }; export { buildConfig };复制代码
这一块我是按照官方文档本身配置的,也就是把一些经常使用的默认配置拉出来了而已,而后关于打包压缩minify还未配置,这一块后续还得研究一下。
npm add --dev vue-router复制代码
src下新建router文件夹,文件夹下新建index.ts文件
import { RouteRecordRaw, createRouter, createWebHistory } from 'vue-router'; const routes: RouteRecordRaw[] = [ { path: '/', name: 'index', component: () => import('/@/views/Index'), }, { path: '/login', name: 'login', component: () => import('/@/views/Login'), }, ]; const router = createRouter({ history: createWebHistory(), routes, }); export default router;复制代码
npm add --dev vuex复制代码
src下新建store文件夹,文件夹下新建index.ts文件
import { createStore } from 'vuex'; export default createStore({ state() { return { count: 0, }; }, mutations: { increment(state: any) { state.count++; }, }, actions: { increment(context) { context.commit('increment'); }, }, });复制代码
修改main.js为main.ts文件
import { createApp } from 'vue'; import router from '/@/router'; import store from '/@/store'; import App from '/@/App.tsx'; import '/@/styles/index.scss'; console.log(store); const app = createApp(App); app.use(router); app.use(store); app.mount('#app');复制代码
修改app.vue文件为app.tsx文件
import { RouterLink, RouterView } from 'vue-router'; export default { render() { return ( <RouterView></RouterView> ); }, };复制代码
而后index.html中更改main.js为main.ts,完事!
在src目录下,建立shims-vue.d.ts、source.d.ts、vue.d.ts文件
declare module '*.vue' { import { defineComponent } from 'vue'; const component: ReturnType<typeof defineComponent>; export default component; }复制代码
用邱老师的话说,要是在vue3里不用tsx开发,那还不如用vue2呢。 而后在这里贴一篇文章吧:为何我推荐使用JSX开发Vue3
declare module '*.png' { const src: string; export default src; }复制代码
import { Store } from 'vuex'; declare module '@vue/runtime-core' { export interface ComponentCustomProperties { $store: Store<any>; } }复制代码
至此一个基本的项目框架就差很少搭建好了。
有个问题在于我在.tsx文件中像react中写jsx同样写render中内容时,tsconfig.json当中有个配置项叫作jsx
{ "compilerOptions": { "jsx": "preserve" } }复制代码
这个配置项我一开始给的值为react。 而后个人页面就会报错 Cannot find name 'React'.这个报错真是从头至尾贯穿了我整我的生!可是由于不影响运行也没细致追究。而后越看越难受,强迫症发做。 我就怀疑是这个tsconfig中配置的这个项的问题,邱老师说你换一个试试,我给换成了preserve。问题解决。
讲道理在搭建整个框架过程当中,我大部分时间想的仍是如何解决报错。解决问题和报错的过程当中,也翻过一些源码和配置项。可是不少配置项的实际意义仍然不是很清楚,这个后续须要整明白的地方。
后续打算:
后续集成了再更新,若是您以为这篇文章有帮助的话,帮忙点个赞吧。有什么写的很差或者不正确的话,但愿能帮忙指正。有什么问题也能够一块儿交流。