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-hoist 为 true
。
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/ionic
和 Ionic
文档。在 @nuxt/ionic Docs > Enabling Capacitor 中,大概步骤已经列写出来了。
- 错误信息提示我们需要生成一个
dist
目录。@nuxt/ionic
文档中说我们可以使用nuxi generate
或者nuxi build
来生成,实际上只有nuxi generate
会生成dist
目录,所以我们需要使用nuxi generate
,也就是运行pnpm run generate
。 - 我们需要运行
npx cap sync
(也就是前面用到的npx @ionic/cli capacitor sync
) 同步dist
目录。 - 我们需要运行
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 排版。欢迎关注我的公众号"程序员想退休"和我的 个人站,获取更多分享。