Git Product home page Git Product logo

mona's Introduction

mona

目录

简介

mona 是抖店开放平台推出的商家应用跨端开发方案,支持使用React 框架来开发应用,以求达到一次开发处处运行

  • 飞鸽插件
  • 店铺装修组件
  • 移动端 h5 应用
  • 字节小程序应用

同时后续会逐渐增加商家应用业务基础组件库,方便开发者更加高效的进行开发,方案尚处在逐渐完善的阶段,有问题欢迎在 issue 中指出,感谢您的支持~~

安装

Node 版本要求

Mona CLI 0.2.x 需要Node.js v14.x 或更高版本。你可以使用nnvmnvm-windows在一台电脑中管理 Node 多个版本 可以使用如下任意命令来安装 Mona CLI

npm install -g @bytedance/mona-cli
#
yarn global add @bytedance/mona-cli

安装完成后,在控制台输入

mona -v

来验证是否安装成功,如果正确打印出版本,则表明安装成功

升级

如果需要升级全局的 Mona CLI,可以运行

npm update -g @bytedance/mona-cli
#
yarn global upgrade --latest @bytedance/mona-cli
#
mona update

创建一个项目

下面我们在本地创建一个项目,使用如下命令

mona init

按照提示依次输入项目名称,选择模板,选择是否使用 typescript 和样式预处理器等按需使用 店铺装修模块需要传入 appid,请在抖店开放平台,创建店铺装修应用后,在应用概览-证书信息中查看 App Key,作为 appid 传入

开发

项目初始化完成后进入项目跟目录,使用如下命令启动开发服务器,可以实时调试

npm run start

打包

开发完成后,对项目进行打包,可以使用如下命令

npm run build

发布上传项目

目前仅支持飞鸽插件、店铺装修模块项目的发布上传 项目开发完成后,需要在抖店开放平台进行发布

在开放平台手动上传

在项目跟目录运行以下命令

npm run compress

来进行项目的压缩,压缩完成后,到开放平台上传压缩包

通过 CLI 上传(目前仅支持店铺模块)

通过 CLI 上传需要先使用mona login登录当前开放平台账号,然后运行

npm run upload

来上传新版本到开放平台

IMPORTANT: 请注意,请保证 appid 是正确的!

CLI 命令

mona采用命令分离的模式,CLI 命令共分为两类,一类是全局命令,一类是与项目相关的命令。

全局命令封装在@bytedance/mona-cli中,需要全局安装,通过mona xxxx进行调用

与项目相关的命令封装在@bytedance/mona-service中,该包随项目进行安装,需要在项目中通过mona-service xxxx进行调用。

全局命令

可以使用mona -h查看帮助命令,mona -v查看当前版本

mona init

初始化一个商家应用/商家应用插件项目

  • -h, --help:输出帮助信息
  • -u, --use-typescript:是否使用 typescript
  • -s, --style:指定样式处理器(css/less)
  • -t, --template:指定模板(plugin)

mona login

登录抖店开放平台

** 如果上传代码的时候提示账号不正确,但确实已经登录了当前账号,可以尝试重新mona logout后,再重新mona login来登录,本地登录态有时会存在过期情况,目前还没有有效手段感知过期状态 **

mona logout

登出抖店开放平台

mona update

更新@bytedance/mona-cli 到最新版本

项目命令

可以使用mona-service -h查看帮助命令,mona-service -v查看当前版本

mona-service build & mona-service start

build命令对项目进行打包,需要通过-t, --target指定要打包的端,目前支持端的有

  • plugin(飞鸽桌面端插件)
  • max(店铺装修组件)
  • max-tempalte(店铺装修模板)
  • web(h5 应用)
  • mini(小程序)

start命令会启动一个本地服务,用法同build

mona-service compress

压缩文件,对项目文件进行压缩。在开放平台手动上传代码包时,需要将代码打包成 zip 包进行上传

可以通过-r, --use-root来制定是打包源码,还是打包产物目录,指定该项则会打包源码。如果是打包产物目录,则不需要该选项。

目前在开放平台中,飞鸽插件需要上传产物目录,装修组件和模板需要上传源码包。后续会统一成源码包。

mona-service publish

上传代码到开放平台,目前仅支持店铺装修模块的上传。使用该命令需要前置使用mona login来登录开放平台。

上传时会自动调用mona-service compress并上传代码到相应应用。

mona-service preview

在本地进行代码预览,目前仅支持店铺装修模块。使用时需传入--target,-t

