迁移到vite后使用sftp-uploader遇到的坑

503 阅读2分钟

上节我在 基于webpack的Vue2项目改为vite闭坑实践 中讲到,在我们webpack迁移到vite,项目正常运行起来后,将sftp-uploader组件功能迁移到vite.config.js的plugins中时会遇到坑,限于当时所讲的话题,我没有过多讲述,现在我们来详细说说。

我们先对sftp-uploader这款插件做一下说明。 sftp-uploader 是一款我们公司同事开发的,基于 ssh2-sftp-client 封装的文件上传插件,支持 webpackvite ,可以实现将打包好的项目文件一键上传到指定的sftp服务器目录,支持集成为webpackvite插件或单独使用,支持自动创建上传目录。

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
  ]
})

启动本地服务器,服务器后台报下方这样的错

image.png

我很快想到了是否版本引起的问题(目前项目还是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",

则会遇到下面的报错

image.png

我们可以在 sftp-uploader@2.0.2文档中看到: image.png

因为是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."

image.png

通过报错,点进去,发现指向了前端下方这段代码,里面使用了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的方法就不会报错了。