Nuxt + Ionic 本地开发

Nuxt 是一个基于 Vue 的强大框架,自带基于文件的路由系统、自动代码拆分、自动导入、良好的 TypeScript 支持等,而 Ionic 允许我们使用 Web 来构建现代、高质量的跨平台移动应用程序。有没有可能将二者结合起来做开发呢?

幸运的是,Nuxt 官方提供了 @nuxt/ionic 模块来集成 Ionic。遗憾的是,截止到 v0.13.1,Nuxt + Ionic 本地开发仍然是一个挑战,如果按照文档来做,大概率会遇到错误而无法继续推进。本文旨在记录复现本地开发错误并探索可行解决方案的过程。

复现本地开发错误

我们首先按照文档尝试本地开发。我的开发环境是 macos Sonoma 14.4.1、Node.js v20.11.0、PNPM v8.15.5。

参考 Nuxt Docs > Installation 创建一个新的 Nuxt 项目。

shell 复制代码
pnpm dlx nuxi@latest init nuxt-ionic

.npmrc 中设置 shamefully-hoisttrue

shell 复制代码
shamefully-hoist=true

参考 @nuxt/ionic Docs > Installation,安装 @nuxt/ionic 依赖、Android Studio 等,参考 React Native 中文网 > 搭建开发环境 配置相关环境并创建模拟器。

shell 复制代码
pnpm install --force && pnpm install @nuxtjs/ionic -D

更新 nuxt.config.ts

typescript 复制代码
// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
  devtools: { enabled: true },
  modules: ['@nuxtjs/ionic'], // [!code ++]
  ssr: false, // [!code ++]
});

再次安装依赖触发 postinstall 钩子,让 Nuxt 创建 Ionic 相关文件。

shell 复制代码
pnpm install

参考 @nuxt/ionic Docs > Enabling Capacitor,启用 Capacitor

shell 复制代码
pnpm add -g @ionic/cli
ionic config set -g npmClient pnpm
ionic integrations enable capacitor
ionic capacitor add ios
ionic capacitor add android

参考 @nuxt/ionic Docs > Routing,更新 app.vue

html 复制代码
<template>
  <ion-page>
    <ion-header>
      <ion-toolbar>
        <ion-title>Home</ion-title>
      </ion-toolbar>
    </ion-header>
    <ion-content class="ion-padding">Hello World</ion-content>
  </ion-page>
</template>

至此,这个项目已经初始化完毕,你可以通过 pnpm run dev -o 来启动项目,在浏览器中会看到如下页面。

开发移动应用自然不能只是把项目运行到浏览器上,我们还需要把项目运行到模拟器或真机上,这里使用 Android 来做演示。参考 @nuxt/ionic Docs > Local Development,创建 ./scripts/android.sh 并写入以下内容。

bash 复制代码
#!/bin/bash
LIP=$(ipconfig getifaddr en0)

echo "🍦 Starting local development to android device - ensure local dev server is running already"
echo "🏗️ Type checking and building for development..."
pnpm run build:dev
echo "🔃 Capacitor installation, podfile installation, sync and copy to app distribution folders..."
npx @ionic/cli capacitor sync android --no-build
echo "🏃 Select an Android device to run the build at local ip address ${LIP} on..."
eval "npx @ionic/cli capacitor run android --livereload-url=http://${LIP}:3000 --external --mode development"

更新 package.json 中的 scripts 字段。

json 复制代码
{
  "scripts": {
    "android": "bash ./scripts/android.sh"
  }
}

🥰 让我们满怀期待地启动项目!

shell 复制代码
pnpm run android

😱 结果狠狠地报错了!

如果正在使用 Windows 系统,推荐使用安装 Git 时附带的 Git Bash。ipconfig getifaddr en0 命令可能会报错,而且报错信息可能与我提供的图例不一致,可以先跳过直接往下看,后面会移除该命令。

探索可行解决方案

😡 一气之下气了一下,气完之后让我们仔细看看错误到底怎么回事。第一个错误是 Missing script: build:dev,也就是说 build:dev 这个命令不存在。第二和第三个错误都是 Could not find the web assets directory: ./dist,也就是说 dist 目录不存在。