// 店铺装修组件预览
mona-service preview -t max

// 店铺装修模板预览
mona-service preview -t max-template

<-----------------------------分割线,以下内容目前不支持店铺模块-------------------------------->

API

api 可以从@bytedance/mona-runtime中导入,如

import { redirectTo } from '@bytedance/mona-runtime';

组件

如果你只是 web 项目,你完全可以使用在 web 中的开发方式,引入 antd 等三方库。

组件可以从@bytedance/mona-runtime中导入,如

import { View, Text } from '@bytedance/mona-runtime';

生命周期

应用生命周期

应用生命周期通过hooks的形式进行暴露,useAppEvent

import { useAppEvent } from '@bytedance/mona-runtime';

const App = () => {
  // onLaunch
  useAppEvent('onLaunch', () => {});

  // onShow
  useAppEvent('onShow', () => {});
};

应用的生命周期有

  • onLaunch
  • onShow
  • onHide
  • onError
  • onPageNotFound

页面生命周期

页面生命周期通过hooks的形式进行暴露,usePageEvent

import { usePageEvent } from '@bytedance/mona-runtime';

const Page = () => {
  // onLoad
  usePageEvent('onLoad', () => {});

  // onReady
  usePageEvent('onReady', () => {});

  // onShow
  usePageEvent('onShow', () => {});
};

应用的生命周期有

  • onLoad
  • onReady
  • onShow
  • onHide
  • onUnload
  • onResize
  • onPullDownRefresh
  • onReachBottom
  • onShareAppMessage
  • onPageScroll

目录结构

.
├── README.md
├── app.config.ts // 应用配置文件
├── mona.config.ts // 项目配置文件
├── package.json
├── src
│   ├── app.tsx
│   ├── common
│   ├── components
│   ├── pages
│   │   ├── Home
│   │   │   ├── index.module.less
│   │   │   ├── index.tsx
│   │   │   └── page.config.ts // 页面配置文件
│   └── typings
│       └── assetsDefinition.d.ts
└── tsconfig.json // ts配置文件

所有的页面文件应放在 pages 中,所有的组件文件应放在 components 中。

项目构建配置文件为mona.config.ts,可以在该文件中更改构建配置

应用配置文件为app.config.ts,可以在该文件中配置路由

页面配置文件分别放在页面文件下page.config.ts中,可以在这里配置页面相关的配置

配置

项目配置

项目配置文件为项目根目录下的mona.config.js,配置文件内容如下:

// mona.config.ts
import { createProjectConfig } from '@bytedance/mona';
export default createProjectConfig({
  projectName: 'demo',
  input: './src/app.tsx',
});
参数 说明 是否必填 类型 默认值
projectName 应用/插件名称 string -
appId 开放平台 app_key 否(店铺装修场景中需必填) string -
input 入口文件路径 string -
chain 定义函数来修改 webpack 配置 (config: Config) => void -
dev 用来修改本地服务配置 string { port: 9999 }
enableMultiBuild 是否开启多端构建,开启后能够识别以端为后缀的文件,并自动引入 boolean true
compilerOptimization 是否开启编译优化,开启后产物会自动删除不必要的模板和不必要的属性 boolean true
transformSvgToComponentInWeb 是否开启 svg 文件转 react 组件(仅在 web 中有效) boolean false
postcss postcss 相关配置 object { pxtransform: { enable: true } }

postcss.pxtransform

移动端适配内容见这里

postcss 目前支持 pxtransform 的配置,该插件主要用于移动端尺寸单位转换以帮助适配。postcss.pxtransform的配置如下

参数 说明 是否必填 类型 默认值
enable 是否开启该插件 boolean true
designWidth 设计稿尺寸 number 750
deviceRatio 设计稿换算规则 object { 640: 2.34 / 2, 750: 1, 828: 1.81 / 2 }
config pxtorem 配置 object 见下表

postcss.pxtransform.config

参数 说明 是否必填 类型 默认值
unitPrecision rem 小数位精度 number 5
propList 允许转换的属性 string[] ['*']
selectorBlackList 黑名单里的选择器将会被忽略 (string RegExp)[]
replace 直接替换而不是追加一条进行覆盖 boolean true
mediaQuery 允许媒体查询里的 px 单位转换 boolean false
minPixelValue 设置一个可被转换的最小 px 值 number 0
exclude 指定的文件将忽略转换 RegExp ((name: string) => boolean)

应用配置

