中文: README_ZH.md
This project is a “web adapter” for NativeScript‑Vue‑Vite. It can transform native app code into a pure Vue Web project that runs in the browser (generated under platforms/web/).
npm install nativescript-web-adapterCompile the web template – install dependencies – start the web project's dev server:
vue
npx ns-web vuenuxt
npx ns-web nuxtiOS
ns run iosAndroid
ns run android- Background & Goals
- Tech Stack & Dependencies
- Native Side (NativeScript)
- Web Side (Generated Vue Project)
- Web Adapter (Generator & Package)
- Run & Build
- Transformation & Adaptation Rules (Detailed)
- Styles & Tailwind Configuration
- Types & TS Configuration
- HMR (Hot Module Replacement)
- FAQ & Limitations
- Improvements & Upgrade Suggestions
- Provide a native app example using
nativescript-vue+@nativescript/vite, showcasing development and HMR on iOS/Android. - Provide a “web adapter” (local package
nativescript-web-adapter) that scans and transforms the project'ssrc/code to generate a Vue application that runs in the browser, enabling quick preview and collaboration on desktop browsers. - The generated Web project lives in
platforms/web/with its own Vite config, dependencies, and entry files, without affecting the native side.
- Native side (NativeScript):
nativescript-vue@3.0.1(usespatch-packageto inject HMR helpers)@nativescript/core@alpha,@nativescript/vite@^0.0.1-alpha.7(NativeScript v9 prerelease)- Example native plugins:
@triniwiz/nativescript-image-cache-it,@valor/nativescript-websockets,nativescript-inappbrowser
- Web side (generated project):
vue@^3.4,vue-router@^4.2vite@^5,@vitejs/plugin-vue@^5tailwindcss@^3.4,postcss,autoprefixer
- Adapter package (local):
nativescript-web-adapter/uses Vite library mode to build UMD/ESM, with built-in generator scripts and a simple CLI.
- Entry
src/app.ts:- Starts the native app via
createApp(Home).start()fromnativescript-vue. - Registers the native element
ImageCacheIt. - On Android, uses
Application.on(Application.launchEvent)to adjust system status/navigation bar styles.
- Starts the native app via
- Page
src/components/Home.vue:- Uses NS layouts and components such as
Frame/Page/ActionBar/GridLayout/Label/Button/ImageCacheIt. - Uses
@tapto open native links (iOS usesUIApplication.openURL, Android usesIntent). - Maintains a simple counter in
mounted/unmountedto demonstrate HMR and state refresh.
- Uses NS layouts and components such as
- Global init
src/globals.ts:- Defines touch animations (iOS:
UIView.animate, Android:View.animate), replaced by a no‑op shim on the Web side.
- Defines touch animations (iOS:
- Native Vite config
vite.config.ts:export default defineConfig(({ mode }) => mergeConfig(vueConfig({ mode }), {}))merges the NS official Vite template to support HMR and build.
- Tailwind & styles:
src/app.cssdefines theme colors and gradient classes (gradient-purple/gradient-light-purple), and sets theActionBarprimary color.tailwind.config.jsusesdarkMode: ["class", ".ns-dark"]and disablespreflight(matching native rendering).
- Output location:
platforms/web/ - Example structure:
platforms/web/
package.json # generated (includes vue + vue-router)
vite.config.ts # generated (server.port = 3005, strictPort = true)
index.html
postcss.config.js
tailwind.config.js
src/
App.vue # root component (<router-view />)
app.ts # entry (register adapter web components, mount '#app')
router/index.ts # default route (Home)
globals.ts # web shim: initGlobals() no-op
components/
Home.vue # copied and transformed from native
websfc/ # adapter web components (ActionBar/Page/Frame)
composables/
websfc/ # adapter composables (useActionBar/usePage/useFrame)
- Default dev URL:
http://localhost:3005/(if the port is taken, it fails directly; setstrictPorttofalseinvite.config.tsto enable fallback).
- Location:
nativescript-web-adapter/ - Key files:
tools/create-web-platform.cjs: generation script (copy, transform, write templates).core/components/*.vue: web SFC containers (ActionBar/Page/Frame).core/composables/*.ts: composables (useActionBar/usePage/useFrame).core/types.ts: component type aliases and composable type exports.index.ts: adapter installer (install(app)registers components and attaches$ns).vite.config.ts: library mode build (external: ['vue'], outputs UMD/ESM).
- CLI:
tools/cli.cjs- Local command:
node nativescript-web-adapter/tools/cli.cjs init - Includes a
create:webNPM script (for the root project to call).
- Local command:
- Native side (with HMR):
npm run dev:ios: run Vite (port5173) and NS iOS debug in parallel.npm run dev:android: run Vite and NS Android debug in parallel.npm run ios/npm run android: usens debugfor debugging builds.
- Generate and run the Web project:
npm run dev:web: run the adapter generator, then enterplatforms/web, install deps, and start the Web Vite dev server.- On first run, it creates
platforms/webalong with required templates and configuration.
The generator’s transformContent() currently performs only necessary code‑level replacements and no longer replaces NS tags in SFC templates with native HTML tags; the UI is handled by custom web components.
- Import replacements and removals:
from 'nativescript-vue'→from 'vue'- Remove
import ... from '@nativescript/core'(the web build does not load the native runtime) - Remove
import ... from '@nativescript/web-adapter'(the generated web project uses local components directly)
- Platform declarations and native calls cleanup:
- Remove common native declarations (e.g.,
declare var com;). - Remove
Application.on(...)and similar platform event registrations (including those with__ANDROID__orApplication.launchEvent).
- Remove common native declarations (e.g.,
- Template retains NS tags:
- Components kept and registered on the Web:
ActionBar/Page/Frame/StackLayout/GridLayout/FlexboxLayout/WrapLayout/ScrollView/Label/Button/Image/HtmlView/ImageCacheIt. - Special downgrade:
ImageCacheItis implemented as a simple<img>on the Web (also provided as a web component of the same name for consistent usage).
- Components kept and registered on the Web:
- Unified native link opening logic:
- Replace the example
enterNow(...)with the browser implementation:window.open('https://viteconf.amsterdam', '_blank').
- Replace the example
- Other cleanup:
- Remove lines involving
android.*,UIApplication,NSURL,NSDictionary,intent, etc. - Remove leftover
else { ... }native branch blocks. - Comment out
registerElement(...)(not needed on the Web).
- Remove lines involving
- Special file handling:
- Replace
globals.tswith a no‑op shim:export function initGlobals() { /* web shim: no-op */ }.
- Replace
Tip: The current transformation is regex‑driven and covers common patterns. For complex conditional branches, dynamic templates, and advanced native APIs, consider moving to TypeScript/Vue SFC AST‑based transformations to improve accuracy and maintainability.
- Native side:
src/app.cssuses@tailwind base/components/utilitiesand defines theme styles and gradient backgrounds.tailwind.config.js:content: ["./src/**/*.{css,vue,ts,tsx}"]darkMode: ["class", ".ns-dark"]corePlugins.preflight: false(disables browser preset resets)
- Web side (generated):
tailwind.config.jsscans./index.htmland./src/**/*.{vue,js,ts,jsx,tsx}and uses standard browser presets.postcss.config.js: enablestailwindcssandautoprefixer.
- Root
tsconfig.json:strict: true, target and module set toesnext.- Path aliases:
~/*,@/*→src/*. vueCompilerOptions.lib = "nativescript-vue"instructs SFC compilation for the NS environment.
- Type declarations:
- Native side
types/shims.vue.d.ts: points*.vuetypes tonativescript-vue’sDefineComponent. - Adapter side
core/env.d.ts: points*.vuetypes tovue’sDefineComponent, consistent with browser compilation.
- Native side
- Adapter
core/types.ts: provides type aliases forActionBar/Page/Framecomponents and exports state types foruseActionBar/usePage/useFrame.
- Native side:
- Uses
@nativescript/vitewithvite serve -- --env.hmrto establish an HMR channel, pushing changes to the device. patches/nativescript-vue+3.0.1.patchinjects withinapp.start:globalThis.__NS_VUE_APP__ = app, helping restore state in deep navigation stacks (e.g., when returning during HMR).
- Uses
- Web side:
- Independent Vite (
platforms/web/vite.config.ts) runs on port3005, using standard Vue HMR and route refresh.
- Independent Vite (
- Native APIs & plugins:
- Complex native interactions (platform‑specific modules, system services) cannot be automatically converted to the Web. They require manual replacement or browser fallback implementations (e.g.,
InAppBrowser→window.openwrapper).
- Complex native interactions (platform‑specific modules, system services) cannot be automatically converted to the Web. They require manual replacement or browser fallback implementations (e.g.,
- Layout & semantic mapping is limited:
- Basic web components are provided (
ActionBar/Page/Frame/Grid/Stack/Flex/Wrap/Scroll/Label/Button/Image/HtmlView/ImageCacheIt). More detailed property‑to‑style mappings will be added later (e.g.,flexDirection/row, grid rows/columns).
- Basic web components are provided (
- Regex‑driven transformation:
- Edge cases may exist for complex code and templates. Gradually moving to AST‑level transformation is recommended.
- Generator template duplicate writes:
- The generator currently writes
platforms/web/package.jsontwice (with different dependency versions). This can be streamlined into a single write to reduce maintenance cost.
- The generator currently writes
- Transformation engine upgrade:
- Replace regex with TypeScript and Vue SFC AST to precisely handle imports, calls, templates, and directive mappings.
- Global initialization & animations:
- Provide optional web animation implementations (CSS transitions/GSAP) for
globals.tsto keep interaction behavior consistent.
- Provide optional web animation implementations (CSS transitions/GSAP) for
- Tests & validation:
- Add unit tests and e2e tests for transformation rules and template generation to ensure stability across different project structures.