Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

feat: Vue Devtools support#1060

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
rigor789 merged 6 commits intonativescript-vue:mainfromheywhy:vue-devtools-support
Sep 10, 2023
Merged
Show file tree
Hide file tree
Changes fromall commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 8 additions & 7 deletionsdemo/App_Resources/Android/src/main/AndroidManifest.xml
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -6,19 +6,20 @@
android:smallScreens="true"
android:normalScreens="true"
android:largeScreens="true"
android:xlargeScreens="true"/>
android:xlargeScreens="true"/>

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

<application
android:name="com.tns.NativeScriptApplication"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme"
android:usesCleartextTraffic="true"
android:hardwareAccelerated="true">

<activity
Expand All@@ -27,7 +28,7 @@
android:configChanges="keyboard|keyboardHidden|orientation|screenSize|smallestScreenSize|screenLayout|locale|uiMode"
android:theme="@style/LaunchScreenTheme"
android:hardwareAccelerated="true"
android:launchMode="singleTask"
android:launchMode="singleTask"
android:exported="true">

<meta-data android:name="SET_THEME_ON_LAUNCH" android:resource="@style/AppTheme" />
Expand All@@ -37,6 +38,6 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="com.tns.ErrorReportActivity"/>
<activity android:name="com.tns.ErrorReportActivity"/>
</application>
</manifest>
2 changes: 1 addition & 1 deletiondemo/package.json
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -14,6 +14,6 @@
"@nativescript/ios": "~8.5.2",
"@nativescript/types": "~8.5.0",
"@nativescript/webpack": "~5.0.14",
"typescript": "~5.1.3"
"typescript": "^5.2.2"
}
}
2 changes: 0 additions & 2 deletionsdemo/tsconfig.json
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -14,8 +14,6 @@
"@/*": ["src/*"],
"nativescript-vue": ["../src/index.ts"]
},
"typeRoots": ["types"],
"types": ["node"],
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"experimentalDecorators": true,
Expand Down
33 changes: 33 additions & 0 deletionsdevtools.js
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
if (__DEV__) {
try {
const _global = globalThis.global;

const host = (_global.__VUE_DEVTOOLS_HOST__ ??= __NS_VUE_DEVTOOLS_HOST__);
const port = (_global.__VUE_DEVTOOLS_PORT__ ??= __NS_VUE_DEVTOOLS_PORT__);
_global.__VUE_DEVTOOLS_TOAST__ ??= (message) => {
console.warn('[VueDevtools]', message);
};

const platform = global.isAndroid ? 'Android' : 'iOS';

const documentShim = {
// this shows as the title in VueDevtools
title: `${platform} :: ${host}:${port} :: NativeScript`,
querySelector: () => null,
querySelectorAll: () => [],
};

_global.document = Object.assign({}, documentShim, _global.document);
_global.addEventListener ??= () => {};
_global.removeEventListener ??= () => {};
_global.window ??= _global;

console.warn(
`[VueDevtools] Connecting to ${global.__VUE_DEVTOOLS_HOST__}:${global.__VUE_DEVTOOLS_PORT__}...`
);
require('@vue/devtools/build/hook.js');
require('@vue/devtools/build/backend.js');
} catch (e) {
console.warn('[VueDevtools] Failed to init:', e);
}
}
100 changes: 98 additions & 2 deletionsnativescript.webpack.js
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,108 @@
const { VueLoaderPlugin } = require('vue-loader');
const spawn = require('cross-spawn');

function findFreePort(startingPort = 8098) {
let found = false;
let port = startingPort;

const isPortFree = (port) =>
new Promise((resolve) => {
const server = require('http')
.createServer()
.listen(port, '0.0.0.0', () => {
server.close();
resolve(true);
})
.on('error', () => {
resolve(false);
});
});

const findFreePort = () => {
isPortFree(port).then((isFree) => {
if (!isFree) {
port++;
return findFreePort();
}
found = true;
});
};

findFreePort();

while (!found) {
process._tickCallback();
const start = Date.now();
while (Date.now() - start < 100) {
// busy wait... not ideal, but we need to find a port synchronously...
}
}

return port;
}

