preface
With the release of version 1.0, Rax’s conversion capabilities on the small program side have been enhanced. Now, you can use Rax for applets just like you used to do for Web/Weex applications. This series of articles will introduce the realization principle of Rax to applet link. This is the first article in this series.
First of all, we need to have a certain understanding of the development mode of small procedures (if there is no special explanation, the small procedures in the article refer to alipay small procedures). You can look up here and get a sense of the framework of the whole applet architecture. This article assumes that the reader already knows the above. To clarify what to do with a transformation link, let’s take the simplest case: when developing a project using Rax, the contents of a single component look like this:
// foo.js
import { createElement } from 'rax';
import View from 'rax-view';
export default (props) => {
return (
<View>Hello World!</View>
);
};
Copy the code
After processing, the applet code corresponding to this component should contain foo.js, foo.axml, and foo.json files with the same name (and an additional foo.acss file if there is styled content). Where foo.js will contain the business logic in the source file, foo.axml will correspond to the JSX in the source file, and foo.json will need to contain declarations that the source file introduces custom components (in this case only rax-view). The Rax to applet link does just that. Of course, this is only a simple single component level conversion, project level construction will have a lot of complex issues to consider, we will analyze the Rax to applet link in engineering implementation principle.
An overview of
Let’s take a look at the overall architecture:
CLI
loader
compiler
runtime
This article introduces two engineering modules, CLI and Loader.
CLI
The CLI and Loader are introduced together because they are functionally closely related. The CLI itself relies on Webpack for dependency analysis of the project, and then invokes various Loaders provided by the Loader layer to process files of corresponding types. The CLI provides two commands: Watch and build. The former is used to monitor code changes and compile in real time. Compared with the former, the latter will eliminate some debugging code (such as Source Map) and compress the code to complete compilation and packaging.
In terms of implementation, the CLI itself is not complicated. In a word, it reads various necessary parameters from the command line and passes them into Webpack for execution. Using webPack’s dependency analysis capabilities, we can iterate through all the valid code and hand it over to the appropriate loader for processing. What does an entry file look like, and how does it declare dependencies? Because in the applets native development framework, the entry file app.js does not declare dependencies, while Pages is registered in app.json. The following needs to introduce the Rax small program project directory.
In order to maintain unity, Rax uses the same set of project directories. When we create a small program project using RAx-scripts, the directory structure looks like this:
.├ ── ├─ ├─ download.txt # ├─ ├─ download.txt # ├─ ├─ download.txt # Download.txt # ├─ ├─ download.txt # Download.txt # Download.txt # Download.txt # Download.txt # download.txt # download.txt Including routing configuration, ├─ ├─ ├─ CSS │ ├─ ├─ ├─ ├─ │ ├─ ├─ index.jsx # ├─ ├─ ├─ ├─ ├─ ├─ ├─ ├─ ├─ ├─ ├─ ├─ ├─ index.jsx # ├ ─ ─ the document # page's HTML template │ └ ─ ─ index. The JSX └ ─ ─ pages # page └ ─ ─ Home # Home page └ ─ ─ index. The JSXCopy the code
App. json contains the routing configuration. The default content is as follows:
{
"routes": [{"path": "/"."source": "pages/Home/index"}]."window": {
"defaultTitle": Rax App "1.0"}}Copy the code
The CLI reads the routes content and includes all referenced Pages files and app.js as entry, similar to the configuration of a multi-page application. At this point, with the Pages file as the entrance, all dependent files will be traversed and handed to the corresponding loader for processing. After loader processing, the final compiled code will be generated to the destination directory, but the bundle generated by WebPack by default is not needed for us, so we can set the outputFileSystem as an in-memory file system so that it will not be produced to disk.
loader
The following five role Loaders exist in jSX2mp-loader to process corresponding files. Their functions are described below.
app && page && component loader
In a word, the main function of the three loaders is to read the corresponding type of file content (app-loader handles the app.js in Rax source code, page-loader handles the page type component defined in the routes attribute in app.json. Component-loader handles component-type components) and is handed over to jSX-Compiler, which then produces compiled code that is written to the specified destination folder. In addition, each loader has its own specific responsibilities:
- app-loader
- Handle app.json
window
Property and make alipay/wechat both ends of the configuration flat
- Handle app.json
- page-loader
- Is written to the JSON file based on the information parsed into the JSX-Compiler for the component referenced by the component
usingComponents
Property, and add these components to the WebPack dependency analysis chain and hand them over to component-Loader - Handle user definitions in app.json
routes
The configuration of each page in the array (i.ewindow
Configuration item) and output it to the JSON file on the corresponding page
- Is written to the JSON file based on the information parsed into the JSX-Compiler for the component referenced by the component
- component-loader
- Is written to the JSON file based on the information parsed into the JSX-Compiler for the component referenced by the component
usingComponents
Property, and add these components to the WebPack dependency analysis chain and hand them over to component-Loader
- Is written to the JSON file based on the information parsed into the JSX-Compiler for the component referenced by the component
file loader
Process static file resources such as images and copy them to the specified destination folder.
script loader
Of all loaders, script-loader has the most heavy task. Script-loader is responsible for processing all JS files. For JS files, one of the most important issues to consider is path-dependent processing. In Rax to applets link, by default we extract and copy the files used in node_module to the target folder for the following two reasons:
- Wechat applet project does not support the direct use of NPM package (wechat did not support it when we designed the scheme, but now we can use NPM package by clicking “Build NPM” function in IDE. The principle is also to copy and extract NPM package file to its specified miniprogram_npm directory).
- Although Alipay applet supports the use of NPM package, if the NPM package does not release ES5 syntax files according to the standard, it cannot be used normally. By default, alipay applet will not compile files in node_modules, because it will slow down the compilation speed (however, in the latest version, Alipay already supports the basic ES6 to ES5 processing for NPM package).
Therefore, dependency path processing is one of the most core functions of script-Loader. Its basic workflow is as follows: Collect NPM dependencies used in code, obtain the real address of NPM package => path processing => Babel compilation => output code to target folder.
In the Rax applets project, you can do this for pure JS files from the NPM package (such as loadsh) or native JS files written by the user (such as utils). For the following two types, script-loader requires some additional operations in addition to the basic flow described above:
Third-party native applets from the NPM package
When the user uses the absolute path to use the third-party native applet library, script-loader needs to read the usingComponents field in the JSON file with the same name in the JS file and add it to the dependency analysis chain of Webpack
Applets from the NPM package developed and distributed under the Polymorphic Component (library) protocol
The polymorphic component (library) protocol can be viewed here. The basic components of Rax support the applets side based on this protocol. In fact, by using the absolute path to introduction of native components use small program can completely meet the requirements, but Rax targeting multiterminal unified development framework, doing so will make development generated when the small program end platform specific code, can’t really do a full set of code to run, so we designed a polymorphic components (library) agreement. The user can import components from the applet side and write code like import View from ‘rax-view’ on the Web/Weex side But it’s actually up to script-loader to read the value of the miniappConfig field in package.json to get the actual address of the native applet component used. Based on polymorphic component (library) protocol, users can easily build and publish Rax applets, and then introduce them into Rax projects.
conclusion
This paper describes the basic principle of JSX2MP-CLI and JSX2MP-Loader, and also summarizes the whole context of Rax to small program link engineering. Stay tuned for further articles on how jSX-Compiler handles compilation and how JSX2MP-Runtime supports runtime and smoothen out the differences between native applets and Rax instances.
other
- Rax open source repository
- The articles
- Spike communication group
- Rax wechat communication group
- Rax applets external user q&A group