如果你相当熟悉 Nuxt,那么我相信你脑海中已经浮现出了答案,那就是通过 pnpm run generate 生成 dist 目录,让后续的流程正常跑通。如果你并不熟悉,那应该怎么办?最简单有效的办法是重新再过一遍 @nuxt/ionicIonic 文档。在 @nuxt/ionic Docs > Enabling Capacitor 中,大概步骤已经列写出来了。

  1. 错误信息提示我们需要生成一个 dist 目录。@nuxt/ionic 文档中说我们可以使用 nuxi generate 或者 nuxi build 来生成,实际上只有 nuxi generate 会生成 dist 目录,所以我们需要使用 nuxi generate,也就是运行 pnpm run generate
  2. 我们需要运行 npx cap sync(也就是前面用到的 npx @ionic/cli capacitor sync) 同步 dist 目录。
  3. 我们需要运行 npx cap open ${platform}(也就是前面用到的 @ionic/cli capacitor run) 来打开对应平台(Android / iOS)的应用。

我们将 pnpm run build:dev 换成 pnpm run generate,然后再次尝试启动。

bash 复制代码
#!/bin/bash
LIP=$(ipconfig getifaddr en0)

echo "🍦 Starting local development to android device - ensure local dev server is running already"
echo "🏗️ Type checking and building for development..."
pnpm run build:dev # [!code --]
pnpm run generate # [!code ++]
echo "🔃 Capacitor installation, podfile installation, sync and copy to app distribution folders..."
npx @ionic/cli capacitor sync android --no-build
echo "🏃 Select an Android device to run the build at local ip address ${LIP} on..."
eval "npx @ionic/cli capacitor run android --livereload-url=http://${LIP}:3000 --external --mode development"

这一次在终端里没有报错了,但是在 Android 模拟器里报错了。

这里说的是不能连接到 http://192.168.0.103:3000,但实际上我们根本不需要连接到这里,我们可以去掉相关部分,然后再次尝试启动。

bash 复制代码
#!/bin/bash
LIP=$(ipconfig getifaddr en0) # [!code --]
# [!code --]
echo "🍦 Starting local development to android device - ensure local dev server is running already"
echo "🏗️ Type checking and building for development..."
pnpm run generate
echo "🔃 Capacitor installation, podfile installation, sync and copy to app distribution folders..."
npx @ionic/cli capacitor sync android --no-build
echo "🏃 Select an Android device to run the build at local ip address ${LIP} on..." # [!code --]
eval "npx @ionic/cli capacitor run android --livereload-url=http://${LIP}:3000 --external --mode development" # [!code --]
echo "🏃 Select an Android device to run the build at local on..." # [!code ++]
npx @ionic/cli capacitor run android --external # [!code ++]

这一步同时移除了 ipconfig getifaddr en0 命令的调用,后面步骤在各系统中执行结果应该一致。

这一次在终端里又出现了新的提示。它想要运行 vue-cli-service build 但是没找到 @vue/cli-service,询问我们要不要安装。

但是我们已经有 dist 目录了,又何必再打包呢?我们添加 --no-build 参数跳过这个步骤,然后再次尝试启动。

bash 复制代码
#!/bin/bash
echo "🍦 Starting local development to android device - ensure local dev server is running already"
echo "🏗️ Type checking and building for development..."
pnpm run generate
echo "🔃 Capacitor installation, podfile installation, sync and copy to app distribution folders..."
npx @ionic/cli capacitor sync android --no-build
echo "🏃 Select an Android device to run the build at local on..."
npx @ionic/cli capacitor run android --external # [!code --]
npx @ionic/cli capacitor run android --external --no-build # [!code ++]

🎉 这次发现 Android 模拟器正常运行了!真的是可喜可贺!

😔 遗憾的是,终端直接退出了,这也就意味着我们改代码之后,还需要手动运行 pnpm run android 才可以看到最新的代码效果。有没有什么办法改代码后自动运行呢?🤔

在没有头绪时,问问 AI 是不错的选择。我这里用的是 VSC 免费插件 Codeium

我们可以逐个检查,结果第一个 nodemon 就非常不错,那我们就用它吧。事实上,nodemon 也是最匹配我们需求、应用最为广泛的包之一。

shell 复制代码
pnpm install nodemon -D

我们需要监听的目录和文件类型比较多,在 package.json 的 scripts 字段中使用会非常长,所以这里使用配置文件 nodemon.json 来设置 nodemon。

json 复制代码
{
  "ignore": [".git", "**/node_modules/"],
  "watch": [
    "./assets",
    "./components",
    "./composables",
    "./content",
    "./layouts",
    "./middleware",
    "./modules",
    "./pages",
    "./plugins",
    "./public",
    "./server",
    "./utils",
    "./.env",
    "./app.vue",
    "./app.config.ts",
    "./capacitor.config.json",
    "./error.vue",
    "./ionic.config.json",
    "./nuxt.config.ts",
    "./tsconfig.json"
  ],
  "ext": "json,js,jsx,ts,tsx,vue"
}