应用配置文件为项目根目录下的app.config.js,配置文件内容如下:

// app.config.ts
import { createAppConfig } from '@bytedance/mona';
export default createAppConfig({
  pages: ['pages/Home/index', 'pages/Info/index', 'pages/List/index'],
});

配置项说明

参数 说明 是否必填 类型 默认值
pages 页面路径 string[] -
entryPagePath 默认启动页面 string -
window 配置默认页面的窗口表现 object -
tabBar 配置底部 tab 表现 object -
navigateToMiniProgramAppIdList 需要跳转的小程序列表 array -
permission 需要部分授权弹窗的副标题 object -
networkTimeout 网络超时时间 object -
light 微应用相关配置 object -

entryPagePath

指定默认启动路径(首页)。如果不填,将默认为 pages 列表的第一项。不支持带页面路径参数。

{
  "entryPagePath": "pages/index/index"
}

pages

这个字段用于配置所有页面路径,配置每项是 路径 + 文件名 这个结构。配置项的第一个页面路径就是小程序启动展示的第一个页面。 如开发目录如下:

├── src
│   ├── pages
│   │   ├── Home
│   │   │   ├── index.module.less
│   │   │   ├── index.tsx
│   │   │   └── page.config.ts // 页面配置文件

那么 pages 应该这样配置:

{
  "pages": ["pages/Home/index"]
}

window

这个字段用于设置顶部状态栏、导航条、标题、窗口背景色。 需要注意的是,这里的窗口是指由端上控制的页面,与开发者用代码绘制的页面不是同一个概念。因此对于 backgroundColor 这类配置项,与开发者在代码中编写的样式不会有优先级覆盖关系。

参数 说明 是否必填 类型 默认值
navigationBarBackgroundColor 导航栏背景颜色,如"#000000";不支持 alpha 值,如"#AABBCCDD" HexColor #000000
navigationBarTextStyle 导航栏标题颜色,仅支持 black/white,同时影响:标题颜色、右胶囊颜色、左返回箭头颜色 string white
navigationBarTitleText 导航栏标题文字内容 string -
navigationStyle 导航栏样式,仅支持 default/custom。custom 模式可自定义导航栏,只保留右上角胶囊状的按钮,可以通过 navigationBarTextStyle 设置胶囊按钮的颜色 string default
backgroundColor 窗口背景色 HexColor #ffffff
backgroundTextStyle 下拉 loading 的样式,仅支持 dark/light string dark
backgroundColorTop 顶部窗口的背景色,仅小程序 iOS 支持 HexColor 同 backgroundColor
backgroundColorBottom 底部窗口的背景色,仅小程序 iOS 支持 HexColor 同 backgroundColor
enablePullDownRefresh 是否开启下拉刷新,详见页面相关事件处理函数 boolean false
onReachBottomDistance 页面上拉触底事件触发时距页面底部距离,单位为 px number 50
transparentTitle 仅在 navigationStyle 为 default 时该字段生效,用来控制导航栏透明设置。默认 none,支持 always 一直透明 / auto 滑动自适应 / none 不透明 string -

tabBar

如果你的小程序包含多个 tab(客户端窗口的底部或顶部有 tab 栏可以切换页面),可以通过 tabBar 配置项指定 tab 栏的表现,以及 tab 切换时显示的对应页面。比如设置 tab 展示标题和 tab 颜色等。

参数 说明 是否必填 类型 默认值
color tab 上的文字默认颜色 HexColor -
selectedColor tab 上的文字选中时的颜色 HexColor -
backgroundColor tab 的背景色 HexColor -
borderStyle tabbar 上边框的颜色, 仅支持 black/white string black
list tab 的列表,详见 list 属性说明,最少 2 个、最多 5 个 tab array -

其中 list 接受一个数组,数组中的每个项都是一个对象,其属性值如下:

参数 说明 是否必填 类型 默认值
pagePath 页面路径,必须在 pages 中先定义 string -
text tab 上按钮文字 string -
iconPath 图片路径,icon 大小限制为 40kb,建议尺寸为 81px * 81px string -
selectedIconPath 选中时的图片路径,icon 大小限制为 40kb,建议尺寸为 81px * 81px string -

navigateToMiniProgramAppIdList

当小程序需要使用 navigateToMiniProgram api 跳转到其他小程序时,需要先在配置文件中声明需要跳转的小程序 appId 列表,最多允许填写 10 个。

permission

部分授权弹窗的副标题支持开发者自定义,每次提审后会审核该文案,如不通过,直接打回;

