Build applet architecture from scratch

mykurisu 2021-09-15 09:04:41

Without permission , Please do not reprint at will , thank you .

The author has come into contact with small program development 3 Over the year , If you ask me how to develop a small program from scratch , Look at this article .

The beginning of everything

To develop applets , The first thing, of course, is to register a small program first .

Applet registration

iShot2021-08-12 23.11.08.png

Wechat applet registration address

Click the arrow to register , Press the interface prompt to complete the registration .

After registration, you can get our first important prop -- APPID

iShot2021-08-12 23.14.01.png

iShot2021-08-12 23.17.36.png

development environment

and H5 Development is the same , It is also necessary to build a development environment for developing small programs . For wechat applet development , The most important environment is the wechat developer tool officially provided by wechat .

Wechat developer tool download address

iShot2021-08-12 23.21.54.png

Click the largest... In the middle of the interface + You can enter the new interface of the applet .

iShot2021-08-12 23.22.27.png

Fill in the small program we just applied for... At the arrow in the figure above APPID that will do , Then it will automatically generate a small program with built-in official template .

thus , We are taking the first step in developing small programs . But at this time, we must not rush to get rid of the code , In fact, there are many things more important than just getting started with the code .

Common cognition

Generally speaking, development is inseparable from collaboration , The most important thing in cooperation is the tacit understanding with small partners , This tacit understanding comes from everyone's Common cognition .

Only everyone's understanding of the project is at the same level , The whole development collaboration will be positive .

Directory structure specification

Don't underestimate each of our files 、 Naming and distribution of folders , With the expansion of the project , Projects with directory structure specifications and projects without specifications , The feeling is very different .

Before talking about directory structure , Let's take a brief look at the package concept of small programs .

  • There are three packages for applets -- Main package 、 Subcontracting and independent subcontracting

  • There is also a limit on the size of the inclusion -- Single subcontract / The main packet size cannot exceed 2M The size of all packets of the whole small program shall not exceed 20M

Because wechat has a limit on the size of the main packet , So we certainly shouldn't put all the logic in the main package .

There is a very obvious difference between main contracting and subcontracting , Subcontracting can refer to all contents in the main package , However, subcontracting rooms cannot be referenced to each other , It's doomed to , Our common logic must be in the main package , At the same time, another conclusion can be drawn -- Business logic can be put into different subcontracts , There is the following figure .(tabBar What is the page ?)

 Directory structure .png

There is another strange saying in the picture , What is a common component library within a subcontract ? Shouldn't all public components be placed in the main package ?

In fact, in the actual development , Due to the differences of various businesses , As a result, not every component we think can be shared , It must be for everyone to use . therefore , The author believes that if it is a common component of the business, it should be placed in the subcontract first , If other business needs do arise , We can do it Component lift , Move it to the main package , And uniformly change the references in the original subcontract .

Independent subcontracting is rarely used in development , So I won't describe it too much here .

Now you should have a certain understanding of the package body of the applet , How should we plan the directory structure in actual development ? Here the author only throws a brick to attract jade , Take a very simple example , Roughly express the writer's ideas .

 Applet root (1).png

First look at the first floor , That is, our root directory , Why is it used here app The folder wraps the contents of the real applet ? This is mainly to pave the way for our future introduction of Engineering , If the root directory is the root directory of the applet , There will be package.json Mixed use , It will be more troublesome to separate at that time .

Then in app Inside , Here is the root directory of the applet , Consistent with the official example app.js/app.json/pages Wait for the documents / Folders are placed here , The only difference is the addition of main Folder , The settings here are in accordance with the above ,main The contents of the main package are placed in the folder ,pages The contents of each business subcontract are placed in the folder , From the file directory, check the main 、 The subcontractor shall be isolated .

Followed by the main Inside the folder , It is also mentioned above , It's all about the main package , So what's in here pages The folder is naturally placed tabBar page , Then the outside is to store all kinds of public resources .

Finally, with main Of the same rank pages Folder , This is the place where all business subcontracts are stored , Each specific business can be independently packaged and stored here .

Coding style specification

The last paragraph is about comparing the structural specifications of the outer layer , Then there should be more details -- Specification of coding style .

In fact, there is not much to say , The coding style of each team must be different , Here is a brief mention .

One is a variable 、 Function name , Naming is actually a very complicated thing , We need to clarify the responsibilities of this variable or function , In this area of responsibility, think about naming that fits its practical purpose , A clear and understandable name is sometimes more important than a good internal implementation .

Then is lint、 Annotate such classic specifications , I won't go into that here .

Development mode * Optional

There are three ways to develop small programs now

  • Multi terminal development framework
  • Secondary encapsulation based on native applet development
  • Native applet development