最后更新 package.json 中的 scripts 字段。

json 复制代码
{
  "scripts": {
    "android": "nodemon --exec "bash ./scripts/android.sh""
  }
}

再次运行 pnpm run android 检查,结果又狠狠地报错了!😡

这是因为当我们使用 nodemon 时,我们无法与终端交互,导致 npx @ionic/cli capacitor run android --external --no-build 这个命令没有指定对应的 target,进而导致报错。

我们可以运行 ionic capacitor run android --list 来获取到可选的设备,自动传递第一个设备的 ID,来解决这个报错。

bash 复制代码
#!/bin/bash
target=$(ionic capacitor run android --list | awk 'NR>3 {print $NF; exit}') # [!code ++]
# [!code ++]
echo "🍦 Starting local development to android device - ensure local dev server is running already"
echo "🏗️ Type checking and building for development..."
pnpm run generate
echo "🔃 Capacitor installation, podfile installation, sync and copy to app distribution folders..."
npx @ionic/cli capacitor sync android --no-build
echo "🏃 Select an Android device to run the build at local on..."
npx @ionic/cli capacitor run android --external --no-build # [!code --]
eval "npx @ionic/cli capacitor run android --external --no-build --target=${target}" # [!code ++]

如果正在使用 Windows 系统,需要先安装 awk 命令,比如使用 chocolatey 安装:choco install awk

再再次运行 pnpm run android 检查,现在一切正常了,修改代码后也能看到最新的代码效果了!🎉

以上提供的脚本内容做简单修改即可适配 iOS,此处不再赘述。最终 package.json 内容如下。

json 复制代码
{
  "name": "nuxt-app",
  "private": true,
  "type": "module",
  "scripts": {
    "build": "nuxt build",
    "dev": "nuxt dev",
    "generate": "nuxt generate",
    "preview": "nuxt preview",
    "postinstall": "nuxt prepare",
    "android": "nodemon --exec "bash ./scripts/android.sh""
  },
  "dependencies": {
    "@capacitor/android": "5.7.4",
    "@capacitor/app": "5.0.7",
    "@capacitor/core": "5.7.4",
    "@capacitor/haptics": "5.0.7",
    "@capacitor/ios": "5.7.4",
    "@capacitor/keyboard": "5.0.8",
    "@capacitor/status-bar": "5.0.7",
    "nuxt": "^3.11.1",
    "vue": "^3.4.21",
    "vue-router": "^4.3.0"
  },
  "devDependencies": {
    "@capacitor/cli": "5.7.4",
    "@nuxtjs/ionic": "^0.13.1",
    "nodemon": "^3.1.0"
  }
}

小结

本文记录了将 Nuxt 和 Ionic 结合起来进行本地开发的过程,包括配置环境、创建项目、遇到问题、探索解决方案等。

Nuxt 和 Ionic 的结合使用在文档上可能存在一些不足,我们可以通过阅读、理解错误信息,结合官方文档、社区资源和 AI 辅助,来完善这部分使用。

希望本文能带给你一点启发和帮助!

本文使用 markdown.com.cn 排版。欢迎关注我的公众号"程序员想退休"和我的 个人站,获取更多分享。

相关推荐
代码搬运媛3 小时前
Jest 测试框架详解与实现指南
前端
counterxing3 小时前
我把 Codex 里的 Skills 做成了一个 MCP,还支持分享
前端·agent·ai编程
wangqiaowq4 小时前
windows下nginx的安装
linux·服务器·前端
之歆4 小时前
DAY_12JavaScript DOM 完全指南(二):实战与性能篇
开发语言·前端·javascript·ecmascript
发现一只大呆瓜4 小时前
Vite凭什么这么快?3分钟带你彻底搞懂 Vite 热更新的幕后黑手
前端·面试·vite
Maimai108084 小时前
React如何用 @microsoft/fetch-event-source 落地 SSE:比原生 EventSource 更灵活的实时推送方案
前端·javascript·react.js·microsoft·前端框架·reactjs·webassembly
kyriewen6 小时前
产品经理把PRD写成“天书”,我用AI半小时重写了一遍,他当场愣住
前端·ai编程·cursor
humcomm7 小时前
元框架的工作原理详解
前端·前端框架
canonical_entropy7 小时前
Attractor Before Harness: AI 大规模开发的方法论
前端·aigc·ai编程
zhangxingchao7 小时前
多 Agent 架构到底怎么选?从 Claude Agent Teams、Cognition/Devin 到工程落地原则
前端·人工智能·后端