阿里云赞助

Extend JS framework

Extend JS framework

This part of the extension of JS framework is still in the discussion, may be adjusted at any time, please pay attention.

Weex wants to be able to respect as many developer development habits as possible.So, in addition to Weex official support Vue 2.0, the developer can also customize and horizontally extension their own or their favorite JS Framework.The steps to customize the JS Framework are as follows:

  • First you have a complete set of JS Framework.
  • Learn about Weex’s JS engine feature support.
  • Adapting Weex’s native DOM APIs.
  • Adapting Weex’s initialization portal and multi-instance management mechanism.
  • Add your own JS Framework to the framework configuration of the Weex JS runtime. Then pack it.
  • Build JS bundles based on the JS Framework. You need to add a specific prefix comment so that the Weex JS runtime can recognize it.

Weex JS engine features support

  • Under iOS, Weex uses the JavaScriptCore that comes with the system, so the ES support depends on the version of the operating system.
    The current conservative judgments, ES5 features on the market mainstream iOS devices are perfectly supported, but some of the features of ES6 + is not supported.

  • Under Android, Weex uses the v8 kernel provided by UC. For performance and stability considerations, we are not using the latest version of the v8 kernel.The same conservative judgment, the ES5 feature can all support, including strict mode Object.freeze and so on.

  • The Weex JS engine does not support HTML DOM APIs and HTML5 JS APIs, including document, setTimeout`, and so on.

  • We added Promise‘s polyfill, as well as the console‘s polyfill.

  • In addition, in order to ensure that the JS engine can manage memory as much as possible, we have a generic global object for the Object.freeze () freeze operation, which includes:

    • Object
      • Object.prototype
      • Array
      • Array.prototype
      • String.prototype
      • Number.prototype
      • Boolean.prototype
      • Error.prototype
      • Date.prototype
      • RegExp.prototype

Adapt to Weex’s initial entry and multi-instance management mechanism

The JS Framework provided by the developer needs to be packaged as a CommonJS package, and the package needs to be extension to the following methods:

Framework initialization

  • init(config)
    • config
      • Document
      • Element
      • Comment
      • TaskSender
      • CallbackManager

This method places the Native DOM class and two auxiliary classes provided by Weex in the config parameter and allows the framework itself to be initialized.

Tip: At the same time, the author can pass in a different config in the framework of the initialization time. This allows for framework testing or environmental simulation.

Introduction to parameter format

  • TaskSender: wip…
  • CallbackManager: wip…

Register available native components and modules

  • registerComponents(components)
  • registerModules(modules)

These two methods are called immediately after the frame is initialized. This framework will be able to know which components and modules the current client supports.

Introduction to parameter format

  • components: Array: Describe the array of components, each of which includes:
    • type: string: Component name, for example div
    • methods: string[]: Optional, a list of method names supported by this component. These methods can follow the native DOM APIs call.
  • modules: Object: Describe the hash table of a series of modules. Key is the module name, the value is an array. The elements of the array describe a method in the module. The information of the method includes:
    • name: string: Method name
    • args: string[]: Parameter number and type description

E.g:

registerComponents([
{ type: 'web', methods: ['goBack', 'goForward', 'refresh']}
])
registerModules({
event: [
{name: 'openURL', args: ['string']}
]
})

Multi - instance lifecycle management

  • createInstance(instanceId, code, config, data, env)
  • refreshInstance(instanceId, data)
  • destroyInstance(instanceId)

Each Weex page has two stages: created and destroyed. At the same time in the Weex page running process, native can send messages to the Weex page. Different frameworks can follow their own ideas to achieve the message.

Introduction to parameter format

  • instanceId: string: The unique id of the Weex page is generated by native.
  • code: string:The Wex page’s JS bundle’s code is passed through native.
  • config: Object?: The configuration information for the Wex page, such as the bundleUrl representing the bundle address, is generated by the native configuration. It has nothing to do with the contents of the JS bundle itself.
  • data: Object?: Native can import an external data when creating a Weex page. The JS framework can also generate different page content for the same JS bundle with different data.
  • env: Object?:The current environment information about the Weex page, the meaning of each field:
    • info: Object: Framework information, see the “JS Bundle format requirements” later.
    • config: Object:Equivalent to the third parameter of the method config
    • callbacks: CallbackManager: only CallbackManagerinstance of Weex page.
    • created: number:The number of seconds that the Wex page was created.
    • framework: string:The name of the framework used by the Wex page. Equivalent to info.framework.

Native communication

  • receiveTasks(instanceId, tasks)

Native can use the refreshInstance method to send a message to the JS framework layer. But in many cases will use receiveTasks to send user events or methods callback to the JS framework.

For example, if the user clicks on a button, native will send a fireEvent type of task to the JS framework, and then the JS framework will handle the corresponding event logic. This part of the working mechanism is related to the design of the addEvent in the native DOM interface.

Another example is the user using fetch to send network requests. When the request is done at the native end, it will be sent to the JS framework with a callback type of task. Since native can not pass the function in JavaScript, it actually only sends a callbackId to the JS framework. This part of the working mechanism is related to the design of CallbackManager.

Auxiliary method

  • getRoot(instanceId): JSON

This method returns the full JSON description of the document body node. Developers can view the full native DOM tree as a result. The format of the specific return value is the same as the return method of the toJSON () method in the native DOM interface. This feature is used extensively as a developer tool extension.

Configure the JS Framework in WeexSDK

Prepare your JS Framework code

// your-own-js-framework.js
export function init (config) { ... }
export function registerComponents (components) { ... }
export function registerModules (modules) { ... }
export function createInstance (id, code, config, data, env) { ... }
export function destroyInstance (id) { ... }
export function refreshInstance (id, data) { ... }
export function recieveTasks (id, tasks) { ... }
export function getRoot (id) { ... }

Register a JS Framework

import * as Vue from '...'
import * as React from '...'
import * as Angular from '...'
export default { Vue, React, Angular };

And then packaged JS runtime, integrated into WeexSDK.

JS Bundle format requirements

Framework info
The note(alias framework info) at the beginning of the JS Bundle file is very important. The format is as follows:

// { "framework": "Vue" }

So that the Weex JS engine will know that the JS bundle needs to use the Vue framework to resolve.Similarly, Weex supports multiple frameworks.It will be based on js bundle notes to select the corresponding framework resolution.