A multiterminal development framework refers to Taro、kbone Such framework , The definition of the latter two development modes is vague , Because under the accumulation and precipitation of the team , Pure native development will also add a variety of secondary packaging to improve efficiency . Therefore, the secondary packaging mode here refers to a higher level , For example, you can use vue3 composition API To develop small program pages .

You may ask , This secondary package and multi terminal inside vue Is there any difference between writing and development ? The biggest difference between them is , The former template is still .wxml While the latter is .vue.

Which of these three ways is better , The author has no final conclusion , Each model has its own advantages and disadvantages , The only thing that's certain is , The selection of mode is inseparable from the project form , We can choose the scheme from these directions : Whether to output multiple terminals 、 What is the team's main technology stack or technology accumulation 、 Do you need to be ready to access the latest features of the applet .....

Infrastructure construction

Project development is actually a bit like building a house , Think of the whole project as a room , Our first priority in building a house is naturally to lay the foundation . Back to our code project , This step I call infrastructure construction . We must first ensure that our foundation is stable 、 Only those with high availability are qualified to talk about how gorgeous the interior decoration of our house is , Otherwise, they are castles in the air , One touch and one fall .

Login status

First, we need to focus on the login status , The login status is the status of the user in our applet Id card , We must ensure that every user can operate our program with the correct login status , Otherwise, there will be unpredictable consequences , If it's light, bury the point and report disorder , More importantly, it will affect the stability of data in the database .

So how to ensure that our login status can be obtained and maintained stably , The author believes that the most basic point is the need for maintenance Unified login method , After the beam path is closed, it can maintain stability . Next, the author will talk about login status in two parts , Due to different business needs , There may be two login states in an applet -- Applet login status as well as Own account system login status .

Applet login status

The applet login status here refers to calling wx.login obtain code And use the code In exchange for the user in this applet openid The process of

Ideally , We should be able to provide a common method to the outside world miniappLogin, This method does not need to care about whether a valid login status has been obtained , Just pass... Every time you call wx.checkSessionAPI Confirm login status , If it fails, log in again .( Back end implementations are provided at the end of the article , And the source code address of the whole process )


Own account system login status

Why is there another login status here ? They are two different login systems , In fact, the login status provided by the applet can also meet our needs for login status , It has a unique identification ID And maintain a set of effective logic , For small businesses, it can be directly applied .

But when the business is large , Especially if you have multiple applets under the same subject , In this case, we need to formulate a new unique identification field , As the identity of this user , And no matter in which applet , The identity of the user is consistent .

This so-called new field is actually our H5 Often seen during development userid,uid wait , The generation of identification varies from person to person , Each team is accountable to its users ID The requirements are different , Some may be ordinary random strings , Some may be encrypted strings . Except for users ID, Generally, the login status also contains a valid token perhaps accessToken Field , Just like wechat session_key equally , Used to judge the validity of login status .

How to generate userid as well as token There is basically no general scheme , All need to be designed in combination with business needs , But the premise is quite clear -- You must successfully obtain the user's openid as well as unionid after , To register users and generate login status .

Request to packaging

Since the separation of front and back ends has become a consensus , request It has become something that the front end must contact .

In a normal project , Almost every page has multiple requests , If we don't make a unified and standardized encapsulation of the request as soon as possible , The project will soon fall into a strange circle -- as time goes on , We will find that the request agreement of the project becomes more and more onerous , In the end, no one dared to sort out the contents of the agreement , For fear that the adjustment will affect the overall request .

Because there are great differences between projects , Of course, we can't come up with a set of request logic that everyone can use , I can only write a little sample code .

carbon (1).png

As the pseudo code above , First, a general request class is declared Request, And on this basis , Develop the request method that the business really needs to use .

In the example , The author simply preset three types of requests defaultRequestconfigRequestcfRequest. In fact, in the actual development , We need a lot more request types than this , But these three kinds of requests are indispensable .

