SoFunction
Updated on 2024-10-30

Getting Started with the Development Paradigm of WeChat Small Programs in Detail

A brief introduction

What is it?

It is a set of enterprise-level development paradigms focused on WeChat applets with a vision:

Make the code in an enterprise-level WeChat applet project, simpler and prettier.

Why was it named that way?

Write beautiful code for wechat mini program by the beautiful we!

"We" is both our We and WeChat's We, both beautiful!

So what are its selling points?

  • Focus on WeChat small program environment, write original WeChat small program code.
  • As it focuses only on WeChat mini-programs, it has a simple source code.
  • The plug-in programming approach makes it easier to encapsulate complex logic.
  • Plus some amenities:
    • Some official plugins.
    • An out-of-the-box framework that includes engineering, project specifications, and solutions to unique problems in the WeChat applet environment.
    • A CLI tool to help you quickly create applications, pages, components and more.

It consists of the following components:

A plug-in core -BeautyWe Core

Abstraction and packaging of App, Page, maintain the traditional WeChat small program development posture, while opening up some of the native capabilities, so that it has the ability to "plug-in".

Some official plugins -BeautyWe Plugins

Thanks to Core's "Pluggable" feature, complex logic is encapsulated and pluggable. Official for common needs to provide a number of plug-ins: such as enhanced storage, publish/subscribe, state machine, Logger, caching policy and so on.

An out-of-the-box project framework -BeautyWe Framework

Describes a project organization , out-of-the-box , integrated BeautyWe Core , and provides such as : global window , development specification , multi-environment development , global configuration , NPM and other solutions .

A CLI tool -BeautyWe Cli

Provides rapid creation of applications , pages , plug-ins , and project building capabilities of the command line tool . And also supports the creation of customized templates .

A simple example

downloading

Wrap your app with BeautyWe

After that, you will be able to use the capabilities provided by the BeautyWe Plugin.

Open native App/Page, support plug-inization

new BtApp({...}) The result of this execution is a wrapper around the native application, which contains 'pluginized' processing, and then returns a new instance that adapts the nativeApp() Methods.

Here's what 'pluginization' actually does.

First, pluginization opens up four capabilities of the native App:

domain (taxonomy)

The piece about merging the plugin's Data field into the native App's Data field is easy to understand.

2. Native hook functions

Make native hook functions (such asonShow, onLoad) Pluggable. Allows native apps with multiple plugins to listen to the same hook function at the same time. How this works is described in detail below.

3. Event Hook Functions

Making event hooks (hooks that interact with the view layer) is the same as "native hooks", although there are some differences in implementation.

4. Customized methods

To ensure that the API provided by the plugin is sufficiently elegant, it is supported when the plugin API is called (e.g., the event plugin).(...) ), the API methods can still be accessed internally via thethis Get the native instance.

Pluginization of Hook Functions

Native hook functions, event hook functions we uniformly refer to as "hook functions".

For each hook function, an execution queue is maintained that is executed as a Series Promise.

in order toonShow As an example, it will be executed in this form:

→ → → ...

Here's a deeper dive into the principles of pluginization:

It works like this:

  • go throughnew BtApp(...) Packaging, all hook functions, will have a separate execution queue, the
  • It will first take the individual hook functions of the nativepush to the corresponding queue. Then every time the plugin is used, the plugin's hook function is broken down and sent to the corresponding queue.push
  • (coll.) fail (a student)Native App(natively) triggers a certain hook when theBtApp The functions in the corresponding queue are executed sequentially as a Promise Series.
  • Special.onLaunch respond in singingonLoad in the execution queue, an initialized task is inserted at the top of the queue (initialize), it will be executed in a synchronized manner and in a sequential mannerInitialize Queue function inside. This is exactly what the plugin lifecycle function in the

This design provides the following features:

1. Pluggable

Simply insert the task into the event queue of the corresponding hook function.

2. Support asynchronous

Since it runs as a Promise Series, one of the tasks returns a Promise, and the next task waits for that task to finish before starting. If an error occurs, it flows into the native onError().

3. Solve the problem of getApp() === undefinded in WeChat applets.

