This topic describes the step-by-step process of developing frontend micro applications.

Directory

After you run npx @tuya-sat/create-micro-app@latest demo -t react-ts in a command-line tool, a react-ts template is created. react-ts template is recommended because some features are compatible with the react only. ts is adopted for efficient code maintenance. The directory of the demo folder is as follows:

.
├── README.md
├── _locales // manifest.json Multilingual UI text.
│ ├── en.json
│ └── zh-CN.json
├── antd.less.overwrite.js // Used to edit the Less variable related to theme color. Both dark and light themes are supported.
├── babel.config.json // The configuration file of `babel-import-plugin`, allowing you to load external CSS files as needed.
├── manifest.json // Declaration of the micro application. See manifest for details.
├── micro.config.js // The configuration file of Webpack and webpack-dev-server as well as the data for debugging.
├── mock // Files for the Mock feature.
│ └── index.json
├── package.json // Includes plugins and plugin set. Dependency prefixed with @tuya-sat will be installed and registered automatically.
├── public // The public file.
│ ├── favicon.ico
│ └── index.html
├── src
│ ├── App.css
│   ├── App.tsx
│ ├── api // An Axios library used to make requests.
│ │ ├── index.ts
│ │ ├── req.ts
│ │ └── res.ts
│ ├── assets // URLs of assets such as images and fonts.
│ │ └── logo.png
│ ├── components
│   │   ├── HelloTemplate
│   │   │   ├── index.module.less
│ │ │ └── index.tsx
│   │   ├── ModalForm
│ │ │ └── index.tsx
│   │   ├── Table
│   │   │   ├── index.module.less
│ │ │ └── index.tsx
│   │   └── Theme
│   │   ├── index.module.less
│   │   └── index.tsx
│ ├── index.css
│ ├── index.tsx // The entry file.
│ ├── lang // The multilingual UI text for micro applications.
│   │   ├── en.ts
│ │ ├── index.ts
│   │   └── zh.ts
│ ├── pages // The page components.
│   │   ├── index.module.less
│   │   └── index.tsx
│ ├── public-path.js // Injects Qiankun-related variables.
│ └── styles // Files for theme colors.
│ ├── dark.less
│   ├── global.less
│   └── light.less
├── tsconfig.json
└── typings.d.ts

Configuration

Open micro.config.js.

/** @typedef {import("@tuya-sat/micro-script").DebuggerConfig} DebuggerConfig */
/** @typedef {import("@tuya-sat/micro-script").WebpackCombineFunction} WebpackCombineFunction */
/** @typedef {import("@tuya-sat/micro-script").CustomDevServer} CustomDevServer */
module.exports = {
/**@type {DebuggerConfig} */
debuggerConfig: {
target: 'xxx', // Proxy protocol+host are required.
username: 'xxxx', // The admin account of the created SaaS.
password: 'xxx', // The password of the admin account.
logSign: true, // Print the request header.
mockPermissions: ['EDIT', 'DELETE'],
},
/**@type {WebpackCombineFunction} */
webpack(config, { isDev, isBuild }) {
config.output.publicPath = isDev ? '/' : './';
return config;
},
/**@type {CustomDevServer} */
devServer(config) {
return config;
},
};

debuggerConfig is used to configure the debugging information. Set target to the URL of the SaaS you have just created. The protocol and host must be entered.

For simplicity, we only show the code you should take care of.

/** @typedef {import("@tuya-sat/micro-script").DebuggerConfig} DebuggerConfig */
/** @typedef {import("@tuya-sat/micro-script").WebpackCombineFunction} WebpackCombineFunction */
/** @typedef {import("@tuya-sat/micro-script").CustomDevServer} CustomDevServer */
module.exports = {
/**@type {DebuggerConfig} */
debuggerConfig: {
target: 'Enter the URL of the created SaaS', // Proxy protocol+host are required.
},
};

Start up project

Run the following command in the project directory:

yarn start

The following figure shows a demo page. In your project, you can delete unwanted components.

quickstart_develop1

The system automatically creates a file .sass-cache.json in the project root directory. This is a cache file for the SaaS configuration. If you encounter unexpected problems during debugging, you can try deleting this file and starting up the service again.

Using mock

As the documentation says, a micro application should declare all the APIs it uses.

Now, a project has been started. With the mock rules, requests are sent from the client to the server and are correctly responded to. Open mock/index.json.

{
"mock": true,
"api": [
{
"path": "/open-api/v1.0/users",
"method": "GET",
"res": {
"msg": "",
"success": true,
"result": {
"data": [
{
"create_time": "1637204610430",
"roles": [
{
"remark": "",
"role_code": "admin",
"role_name": "admin"
}
],
"user_id": "bay1637204610495B***",
"user_name": "admin",
"user_nick_name": "Admin"
},
{
"create_time": "1637741963865",
"roles": [
{
"remark": "",
"role_code": "test",
"role_name": "test"
}
],
"user_id": "bay16372041489899***",
"user_name": "test",
"user_nick_name": "Admin"
}
]
}
},
"mock": true
},
{
"path": "/open-api/v1.0/users",
"method": "DELETE",
"res": {
"msg": "",
"success": true,
"data": {}
},
"mock": true
},
{
"path": "/open-api/v1.0/users",
"method": "PUT",
"res": {
"msg": "",
"success": true,
"data": {}
},
"mock": true
}
]
}

The outermost json object has a mock field:

{
"mock": true,
"api": [...]
}

