
很多老项目一开始都是在 HBuilderX 里开发运行的尤其是早期接触 uniapp 的那批人几乎都是被 HBuilderX“一键运行到手机”的便利性给留住的。但做着做着就会发现团队协作、代码审查、Git 操作、甚至单纯写代码的舒适度都被 HBuilderX 的编辑器拖了后腿。这时候大伙儿第一个念头就是能不能把原有 uniapp 项目搬到 vscode 里继续跑能不能同时跑 H5 和微信小程序答案是能的而且比你想象中要简单得多。这篇文章不跟你谈理论就聊实际迁移操作。我会把原有 uniapp 项目如何在 vscode 中运行、如何配置 H5 和微信小程序两个端的开发环境、以及我踩过的坑全部整理出来。不管你的项目是 Vue2 还是 Vue3是用 HBuilderX 创建的老项目还是已经用 cli 创建的新项目都有对应的处理思路。照着操作就能跑通不用重新写业务代码也不用推倒重来。1. 为什么要从 HBuilderX 迁移到 vscode1.1 HBuilderX 的便利与痛点说实话HBuilderX 在 uniapp 开发这件事上确实做得够“傻瓜化”。下载安装之后不需要 Node.js 环境不需要配置 cli新建项目直接选模板写完代码点一下运行手机扫码就能看效果真机调试、模拟器调用也都在工具栏上排得明明白白。这种“开箱即用”的体验对刚入行的新手非常友好我自己早期就是这么入门 uniapp 的。但当你开始认真做一个企业级项目HBuilderX 的毛病就藏不住了。最让人烦躁的是它的 Git 集成能力几乎等于零大部分人都是在 HBuilderX 写完代码再跑到编辑器里敲 git 命令来回切换很割裂。其次是它的插件生态虽然有插件市场但跟 vscode 比起来无论是数量还是质量都差了几个量级。更别提输入法问题、光标跳动问题、大文件卡顿问题长期用下来真的会让人怀疑人生。还有一个特别现实的原因很多团队已经形成了以 vscode 为核心的工作流。团队规范、ESLint 配置、Prettier 格式化、GitLens 查看代码提交记录、GitHub Copilot 写代码提示这些东西在 vscode 里是成体系存在的。你要是让整个团队为了 uniapp 项目专门去用 HBuilderX那等于把团队工作流撕成两半。这种情况下把 uniapp 项目迁到 vscode 就变成了刚需。1.2 cli 方式与 HBuilderX 方式的本质区别要理解迁移这件事先得搞清楚 uniapp 项目在两种编辑器里的运行机制差异。HBuilderX 里跑项目它背后是用自己内置的编译器对代码进行编译然后调用对应的运行环境。而在 vscode 里跑 uniapp用的是官方提供的dcloudio/uni-app相关 npm 包通过命令行工具cli调用编译能力编译产物再由 vscode 配合相应的运行命令输出到目标平台。这里面有一个很多人不知道的点HBuilderX 的核心编译器跟 cli 用的编译器其实是一套东西只是在封装形式上不同。HBuilderX 是把编译能力做进了 IDE 里cli 则是把编译能力放进了 npm 依赖里。这就意味着你用 HBuilderX 写的 uniapp 项目底层代码结构本身就是可以被 cli 方式识别的这也是为什么“原有 HBuilderX 项目迁移到 vscode”这件事在技术上是完全行得通的。但要注意一个细节HBuilderX 新建的项目不一定带package.json因为它默认不依赖 npm 包管理而 cli 方式运行项目必须有package.json。所以迁移的核心工作并不是“改代码”而是“补工程化依赖 添加编译脚本 配置对应文件”。想清楚这一点后面操作就不会抓瞎。1.3 什么项目适合迁移、什么项目不适合迁不是所有 uniapp 项目都适合迁到 vscode这是个很现实的判断。如果你的项目同时要打包 Android 和 iOS而且用了大量原生插件、原生混淆配置、自定义基座调试那纯 vscode 方案会很难受因为 App 端的原生打包能力目前还是 HBuilderX 的强项cli 项目虽然也能云打包但很多原生插件配置依然绕不开 HBuilderX 的可视化界面。但如果你只盯着 H5 和微信小程序这两个端那 vscode 方案可以说是完美匹配。H5 和小程序端的编译完全依赖 npm 包不需要任何 HBuilderX 环境跑起来非常干净。微信小程序的预览、调试、上传依然用微信开发者工具只是项目代码由 vscode 这边编译出来再导入到微信开发者工具里。这也是我目前最推荐的用法App 端留在 HBuilderX 处理H5 和微信小程序端用 vscode 开发运行。还有一种情况不建议迁移项目里大量依赖 HBuilderX 的“uni_modules 离线插件”且这些插件只在 HBuilderX 插件市场存在迁移后可能会遇到插件依赖缺失的问题。不过大多数情况下 uni_modules 本身就是文件形式存在于项目里的cli 方式也能识别具体要看插件是否依赖 HBuilderX 特定的原生打包流程。这个在后面会细说。2. 环境准备与项目初始化2.1 Node.js 版本选择在 vscode 里跑 uniapp 项目Node.js 是绕不开的一道坎。HBuilderX 把 Node.js 藏在内部用你感觉不到但 cli 方式是明晃晃地依赖 Node 环境的。我先说结论建议 Node.js 16.x 或 18.x不建议一上来就装最新的 20.x 甚至 22.x。为什么这么说因为 uniapp 官方脚手架对 Node 版本是有约束的。Vue3 版本的 uniapp 项目用 Vite 3 或 Vite 4 做编译Vite 3 官方支持的 Node 版本是 14.18 和 16Vite 4 支持 14.18、16 和 18。你用 Node 20 跑 Vite 4 虽然大部分情况下也能工作但偶尔会出现一些莫名其妙的digital envelope routines::unsupported报错这种报错本质上是 OpenSSL 版本和 Node 版本不匹配导致的排查起来非常浪费精力。直接用 Node 18 会省心很多。建议用 nvm 来管理 Node 版本。因为你的电脑上可能还有别的项目在跑Node 版本要求各不相同用 nvm 可以随时切换。安装完 nvm 之后执行nvm install 18 nvm use 18装完顺手用node -v确认一下版本号确保当前终端里生效的是 18.x。这一步看似基础但很多人后面编译报错回头一查才发现是因为 Node 版本不对。2.2 创建新的 cli 工程还是改造老项目这是迁移前必须做的选择。有两套路线路线 A创建全新 cli 工程然后把老项目的源码复制进去。这个路线最省事也是官方推荐的做法。先按 uniapp 官方文档创建 Vue3/Vite 模板工程拿到一个标准的 cli 目录结构再把原有项目的src或者pages、static等目录覆盖进去最后安装依赖、运行调试。这个方式的优点是工程化配置最干净不容易残留 HBuilderX 相关的旧配置缺点是可能会漏掉一些老项目里的特殊配置比如pages.json里的某些自定义属性、manifest.json里的 SDK 配置等需要逐个核对。路线 B在原有 HBuilderX 项目根目录手工补全 cli 需要的文件。这个路线是在老项目里添加package.json、vite.config.js、index.html等文件然后安装对应依赖。这个方式的优点是完全保留原有目录结构和业务代码适合那些项目文件特别多、复制容易出错的老项目缺点是你要自己处理版本对齐问题而且如果原有项目里有一些 HBuilderX 特有的依赖引用排查起来会比较费劲。我的建议是能走路线 A 就别走路线 B。复制源码比补配置要可靠得多而且 cli 工程模板里自带了很多正确的默认配置老项目里没有的配置项你不需要删新模板里多出来的配置项往往正是 cli 运行所必需的。直接在模板基础上改相当于站在“正确答案”上做题。2.3 创建 Vue3/Vite 版 uniapp 项目如果你选择了路线 A创建新工程的流程是这样的。打开终端执行官方脚手架命令npx degit dcloudio/uni-preset-vue#vite my-uniapp-project这里的uni-preset-vue是 uniapp 官方提供的 Vue3 项目预设模板#vite表示拉取 vite 分支。如果你想创建 Vue2 版本命令会稍有不同需要用 vue-cli 方式。但我个人强烈建议新工程一律上 Vue3原因不只是 Vue3 本身更现代还因为 uniapp 官方对 Vue3/Vite 的维护力度明显更大后续新功能、新组件适配都以 Vue3 为主。进入项目目录然后安装依赖cd my-uniapp-project npm install依赖安装可能需要一两分钟耐心等一下。装完之后你会在项目根目录看到一个标准的 cli uniapp 目录结构。这里我多说一句这个模板默认的src目录里就是 uniapp 的页面结构包含pages.json、manifest.json、App.vue、main.js、pages目录、static目录。你把自己老项目里对应的内容复制过去替换掉同名文件基本就完成迁移了。如果你本来用的就是 cli 创建的 uniapp 项目那更简单不需要重新创建工程直接进入下一步在 vscode 里写代码调试就行。2.4 vscode 插件安装与必备配置在 vscode 里跑 uniapp有两个插件是你必须装的第一个是Vue OfficialVolar注意 Vue3 项目不要装 Vetur这两者在 Vue3 下会打架。安装 Volar 之后它会接管.vue文件的语法高亮、代码提示和类型检查是开发体验最关键的插件。第二个是uni-helper这个插件提供pages.json、manifest.json等 uniapp 专属配置文件的智能提示和校验。没有它你在写pages.json的时候很容易写错属性名或者漏掉必填字段编译时才报错效率很低。另外两个强烈推荐的插件是ESLint承接团队规范检查代码风格不统一的问题在保存时直接标红。Prettier - Code formatter格式化代码统一全组成员的代码风格。安装完之后建议在 vscode 的settings.json里加一个配置让保存时自动格式化{ editor.formatOnSave: true, editor.codeActionsOnSave: { source.fixAll.eslint: true } }还有一个小点打开项目的时候把 vscode 下方的“选择语言模式”确认在 Vue 或 JavaScript 上有时候 vscode 自动识别语言模式会出错导致代码高亮异常。3. 配置 H5 和微信小程序运行指令3.1 package.json 里的 scripts 脚本创建好 cli 工程之后第一件事是打开根目录下的package.json找到scripts字段。标准模板里默认会有几个脚本但网上很多教程给的都不全我直接给你一套我验证过可以跑通的配置scripts: { dev:h5: uni, dev:mp-weixin: uni -p mp-weixin, build:h5: uni build, build:mp-weixin: uni build -p mp-weixin }说明一下dev:h5是启动 H5 开发模式默认端口是 8080你后面也可以在vite.config.js里改端口。dev:mp-weixin是启动微信小程序开发模式这里的-p参数表示 platformmp-weixin就是微信小程序平台的固定标识。build:h5和build:mp-weixin是生产打包指令分别输出到dist/build/h5和dist/build/mp-weixin目录。这套脚本理论上也是 cli 方式的核心用法。你不需要记忆所有的 uniapp 命令参数只要知道 dev开发模式和 build生产构建加上对应的平台标识能组合出所有端的运行和打包命令就够了。3.2 vite.config.js 的常用配置Vue3 的 uniapp 项目编译核心在vite.config.js文件。模板自带的vite.config.js通常长这样import { defineConfig } from vite import uni from dcloudio/vite-plugin-uni export default defineConfig({ plugins: [uni()] })这个配置只是基础实际项目里我一般会额外加上几个东西。第一是路径别名把指向src目录这样写代码的时候/pages/index/index这种引用方式才不用改import { resolve } from path export default defineConfig({ plugins: [uni()], resolve: { alias: { : resolve(__dirname, src) } } })第二是开发服务器的代理配置。这个非常关键因为 H5 端在浏览器里跑的时候会有跨域问题你的前端请求http://localhost:8080/api但后端接口可能在http://192.168.1.100:8081如果不配代理浏览器会直接拦截跨域请求。配置方式是在defineConfig里加server.proxyserver: { port: 8080, proxy: { /api: { target: http://192.168.1.100:8081, changeOrigin: true, rewrite: path path.replace(/^\/api/, ) } } }这里解释一下rewrite如果你的后端接口路径本身不带/api前缀那就需要把请求里的/api去掉再转发到后端。如果你后端本身就要求带/api前缀那这个rewrite就不需要直接changeOrigin: true就行。第三是gzip 压缩配置H5 打包的时候建议加上不然首屏体积很吃亏npm install vite-plugin-compression -D然后在配置里引入import viteCompression from vite-plugin-compression plugins: [ uni(), viteCompression() ]这里有个重点vite.config.js 是同时在 H5 和微信小程序编译时生效的。如果你在小程序环境里出现了一些和路径、代理相关的报错先看看server和resolve配置是不是影响了编译。一般来说server.proxy只在 dev server 里生效小程序编译不受它影响但resolve.alias会同时影响两个端改的时候要小心。3.3 启动 H5 开发服务所有配置完成后在 vscode 的终端里执行npm run dev:h5首次启动会看到编译进度过了几秒到十几秒不等终端会输出Local: http://localhost:8080/。这时候你在浏览器里打开这个地址就能看到页面。这里有个细节H5 端默认的路由模式是hash路由也就是地址栏里会有一个#号比如http://localhost:8080/#/pages/index/index。如果你不喜欢 hash 路由可以在manifest.json里的h5配置项里把router的mode改成historyh5: { router: { mode: history } }但要注意改成history后生产环境部署时服务端要做对应的路径重写处理把所有请求都指向index.html否则刷新页面会 404。开发环境用 hash 路由最省心线上部署如果没有特殊要求我也建议就保持 hash 路由。3.4 启动微信小程序编译并接入微信开发者工具微信小程序的运行方式和 H5 不一样它不是直接在浏览器里预览而是先在 vscode 里编译出小程序的代码然后用微信开发者工具打开编译产物。执行npm run dev:mp-weixin终端会输出编译进度编译完成后会生成dist/dev/mp-weixin目录这个目录就是微信小程序的源码包。注意这个命令是持续监听的就是你在 vscode 里改代码保存后它会自动重新编译微信开发者工具里会实时刷新这一点跟 H5 热更新是类似的。然后打开微信开发者工具点“导入项目”目录选择dist/dev/mp-weixinAppID 填你自己的小程序 AppID。如果你还没有注册小程序账号也可以先点“测试号”来体验但功能上会有一些限制比如不能调用部分需要正式 AppID 的 API。这里有个特别容易踩的坑微信开发者工具的项目名称和路径不能包含中文和特殊符号否则会报错。我以前给一个客户迁移项目他的电脑用户名是中文的导致项目路径里有中文导入项目后无论如何都编译不通过后来把项目挪到纯英文路径下才解决。项目路径里的空格也会造成类似的问题尽量保持全英文路径。导入成功后你会在微信开发者工具里看到页面。这时候vscode 里改代码保存微信开发者工具会自动刷新和 HBuilderX 里运行小程序的效果一致。3.5 H5 和微信小程序同时跑起来的注意事项实际开发中同一时间既开 H5 又开小程序是很常见的情况。你可能在微信小程序里调接口调样式又要在浏览器里看页面效果。这两个端可以同时跑互不干扰但有几个注意点。第一个是端口问题。H5 默认占用 8080如果这个端口被别的项目占了启动会失败你可以在vite.config.js里改端口server: { port: 8081 }第二个是环境变量区分。小程序和 H5 的 API 地址经常不一样你可以创建.env.development和.env.production文件在里面定义变量然后在代码里通过import.meta.env.VITE_API_BASE_URL访问。比如# .env.development VITE_API_BASE_URLhttps://dev-api.example.com# .env.production VITE_API_BASE_URLhttps://api.example.com这样开发环境走开发接口打包上线时自动切换成线上接口。第三个是条件编译。如果你有某些代码只想在 H5 端执行某些代码只想在小程序端执行uniapp 官方提供了一套条件编译写法// #ifdef H5 console.log(只在 H5 端生效) // #endif // #ifdef MP-WEIXIN console.log(只在微信小程序端生效) // #endif这套语法在迁移老项目的时候特别有用因为老项目里多少都会有一些平台差异的处理逻辑用条件编译包起来代码一处编写两个平台各自编译各自运行。4. 老项目迁移的实操细节4.1 复制源码时需要留意的文件如果你选择路线 A新 cli 工程 复制源码有几个文件必须重点核对这不是简单复制粘贴就完事的。第一个是manifest.json。这个文件是 uniapp 项目的全局配置里面包含应用名称、AppID、小程序 AppID、各平台的 SDK 配置等。老项目的manifest.json里肯定有你自己填过的 appid、小程序 appid这些值必须原封不动地搬到新工程里。尤其注意mp-weixin配置块里的appid如果漏了微信开发者工具导入时会提示 AppID 不匹配。第二个是pages.json。这个文件定义了页面路由、导航栏样式、tabBar 等直接决定你的项目能不能正常跳转和显示。复制的时候是整个文件覆盖但如果你新工程模板里的pages.json里有一些默认页面比如模板自带的 index 页面配置覆盖后会被你自己的配置替代这个没问题。第三个是static目录。这个目录存放静态资源比如图片、字体、本地 JSON 文件等。在 cli 工程里src/static目录对应的是小程序编译产物的static目录H5 端会原样复制到dist/dev/h5/static。老项目里静态资源的引用路径可能写的是/static/xxx.png这种写法在 H5 端没问题但在小程序端可能有问题建议把路径改成相对路径引用或者统一使用 uniapp 的静态资源规范方式/static/xxx.png配合路径别名。第四个也有点坑老项目里如果有uni.scss这个文件记得一起搬过来。uni.scss是 uniapp 的全局样式变量文件里面的变量会注入到每个页面组件的样式中。如果你漏了它页面上大量使用$uni-color-primary这类变量的地方全部会报样式失效页面会变得一团糟。4.2 依赖安装与版本对齐复制完源码之后进入新项目根目录安装依赖。这里要特别注意如果老项目用了sass或scss语法新项目里也要安上不然编译报错。我见过最典型的场景就是模板项目默认不带sass老项目写了一大堆scss样式迁移过来一跑全是Syntax Error: Undefined variable之类的报错。安装命令npm install sass -D注意 Vite 3/4 下建议用sass不要再装node-sass后者和新版 Vite 经常不兼容编译时会有一堆原生模块编译报错。还有一个需要对齐的依赖是dcloudio系列包。cli 方式下所有 uniapp 的编译能力都是通过dcloudio/uni-app、dcloudio/vite-plugin-uni、dcloudio/uni-mp-weixin等 npm 包提供的这些包是有版本匹配关系的。创建新模板时这些包都是同一版本如果你是从老项目里手工改造路线 B一定要保证这些包版本完全一致否则编译出来的代码会出现各种奇怪的 bug。我自己遇到过最典型的一次dcloudio/uni-app是 3.0.0-3081220230825001 版本但dcloudio/vite-plugin-uni是另一个版本结果编译出来的小程序代码里出现了一个undefined is not a function的错误排查了整整一下午才发现是版本不一致导致的。后来把 package.json 里所有dcloudio开头的依赖统一成相同版本才恢复正常。4.3 原有 HBuilderX 项目的特殊处理如果你的老项目是用 HBuilderX 创建的里面可能会有一些 HBuilderX 特有的配置文件。比如项目根目录下可能会有.hbuilderx文件夹或者manifest.json里有一些 HBuilderX 可视化配置生成的字段。这些文件迁移到 vscode 之后一般没有用但也不影响运行留着问题不大。真正需要注意的是老项目如果是 HBuilderX 的“非 cli 工程”它的源码不在src目录下而是直接把pages、static、App.vue这类文件放在项目根目录。这种结构在 cli 工程里是不认的cli 工程默认源码都在src目录下。所以迁移时要把这些文件都挪到src目录里。这是最容易搞错的一步我就见过有人把整个项目文件直接在根目录下跑npm run dev:h5结果编译出一堆找不到页面文件的报错。具体操作是在 cli 工程里把老项目根目录下的App.vue、main.js、pages.json、manifest.json、uni.scss全部移动到新工程的src目录下再把老项目的pages目录、static目录也移动或复制到src目录下。移动完成后再对比一下pages.json里的页面路径确保路径写法能对应上实际文件位置。4.4 easycom 和 uni_modules 依赖的处理老项目里如果安装了 uni_modules 插件这些插件在 cli 工程里也能用。uni_modules目录通常放在src目录下里面的每个插件自带组件和 js 模块。迁移的时候把uni_modules整个目录复制到src目录下即可。这里有个主流配置叫easycom它让开发者不需要手动import和注册组件只要在页面模板里写了uni-xxx这样的标签编译时会自动按规则引入对应组件。cli 工程的pages.json里默认开启了 easycomeasycom: { autoscan: true, custom: { ^uni-(.*): /uni_modules/uni-$1/components/uni-$1/uni-$1.vue } }如果你的老项目用了uni-ui组件库那在 cli 工程里通常需要把uni-ui也作为依赖安装。比如npm install dcloudio/uni-ui或者直接使用 uni_modules 方式放在src/uni_modules目录下。两种方式对开发者来说差别不大但要注意版本配套问题。uni-ui 的版本迭代比较频繁有些新版本会要求较高的 uniapp 版本如果你迁移后发现组件渲染异常优先检查 uniapp 核心包版本是不是太低。4.5 API 地址与环境变量配置迁移老项目时最容易被忽略但又最重要的配置是接口地址。H5 和小程序对接口地址的要求不一样H5 端可能会遇到跨域问题需要代理小程序端不需要代理但必须配置合法域名微信公众平台后台添加 request 合法域名开发环境下可以在微信开发者工具里勾选“不校验合法域名”。我的建议是不要在代码里写死接口地址而是用环境变量在编译时注入。在项目根目录创建.env.development和.env.production# .env.development VITE_API_BASE_URL https://dev-api.example.com VITE_APP_ENV development # .env.production VITE_API_BASE_URL https://api.example.com VITE_APP_ENV production然后在项目里的请求封装文件里读取const BASE_URL import.meta.env.VITE_API_BASE_URL export function request(url, method, data) { return new Promise((resolve, reject) { uni.request({ url: BASE_URL url, method, data, success: res resolve(res.data), fail: err reject(err) }) }) }这样本地开发走开发环境地址打包上线自动切换成生产地址不用改代码。如果你在微信开发者工具里预览时接口请求报错 400 或者 URL 无效大概率是环境变量没配对先检查编译出来的代码里 BASE_URL 是不是正确的那份。5. 常见问题与排查技巧实录5.1 H5 端编译成功但浏览器打开白屏这个现象很常见npm run dev:h5终端显示编译成功Local: http://localhost:8080也出来了但浏览器打开就是一个纯白页面什么内容都没有。我遇到过的原因主要有三个。第一个是pages.json里的第一个页面路径写错了。uniapp 默认把pages.json里pages数组的第一个页面作为应用启动页如果你第一个页面路径不存在编译不报错但运行白屏。排查方式直接访问http://localhost:8080/#/pages/index/index看看能不能手动定位到页面如果能访问说明首启动页配置有问题调整 pages 数组顺序即可。第二个原因是入口文件main.js的挂载逻辑不对。Vue3 的 uniapp 项目入口文件应该是import { createSSRApp } from vue import App from ./App.vue export function createApp() { const app createSSRApp(App) return { app } }注意createSSRApp是 uniapp 在 Vue3 下的专用挂载方式如果你误写成了createApp编译能通过但运行时会白屏或者报错。第三个原因是index.html这个入口文件没放在项目根目录。Vite 构建需要根目录下有一个index.html作为应用的 HTML 入口模板项目里默认有但如果你迁移时不小心删了或者挪了位置就会导致 H5 编译产物没有正确的 HTML 挂载点白屏很正常。5.2 小程序编译成功但微信开发者工具里空白这个问题的排查思路和 H5 白屏不完全一样。小程序编译成功后微信开发者工具导入项目看到的如果是一个空白界面先看 Console 面板有没有报错。最常见的原因是AppID 不匹配。你项目的manifest.json里的mp-weixin.appid和微信开发者工具里导入时填的 AppID 不一致或者根本没填微信开发者工具可能会提示“未找到 appid”或者直接白屏。解决方式是在manifest.json里补上正确的 appid然后重新npm run dev:mp-weixin。第二个常见原因基础库版本太低。老项目里用了一些新 API但微信开发者工具的基础库版本很旧运行时会报xxx is not a function或者页面直接渲染失败。在微信开发者工具右上角“详情”-“本地设置”里把调试基础库版本调高一点一般调到 2.30 能覆盖绝大多数 API。第三个原因是页面路径大小写问题。小程序端对文件路径敏感如果你的页面文件名是Index.vue但pages.json里写的是pages/index/index开发时可能不报错但真机预览或体验版里会出现找不到页面的问题。这在老项目迁移后特别容易发生因为 Windows 系统下文件名大小写不敏感macOS 下又敏感一套代码在不同人电脑上表现不一样。建议统一用小写字母命名页面文件。5.3 请求接口时 H5 跨域、小程序报域名不合法这是开发中最常见的两类问题而且原因和处理方式完全不同。H5 端跨域浏览器的同源策略限制导致http://localhost:8080的页面请求http://dev-api.example.com的接口被拒绝Console 里会看到CORS policy相关的红色报错。解决办法是在vite.config.js里配 proxy上面 3.2 已经讲过或者让后端开启 CORS 响应头。开发环境强烈建议用 proxy因为不用麻烦后端同事。小程序端域名不合法微信小程序要求所有请求域名必须是 HTTPS 且在小程序后台配置了 request 合法域名。开发环境下可以在微信开发者工具右上角“详情”-“本地设置”里勾选“不校验合法域名、web-view业务域名、TLS 版本以及 HTTPS 证书”。但注意这个勾选只对开发环境有效真机预览时如果不校验域名需要打开调试模式。上线前务必去微信公众平台把正式版使用的域名在“开发管理”-“开发设置”-“服务器域名”里配好否则用户打开体验版或正式版时接口全部被拦截。我之前做过一个微信小程序项目开发阶段一直勾选“不校验域名”跑得好好的结果上传体验版后所有接口都失败了一查才发现是忘配服务器域名。这种事踩过一次就记住了现在每次发版前检查清单里都有一条确认小程序后台的 request 合法域名。5.4 端口占用导致 H5 启动失败npm run dev:h5启动时报Port 8080 is already in use是很常见的问题。解决办法有两个一是关掉占用 8080 端口的进程二是换一个端口。我比较推荐第二种因为同时跑多个项目是常态server: { port: 5173, strictPort: false }strictPort: false的意思是如果 5173 也被占了vite 会自动顺延到 5174、5175 等下一个可用端口。这个配置非常实用特别是在团队协作场景下大家同时开着多个 dev server固定端口反而容易冲突。5.5 运行过程中改动代码不生效或热更新失效vscode 里跑 uniapp热更新偶尔会失灵表现为改了代码保存后浏览器或微信开发者工具没有自动刷新或者刷新了但页面没变化。先检查是不是终端里编译报错了。很多情况是代码写错了但 dev server 还在跑终端里刷了很多红色报错页面自然不更新。这种情况先在终端里看有没有报错信息有就先把错误改掉。如果终端没有任何报错但页面还是不更新大概率是uniapp 编译缓存的问题。清掉缓存重新编译rm -rf node_modules/.cache npm run dev:h5对小程序的缓存可以直接在微信开发者工具里点“清缓存”-“清除全部缓存”然后重新编译。这种方法能解决绝大多数“改代码不生效”的问题。还有一个容易忽略的坑如果你的项目里用了pages.json动态修改页面配置的逻辑在微信小程序端热更新时可能不会响应pages.json的改动。这种文件改动在 cli 方式下可能需要手动重启npm run dev:mp-weixin才能生效不要傻等。5.6 常见报错排查速查表直接整理一张表方便你收藏备用报错信息可能原因处理方法digital envelope routines::unsupportedNode 版本过高切换到 Node 16/18Module not found: Cant resolve sass缺少 sass 依赖安装 sass不要装 node-sassPort 8080 is already in use端口被占用换端口或关掉占用进程Failed to load resource资源路径或接口地址错误检查静态资源引用和 API 地址配置app.json not found编译产物不完整删除dist/dev/mp-weixin重新编译[plugin:vite:uni] No pages foundpages.json 页面配置为空或路径错误检查 pages.json 的 pages 数组Component is not found in patheasycom 组件路径不正确检查 uni_modules 目录和 easycom 配置import.meta.env is not defined环境变量写法错误Vue3 使用import.meta.envVue2 使用process.env这张表是我这几年踩坑经验的浓缩基本覆盖了从 HBuilderX 迁到 vscode 后最常见的报错场景。6. 迁移完成后的常用工作流与建议6.1 日常开发vscode 微信开发者工具协同迁移完成后我个人的工作流是这样的vscode 里开npm run dev:h5跑浏览器调试同时开一个终端跑npm run dev:mp-weixin给微信开发者工具实时预览。改代码时优先在浏览器里看样式和交互因为浏览器调试工具比微信开发者工具好用得多确认没问题后切到微信开发者工具里验证小程序端的表现。这里有个小技巧微信开发者工具里改样式反应比较慢而且没有浏览器那么方便的 DevTools所以实际上我大部分样式调整都在 H5 端完成然后到小程序端做兼容性检查。只要你在代码里没有滥用document、window这类浏览器特有对象H5 端的样式表现基本就是小程序的最终样式。偶尔会有一些 CSS 属性差异比如position: sticky在微信小程序某些版本下的兼容性问题这时候再单独处理就行。6.2 用 Git 管理 cli 项目的技巧cli 项目的工程化优势之一就是可以正常用 Git 管理。迁移完成后项目根目录下会有一个.gitignore文件建议确认一下里面的忽略规则是否包含以下目录node_modules/ dist/ .DS_Store必须把dist目录加入忽略列表因为dist是编译产物每次运行都会重新生成不加入忽略列表会导致 Git 提交记录里出现大量无意义的变更。另外.hbuilderx目录如果是 HBuilderX 迁移过来的也建议加进.gitignore。有一点特别重要微信开发者工具的 project.config.json 文件不要随手提交到 Git 仓库。这个文件包含你本地微信开发者工具的配置路径和项目 id不同开发者本地环境不一样提交上去会引起冲突。建议在.gitignore里加上project.config.json project.private.config.json如果你希望团队成员打开微信开发者工具时能自动识别项目配置可以用project.config.json的模板文件共享但要注意里面的miniprogramRoot字段要指向dist/dev/mp-weixin因为 cli 项目的微信小程序编译产物在 dist 目录不是项目根目录。6.3 新老项目并行维护时的注意事项有些时候你并不能一次性把老项目完全迁移过来比如老项目还在线上运行你只能在开发分支上做迁移测试。这时候要注意不要直接改老项目的源码目录结构因为你随时可能要回退版本。我的做法是复制一份老项目代码到本地另外的目录里做迁移迁移完成验证通过后再合并到主分支。这样线上版本不受影响迁移进度可控。还有一个问题老项目和新项目如果同时维护代码里往往会积累一些针对 HBuilderX 环境的兼容代码比如// #ifdef APP-PLUS这种条件编译块在 cli 工程里依然有效。APP-PLUS标识在 cli 方式下对应的是APP或APP-PLUS这里不需要改动。但要提醒一点老项目如果用了 HBuilderX 内置的plus对象比如plus.android在 cli 工程里这些 API 在小程序端和 H5 端是不存在的运行时会报错。如果你只维护 H5 和小程序端可以在代码里用条件编译把plus相关的逻辑包起来或者直接在老代码里把这些功能先注释掉避免影响新端稳定运行。6.4 最后一件事把项目跑起来之后别忘了提交一次迁移完成后我强烈建议你做的第一件事不是接着改需求而是把整个项目跑一遍主流程然后提交一个完整的 Git 版本。这个提交的作用是给后续所有开发建立一个「可运行的基线版本」。以后不管是改配置、升级依赖还是新加功能都可以以这个版本为参照出了问题随时能回滚。我还习惯把这个基线版本打上 tag比如v1.0.0-vscode-migration这样团队里新入职的同事拉下来就知道这个版本是可运行的。以后谁改了东西跑不起来了直接对比这个 tag 就能快速定位是哪里引入的问题。7. 写在最后的一些体会迁移 uniapp 项目到 vscode 这件事说到底不是技术难题而是一个工程习惯的转变。HBuilderX 把太多事情封装在图形界面里让你感觉不到编译过程的复杂度而 vscode cli 方式把这些过程全都暴露在终端面前一开始可能会觉得不习惯但熟悉之后你会发现这种“透明”恰恰是效率的保证。我在实际迁移了多个项目之后的感受是vscode 并没有让 uniapp 开发变得更复杂反而是把那些原本藏在 HBuilderX 里不可控的部分比如编译缓存、依赖版本、环境变量交还给你让你有能力去排查和解决它们在 HBuilderX 里根本说不清的问题。尤其是团队协作方面Git 操作、Code Review、CI/CD 全都顺了配合微信开发者工具实时预览开发体验确实提升了一大截。最后再分享一个小经验如果你组里有同事还在用 HBuilderX 跑同一个项目不要急于让他立刻切到 vscode先让他按这篇文章跑通一遍重点体验一下 H5 和小程序的启动流程。等项目跑顺了再统一团队工作流阻力会小很多。毕竟工具迁移这件事最难的从来不是技术而是习惯。