// General service request 
const defaultRequest = (...args) => {
const r = new Request({ baseURL: BASE_URL })
return r.request(...args);
 Copy code 

First of all defaultRequest, As the name suggests, it is the default request mode , In addition to interacting with users, the front end , The most common thing to do is to interact with the back end , This request is used in this case , It may be a form submission or a status query ......

// Page configuration request 
const configRequest = (someKey, data = {}) => {
const r = new Request({ baseURL: `${BASE_URL}/config-api` });
return r.request('getConfigBySomeKey', { someKey, });
 Copy code 

Then is configRequest, This is a special request paradigm conceived by the author . Now? Configuration change It's already mainstream thinking , We all want to achieve rapid verification through the configuration of the front-end page 、 The purpose of agile , So we should also take it into account when designing the framework . We should consciously separate configuration requests from business requests , In the original development , We always couple them together . But think about it , They differ significantly , One is to pull the interface configuration , The other is the trigger of back-end operation , We can decouple the project when it is conceived .

// Cloud function request 
const cfRequest = (cfKey, data = {}) => {
const r = new Request({ baseURL: BASE_CF_URL });
return r.request(cfKey, { });
 Copy code 

See here , Maybe some children's shoes with rich practical experience will ask , There are some cases , What we need at the front end is not a static configuration , It is a configuration that requires a series of processing with the back-end data . This question is very valuable , This situation is inevitable , But it can also be completely solved , With our last request cfRequest that will do .

Cloud functions , It's not particularly novel , But I feel that the penetration rate is still not too high . Talk a little about ideas , Here I think cfRequest It's a high-order configRequest, We can do it in the cloud function defaultRequestconfigRequest Request , And configure the processing according to the returned data , Output out of the box data to the front end .

in addition , The cloud function can not only be used for page configuration pull , It can also be based on what the backend provides Atomic level Interface , Add, delete, modify and check , There will be no expansion here , Issues involving the team's responsibility boundary for cloud functions , If given the chance , It can be described in a new article .

Finally, I'd like to say one more word , The advantages of encapsulating requests are in addition to convenience 、 There is another important point beyond the specification , It can be used for subsequent Report of buried points Provide great convenience .

About Request The complete code can be Click here (Github)

Route encapsulation

Jump of applet API It's special , And H5 The route jump is different , But our idea of encapsulation is actually the same .

Routing encapsulation is mainly to solve the following problems :

  • Maximum page level
  • Routing data transfer
  • Report of buried points

The routing level of wechat applet only supports to 10 layer , If you want to jump to a new page on the tenth page, you will report an error and cannot jump normally . So we need to deal with navigateTo Type jump, plus the judgment of the current page level , If the page level has reached 10 layer , Can be navigateTo The jump becomes redirectTo, So as to ensure that this jump can be carried out normally .

options.action = 'navigateTo';
const { _pathName, _query } = _navigateFormator(path, query);
if (getCurrentPages().length >= 10) {
options.action = 'redirectTo';
 Copy code 

Then there is the problem of data transmission , When we do all kinds of jumps , Always want to transfer some data from the original page to the target page . Although the applet now provides EventChannel To communicate between pages , But the usage is still troublesome . If we can stop the jump mode of the whole project , Then we can maintain the page transfer data in the unified encapsulated routing method .

constructor(options = {}) {
this.routes = {};
router(path, query, options) {
// ...
const preloadData = typeof options.preloadData === 'function' ? options.preloadData() : options.preloadData;
const routeID = _randomString(6);
query.__routeID = routeID;
this.routes[routeID] = {
// ...
 Copy code 

Finally, there is the problem of buried point reporting , Like the request mentioned above , Unified operation , Reporting to the burial site is beneficial without harm . We can implement a default jump complete Callback , Implement the logic related to reporting in this callback . Here is a simple package router Code , There are many details that can be optimized according to business needs , It doesn't extend here .

About Router The complete code can be Click here (Github)

page 、 Component initialization function

The essence is exposed to applets Page、Component Function for secondary encapsulation .

With the development in depth , We want to be able to get some globally shared parameters or methods at the beginning of page loading , At this time, you need to develop pages 、 Component initialization function . The author sums up , When we encounter the following situations, we can consider developing a unified initialization function .

  • Some operations need to be performed uniformly during page or component initialization , For example, load and report
  • You need to get some global parameters or tool classes in multiple pages or components

carbon (2).png

As above code block , stay defaultPage Object declares onLoad function , Perform some page initialization operations inside , It is agreed that all the data generated in this stage will be stored in$$define in .

In the example , The author has completed these initial actions :

  • Get global data
  • Save page link parameters Everyone should encounter this troublesome problem when developing small program pages , In Africa onLoad It's always troublesome to get link parameters during the cycle .
  • Process agreed data Under strong constraints , We can preprocess some agreed data , For example, for url decode ......

It's just the tip of the iceberg , You can according to business needs , Add more logic , Make development more convenient .

The complete code for the initialization function can Click here (Github)

Common component library

The public component library in the applet is the same as we usually H5 What you see inside is different , Because applets have two limitations Inclusion size Subcontracting rooms shall not refer to each other , So we can't put the component library in a subcontract alone , Can only be put in the main bag , Then it extends to another problem , The volume of inclusion .

stay Directory structure specification It is mentioned in the section , The author does not advocate that all extracted components be placed in the main package as global public components , And adopt a Component lift The way , When a component really needs to be referenced by other businesses , It can be promoted to the main package , This not only ensures the stable development of the main package volume , It can also conduct secondary audit on components .

Infrastructure documentation

!! The construction and accumulation of team technical documents must not be ignored

Quote a classic sentence that you don't know where it came from -- The auxiliary of iron , The output of running water

Use the scenario in this article to simply misunderstand once :

The turnover rate within the team is probably frequent , Whether it is post adjustment or manpower increase or decrease , Are inevitable . At this time, we need a stable auxiliary To ensure the sustainability of our project , That's our Technical documentation .

So what is the role of technical documents ? It may be difficult to detect their existence at ordinary times , Even when you want to write , It's going to be hard .

Based on my experience in the team over the years , The following points are summarized :

  • The technical documentation is a guide The original intention of technical documents is to provide guidance services for new students or new students , The level of detail of documents directly affects the speed of everyone's integration into the project .

  • Writing technical documents is a kind of double disk Take a component document as an example , There must be a record of component usage in the document , Like receiving parameters or passing events , Will reappear in front of the component author at this time . This is a good opportunity to resume the offer , We can revisit the component details , For example, whether a parameter really must , Another example is whether an event should notify the parent component ......

  • Technical documents are the embodiment of team technology precipitation The author thinks , A technical team not only ensures the maintenance iteration of project requirements , It should also have its own technical precipitation , Technical documentation is one of the methods of technical precipitation . In the short term , Technical document editing can be a thankless job , But look far away , This is a kind of Planting trees Move , as time goes on , We will look back at this towering tree in the shade .

Business development

Every company has its own business development process , This piece cannot be unified , We should fully observe the company's internal workflow and combine the company's business form , Dynamically adjust the development mode most suitable for the team .

Test and release

This part mainly describes the black box test process , And by the way, it introduces release related content .

Before we get to the topic , We need to think about one thing -- Judge whether it is necessary to apply according to the scale of its own business Two Applet .

If it is a relatively large business , It is recommended to prepare two applets , One for testing , The other is for official release .

If you can make it clear that the business is small , Or a MVP project , We can just prepare a small program .

below , The author will start from these two projects , The test modes of the two projects are introduced respectively .

MVP project

 Agile Projects .png

There are currently three versions of applets Development Edition Experience version as well as Official version , Both the development version and the experience version have certain access restrictions , The official version is accessible to all users . According to the characteristics of each version , We can make the following version planning :

  • Development Edition -- Usually used by developers , Version is the local applet code , It is only used for self-test in the development stage .
  • Experience version -- A version with relatively stable functional features , Generally used to test intervention , It can be used for product walk through in the later stage .
  • Official version -- The functional features have been very stable and tested 、 walkthrough , At this stage, the applet will be officially released .

This is the ideal version plan , But in the actual project promotion , There will certainly be multiple requirements interspersed development to , At this time, the experience version will be repeatedly overwritten , It is very unfavorable to test and walk through . So why can't we test with the development version ?

Not at all , Because there are very few users who can have development permission , If the team is small , Yes, they can all be tested in the development version , Then walk through the experience version . But a slightly larger team can't do that , Only testers can be migrated to experience permissions .

If you find , The project is much larger than expected , And the team is also relatively large , We should consider converting the project into A large project Test plan of .

A large project

 A large project .png

Pictured , Large projects will have two small programs , A small program dedicated to testing , The functions of each version are the same as MVP The project is similar to , The only difference is that the timing of the walk-in has changed , In large projects, we will choose a more stable version for product development 、 Design walk through , That is, the official version of the applet .

Another small program is a small program that will be released , The code is absolutely stable when it comes here , So only one experience version is left here , Pre release experience in this experience version , Basically, it can be understood as a formal applet in gray stage .

In the above test section , There are many versions , So how are these versions released 、 Deployed to wechat ?

  • Use wechat developer tools

  • Use the official wechat CI Tools

Both of the above methods can turn the local development version applet into an experience version applet , If you want external users to access our applet, you need to log in WeChat public platform , Enter the operation background of the corresponding applet , Conduct version review and release , There's nothing to say about this , Fill in the data submitted by the applet according to the instructions on the interface .


Thank you for seeing the end :)

If the above contents are successfully built , Our little program has a prototype , With the deepening of business development , We can summarize and abstract more in line with the team's business development “ wheel ”, Make our applet more robust .

Next, the author will give you some additional business realization , The following implementation and the code implementation mentioned above will be implemented in This warehouse It's recorded in .

iShot2021-09-08 23.30.29.png

in addition , There's another one in the warehouse miniapp-startkit Catalog , This is a project that will continue to iterate , It is the final implementation of the content of this article , Students in need can star Focus on ~

Please bring the original link to reprint ,thank
Similar articles