The essence of this problem is due toApp() the native instance is not created. But since Promise is a microtask in the event loop, it is registered in the next loop. So when the Promise is executed App() It was done a long time ago.

Some official plugins

BeautyWe officially offers a range of plugins:

  • Enhanced Storage: Storage
  • Data List: List Page
  • Caching strategy: Cache
  • Logger
  • Event publish/subscribe: Event
  • Status machine: Status

They are simple to use and plug in wherever they are needed.

For reasons of space, here are a few interesting ones to talk about, and for more you can look at the official documentation:BeautyWe

Enhanced Storage Storage

This function is provided by@beautywe/plugin-storage Offer.

Since the data storage lifecycle of WeChat applets natively is the same as that of the applets themselves, i.e., the data is always available except when the user deletes it voluntarily or it is automatically cleaned up after a certain period of time.

So the plugin is in the/setStorage The foundation of the program provides two extension capabilities:

  • expiration control
  • Isolation of versions

Some simple examples

mounting

import { BtApp } from '@beautywe/core';
import storage from '@beautywe/plugin-storage';

const app = new BtApp();
(storage());

expiration control

// Expires in 7 days
('name', 'jc', { expire: 7 });

Isolation of versions

({ appVersion: '0.0.1' });
('name', 'jc');

// Return to jc
('name');

// When the version is updated
({ appVersion: '0.0.2' });

// Returns undefined.
('name');

See more@beautywe/plugin-storage Official Documentation

Data List List Page

For the very common business scenario of paging through a list of data, the @beautywe/plugin-listpage A packaged solution is provided:

  • Satisfy the business scenario of "data list paging".
  • Pagination support
  • Support for multiple data lists
  • Automatic capture of dropdown reloads:onPullDownRefresh
  • Automatic capture of pull-up loads:onReachBottom
  • Comes with a request lock to prevent Parkinson's hand shaking users
  • Simple and Elegant API

A simple example:

import BeautyWe from '@beautywe/core';
import listpage from '@beautywe/plugin-listpage';

const page = new ();

// Using the listpage plugin
(listpage({
 lists: [{
 name: 'goods', // Data name
 pageSize: 20, // How many pieces of data per page, default 10

 // The data source for each page, the function is called every time the page is loaded, and then the returned data is fetched.
 fetchPageData({ pageNo, pageSize }) {
 
 // Getting data
 return ({ pageNo, pageSize })
 
 // Sometimes it's necessary to process data from the server. dataCooker is a function you define.
 .then((rawData) => dataCooker(rawData));
 },
 }],
 enabledPullDownRefresh: true, // Enable dropdown overloading, default false
 enabledReachBottom: true, // Enable pull-up loading, false by default.
}));

// The goods data will be loaded, with goods being the name defined above.
//  = {
// data: [...] , // The view layer, which uses this field to retrieve specific data
// hasMore: true, // view level, recognizes if there is a next page by this field
// currentPage: 1, // The view layer, which recognizes the current page by this field
// totalPage: undefined,
// }

Just telllistpage How to get the data, it will automatically handle the "dropdown reload" and "pullup page" operations, and then update the data to the Down.

The View layer only needs to describe how the data will be displayed:

<view class="good" wx:for="">
 ...
</view>
<view class="no-more" wx:if=" === false">
 No more.
</view>

listpage also supports multiple data lists and other more configurations, see details:@beautywe/plugin-listpage

Cache Policy Cache

@beautywe/plugin-cache provides a WeChat applet-side caching policy, which is underpinned by thesuper-cache Provide support.

characterization

  • Provide a set of solutions for "slow server-side interface time-consumption, but high loading performance requirements" scenarios
  • Satisfy the most basic caching needs, read (get) and save (set)
  • Support for logical proxies against the cache
  • Flexible and configurable data storage

How it work

The general form of requesting data is to get the data from the server when the page is loaded and then wait for the data to be returned before rendering the page:

However, this model, will be affected by the server-side interface time-consuming, network environment and other factors affect the loading performance.

For pages with high loading performance requirements (e.g. home page), we have many solutions for general web development (e.g. server-side rendering, server-side caching, SSR, etc.).
However, there are some environments where this technique cannot be used (e.g., microsoft applets).

Super Cache provides a solution for intermediate data caching:

