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 through
new BtApp(...)
Packaging, all hook functions, will have a separate execution queue, the - It will first take the individual hook functions of the native
push
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 the
dist
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 webpack
src/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.