function startVueDevtools(port, isAndroid = false) {
console.log(`[VueDevtools] Starting standalone Vue Devtools on port ${port}`);
if (isAndroid) {
console.log(
`[VueDevtools] If the app doesn't automatically connect, check if http traffic is allowed. (e.g. on Android, you may need to set android:usesCleartextTraffic="true" in AndroidManifest.xml)`
);
}
spawn(require.resolve('@vue/devtools/bin.js'), [], {
stdio: 'ignore',
env: {
...process.env,
PORT: port,
},
});
}

/**
* @param {typeof import("@nativescript/webpack")} webpack
*/
module.exports = (webpack) => {
webpack.useConfig('vue');

webpack.chainWebpack((config) => {
webpack.chainWebpack((config, env) => {
const additionalDefines = {
__VUE_PROD_DEVTOOLS__: false,
};

// todo: support configuring the devtools host/port from the nativescript.config.ts...
if (!!env.vueDevtools) {
// find a free port for the devtools
const vueDevtoolsPort = findFreePort(8098);
const isAndroid = webpack.Utils.platform.getPlatformName() === 'android';

// on android simulators, localhost is not the host machine...
const vueDevtoolsHost = isAndroid
? 'http://10.0.2.2'
: 'http://localhost';

additionalDefines['__VUE_PROD_DEVTOOLS__'] = true;
additionalDefines['__NS_VUE_DEVTOOLS_HOST__'] =
JSON.stringify(vueDevtoolsHost);
additionalDefines['__NS_VUE_DEVTOOLS_PORT__'] = vueDevtoolsPort;

const devtoolsEntryPath = require.resolve('./devtools.js');
const entryPath = webpack.Utils.platform.getEntryPath();
const paths = config.entry('bundle').values();
const entryIndex = paths.indexOf(entryPath);

if (entryIndex === -1) {
// if the app entry is not found, add the devtools entry at the beginning - generally should not happen, but just in case.
paths.unshift(entryPath);
} else {
// insert devtools entry before the app entry, but after globals etc.
paths.splice(entryIndex, 0, devtoolsEntryPath);
}

config.entry('bundle').clear().merge(paths);

// start the devtools...
startVueDevtools(vueDevtoolsPort, isAndroid);
}

// resolve any imports from "vue" to "nativescript-vue"
config.resolve.alias.set('vue', 'nativescript-vue');

Expand DownExpand Up@@ -41,7 +137,7 @@ module.exports = (webpack) => {
config.plugin('DefinePlugin').tap((args) => {
Object.assign(args[0], {
__VUE_OPTIONS_API__: true,
__VUE_PROD_DEVTOOLS__: false,
...additionalDefines,
});

return args;
Expand Down
3 changes: 3 additions & 0 deletionspackage.json
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -4,6 +4,7 @@
"main": "dist/index.js",
"files": [
"dist/",
"devtools.js",
"nativescript.webpack.js"
],
"license": "MIT",
Expand All@@ -16,8 +17,10 @@
},
"dependencies": {
"@vue/compiler-sfc": "^3.3.4",
"@vue/devtools": "^6.5.0",
"@vue/runtime-core": "^3.3.4",
"@vue/shared": "^3.3.4",
"cross-spawn": "^7.0.3",
"set-value": "^4.1.0",
"vue-loader": "^17.2.2"
},
Expand Down
2 changes: 1 addition & 1 deletionpackages/stackblitz-template/package.json
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -14,7 +14,7 @@
"@nativescript/webpack": "~5.0.0",
"@types/node": "~17.0.21",
"tailwindcss": "^3.1.8",
"typescript": "~4.9.5"
"typescript": "^5.2.2"
},
"stackblitz": {
"installDependencies": true,
Expand Down
2 changes: 0 additions & 2 deletionspackages/stackblitz-template/tsconfig.json
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -13,8 +13,6 @@
"~/*": ["src/*"],
"@/*": ["src/*"]
},
"typeRoots": ["types"],
"types": ["node"],
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"experimentalDecorators": true,
Expand Down
2 changes: 1 addition & 1 deletionpackages/template-blank/package.json
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -12,6 +12,6 @@
"@nativescript/webpack": "~5.0.0",
"@types/node": "~17.0.21",
"tailwindcss": "^3.1.8",
"typescript": "~4.9.5"
"typescript": "^5.2.2"
}
}
2 changes: 0 additions & 2 deletionspackages/template-blank/tsconfig.json
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -13,8 +13,6 @@
"~/*": ["src/*"],
"@/*": ["src/*"]
},
"typeRoots": ["types"],
"types": ["node"],
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"experimentalDecorators": true,
Expand Down
1 change: 1 addition & 0 deletionssrc/components/ActionBar.ts
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -49,6 +49,7 @@ registerElement('NSCActionBar', () => NSCActionBar, {
});

export const ActionBar = /*#__PURE__*/ defineComponent({
name: 'ActionBar',
setup(props, ctx) {
return () => {
return h(
Expand Down
1 change: 1 addition & 0 deletionssrc/components/ListView.ts
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -41,6 +41,7 @@ function getListItem(item: any, index: number): ListItem {
const LIST_CELL_ID = Symbol('list_cell_id');

export const ListView = /*#__PURE__*/ defineComponent({
name: 'ListView',
props: {
items: {
validator(value) {
Expand Down
2 changes: 1 addition & 1 deletionsrc/dom/index.ts
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
import { markRaw } from"@vue/runtime-core";
import { markRaw } from'@vue/runtime-core';
import {
getViewClass,
getViewMeta,
Expand Down
4 changes: 2 additions & 2 deletionssrc/index.ts
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -16,7 +16,7 @@ import { renderer } from './renderer';
import { install as modalsPlugin } from './plugins/modals';
import { install as navigationPlugin } from './plugins/navigation';
import { isKnownView, registerElement } from './registry';
import {setRootContext } from './runtimeHelpers';
import {setRootApp } from './runtimeHelpers';

declare module '@vue/runtime-core' {
interface App {
Expand DownExpand Up@@ -89,7 +89,7 @@ export const createApp = ((...args) => {
const componentInstance = app.mount(createAppRoot(), false, false);

startApp(componentInstance);
setRootContext(componentInstance.$.appContext);
setRootApp(app);

return componentInstance;
};
Expand Down
40 changes: 21 additions & 19 deletionssrc/runtimeHelpers.ts
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
import { View } from '@nativescript/core';
import {
AppContext,
App,
Component,
h,
RendererElement,
RendererNode,
VNode,
Expand All@@ -14,51 +13,54 @@ type Props = Record<string, unknown>;

const __DEV__ = true;

letrootContext: AppContext = null;
letrootApp: App = null;

export constsetRootContext = (context: AppContext) => {
rootContext =context;
export constsetRootApp = (app: App) => {
rootApp =app;
};

export const createNativeView = <T = View>(
component: Component,
props?: Props,
contextOverrides?:any
contextOverrides?:{ reload?(): void }
) => {
let vnode: VNode;
let isMounted = false;
let container: NSVNode;
const newApp = renderer.createApp(component, props);
// Destructure so as not to copy over the root app instance
const { app, ...rootContext } = rootApp._context;
const context = { ...rootContext, ...contextOverrides };

type M = VNode<RendererNode, RendererElement, { nativeView: T }>;

return {
context,
get vnode() {
return newApp._instance?.vnode;
},
get nativeView(): T {
return vnode.el.nativeView;
returnthis.vnode?.el.nativeView;
},
mount(root: NSVNode = new NSVRoot()) {
if (isMounted) {
return vnode as M;
returnthis.vnode as M;
}

vnode = h(component, props);

vnode.appContext = context;
Object.keys(context).forEach((key) => {
newApp._context[key] = context[key];
});

renderer.render(vnode,root);
newApp.mount(root);

isMounted = true;
container = root;

return vnode as M;
returnthis.vnode as M;
},
unmount() {
if (!isMounted) return;
vnode = null;
renderer.render(null, container);

newApp.unmount();

isMounted = false;
container = null;
},
};
};
Expand Down
Loading

[8]ページ先頭

©2009-2025 Movatter.jp