Is your feature request related to a problem? Please describe.
Currently for building small ui component or small changes for Nativescript, you need to create and run in all mobile devices it's a very time consuming
Describe the solution you'd like
Run Nativescript components and APIs on the web using DOM.I am thinking/planning to create a library support Nativescript render on Web for faster development.
Like in react native they have https://github.com/necolas/react-native-web.
Any sponsor for me.
Want to back this issue? Post a bounty on it! We accept bounties via Bountysource.
Hi @arpit2438735
Have you checked the new experimental feature hot module replacement? The feature allows you to swap bits of code while your application is running. With HMR if you change a file in your project, you don't have to restart the application to apply the update. Check out the blog post here.
Hi @tsonevn hot module replacement is nice.
My idea is somehow different, let say I created a component or page and I wanted to checkout the component/page which I created how it gonna look like in mobile for that case I need to open my mobile and it's very time consuming (even though this is final step).Let say comps are getting changed in each month.How to stay ahead of time without spending much time in all mobile device(iOS and Android).We can have a page where it loads all the component how it gonna look like on mobile and for final touch we will ultimately do E2E test.Just like what we have Chrome Inspector where we check styling for our page in all devices like that what I am planning over browser so to iterate in faster rate.
Hi @arpit2438735,
I made further research on your suggestion and found this issue, where a similar topic is discussed. Also, I found this nativescript-angular-web-components project, which seems to provide the same functionality for NativeScript AngulaΡ. I haven't check if the project is working with the latest NativeScript, but you may use it as a template while creating your library.
Thanks @tsonevn .I was looking the same thing
I'd like to resurrect the original issue for this same topic, #1612, but it's since been locked. It originally had interest from @jeffwhelpley, @enchev, @NathanWalker, @eesdil, @NathanaelA, @harvey-woo, @slavchev, @sipacate, @rodenp, @prijindal, @dragGH102, @fisherspy, and @ronnyek. The issue was ultimately closed in 2016 in favour of code-sharing with Angular, but that's a totally different concept.
| | Code-sharing | Transpilation |
| ------------- | ------------- | ------------- |
| Definition | Logic is shared, but view is written once for each platform | Both can be totally shared |
| Analogy | Web code: React DOM
β .web.js
files, and web-specific elements such as <div>
.
Native code: React Native
β .native.js
/ .ios.js
/ .android.js
files, and platform-agnostic elements such as <View>
, but could equally work as platform-specific here.
| Web code: React Native Web
β .js
/ .web.js
files, and elements such as <View>
that exactly match those platform-agnostic ones used by React Native.
Native code: React Native
β .js
/ .native.js
/ .ios.js
/ .android.js
files, and platform-agnostic elements such as <View>
.
|
We don't want to code-share (as Angular and Vue already support); the purpose of NativeScript Web would be to transpile.
A "NativeScript Web" library would enable users to make one singular codebase (right down to the view code) and build for both mobile and web from it.
It's a killer feature that NativeScript is sorely missing. Currently, the state-of-the-art for this is React Native + React Native Web. This stack is successfully used in production by: Twitter,
Major League Soccer,
Flipkart,
Uber,
The Times, DataCamp. So there is big demand for this kind of capability. I'm using RNW at work myself, and it's awesome.
The even-more-killer-feature that NativeScript Web could offer is that, once implemented, it would trivially bring a web target all platforms (via Core, Angular, Vue, React, and Svelte flavours). For example, from the same React NativeScript codebase, one would merely have to run tns run ios
for an iOS build or webpack --config webpack.web.config.js
(or tns run web
if the CLI were to support it first-class) for a web build. The same would apply for any other flavour; there would be few or no code-changes needed in the renderers at all, if NativeScript for Web were implemented in the right way (e.g. provided that the same interfaces for appending child nodes to parents, such as page.contentView = stackLayout;
would still work on Web).
I'm sure that this affordance to "write in the UI renderer of your choice, for any platform" would really make the world take notice of NativeScript! The Hacker News article writes itself.
@NathanWalker worked on nativescript-angular-web-components
, but I'm too jetlagged right now to discern at a glance whether it's a code-sharing approach or a transpilation approach. It sounds like the latter. However, it's limited by only catering for Angular.
@bundyo appears to have been experimenting with implementing NativeScript for Web on-and-off for at least 2-3 years. I remember seeing a video/screenshot of his proof-of-concept on Twitter, but can't find it again β I can say that it looked really promising, however. I see he has the repository ns-web.
I've already filed an issue for a DOMView
component (#7995) which @bundyo and others have shown an interest in. I'll file a separate issue to specify DOMText
, too. These would respectively correspond to React Native's incredibly useful View
and Text
elements, and would be helpful in solving the problem of mapping NativeScript's various different layout and text elements to convincing Web equivalents.
We evaluated internally whether we should put this feature on our roadmap several times. Currently, the NativeScript Core team doesn't have the capacity needed to deliver on this. If somebody from the community wants to step up - we can find ways to make it work and will provide guidance.
I would be interested for setting it up.Can you give me a walkthrough or guidance in what direction you guys are thinking?
I'll chime in too with some more information.
We added several questions to one of the {N} surveys and there was not enough demand for such a feature and based on its complexity we called it off.
There are several points in which {N} Web would work:
The first one is usually required by bigger apps by companies that started directly with a mobile app - Twitter and Uber are such - they have a need for an easier way to do a lighter PWA app that can be used directly in the browser. Most other users travel the opposite way - they first create a web app and then try to find a way to do a mobile. Then there are the users that plan web and mobile at the same time - there might be more of them lately, but if they target desktop, they won't go a direct PWA way as mobile experience is sub-par on desktop. This of course won't stop some companies from doing it anyway (I'm looking at you, Twitter).
The second point is the biggest win here. Documentation would greatly benefit from runable samples in the browser. For Playground the situation won't be that great though - the Preview app supports some {N} plugins, but some of them are either impossible or hard to do on in web.
The third point fell off as we adopted another company product which had an already established drag & drop designer.
As Emo said, the complexity that a NativeScript Web platform would bring was too much for the team - it had to support a third platform, which is adding 50% more work to the current work required to support NativeScript. In addition, it will add the (albeit optional) requirement for plugin authors to support the new Web platform, including the Pro UI plugins, which are rather big. We can probably reuse Kendo controls for some of the functionality, however things like charts and gauges are not part of their free offering.
Spinning off this as a community project might be possible. It might need to add pluggable custom platforms in {N} CLI and dev-webpack, but apart from that the rest should be possible to be registered as an external platform plugin, now that {N} has gone completely Webpack.
All of this holds true for a hypothetical {N} Desktop platform with the difference of the target users, of which there might be more interested ones.
I can try spin off an external plugin platform on top of my hackaton efforts just to see what is needed to be done in {N} core.
Oh, completely forgot - here is a running {N}-Vue app in the browser without other changes than removing the Firebase plugin and replacing it with a JSON object:
https://deploy-preview-5--elated-bell-28e411.netlify.com/
Note: FontAwesome 4 is not loading for some reason, should work with local install.
The POC I've done in the hackaton uses custom elements to instantiate {N} widgets in web. Also tns-core-modules where retrofitted with a third Web platform which to allow loading them in a browser.
The biggest issue I've seen in the core modules is that they make use of a custom implemented WeakRef in the runtimes, which needs to be handled somehow in the browser - I don't think any browser has implemented it and there are no shims as it requires native implementation and access to the garbage collector.
I believe NativeScript popularity is not bigger because lack of broad knowledge on what you can do with it, like targeting web and mobile with same code base if you use NativeScript Angular schematics. I also believe that approach needs to be the default one instead of an optional thing.
Oh, completely forgot - here is a running {N}-Vue app in the browser without other changes than removing the Firebase plugin and replacing it with a JSON object:
https://deploy-preview-5--elated-bell-28e411.netlify.com/
Note: FontAwesome 4 is not loading for some reason, should work with local install.
Whoah....
Can you share a bit about how you pulled this off?
Did this require you to write different platform-specific views, or is this the EXACT same file being rendered in the browser?
I am SO interested in this.
Did this require you to write different platform-specific views, or is this the EXACT same file being rendered in the browser?
I'm sure @bundyo will have received the summons to expand on this, but yes, the point of NativeScript Web is that the very same codebase, comprised of NativeScript cross-platform UI elements such as <FlexboxLayout>
elements and similar, would be transpiled to equivalent DOM components such as <div style="display: flex;">
π
Kamen has been working on a NativeScript for Web library on-and-off as a hobby project. I believe that this is the repo: https://github.com/bundyo/ns-web
I'm currently working on making web and desktop platforms to separate plugins, as in their current form they are hard to keep up to date. Then I'll open-source them, so that everyone can contribute.
In the web case above, this is an unmodified Vue template running in the browser - no changes from the native one.
Of course even now they are still in a PoC state, so quite a bit of work is needed to make them usable in real projects.
@shirakaba @bundyo
I can't believe I hadn't heard of this before, that's incredible!
My company is currently rebuilding our Android and iOS mobile apps into a unified codebase as part of an entire architecture overhaul for scale atm.
We chose NativeScript despite the relative lack of popularity over React Native because of vastly superior performance (RN required heavy manual optimization to render a scrollable list of just 300 text items and even then was still buggy) and our team's heavy Vue preference.
The only negative was lack of ecosystem, which means we wouldn't be able to leverage RN Web if we wanted to host a mobile web app, but this sounds like it could potentially provide that option :heart_eyes:
(Other libs like Stripe and Google Maps we are using through a webview which appears to function fine, except that webview doesn't hot reload properly sometimes and requires a full restart)
Well, I have two options for this "problem", the frist solution is with a compoment for a farmework (angular, vue or svelet)
This is a example for Angular.
The second solution, is with WebCompoments. Than, this is an example for that
// Import the LitElement base class and html helper function
import { LitElement, html } from 'lit-element';
// Extend the LitElement base class
class TextView extends LitElement {
static get properties() {
return {
autocorrect: Boolean,
keyboardType: String,
maxLength: Number,
returnKeyType: String,
secure: Boolean,
value: String,
disabled: Boolean
};
}
constructor() {
super();
this.autocorrect = true;
this.keyboardType = 'text';
this.maxLength = Infinity;
this.returnKeyType = 'done';
this.secure = false;
this.value = '';
this.disabled = false;
this.addEventListener('DOMContentLoaded', this.handerEvent('load'));
}
focus (){
console.log('focus -funciton');
}
dismissSoftInput (){
console.log('dismissSoftInput -funciton');
}
handerEvent(name, isInput){
return (event) => {
if(isInput){
this.value = event.originalTarget.value;
}
this.dispatchEvent(new CustomEvent(name, {
data: event.data,
detail: event.detail,
bubbles: event.bubbles,
composed: event.composed,
cancelBubble: event.cancelBubble,
cancelable: event.cancelable
}));
}
}
get type(){
if(this.secure){
return 'password';
}
if(this.returnKeyType === 'search'){
return this.returnKeyType;
}
return {
'url' : 'text',
'phone' : 'tel',
'integer' : 'number',
}[ this.keyboardType ] || this.keyboardType;
}
render(){
return html`
<input type="${this.type}"
?disabled="${this.disabled}"
.value="${this.value}"
@abort="${this.handerEvent('abort')}"
@animationcancel="${this.handerEvent('animationcancel')}"
@animationend="${this.handerEvent('animationend')}"
@animationiteration="${this.handerEvent('animationiteration')}"
@auxclick="${this.handerEvent('auxclick')}"
@blur="${this.handerEvent('blur')}"
@cancel="${this.handerEvent('cancel')}"
@canplay="${this.handerEvent('canplay')}"
@canplaythrough="${this.handerEvent('canplaythrough')}"
@change="${this.handerEvent('change', true)}"
@click="${this.handerEvent('click')}"
@close="${this.handerEvent('close')}"
@contextmenu="${this.handerEvent('contextmenu')}"
@copy="${this.handerEvent('copy', true)}"
@cuechange="${this.handerEvent('cuechange')}"
@cut="${this.handerEvent('cut')}"
@dblclick="${this.handerEvent('dblclick', true)}"
@durationchange="${this.handerEvent('durationchange', true)}"
@ended="${this.handerEvent('ended')}"
@error="${this.handerEvent('error')}"
@focus="${this.handerEvent('focus')}"
@formdata="${this.handerEvent('formdata')}"
@gotpointercapture="${this.handerEvent('gotpointercapture')}"
@input="${this.handerEvent('input')}"
@invalid="${this.handerEvent('invalid')}"
@keydown="${this.handerEvent('keydown')}"
@keypress="${this.handerEvent('keypress')}"
@keyup="${this.handerEvent('keyup')}"
@loadeddata="${this.handerEvent('loadeddata')}"
@loadedmetadata="${this.handerEvent('loadedmetadata')}"
@loadend="${this.handerEvent('loadend')}"
@loadstart="${this.handerEvent('loadstart')}"
@lostpointercapture="${this.handerEvent('lostpointercapture')}"
@mousedown="${this.handerEvent('mousedown')}"
@mouseenter="${this.handerEvent('mouseenter')}"
@mouseleave="${this.handerEvent('mouseleave')}"
@mousemove="${this.handerEvent('mousemove')}"
@mouseout="${this.handerEvent('mouseout')}"
@mouseover="${this.handerEvent('mouseover')}"
@mouseup="${this.handerEvent('mouseup')}"
@paste="${this.handerEvent('paste', true)}"
@pause="${this.handerEvent('pause')}"
@play="${this.handerEvent('play')}"
@pointercancel="${this.handerEvent('pointercancel')}"
@pointerdown="${this.handerEvent('pointerdown')}"
@pointerenter="${this.handerEvent('pointerenter')}"
@pointerleave="${this.handerEvent('pointerleave')}"
@pointermove="${this.handerEvent('pointermove')}"
@pointerout="${this.handerEvent('pointerout')}"
@pointerover="${this.handerEvent('pointerover')}"
@pointerup="${this.handerEvent('pointerup')}"
@reset="${this.handerEvent('reset', true)}"
@resize="${this.handerEvent('resize')}"
@scroll="${this.handerEvent('scroll')}"
@select="${this.handerEvent('select')}"
@selectionchange="${this.handerEvent('selectionchange')}"
@selectstart="${this.handerEvent('selectstart')}"
@submit="${this.handerEvent('submit', true)}"
@touchcancel="${this.handerEvent('touchcancel')}"
@touchstart="${this.handerEvent('touchstart')}"
@transitioncancel="${this.handerEvent('transitioncancel')}"
@transitionend="${this.handerEvent('transitionend')}"
@wheel="${this.handerEvent('wheel')}"
/>
`;
}
}
// Register the new element with the browser.
customElements.define('textview', TextView);
The two ways have a multiple problems. I think the best solution is the WebCompoments! With use to Compoments internal...
Most helpful comment
Prior discussion
I'd like to resurrect the original issue for this same topic, #1612, but it's since been locked. It originally had interest from @jeffwhelpley, @enchev, @NathanWalker, @eesdil, @NathanaelA, @harvey-woo, @slavchev, @sipacate, @rodenp, @prijindal, @dragGH102, @fisherspy, and @ronnyek. The issue was ultimately closed in 2016 in favour of code-sharing with Angular, but that's a totally different concept.
Difference between code-sharing and transpilation approaches
| | Code-sharing | Transpilation |
| ------------- | ------------- | ------------- |
| Definition | Logic is shared, but view is written once for each platform | Both can be totally shared |
| Analogy | Web code: React DOM
β
.web.js
files, and web-specific elements such as<div>
.Native code: React Native
β
.native.js
/.ios.js
/.android.js
files, and platform-agnostic elements such as<View>
, but could equally work as platform-specific here.| Web code: React Native Web
β
.js
/.web.js
files, and elements such as<View>
that exactly match those platform-agnostic ones used by React Native.Native code: React Native
β
.js
/.native.js
/.ios.js
/.android.js
files, and platform-agnostic elements such as<View>
.|
We don't want to code-share (as Angular and Vue already support); the purpose of NativeScript Web would be to transpile.
Benefits
A "NativeScript Web" library would enable users to make one singular codebase (right down to the view code) and build for both mobile and web from it.
It's a killer feature that NativeScript is sorely missing. Currently, the state-of-the-art for this is React Native + React Native Web. This stack is successfully used in production by: Twitter,
Major League Soccer,
Flipkart,
Uber,
The Times, DataCamp. So there is big demand for this kind of capability. I'm using RNW at work myself, and it's awesome.
The even-more-killer-feature that NativeScript Web could offer is that, once implemented, it would trivially bring a web target all platforms (via Core, Angular, Vue, React, and Svelte flavours). For example, from the same React NativeScript codebase, one would merely have to run
tns run ios
for an iOS build orwebpack --config webpack.web.config.js
(ortns run web
if the CLI were to support it first-class) for a web build. The same would apply for any other flavour; there would be few or no code-changes needed in the renderers at all, if NativeScript for Web were implemented in the right way (e.g. provided that the same interfaces for appending child nodes to parents, such aspage.contentView = stackLayout;
would still work on Web).I'm sure that this affordance to "write in the UI renderer of your choice, for any platform" would really make the world take notice of NativeScript! The Hacker News article writes itself.
Prior work
@NathanWalker worked on
nativescript-angular-web-components
, but I'm too jetlagged right now to discern at a glance whether it's a code-sharing approach or a transpilation approach. It sounds like the latter. However, it's limited by only catering for Angular.@bundyo appears to have been experimenting with implementing NativeScript for Web on-and-off for at least 2-3 years. I remember seeing a video/screenshot of his proof-of-concept on Twitter, but can't find it again β I can say that it looked really promising, however. I see he has the repository ns-web.
Platform-agnostic web-like DOMView and DOMText elements
I've already filed an issue for a
DOMView
component (#7995) which @bundyo and others have shown an interest in. I'll file a separate issue to specifyDOMText
, too. These would respectively correspond to React Native's incredibly usefulView
andText
elements, and would be helpful in solving the problem of mapping NativeScript's various different layout and text elements to convincing Web equivalents.