Thoughts:

  • When you need to get a piece of data, if there is a cache, the old data is given to you first.
  • Then get new data from the server and refresh the cache.
  • If there is no cache to begin with, the server-side data is requested and returned.
  • The next time you request a cache, start with the first step.

This solution, which gives up a little bit of real-time data (not the first request, only the last latest data can be obtained), greatly improves the loading performance of the front-end.
Suitable scenarios:

  • Data real-time requirements are not high.
  • The server-side interface is time-consuming.

utilization

import { BtApp } from '@beautywe/core';
import cache from '@beautywe/plugin-cache';

const app = new BtApp();
(cache({
 adapters: [{
 key: 'name',
 data() {
 return ('xxx/name');
 }
 }]
}));

suppose that... ('xxx/name') is the request server interface that returns data:data_from_server

Then:

('name').then((value) => {
 // value: 'data_from_server' 
});

For more configurations, see details:@beautywe/plugin-cache

Logger

leave it (to sb) @beautywe/logger-plugin A lightweight logging solution provided which supports:

  • Controlled log level
  • Customized Prefixes
  • Harmonization of log processing

utilization

import { BtApp } from '@beautywe/core';
import logger from '@beautywe/plugin-logger';

const page = new BtApp();

(logger({
 // options
}));

API

('this is info');
('this is warn');
('this is error');
('this is debug');

// Output
// [info] this is info
// [warn] this is warn
// [error] this is error
// [debug] this is debug

Level control

Configuration can be used to control which levels should be printed:

(logger({
 level: 'warn',
}));

in that casewarn upperlog (info, debug)This satisfies the different logging needs of development and production environments.

The level grades are as follows:

 = {
 error: 1,
 warn: 2,
 info: 3,
 debug: 4,
};

For more configurations, see details:@beautywe/plugin-logger

BeautyWe Framework

@beautywe/core respond in singing@beautywe/plugin-... Gives small programs:

  • Open Native, Pluginized Support -- by core
  • Various plugins -- by plugins

However, there are a lot of other pain points that you will actually encounter in development that are not addressed by the above two.

Such as project organization, specification, engineering, configuration, multiple environments, etc.

These are the categories that "BeautyWe Framework" will address.

It provides these features as an out-of-the-box set of project frameworks:

  • Integrating BeautyWe Core
  • NPM Support
  • global window
  • Global Page, Component
  • Global Configuration File
  • Multi-environment development
  • Example Pages
  • Normal project needs standard equipment: ES2015 +, sass, uglify, watch and so on.
  • and what we consider good project specifications (eslint, commit log, directory structure, etc.)

Also for space reasons, pick a few interesting to talk about, more can look at the official documents: BeautyWe

Quick Creation

first install@beautywe/cli

$ npm i @beautywe/cli -g

Creating Applications

$ beautywe new app

> appName: my-app
> version: 0.0.1
> appid: 123456
> Is this okay?:
> {
> "appName": "my-app",
> "version": "0.0.1",
> "appid": "123456"
> }

After answering a few questions, the project is generated:

my-app
├── 
├── 
└── src
 ├── 
 ├── 
 ├── 
 ├── assets
 ├── components
 ├── config
 ├── examples
 ├── libs
 ├── npm
 ├── pages
 └── 

Create pages, components, plug-ins

web page

  • The main package page:beautywe new page <path|name>
  • Subcontracting page:beautywe new page --subpkg <subPackageName> <path|name>

subassemblies

beautywe new component <name>

plug-in (software component)

beautywe new plugin <name>

Customized templates

exist./.templates directory that holds the creation templates for the Quick Create command:

$ tree .templates

.templates
├── component
│ ├── 
│ ├── 
│ ├── 
│ └── 
├── page
│ ├── 
│ ├── 
│ ├── 
│ └── 
└── plugin
 └── 

The templates inside can be modified to accommodate custom template creation at the project level.

global window

We all know that WeChat applets are 'single window' interaction platforms, where one page corresponds to one window.

And in business development, there are often statements such as this one:

  • Customized toast styles
  • Bottom of page copyright
  • Global loading styles
  • Global hover control

......

A slightly less elegant implementation could be to make separate components and bring them in on every page.

