feat: support nvue pages - #41
Conversation
📝 WalkthroughWalkthroughThe plugin now resolves ChangesNVUE page support
Estimated code review effort: 3 (Moderate) | ~25 minutes Sequence Diagram(s)sequenceDiagram
participant PagesJson
participant loadPagePaths
participant VitePlugin
participant transformNvuePage
participant NVUEPage
PagesJson->>loadPagePaths: page entries
loadPagePaths->>VitePlugin: resolved NVUE paths
VitePlugin->>transformNvuePage: matched NVUE module and root path
transformNvuePage->>NVUEPage: wrapped template and rewritten script
Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@test/transform.test.ts`:
- Around line 93-125: The test case in “pages.json loading” must verify that
nonexistent extensionless pages are excluded. Keep the “pages/about” entry in
pages.json, but update the expected pages list to omit it and explicitly assert
that neither pages/about.vue nor pages/about.nvue is returned, while preserving
the existing expectations for files that exist.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 4d4e374b-df7f-4f3a-90c8-b7bb62899762
📒 Files selected for processing (5)
README.mdsrc/index.tssrc/page.tssrc/utils.tstest/transform.test.ts
| describe('pages.json loading', () => { | ||
| it('matches existing vue and nvue files for extensionless page paths', () => { | ||
| const rootPath = createTempRoot() | ||
| mkdirSync(join(rootPath, 'pages'), { recursive: true }) | ||
| mkdirSync(join(rootPath, 'pkg', 'sub'), { recursive: true }) | ||
| writeFileSync(join(rootPath, 'pages', 'index.vue'), '') | ||
| writeFileSync(join(rootPath, 'pages', 'index.nvue'), '') | ||
| writeFileSync(join(rootPath, 'pkg', 'sub', 'profile.nvue'), '') | ||
| writeFileSync(join(rootPath, 'pages.json'), `{ | ||
| "pages": [ | ||
| { "path": "pages/index" }, | ||
| { "path": "pages/about" } | ||
| ], | ||
| "subPackages": [ | ||
| { | ||
| "root": "pkg", | ||
| "pages": [ | ||
| { "path": "sub/profile" } | ||
| ] | ||
| } | ||
| ] | ||
| }`) | ||
|
|
||
| const pages = loadPagesJson(join(rootPath, 'pages.json'), rootPath) | ||
|
|
||
| expect(pages).toEqual([ | ||
| normalizePath(join(rootPath, 'pages', 'index.vue')), | ||
| normalizePath(join(rootPath, 'pages', 'index.nvue')), | ||
| normalizePath(join(rootPath, 'pages', 'about.vue')), | ||
| normalizePath(join(rootPath, 'pkg', 'sub', 'profile.nvue')), | ||
| ]) | ||
| }) | ||
| }) |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Do not expect a nonexistent page file.
The fixture creates neither pages/about.vue nor pages/about.nvue, yet the assertion expects pages/about.vue. This contradicts the requirement to match only existing extensions and would either fail against the correct implementation or hide a discovery bug. Keep pages/about in the fixture and assert that neither concrete path is returned.
Proposed test correction
expect(pages).toEqual([
normalizePath(join(rootPath, 'pages', 'index.vue')),
normalizePath(join(rootPath, 'pages', 'index.nvue')),
- normalizePath(join(rootPath, 'pages', 'about.vue')),
normalizePath(join(rootPath, 'pkg', 'sub', 'profile.nvue')),
])
+ expect(pages).not.toContain(normalizePath(join(rootPath, 'pages', 'about.vue')))
+ expect(pages).not.toContain(normalizePath(join(rootPath, 'pages', 'about.nvue')))📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| describe('pages.json loading', () => { | |
| it('matches existing vue and nvue files for extensionless page paths', () => { | |
| const rootPath = createTempRoot() | |
| mkdirSync(join(rootPath, 'pages'), { recursive: true }) | |
| mkdirSync(join(rootPath, 'pkg', 'sub'), { recursive: true }) | |
| writeFileSync(join(rootPath, 'pages', 'index.vue'), '') | |
| writeFileSync(join(rootPath, 'pages', 'index.nvue'), '') | |
| writeFileSync(join(rootPath, 'pkg', 'sub', 'profile.nvue'), '') | |
| writeFileSync(join(rootPath, 'pages.json'), `{ | |
| "pages": [ | |
| { "path": "pages/index" }, | |
| { "path": "pages/about" } | |
| ], | |
| "subPackages": [ | |
| { | |
| "root": "pkg", | |
| "pages": [ | |
| { "path": "sub/profile" } | |
| ] | |
| } | |
| ] | |
| }`) | |
| const pages = loadPagesJson(join(rootPath, 'pages.json'), rootPath) | |
| expect(pages).toEqual([ | |
| normalizePath(join(rootPath, 'pages', 'index.vue')), | |
| normalizePath(join(rootPath, 'pages', 'index.nvue')), | |
| normalizePath(join(rootPath, 'pages', 'about.vue')), | |
| normalizePath(join(rootPath, 'pkg', 'sub', 'profile.nvue')), | |
| ]) | |
| }) | |
| }) | |
| describe('pages.json loading', () => { | |
| it('matches existing vue and nvue files for extensionless page paths', () => { | |
| const rootPath = createTempRoot() | |
| mkdirSync(join(rootPath, 'pages'), { recursive: true }) | |
| mkdirSync(join(rootPath, 'pkg', 'sub'), { recursive: true }) | |
| writeFileSync(join(rootPath, 'pages', 'index.vue'), '') | |
| writeFileSync(join(rootPath, 'pages', 'index.nvue'), '') | |
| writeFileSync(join(rootPath, 'pkg', 'sub', 'profile.nvue'), '') | |
| writeFileSync(join(rootPath, 'pages.json'), `{ | |
| "pages": [ | |
| { "path": "pages/index" }, | |
| { "path": "pages/about" } | |
| ], | |
| "subPackages": [ | |
| { | |
| "root": "pkg", | |
| "pages": [ | |
| { "path": "sub/profile" } | |
| ] | |
| } | |
| ] | |
| }`) | |
| const pages = loadPagesJson(join(rootPath, 'pages.json'), rootPath) | |
| expect(pages).toEqual([ | |
| normalizePath(join(rootPath, 'pages', 'index.vue')), | |
| normalizePath(join(rootPath, 'pages', 'index.nvue')), | |
| normalizePath(join(rootPath, 'pkg', 'sub', 'profile.nvue')), | |
| ]) | |
| expect(pages).not.toContain(normalizePath(join(rootPath, 'pages', 'about.vue'))) | |
| expect(pages).not.toContain(normalizePath(join(rootPath, 'pages', 'about.nvue'))) | |
| }) | |
| }) |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@test/transform.test.ts` around lines 93 - 125, The test case in “pages.json
loading” must verify that nonexistent extensionless pages are excluded. Keep the
“pages/about” entry in pages.json, but update the expected pages list to omit it
and explicitly assert that neither pages/about.vue nor pages/about.nvue is
returned, while preserving the existing expectations for files that exist.
将 loadPagesJson 重命名为 loadPagePaths,抽出 getRelativePath,并简化插件内页面过滤与转换入口。
统一使用 uni-app 的 view 标签,避免在 App/nvue 场景下使用不兼容的 div。
新增 uni-app-plus / uni-app-vite 依赖,并提供 dev:app、build:app 脚本便于本地验证 nvue。
新增 setup 与 Options API 两套 nvue 示例页,并在首页加入跳转入口。
基于示例工程验证 nvue 页面路径解析与 GlobalKuRoot 本地注入,并补充 example:verify:nvue 脚本。
去掉与功能清单重复的 nvue 展开段落,并清理过时 roadmap 项。
cb4f53e to
9916d41
Compare
|
thank you ❤ |
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@examples/src/components/GlobalToast.vue`:
- Around line 16-21: Update the .toast-wrapper styles in GlobalToast so the NVUE
overlay fills the page without using percentage width or height; replace those
percentage dimensions with NVUE-supported anchor offsets or dimensions while
preserving its fixed, top-left positioning.
In `@src/index.ts`:
- Around line 73-74: The page-path cache updated by loadPagePaths must also
refresh when listed .vue or .nvue files are added, removed, or renamed during
development, not only when pages.json changes. Extend the relevant watcher or
handleHotUpdate flow in src/index.ts to detect those page-file updates,
recompute pagePaths with loadPagePaths, and add coverage for a newly added .nvue
page being transformed without touching pages.json.
- Around line 92-96: Update normalizePlatformPath to apply the same
platform-suffix normalization used for .vue files to .nvue files, converting IDs
such as pages/foo.app.nvue to pages/foo.nvue. Preserve existing behavior for
.vue paths and ensure filterPage receives the normalized NVUE ID so
transformNvuePage is not skipped.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 127670e2-768f-4e68-bab6-23aad3299285
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (15)
README.mdexamples/package.jsonexamples/src/KuRoot.vueexamples/src/components/GlobalToast.vueexamples/src/layouts/default.vueexamples/src/pages.jsonexamples/src/pages/index.vueexamples/src/pages/nvue-demo.nvueexamples/src/pages/nvue-options.nvuepackage.jsonsrc/index.tssrc/page.tssrc/utils.tstest/examples-nvue.test.tstest/transform.test.ts
🚧 Files skipped from review as they are similar to previous changes (3)
- src/utils.ts
- src/page.ts
- test/transform.test.ts
| .toast-wrapper{ | ||
| position: fixed; | ||
| top: 0; | ||
| left: 0; | ||
| width: 100%; | ||
| height: 100%; |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf 'Files of interest:\n'
git ls-files | rg '(^|/)GlobalTo(ast)?\.vue$|KuRoot\.vue$|nvue|package\.json$|manifest\.json$' || true
printf '\nGlobalToast.vue excerpt:\n'
if [ -f examples/src/components/GlobalToast.vue ]; then
nl -ba examples/src/components/GlobalToast.vue | sed -n '1,120p'
fi
printf '\nKuRoot.vue excerpt around GlobalToast import/use:\n'
if [ -f examples/src/KuRoot.vue ]; then
nl -ba examples/src/KuRoot.vue | sed -n '1,160p'
fi
printf '\nSearch for GlobalToast usage/import:\n'
rg -n "GlobalToast|toast" examples/src -S || true
printf '\nPackage/uniplatform hints:\n'
for f in package.json examples/package.json manifest.json examples/manifest.json; do
if [ -f "$f" ]; then
echo "--- $f"
sed -n '1,220p' "$f"
fi
doneRepository: uni-ku/root
Length of output: 458
🌐 Web query:
uniapp NVUE CSS width: 100% height: 100% unsupported percentage layout
💡 Result:
In uni-app, nvue pages render using native components rather than a webview, which imposes specific limitations on CSS [1][2][3]. Percentage-based layout, such as width: 100% or height: 100%, is not supported in nvue [4][5][6][1]. This is because the underlying native layout engine only supports Flexbox [4][6], and percentage values are not valid units in this native environment [5][7]. To achieve full-width or full-height layouts in nvue, you should use the following alternatives: For full width: Use width: 750rpx [5][7]. In uni-app, 750rpx is defined as the total width of the screen [5]. For full height: Use flex: 1 on the container [5][7]. This instructs the element to occupy the available remaining space within its parent, effectively filling the container's height when the parent is also set up correctly or occupies the screen [5]. Summary of constraints: 1. Percentage units (%, vh, vw, rem) are not supported [5][7][1]. 2. CSS layout must be based on Flexbox [4][6]. 3. Only px (absolute pixels) and rpx (relative pixels) are supported for length units [5][1]. If you need to set a container to be full-screen, ensure that all parent elements also have their height managed (e.g., using flex: 1) to ensure the layout propagates correctly to the bottom of the screen [5].
Citations:
- 1: https://uniapp.dcloud.net.cn/tutorial/syntax-css.html
- 2: https://en.uniapp.dcloud.io/tutorial/syntax-css.html
- 3: https://uniapp.dcloud.io/tutorial/syntax-css
- 4: https://en.uniapp.dcloud.io/nvue-css.html
- 5: https://juejin.cn/post/7181695650583543865
- 6: https://uniapp.dcloud.io/tutorial/nvue-css
- 7: https://www.codeleading.com/article/77255925760/
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf 'GlobalToast.vue excerpt:\n'
awk '{printf "%4d: %s\n", NR, $0}' examples/src/components/GlobalToast.vue | sed -n '1,160p'
printf '\nKuRoot.vue excerpt around GlobalToast import/use:\n'
awk '{printf "%4d: %s\n", NR, $0}' examples/src/KuRoot.vue | sed -n '1,220p'
printf '\nSearch for GlobalToast usage/import:\n'
rg -n "GlobalToast|<GlobalToast|toast-wrapper|toast" examples/src -S || true
printf '\nnvue platform files summary:\n'
for f in examples/src/manifest.json examples/src/pages/nvue-demo.nvue examples/src/pages/nvue-options.nvue test/examples-nvue.test.ts; do
if [ -f "$f" ]; then
echo "--- $f"
awk '{printf "%4d: %s\n", NR, $0}' "$f" | sed -n '1,220p'
fi
doneRepository: uni-ku/root
Length of output: 9233
Avoid percentage dimensions in the NVUE toast overlay.
NVUE does not support percentage layout units, so width: 100% / height: 100% on the shared GlobalToast wrapper may not cover the page reliably. Use anchor offsets or NVUE-supported dimensions here.
Proposed fix
.toast-wrapper{
position: fixed;
top: 0;
left: 0;
- width: 100%;
- height: 100%;
+ right: 0;
+ bottom: 0;
background-color: rgba(0, 0, 0, 0.5);📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| .toast-wrapper{ | |
| position: fixed; | |
| top: 0; | |
| left: 0; | |
| width: 100%; | |
| height: 100%; | |
| .toast-wrapper{ | |
| position: fixed; | |
| top: 0; | |
| left: 0; | |
| right: 0; | |
| bottom: 0; |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@examples/src/components/GlobalToast.vue` around lines 16 - 21, Update the
.toast-wrapper styles in GlobalToast so the NVUE overlay fills the page without
using percentage width or height; replace those percentage dimensions with
NVUE-supported anchor offsets or dimensions while preserving its fixed, top-left
positioning.
Source: MCP tools
| pagePaths = loadPagePaths(pagesPath, rootPath) | ||
| } |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Refresh resolved page paths when page files change.
loadPagePaths probes the filesystem for .vue/.nvue files, but this watcher reloads only when pages.json changes. Adding, removing, or renaming a listed page during dev can therefore leave pagePaths stale, so a newly added .nvue page is not transformed until pages.json is touched. Recompute on relevant page-file updates (for example via handleHotUpdate) and cover this case in tests.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/index.ts` around lines 73 - 74, The page-path cache updated by
loadPagePaths must also refresh when listed .vue or .nvue files are added,
removed, or renamed during development, not only when pages.json changes. Extend
the relevant watcher or handleHotUpdate flow in src/index.ts to detect those
page-file updates, recompute pagePaths with loadPagePaths, and add coverage for
a newly added .nvue page being transformed without touching pages.json.
| const filterPage = createFilter(pagePaths, excludedPaths) | ||
| if (filterPage(pageId)) { | ||
| ms = await transformPage(code, options.enabledGlobalRef) | ||
| ms = id.endsWith('.nvue') | ||
| ? await transformNvuePage(code, getRelativePath(id, appKuPath), options.enabledGlobalRef) | ||
| : await transformPage(code, options.enabledGlobalRef) |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
rg -n -A12 -B3 '\bnormalizePlatformPath\b' src/utils.ts src/index.ts || true
rg -n 'app\.nvue|\.app\.nvue|platform.*nvue|nvue.*platform' src test examples || trueRepository: uni-ku/root
Length of output: 2161
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
printf 'List relevant source files:\n'
fd -a 'index.ts|utils.ts|page.ts' . | sed 's#^\./##'
printf '\nsrc/utils.ts outline:\n'
ast-grep outline src/utils.ts || true
printf '\nsrc/utils.ts relevant section:\n'
sed -n '1,220p' src/utils.ts | cat -n
printf '\nsrc/index.ts relevant section:\n'
sed -n '1,130p' src/index.ts | cat -n
printf '\nSearch page filter/pagePaths logic:\n'
rg -n -A20 -B10 'createFilter|pagePaths|excludedPaths|loadPagePaths' src package.json || trueRepository: uni-ku/root
Length of output: 16066
🌐 Web query:
vite-plugin-uni-platform platform-specific files convention .<platform>. extname .nvue
💡 Result:
In the context of uni-app and the vite-plugin-uni-platform, platform-specific file handling and the.nvue extension serve distinct but complementary purposes. 1. Platform-Specific Files Convention The @uni-helper/vite-plugin-uni-platform plugin enables a file-naming convention that allows you to provide platform-specific implementations for any file (e.g.,.ts,.js,.css,.vue) without using conditional compilation comments [1][2]. By adding a platform suffix to the filename, the plugin automatically resolves the correct file based on the target platform during the build process [2][3]. Convention: filename..extension [2] Example: - request.ts (Default/Fallback) [2] - request.h5.ts (H5-specific) [2] - request.mp-weixin.ts (WeChat Mini Program-specific) [2] When you import the file, you omit the platform suffix (e.g., import { request } from './request'), and the plugin resolves it to the matching platform file [2][3]. 2..nvue Extension The.nvue (Native Vue) extension is a core uni-app feature, not a plugin-specific convention. It is used exclusively on the App platform to signal that the page should be rendered using the native rendering engine rather than the standard webview-based rendering used for.vue files [4][5]. Key points regarding.nvue: - Behavior: On the App side, if both a.vue and an.nvue file exist with the same name, the.nvue file takes precedence [5][6]. On non-App platforms, the.vue file is preferred, and the.nvue file is typically ignored [5][7]. - Purpose: It provides better performance for complex pages by utilizing native components [5][7]. - Integration: While the vite-plugin-uni-platform manages file-based platform differentiation,.nvue files are handled by the uni-app compiler itself to dictate the rendering engine on mobile apps [4][5]. Summary You can combine these concepts: if you need a native-rendered page that is only included in a specific build, you could theoretically use platform-specific naming (e.g., page.h5.vue) or handle it via uni-app's native rendering rules [4][6]. However, the plugin convention is primarily for code-level modularity (utils, components), while.nvue is for mobile-native UI rendering [2][5].
Citations:
- 1: https://github.com/uni-helper/vite-plugin-uni-platform
- 2: https://github.com/uni-helper/skills/blob/main/skills/uni-helper/references/plugin-platform.md
- 3: 支持自定义编译平台 uni-helper/vite-plugin-uni-platform#4
- 4: https://en.uniapp.dcloud.io/tutorial/page.html
- 5: https://en.uniapp.dcloud.io/tutorial/nvue-outline.html
- 6: https://uniapp.dcloud.io/tutorial/nvue-outline
- 7: https://en.uniapp.dcloud.io/nvue-outline.html
🌐 Web query:
site:github.com uni-helper/vite-plugin-uni-platform isPlatformSpecificFilename normalizedPlatformSpecificFilename extname nvue
💡 Result:
The uni-helper/vite-plugin-uni-platform plugin provides file-based platform compilation for uni-app, allowing developers to use platform-specific file extensions (e.g.,.h5.ts,.mp-weixin.ts) to manage platform-specific implementations without manual conditional compilation [1][2]. Regarding the specific internal utilities and concepts mentioned: isPlatformSpecificFilename and normalizedPlatformSpecificFilename These are internal functions (or naming conventions for them) within the plugin's resolution logic [3]. The plugin uses a resolveId hook that identifies files by checking their suffixes against the current build platform [3]. When a developer imports a file without a suffix (e.g., import { request } from './utils/request'), the plugin uses internal resolution logic to match and resolve the import to the correct platform-specific file (e.g.,./utils/request.mp-weixin.ts) if it exists [2][3]. extname and nvue The plugin handles file extensions by looking for platform suffixes before the standard extension [1][2]. While nvue files (a Uni-app specific format for native rendering) are part of the broader uni-app ecosystem, issues regarding nvue and page routing often arise when using this plugin in combination with @uni-helper/vite-plugin-uni-pages [4]. Specifically, creating a.nvue file with the same name as a.vue file can sometimes lead to conflicts in the auto-generated pages.json if the pages are not filtered correctly [4]. To resolve such conflicts, developers often need to configure exclusion patterns in the uni-pages configuration (e.g., exclude: ['/*.nvue']) [4]. In summary, the plugin operates by intercepting imports and file paths to replace generic file references with platform-suffixed versions during the compilation process [1][5]. Users should ensure that when using this alongside auto-routing plugins, they correctly manage platform filtering and file extensions to avoid compilation or routing conflicts [6][5][4].
Citations:
- 1: https://github.com/uni-helper/vite-plugin-uni-platform
- 2: https://github.com/uni-helper/skills/blob/main/skills/uni-helper/references/plugin-platform.md
- 3: 支持自定义编译平台 uni-helper/vite-plugin-uni-platform#4
- 4: 创建同名.nvue文件后,page.json会生成两个一样的page,导致冲突 uni-helper/vite-plugin-uni-pages#174
- 5: https://github.com/FliPPeDround/vite-plugin-uni-platform
- 6: 支持
name.[platform].vue页面 uni-helper/vite-plugin-uni-pages#77
🌐 Web query:
github.com uni-helper vite-plugin-uni-platform "resolve platform specific" "nvue"
💡 Result:
The @uni-helper/vite-plugin-uni-platform plugin is designed to enable file-based platform-specific compilation in uni-app projects by allowing developers to use platform suffixes in filenames (e.g., file.h5.ts, file.mp-weixin.ts) [1][2][3]. When an import occurs without the platform suffix (e.g., import { data } from './utils/file'), the plugin automatically resolves the import to the appropriate platform-specific file based on the current build target [2][3]. Regarding nvue and platform-specific resolution: 1. Mechanism: The plugin relies on Vite's resolveId and load hooks to intercept module resolution [4]. It checks for the existence of platform-specific files and swaps them into the build process based on the current environment [4]. This mechanism is generally file-type agnostic and operates at the module resolution level, meaning it can be applied to files that are eventually processed by the uni-app compiler, including those used in nvue contexts, provided they follow standard module resolution patterns [2][4]. 2. Limitations with nvue: While the plugin handles file resolution, nvue (uni-app's native rendering engine) has strict requirements regarding supported components and rendering environments. If an nvue component or file structure is specifically being targeted, you must ensure that your platform-specific files (e.g., file.app.nvue or file.app.vue) comply with the restrictions of the native nvue environment, as the plugin merely manages which file is selected, not the content's validity within that environment [2][4]. 3. Recent Updates: Support for custom platforms has been introduced, allowing for more flexible configurations beyond standard uni-app platform names [5][6]. If you are using specific platform variants, ensure you are on a recent version of the plugin that supports these definitions [6][7]. For template-level platform-specific logic, consider using @uni-helper/vite-plugin-uni-platform-modifier, which provides platform modifiers for attributes and directives (e.g., v-if.h5) to achieve conditional compilation without needing entirely separate files [8][9].
Citations:
- 1: https://registry.npmjs.org/%40uni-helper%2Fvite-plugin-uni-platform
- 2: https://github.com/uni-helper/skills/blob/main/skills/uni-helper/references/plugin-platform.md
- 3: https://uni-helper.js.org/vite-plugin-uni-platform/
- 4: https://juejin.cn/post/7269652047111749667
- 5: 支持自定义编译平台 uni-helper/vite-plugin-uni-platform#4
- 6: uni-helper/vite-plugin-uni-platform@64eb2d2
- 7: uni-helper/vite-plugin-uni-platform@v0.0.5...v0.1.2
- 8: https://github.com/uni-helper/skills/blob/main/skills/uni-helper/references/plugin-platform-modifier.md
- 9: https://github.com/uni-helper/vite-plugin-uni-platform-modifier
Normalize .nvue platform-specific IDs in normalizePlatformPath.
normalizePlatformPath only handles .vue files, so platform-qualified NVUE pages like pages/foo.app.nvue are not normalized to pages/foo.nvue; with pagePaths containing pages/foo.nvue, filterPage(pageId) misses the file and the NVUE transform is skipped. Include .nvue pages in the normalization logic.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/index.ts` around lines 92 - 96, Update normalizePlatformPath to apply the
same platform-suffix normalization used for .vue files to .nvue files,
converting IDs such as pages/foo.app.nvue to pages/foo.nvue. Preserve existing
behavior for .vue paths and ensure filterPage receives the normalized NVUE ID so
transformNvuePage is not skipped.
变更说明
pages.json识别并转换.nvue页面,未写扩展名时会同时匹配已存在的.vue与.nvue文件App.ku.vue,避免依赖 nvue 不支持的全局组件注册PageMeta提取、局部/全局 root ref 行为,并跳过 SFC 子块二次转换验证
pnpm exec vitest runpnpm buildpnpm exec eslint .Summary by CodeRabbit
pages.json, including extensionless entries and mixed.vue/.nvuefiles within subpackages.