The mock field is used to enable mock for APIs in all api arrays. It acts as a global on/off switch for the mock feature. If mock is set to false, all APIs in the api arrays are not mocked, but not vice-versa.

In an api array, each API has its own mock setting:

{
"mock": true,
"api": [
{
"path": "/open-api/v1.0/users",
"method": "PUT",
"res": {
"msg": "",
"success": true,
"data": {}
},
"mock": true // Check out here.
}
]
}

To mock this API, this mock field must be set to true. If it is set to false, even if the outermost mock is set to true, the mock feature will not work.

INFO

Changes made to mock/index.json take effect immediately, without the service being restarted.

For more information about mock configuration, see Permissions Mock.

Permission simulation

As the documentation says, each micro application can declare its permissions. Permissions are associated with APIs.

For more information about the manifest configuration, see Description Protocol.

Open manifest.json.

{
"type": "micro-apps/v1.1",
"appName": "demo",
"supportedPlatform": ["DESKTOP"],
"annotations": {
"sdf.cli:microFramework": "REACT_JS",
"sdf.feat:colorTheme": true
},
"universalId": "42350097-d1bd-441f-b174-21e10afe7***",
"appEngine": "MICRO-FRONTEND",
"name": "lang.name",
"defaultMenuIcon": {
"type": "tuyaIcon",
"name": "sat_factory_modeling"
},
"description": "lang.description",
"entries": [],
"configs": [],
"privileges": [
{
"name": "lang.edit",
"code": "EDIT"
},
{
"name": "lang.delete",
"code": "DELETE"
}
],
"apis": [
{
"namespace": "",
"method": "GET",
"path": "/v1.0/users",
"privilegeCode": "",
"type": "OpenAPI"
},
{
"namespace": "",
"method": "PUT",
"path": "/v1.0/users",
"privilegeCode": "EDIT",
"type": "OpenAPI"
},
{
"namespace": "",
"method": "DELETE",
"path": "/v1.0/users",
"privilegeCode": "DELETE",
"type": "OpenAPI"
}
],
"dependencies": []
}

This is a complete manifest.json file. Check out the privileges field:

{
"privileges": [
{
"name": "lang.edit",
"code": "EDIT"
},
{
"name": "lang.delete",
"code": "DELETE"
}
] // Check out here.
}

privileges is an array, with each element containing the name and code properties. code is the key value of a privilege.

In some use cases, UI rendering depends on the privilege. For example, the Delete button rendering varies depending on the role of the user. For users granted the DELETE privilege, the button is active, while for users not granted the DELETE privilege, the button is grayed out. We need to mock the button behaviors locally. In the demo, the Delete button is active.

quickstart_develop2

Let's see how this is implemented. The following code is from the file micro.config.js:

module.exports = {
/**@type {DebuggerConfig} */
debuggerConfig: {
mockPermissions: ['EDIT', 'DELETE'], // Check out here.
},
};

mockPermissions in debuggerConfig is an array of privilege codes. The above code indicates that the user that is accessing this micro application has the EDIT and DELETE privileges. Assume that this user does not have the DELETE privilege. You can delete the DELETE string from mockPermissions. After the code is edited:

module.exports = {
/**@type {DebuggerConfig} */
debuggerConfig: {
mockPermissions: ['EDIT'], // Check out here.
},
};

Refresh the page. The Delete button is greyed out.

quickstart_develop3

Let's see how this is implemented. Open src/components/Table/index.tsx and go to line 92.

<Button
type="link"
disabled={!hasPermission!('DELETE')} // Check out here.
onClick={() => deleteUsers(record.user_id)}
>
{t('table.delete')}
</Button>

The status of the Button component depends on the result returned by the function hasPermission!('DELETE'). hasPermission is an API exposed by the main application. The request parameter is the value of the code we delete from mockPermissions. mockPermissions does not contain this value, so hasPermission!('DELETE') returns false.

When you develop micro applications locally, the function hasPermission can be used as follows:

function hasPermission(code) {
return mockPermissions.includes(code);
}

In actual use, this function does not look like this.

Debug with the backend

In actual use, the backend API will check the user login status, so we need to simulate the login behavior. We need to edit micro.config.js to configure the username and password.

module.exports = {
/**@type {DebuggerConfig} */
debuggerConfig: {
target: 'Enter the URL of the created SaaS', // Proxy protocol+host are required.
username: 'xxxx', // The admin account of the created SaaS.
password: 'xxx', // The password of the admin account.
logSign: true, // Print the request header.
mockPermissions: ['EDIT', 'DELETE'],
},
};

username and password have not been configured. Configure them to the admin account and password you set for the created SaaS.

module.exports = {
/**@type {DebuggerConfig} */
debuggerConfig: {
target: 'Enter the URL of the created SaaS', // Proxy protocol+host are required.
username: 'Admin Account', // The admin account of the created SaaS.
password: 'Password', // The password of the admin account.
logSign: true, // Print the request header.
mockPermissions: ['EDIT', 'DELETE'],
},
};

Exit the service and run the following command to restart the service.

yarn start:proxy

Then, you can debug APIs. The command-line tool will output the header of the request via a proxy.

CAUTION

  • mock/index.json is still valid. If the API you are debugging is located in this file, set the mock of this API to false or set the global mock to false.
  • Prefix the API in the code with open-api or custom-api. Check whether the response in src/api/res.ts is as expected.

This is a simple process to develop a micro application.