With this approach, we would have a lot of duplicate code, and every time we create a new page, we would have to introduce it all over again, and it would be cumbersome to maintain it later.

And the concept of 'global window' is that you want to have a place on top of all the pages where global logic and interactions can be shelved.

global-view component

This is a custom component with source code in /src/components/global-view

The wxml for each page only needs to be wrapped in one layer at the top:

<global-view >
 ...
</global-view>

Interactions, styles, and components that need to be implemented globally, it is sufficient to maintain only this component.

Global Configuration File

existsrc/config/ directory, where you can store various global configuration files and support running them as (thanks to the Power feature).

as ifsrc/config/:

const env = .RUN_ENV || 'dev';

const logger = ({
 prefix: 'BeautyWe',
 level: 'debug',
}, {
 // Configuration of the development environment
 dev: {
 level: 'debug',
 },
 // Configuration of the test environment
 test: {
 level: 'info',
 },
 // Configuration of the online environment
 prod: {
 level: 'warn',
 },
}[env] || {});

 = logger;

We can then read the config contents like this:

import { logger } from '/config/index';

//  Will vary depending on the environment。

Beautywe Framework integrates config into thegetApp() in the example of the

getApp().config;

Multi-environment development

BeautyWe Framework supports multi-environment development with three predefined strategies:

  • dev
  • test
  • prod

We can run all three build strategies with the command:

beautywe run dev
beautywe run test
beautywe run prod

Differences between the three environments

The Beautywe Framework source code uses multiple environments in two ways by default:

  • Build tasks (/env/...
  • Global Configuration (src/config/...

Differences in construction tasks

Build Tasks clarification dev test prod
clean Clear the dist file
copy Copying resource files
scripts Compiling JS files
sass Compiling scss files
npm Compiling npm files
nodejs-power Compile files
watch Listening for file changes
scripts-min Compressing JS files
sass-min Compressing scss files
npm-min Compressing npm files
image-min Compressing Image Files
clean-example Clear the sample page

Power

Beautywe Framework's code runs in two environments:

  • Runtime environments, such as build tasks, etc.
  • WeChat applet runtime environment, such as packaged into thedist Code for the folder.

course of action

Power is essentially a statically compiled implementation.
Output the results of a file running in the environment to the WeChat applet running environment to meet specific needs.

Power takes a similarly named file in the project's src directory and runs with it.
The result of the run is then written as a "literal object" to a file with the same name in the dist directory.

in order tosrc/config/ As an example:

const fs = require('fs');
const path = require('path');

const files = ((__dirname));

const result = {};

files
 .filter(name => name !== '')
 .forEach((name) => {
 (result, require((__dirname, `./${name}`)));
 });

 = result;

The file, after the Power build.

dist/config/:

 = {
 "appInfo": {
 "version": "0.0.1",
 "env": "test",
 "appid": "wx85fc0d03fb0b224d",
 "name": "beautywe-framework-test-app"
 },
 "logger": {
 "prefix": "BeautyWe",
 "level": "info"
 }
};

This is satisfied by expanding the configuration file into the src/config/ directory as often as you like, and it will be automatically packaged.

Power has been integrated into dev, test, prod for multi-environment development.

Of course, you can run this build task manually:

$ gulp nodejs-power

NPM

The principle behind the BeautyWe Framework's implementation of npm support is simple and can be summarized in one sentence:

Packing with webpacksrc/npm/ and outputs it in commonjs format to thedist/npm/

The benefits of doing so:

  • Simple to realize.
  • Allow npm packages to be centralized and well thought out each time a dependency is introduced to avoid flooding (especially in multi-player development).
  • Use the ll dist/npm/ command to quickly see how much of your project is occupied by npm packages.

Add npm dependency

existsrc/npm/ file for export:

export { default as beautywe } from '@beautywe/core';

Then import in other files:

import { beautywe } from './npm/index';

more

In a nutshell, BeautyWe is a set of development paradigms for WeChat applets.

core and plugins extend natively, providing encapsulation and plug-and-play use of complex logic.

And framework is responsible for delivering a full suite of enterprise-level project solutions for WeChat applets out of the box.

There is more in it, so feel free to browse the official website:

This is the whole content of this article.