不可自定义副标题的权限是:个人信息、手机号。

如果开发者没有填写某个 scope, 就使用该 scope 的默认文案,各 scope 的默认文案如下:

scope 默认文案
scope.userLocation 用于提供个性化服务及体验
scope.address 一键访问“今日头条/抖音/皮皮虾”收货地址,便捷管理
scope.record 用于采集声音
scope.album 用于选取图片视频,或保存图片视频到你的相册
scope.camera 用于拍摄图片、录制视频

networkTimeout

各类网络请求的超时时间,单位均为毫秒。

参数 说明 是否必填 类型 默认值
request request 的超时时间,单位:毫秒 number 60000
connectSocket connectSocket 的超时时间,单位:毫秒 number 60000
uploadFile uploadFile 的超时时间,单位:毫秒 number 60000
downloadFile downloadFile 的超时时间,单位:毫秒 number 60000

light

微应用相关配置

参数 说明 是否必填 类型 默认值
mode 微应用展现方式 'sidebar-semi-420','sidebar-semi-600','sidebar-semi-800','sidebar-semi-960' 'sidebar-semi-420'

mode 主要有四个值,sidebar-semi代表右侧抽屉弹窗,-420代表弹窗宽度尺寸,目前共有四种尺寸420600800960

页面配置

页面配置文件为每个页面目录下的page.config.js,如果 app.config.jswindow 字段里面配置了某个页面的窗口样式,同时该页面也在自己的 page.config.js 文件中做了对应字段的配置的话,框架会优先采用页面里面的 page.config.js 相应配置项,配置文件内容如下:

// page.config.ts
import { createPageConfig } from '@bytedance/mona';
export default createPageConfig({
  navigationBarTitleText: 'page title',
});
参数 说明 是否必填 类型 默认值
navigationBarBackgroundColor 导航栏背景颜色,如"#000000";不支持 alpha 值,如"#AABBCCDD" HexColor #000000
navigationBarTextStyle 导航栏标题颜色,仅支持 black/white,同时影响:标题颜色、右胶囊颜色、左返回箭头颜色 string white
navigationBarTitleText 导航栏标题文字内容 string -
navigationStyle 导航栏样式,仅支持 default/custom。custom 模式可自定义导航栏,只保留右上角胶囊状的按钮,可以通过 navigationBarTextStyle 设置胶囊按钮的颜色 string default
backgroundColor 窗口背景色 HexColor #ffffff
backgroundTextStyle 下拉 loading 的样式,仅支持 dark/light string dark
enablePullDownRefresh 是否开启下拉刷新,详见页面相关事件处理函数 boolean false
disableScroll 设置为 true 则页面整体不能上下滚动;只在 page.json 中有效,无法在 app.json 中设置该项 boolean false
disableSwipeBack 禁止页面右滑手势返回 boolean false
onReachBottomDistance 页面上拉触底事件触发时距页面底部距离,单位为 px number 50

多端开发

在开发过程中,有时需要正对不同的端书写不同的代码,这个时候需要判断环境,可以使用如下方式来书写多端代码

使用环境变量判断

使用process.env.MONA_TARGET来判断环境,目前有效值为web/mini/plugin

代码示例

<View>
  {process.env.MONA_TARGET === 'web' ? <Text>I am web</Text> : nul}
  {process.env.MONA_TARGET === 'mini' ? <Text>I am mini</Text> : nul}
<View>

多端文件构建

为了更方便的书写不同端的不同逻辑,不同的端可以使用不同的后缀名称,如*.web.js*.mini.js

代码示例

import Title from './Title';

当要引入一个Title组件,比如在小程序端需要有额外的处理,则可以在Title.js组件同级添加Title.mini.js来处理,mona 在打包 mini 端的时候,如果发现.mini后缀的文件则会自动打包Title.mini.js而不是Title.js

├── Title.js 除小程序外的其他版本
└── Title.mini.js  小程序版本

该方式可以通过mona.config.js下的enableMultiBuild来控制是否开启,默认是开启状态。如果你不需要多端构建,可以关闭该开关,来加快打包速度。

public 目录

在项目根目录下创建public目录,该目录下的所有文件会全部被复制到输出目录,你可以将一些图片等文件放在该目录下,以供iconPath或其他场景使用,如

// app.config.ts
import { createAppConfig } from '@bytedance/mona';
export default createAppConfig({
  // ...more config
  tabBar: {
    list: [
      {
        pagePath: 'pages/home/index',
        text: 'home page',
        iconPath: '/image.png',
      },
    ],
  },
});

