Be more productive when Building mobile apps with new Tabris.js 3.0 Beta 1 release
Ready for round three?
Say hello to Tabris 3.0 – Beta 1! We’re only half way done with development for 3.0 and it is already promising to be a great release. It will not contain as many breaking changes as 2.0 did, but surely just as many (or may be even more) improvements. This time around our focus is on performance, convenience and productivity.
To test the beta, first download the Developer App for Tabris.js 3:
Then install the beta version of the CLI and create a new app:
1 2 3 |
npm install tabris-cli@3.0.0-beta1 -g tabris init npm start |
The CLI versions 2 and 3 are incompatible, you need to downgrade the CLI to the last 2.x release to continue development on a Tabris.js 2 project! The Tabris CLI version 3 can now be used on Tabris.js 2 projects, too.
You can find the updated documentation for Tabris.js 3 here. Note the migration guide!
So without further ado, here is what’s new.
Workers!
You can now run code parallel to the main thread. Not only can that give you a performance boost for CPU intensive tasks, it prevents the UI from becoming unresponsive. The Worker API follows the w3c worker API (MDN) so it should be very familiar.
In a worker you have access to almost all Tabris APIs, except for those related to UI and a few noted exceptions. With the 3.0.0 beta1 release the transferList
parameter of the postMessage()
method is not yet supported. Currently all arguments are passed by copy.
Example App:
1 2 3 4 5 6 7 8 9 10 |
const worker = new Worker('worker-add-numbers.js'); worker.onmessage = (event) => { console.log(`result: ${event.data}`); worker.terminate(); }; worker.onerror = (error) => { console.log(`onerror: ${JSON.stringify(error)}`); worker.terminate(); }; worker.postMessage([number1, number2]); |
Example Worker:
1 2 3 4 5 6 |
onmessage = e => { const number1 = e.data[0]; const number2 = e.data[1]; const result = number1 + number2; postMessage(result); }; |
New Event API
For Tabris 3.0 we ported the enhanced event API introduced in the tabris-decorators module to the core tabris module. It does not replace the old API, but offers a more convenient, higher level interface especially useful for TypeScript projects and asynchronous programming via async/await.
1 2 3 4 5 6 |
(async function() { textView.onTextChanged(handleTextChanged); textView.text = 'Tap here!'; await textView.onTap.resolve(); textView.text = 'Thank you!'; }()); |
And the best thing about it: You can use the new Listeners interface in your own code, with any object – not just widgets!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
class MyModel { public onNameChanged: Listeners<{value: String}> = new Listeners(this, 'nameChanged'); private _name; set name(value: string) { this._name = value; this.onNameChanged.trigger({value}); } get name() { return this._name; } } const model = new MyModel(); model.onNameChanged(ev => console.log(`New name: ${ev.value}`)); model.name = 'foo'; // "New name: foo" |
JSX and TypeScript improvements
TypeScript and JSX will be considered the default for Tabris.js 3 app development. Of course you don’t have to use them, or you can use one without the other. The documentation will still cover all variations.
For Beta 1 we revised many internals to help with future JSX and TypeScript enhancements. A number of APIs have already been tweaked for convenience and consistency. Check the migration guide for details on that.
One especially noteworthy change is that JSX is no longer technically limited to Widget and WidgetCollection types. The first non-widget to support JSX is ActionSheet, though eventually all other Popups will be supported as well.
1 2 3 4 5 6 7 8 9 10 |
ActionSheet.open( <ActionSheet title='Actions' onSelect={onSelect} onClose={onClose}> Select any of the actions below to proceed. <ActionSheetItem title='Search' image='resources/search-black-24dp@3x.png' /> <ActionSheetItem title='Share' image='resources/share-black-24dp@3x.png' /> <ActionSheetItem title='Settings' image='resources/settings-black-24dp@3x.png' /> <ActionSheetItem title='Delete' style='destructive' image='resources/delete-black-24dp@3x.png' /> <ActionSheetItem title='Cancel' style='cancel' image='resources/close-black-24dp@3x.png' /> </ActionSheet> ); |
Image scale by convention
The above snippet also provides another early example of tweaking our existing APIs for convenience: Providing images for high density displays does not require you to give a scale factor explicitly if it can be determined by the file name:
1 |
<ActionSheetItem image={{src: 'resources/search-black-24dp@3x.png', scale: 3}} /> |
Due to the “@3x” in the file name this code can be replaced by:
1 |
<ActionSheetItem image='resources/search-black-24dp@3x.png' /> |
Remote Console
Sideloading via QR-Code
No longer do you have to manually enter the IP of your development machine when sideloading code via the Tabris CLI to the developer app. The serve command now prints a QR code for you to scan:
View log statements on the development machine
From now on, errors, warning and calls to the console object methods are not just logged to the in-app developer console, but also to the developer machine. This works out-of-the-box whenever the app code is side-loaded via the tabris-cli (3.x) serve command.
But not only this, you can even enter JavaScript commands via the CLI. Simply add the -i (for “interactive”) option and wait for the device to connect:
Note that currently only the last connected device is connected to the remote console. This may change in the future.
Print widget hirarchy via console.dirxml
The console object itself also learned some new tricks that go nicely with the new remote console. One of them is the new dirxml command that will give you an XML-like presentation of any given widget:
Auto-reload app when saving source files
Restarting the app you’re developing is a task you probably have to do dozens and dozens of times on a single day. So far the quickest way to do this was to open the in-app developer console, but now it’s even quicker. Add the -a (for auto reload) option to the CLI serve command, and the app reloads whenever one of your source file changes.
Platform specific changes
Android
The Tabris.js Android client has seen several internal performance improvements and updates you should be aware of. We know target Android 5.0 (API level 21) as the minimum supported version (up from Android 4.2). The targeted Android version is now also the latest Android 9.0 (API level 28). In addition the tabris-android platform is now based on cordova 7.x which changes the folder structure slightly (see cordova release blog post).
iOS
The Tabris.js iOS client has changed constructor’s signature of Tabris.js objects. This affects plugins making existing ones incompatible with version 3.0. You can check new signature in header files of Tabris.js framework or take a look at an example of Tabris.js 3.0 compatible plugin here.
Documentation
We got plenty of feedback on our documentation (or lack thereof), and improving it will be a top priority from now on. This is not (and can not be) a short term project, the developer guide, API reference, tutorials and blog posts will see continuous improvement over the entire lifespan of Tabris 3.x. For now we have re-written some of our articles of the developer guide, started tweaking the API reference and started a blog series on tabris-decorators. We have some ideas beyond all that, but nothing ready to announce yet.
There are even more changes planned for Tabris.js 3.0. If you’d like to know more, why not have a look at the Tabris.js 3.0 project on GitHub.
Feedback is welcome on our Slack channel or on GitHub.
Happy coding!
Feedback is welcome!
Want to join the discussion?Feel free to contribute!