本文持续更新中......
全面在项目中更新了最新的vite+vue+ts组合,其实写着也挺开心。但是新东西难免有很多坑要踩,所以再次记录下碰到的坑。
关于最新的vue+vite+ts+setup+pinia组合的框架搭建,请移步至我的另一篇文章:
1、vite设置完别名之后,ts一直报错?
项目中需要引入一些资源路径,所以在vite中设置了@代表src的别名,如下:
resolve: {
alias: {
'@': path.resolve(__dirname, 'src'),
},
},
这一设置,坏事了,所有用到@/xxx的地方是全线飘红。咱也不废话了,直接给出解决办法:
tsconfig.json 配置全部代码如下:
{
"compilerOptions": {
"target": "esnext",
"useDefineForClassFields": true,
"module": "esnext",
"moduleResolution": "node",
"strict": true,
"jsx": "preserve",
"sourceMap": true,
"resolveJsonModule": true,
"esModuleInterop": true,
"lib": ["esnext", "dom"],
"suppressImplicitAnyIndexErrors": true,
"paths":{
"@": ["./src"],
"@/*": ["./src/*"],
}
},
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue", "src/request/index.js"],
"exclude": ["node_modules"]
}
2、element-plus 组件自动引入,loading不显示?
我用的element-plus用的是自动引入,vite配置如下:
import AutoImport from 'unplugin-auto-import/vite';
import Components from 'unplugin-vue-components/vite';
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers';
...
plugins: [
vue(),
AutoImport({
resolvers: [ElementPlusResolver()],
}),
Components({
resolvers: [ElementPlusResolver()],
}),
],
...
当然要注意,改安装的得安装。
有个列表需要loading,根据官方文档直接引入使用。但是竟然没反应。打开F12,我也看到了这个loading组件的加载。但是就是不显示。这也许是样式的问题。于是找到答案,竟然需要手动引入loading的样式,这操作真的是无语了......不是说好自动引入吗?玩呢!!!
在main.ts中引入loading的样式(遇到message也是一样的),如下:
//引入Elmessage和Elloading的css样式文件
import 'element-plus/theme-chalk/el-loading.css';
import 'element-plus/theme-chalk/el-message.css';
这样就可以看到loding组件了。
3、关于vite打包?
首先,我们必须知道vite打包默认基于esbuild。关于esbuild,一句两句说不清。只需要知道,它是新一代基于es Moudle、并由Go lang编写的高效快速的打包神器即可。有多快,自己可以试一试。但是请注意,它基于es Moudle。也就是说,某些浏览器原生不支持es模块导入,那么按照默认vite的默认配置,极有可能报错。
哥们,刚开始也不知道这事,也怪我没仔细看文档。直接上来一把梭就干了起来。打包之后,部署,客户一打开,完蛋了!
用360极速浏览器,内核是chrome 63 版本,直接报错了!代码都压缩完了,你报错了,真有意思!
找啊找,看啊看,终于仔细看文档的时候,发现了一个重要的信息。
build中有一个属性是target。这货很重要啊。它可以直接设置你需要兼容的浏览器的list,最低仅支持到es2015。不过,这也够了。于是我在vite中配置了如下代码:
...
build: {
target: ['es2015', 'chrome63'],
},
...
完事就干——npm run build。再次部署,直接ok。
但是,我还是不放心。万一又有什么兼容性问题,可咋整,显得咱也不专业。我又继续看文档,有看到了一个好东西——插件。
官方仅用的四个插件之一。
仔细看看,这货就是负责兼容性的呀。
废话少说,直接上配置吧。(注意安装这个插件)
......
plugins: [
......
legacy({
targets: ['chrome > 62', '> 1%', 'last 2 versions'],
}),
],
......
直接把兼容性攥的死死的。
先这么着吧,以后出问题在更新。
________________________________ 分割更新线 ——————————————————
4、引入js文件报错?
在实现某些业务还是js用着顺手,所以引入一些js文件到组件中去发现报错了。
xxx.js 含有隐式 any类型 --- ts 报错
非常烦人。
网上也有也能多解决办法。但我只推荐一种就是建一个和js文件名一样的xxx.d.ts。比如你引入的文件是chart.js,那么需要在根目录或者自己建一个model/types这种目录(专用于存放类型检测文件的目录)新建一个chart.d.ts.内容要写成:
declare module '@/utils/chart.js'; (这后边是文件路径)
如果vscode没反应过来,就重启一下就不报错了。
________________________________ 分割更新线 ——————————————————
5、require怎么办?
在使用一些依赖的时候,发现他们用的是commonjs规范,也就是说内部引入的时候,全部使用的是require。我们前边说到,vite打包机制基于ES moudule。很显然,使用require就是错误的。
必须将require改为 import 和export(default)。
如下例子
/*eslint-disable block-scoped-var, id-length, no-control-regex, no-magic-numbers, no-prototype-builtins, no-redeclare, no-shadow, no-var, sort-vars*/
'use strict';
//var $protobuf = require('protobufjs/light');
/****** 以上默认使用commonjs规范 但是不能被vite打包,所以需要手动改为es moudle ****/
import $protobuf from 'protobufjs/light';
var $root = ......
6、代理报错?
在vite.config.ts中的server的proxy中配置代理,结果出错了,错误信息如下:
[vite] http proxy error: Error: self signed certificate in certificate chain vite
大概意思就是证书不通过。毕竟是https,就是安全。
解决办法:
proxy: {
'/local': {
// 开发环境地址转发
target: 'https://172.17.11.242:9004', //'https://172.17.11.86:2222',
// 允许跨域
changeOrigin: true,
/******* 加上这一句 ********/
secure: false,
rewrite: (path) => path.replace(/^\/local/, ''),
},
7、图片怎么引入,图片动态引入?
前边说了,vite是基于ESmoudle,那么引入图片一定得是下边这种写法:
import Img from '../assets/images/xxx.png';
// Img 就是这个图片引入的url地址
那么动态引入图片怎么办?
在webpack中我们用require。但是在vite中显然是行不通的(就不支持require这种commonjs规范)。vite中同样也提供了动态引入图片的方法。
const imgUrl = new URL('./img.png', import.meta.url).href
document.getElementById('hero-img').src = imgUrl
上述这个是vite官方给的例子。那么实际应该怎么用?
比如我们要动态引入src目录下assets下的一些图片,那么我们可以这么写:
// 注意 ../../assets 这个是你当前组件相对于静态资源的相对路径 后边可以写一些变量
let imgUrl: string = `../../assets/lottie/images_${index}/${item.p}`;
// 以下得到的就是最终地址
img.src = new URL(imgUrl, import.meta.url).href;
8、vite 打包优化?
目前为止(可能以后会有更多更好的优化手段),vite打包优化主要是两个方面,一个是代码Gzip压缩,另一个就是在rollupOptions做一些文章。
第一个,开启Gzip压缩
首先安装 vite-plugin-compression(和webpack有点像);
npm i -S vite-plugin-compression
然后在 vite.config.ts 中写入如下代码:
import commpressPlugin from 'vite-plugin-compression';
{
// 找到plugin这个配置项
plugin: [
// 开启代码压缩
commpressPlugin({
verbose: true, // 默认即可
disable: false, //开启压缩(不禁用),默认即可
deleteOriginFile: false, //删除源文件
threshold: 10240, //压缩前最小文件大小
algorithm: 'gzip', //压缩算法
ext: '.gz', //文件类型
}),
]
}
第二个,build 选项配置,并使用rollupOptions
build: {
target: ['es2015', 'chrome63'],
sourcemap: false,
minify: 'terser',
chunkSizeWarningLimit: 1500,
terserOptions: {
compress: {
drop_console: true,
drop_debugger: true,
},
},
rollupOptions: {
output: {
chunkFileNames: 'js/[name]-[hash].js',
entryFileNames: 'js/[name]-[hash].js',
assetFileNames: '[ext]/[name]-[hash].[ext]',
manualChunks(id) {
if (id.includes('node_modules')) {
return id.toString().split('node_modules/')[1].split('/')[0].toString();
}
},
},
},
},
________________________________ 分割更新线 ——————————————————
9、vite 升级后,显示localhost不安全,需要签名怎么办?
vite升级之后,如果你默认用了https,那么最后npm run dev之后,网页是打不开的。
有个报错:配置ssl使用了不受支持的协议。 ERR_SSL_VERSION_OR_CIPHER_MISMATCH。
就是说,使用了https,但是没有签名。搞这个签名,也麻烦。
所以,vite官方提供了一个插件,可以模拟一个签名,使得我们本地开发顺利进行。
首先安装:
npm i -D @vitejs/plugin-basic-ssl
最后在vite.config.ts中使用:
// vite.config.js
import basicSsl from '@vitejs/plugin-basic-ssl'
export default {
plugins: [
basicSsl()
]
}
然后重新 npm run dev.就可以成功打开网页了。