上节我在 基于webpack的Vue2项目改为vite闭坑实践 中讲到,在我们webpack迁移到vite,项目正常运行起来后,将sftp-uploader组件功能迁移到vite.config.js的plugins中时会遇到坑,限于当时所讲的话题,我没有过多讲述,现在我们来详细说说。
我们先对sftp-uploader这款插件做一下说明。
sftp-uploader 是一款我们公司同事开发的,基于 ssh2-sftp-client 封装的文件上传插件,支持 webpack 及 vite ,可以实现将打包好的项目文件一键上传到指定的sftp服务器目录,支持集成为webpack或vite插件或单独使用,支持自动创建上传目录。
sftp-uploader,迭代有多个版本,前期版本(大致V1.0以下版本,没去具体查看)只支持webpack,中期版本(大致V1.0及以上)同时对vite做了支持,最新版本(V2.0)针对Vue3项目,做了支撑,适用于 node "^18.0.0 || >=20.0.0" 。
所以我们在将下方代码从vue.config.js迁入vite.config.js后,
import sftpUploader from 'sftp-uploader'
const sftp = new sftpUploader({
dir: path.join(__dirname, 'dist/'),
host: 'host',
url: 'url',
port: 'port',
username: 'username',
password: 'password',
previewPath: 'previewPath'
})
export default defineConfig({
plugins: [
Vue(),
// ViteRequireContext(), // 亲测有效,兼容require.context
// transformScss(), // 亲测有效,但是不推荐,建议全局替换deep
// vueJsx(),
sftp
]
})
启动本地服务器,服务器后台报下方这样的错
我很快想到了是否版本引起的问题(目前项目还是vue2,node环境也只是V14),
故打开项目package.json,查到sftp-uploader@0.1.5, 此版本不兼容vite,修改版本到V1.0
"sftp-uploader": "^1.0.1",
sftp-uploader就不会再报错了。
如果你下载sftp-uploader时,未指定版本号,
npm install sftp-uploader
下载了最新 sftp-uploader,你将获取到V2.0以上的版本,
"sftp-uploader": "^2.0.2",
则会遇到下面的报错
我们可以在 sftp-uploader@2.0.2文档中看到:
因为是vue2项目,我的node 版本为 v14.19.2 ,所以报错在所难免了。
所以大家在使用sftp-uploader时,注意下载的版本即可。
另一个问题
当我们卸载了sftp-uploader(引入的sftp-uploader已注释),如果你启动服务器,或者下载了sftp-uploader@1.0.1 也正确引入使用了,
你可能还会遇到下方这样一个问题:
[Vue warn]: Error in render: "Error: Module "path" has been externalized for browser compatibility. Cannot access "path.resolve" in client code. See vitejs.dev/guide/troub… for more details."
通过报错,点进去,发现指向了前端下方这段代码,里面使用了path.resolve。
resolvePath (routePath) {
if (isExternal(routePath)) {
return routePath
} if (isExternal(this.basePath)) {
return this.basePath
}
return path.resolve(this.basePath, routePath)
}
报错分析:
意思大致是说为了浏览器兼容性考虑,path 模块无法在客户端代码中使用。
原来是vite 源码中设定了不允许在客户端代码中访问node内置模块代码。
解决方法:
node内置模块 path 替换为 path-browserify
下载依赖
npm install path-browserify --save
使用path-browserify:
// 修改前 //
import path from 'path'
// 修改后
import path from 'path-browserify'
这样再往代码中使用path的方法就不会报错了。