或使用链接引用资源的场景,但这里推荐使用 import 的方式引用图片

// ...more code
return (
  <Image src="/image.png">
)

query 参数获取

在页面间跳转时,可以在路径后加入查询参数,如

navigateTo('/pages/home/index?name="xiaoming"');

查询参数的只可以在页面组件的props中进行获取,其中search为查询参数字符串,searchParams为解析后的查询参数。或者从页面生命周期onLoad中直接获取searchParams

import { PageProps, usePageEvent } from '@bytedance/mona';

const Home: React.FC<PageProps> = ({ search, searchParams }) => {
  console.log(search, searchParams);
  // 输出:?name="xiaoming" { name: "xiaoming" }
  usePageEvent('onLoad', params => console.log(params));
  return <div></div>;
};

移动端适配

css 中的单位在小程序中会自动转为rpx在 web 中会自动转为rem,你不需要关心如何换算,只需要按照设计稿实际尺寸来书写就可以。Mona 会默认以750px标准设计稿作为换算尺寸的标准单位。如果设计稿不是750px那么你可以在mona.config.jspostcss.pxtransform中修改deviceRatiodesignWidth

如果不想部分属性被转换,可以使用Px或者PX这样这种形式,则插件会忽略转换

使用小程序原生模块

小程序页面

与其他页面无异,直接在app.config 中的pages属性中加入路径即可

小程序组件

示例:

//@ts-ignore
import CustomComponent from 'native://../CustomComponent/index';

export default function () {
  return (
    <CustomComponent ref={customRef} headerText={'headerText属性'}>
      <View>这是Children</View>
    </CustomComponent>
  );
}

导入

路径前加入native://前缀, 路径是一个相对路径 或者 是与app.configpages路径相同的路径。

使用

在原生模块组件的 jsx 上,不允许写 spread attribute。例如:

// bad
<CustomComponent {...props}>
  <View>这是Children</View>
</CustomComponent>

// good
<CustomComponent  ref={customRef} headerText={'headerText属性'}>
  <View>这是Children</View>
</CustomComponent>

常见问题

mona 性能如何

我们初步测试了同时增加 100 个以及 1000 个节点在字节小程序中的表现,实际表现如下

100 1000

当前可用性

目前我们已完全支持小程序转换,并实现了 web 大部分的组件和 api。目前处于测试打磨阶段,后续会不断完善。使用中的任何问题欢迎多多提出。

原理

mona 在小程序侧采用了运行时方案,配合 React 进行 diff 并将需要更新的虚拟 dom 树压缩后,通过 setData 传递到渲染层,通过模板组件动态构建页面,从而达到小程序渲染的目的。同时在 web 侧我们完整实现了字节小程序常用的基本组件和 api,这就使得 web 和小程序的还原度很高。

特性

  • 多端构建
  • 完整的 ts 提示
  • 完整的字节小程序组件和 api
  • 较优的运行性能
  • 较小的打包体积

飞鸽插件开发须知

飞鸽配置文件

飞鸽插件开发工具型需在 mona 项目根目录下配置pigeon.json文件。该文件结构下所示

// pigeon.json
{
  // 自定义按钮配置
  "custom_button": {
    // 售后单
    "after_sale": [
      {
        "id": "xxxx",
        "name": "按钮名称",
        "params": {
          "a": "v"
        }
      },
      {
        "id": "xxxxx",
        "name": "按钮名称",
        "params": {
          "xxxx": "xxxxx"
        }
      }
    ],
    // 商品单
    "sku_order": [],
    // 店铺单
    "order": [],
    // 商品列表
    "product": []
  }
}

custom_button用来配置自定义按钮,商家可以选择是否开启,开启后按钮会按照场景展示在不同位置

目前场景有

  • 售后单(after_sale)
  • 商品单(sku_order)
  • 店铺单(order)
  • 商品列表(product)

可以在每个按钮中通过params自定义参数,按钮跳转插件时就会带有该自定义参数

请注意:其中按钮 id 不可重复,每次发布新版本,如果 id 不变则视为同一个按钮(会保持按钮开关状态不变),否则视为新的按钮,新按钮默认处于关闭状态

mona's People

Contributors

1198994985 avatar xwchris avatar bwhirring avatar ctititic avatar github-actions[bot] avatar kenny-shaw avatar teefing avatar ai01 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.