Skip to main content
MorJS compiles Alipay mini-program source code into a WeChat-compatible output. The compiler rewrites file extensions, converts Alipay template directives to wx: prefixed equivalents, renames the global object from my to wx, and injects a runtime shim that bridges lifecycle and API differences.

Configuration

Set sourceType to alipay and target to wechat in mor.config.ts:
// mor.config.ts
import { defineConfig } from '@morjs/cli'

export default defineConfig([
  {
    name: 'wechat',
    sourceType: 'alipay',  // source DSL is Alipay
    target: 'wechat',      // compile to WeChat
    compileMode: 'bundle',
  }
])

File Extension Mapping

The compiler rewrites every source file extension to the WeChat equivalent:
AlipayWeChatPurpose
.axml.wxmlTemplate
.acss.wxssStyles
.sjs.wxsScript modules
.js.jsPage / component logic
.json.jsonConfiguration
The default output directory is dist/wechat.

Global Object: mywx

Alipay exposes its APIs through my; WeChat uses wx. MorJS handles the transformation through autoInjectRuntime.api, which accepts the same three modes as the reverse direction:
Textual replacement of every my identifier with wx. No additional runtime import is injected. Use only when the APIs you call have identical signatures on both platforms.
autoInjectRuntime: {
  api: 'lite'
}
Only replaces my.<method>() call expressions — bare my references are left as-is.
autoInjectRuntime: {
  api: 'minimal'
}

Template Directive Mapping

Alipay directives (a:) are rewritten to WeChat directives (wx:) at compile time:
Alipay directiveWeChat directive
a:ifwx:if
a:elifwx:elif
a:elsewx:else
a:forwx:for
a:for-itemwx:for-item
a:for-indexwx:for-index
a:keywx:key
SJS module tags are renamed as well:
AlipayWeChat
<import-sjs from="./a.sjs" name="m" /><wxs src="./a.wxs" module="m"></wxs>
WeChat’s <wxs> tag does support inline script content (isSupportSjsContent: true). Existing .sjs external references are rewritten to .wxs automatically.

Runtime Injection: autoInjectRuntime

MorJS replaces Alipay constructor calls with runtime wrappers:
Alipay callInjected MorJS runtime
App({})wApp({}) from @morjs/runtime-mini
Page({})wPage({})
Component({})wComponent({})
Mixin({})mapped to WeChat Behavior({}) via behaviorOrMixin
autoInjectRuntime: {
  app: true,
  page: true,
  component: true,
  mixin: true,   // Mixin → Behavior for WeChat targets
  api: 'enhanced'
}

Mixin → Behavior Conversion

Alipay uses Mixin({}) where WeChat uses Behavior({}). MorJS maps between them through the shared behaviorOrMixin runtime module. The mixin injection option (enabled by default for Alipay sources) handles this:
// Alipay source
const myMixin = Mixin({
  data: { count: 0 },
  methods: { increment() { this.setData({ count: this.data.count + 1 }) } }
})

// After compilation → WeChat
const myMixin = Behavior({
  data: { count: 0 },
  methods: { increment() { this.setData({ count: this.data.count + 1 }) } }
})

API Differences

The enhanced runtime (apisToOther.ts) translates the following Alipay APIs to their WeChat equivalents:
Alipay APIWeChat APINotes
my.showActionSheet({ items })wx.showActionSheet({ itemList })Parameter renamed
my.showToast({ content, type })wx.showToast({ title, icon })type: 'exception''error' on WeChat
my.showLoading({ content })wx.showLoading({ title })Parameter renamed
my.confirm({ cancelButtonText, confirmButtonText })wx.showModal({ cancelText, confirmText })Mapped
my.alert({ buttonText })wx.showModal({ confirmText, showCancel: false })Mapped
my.setNavigationBar({ title, backgroundColor })wx.setNavigationBarTitle + wx.setNavigationBarColorSplit into two calls; front color auto-derived from background

Component Lifecycle Mapping

Alipay and WeChat components differ in their lifecycle names:
AlipayWeChat
onInitattached (via composed lifecycle)
didMountready
didUpdatesimulated via observers['**'] + custom hook
didUnmountdetached
deriveDataFromPropssimulated via wildcard observer
Alipay’s props system differs from WeChat’s properties. The aComponent→wechat runtime separates function props (event handlers) from data props, stores them in component data, and uses observers to keep this.props in sync. This means this.props.onXxx() calls work as expected on WeChat.

Template Compatibility Transformations

Beyond directive renaming, the compiler applies several structural fixes:
Alipay uses onTap="handler" style event attributes. The compiler rewrites these to WeChat’s bind:tap="handler" syntax and, for custom component events, routes them through MorJS’s $morEventHandlerProxy mechanism so that function props work correctly across the bridge.
Alipay supports template literals inside {{ }}, e.g. {{`Hello ${name}`}}. WeChat does not. The compiler transpiles these to ES5 string concatenation: {{'Hello ' + name}}.
Alipay allows object notation in style: style=\"{{ height: '20rpx' }}\". The compiler converts these to {{morSjs.s({ height: '20rpx' })}} and injects the helper SJS module automatically.
Alipay’s <view disable-scroll> has no WeChat equivalent. MorJS emits a catchTouchMove attribute bound to a $morDisableScrollProxy handler that prevents scroll propagation.
Alipay’s <text number-of-lines="2"> is compiled to the equivalent CSS overflow: hidden; -webkit-line-clamp: 2 inline style for WeChat.
Alipay’s open-type="getAuthorize" scope="phoneNumber" is mapped to WeChat’s open-type="getPhoneNumber" with the corresponding bind:getphonenumber event attribute.

Common Gotchas

The WeChat compiler resolves npm main fields in the order: wechatminiprogrammain. Libraries that only export an alipay field will fall back to main. Ensure component libraries include a miniprogram or wechat field.
WeChat compiles scripts to ES5 + CommonJS by default. Alipay sources targeting ES2015+ features may require additional Babel transforms. Check that your tsconfig target is compatible.
Alipay has my.getSystemInfoAsync; the runtime maps it to wx.getSystemInfo with a response normalisation step that copies SDKVersion from the global object.
Alipay’s my.connectSocket returns a task object with methods such as onClose, onMessage, send, and close. The WeChat equivalent exposes separate global wx.onSocketClose / wx.sendSocketMessage APIs. The runtime shim bridges the response object so that task-style usage works on WeChat.
Alipay’s input event for the <input> component was previously not correctly wired when compiling to WeChat. This was fixed in v1.0.113. Ensure you are on a recent version.

Conditional Compilation

/* #if TARGET === 'wechat' */
wx.showModal({ title: 'WeChat only' })
/* #elif TARGET === 'alipay' */
my.alert({ content: 'Alipay only' })
/* #end */
File-level conditional compilation is also supported via the .wx.js / .my.js suffix convention configured in conditionalCompile.fileExt.

Build docs developers (and LLMs) love