Ada is an evolutionary large front-end architecture independently developed by Zhaopin. After it was officially put into use in 2017, it has continued to evolve for three years, covering all aspects from RESEARCH and development to operation and maintenance. It has cross-technology stack engineering system, interactive graphical interface development tools, automatic release process, Serverless runtime and perfect monitoring and warning facilities. At present, it has supported hundreds of projects within the group, with thousands of online urls and more than a billion requests per day.

This paper will extract some key characteristics of Ada and introduce the evolution results and design ideas of Ada.

Evolvable engineering mechanisms

“Evolvable” is the core design idea of Ada.

Ada’s original version was actually the kernel, and it has been evolving every two to three weeks since its launch, constantly consolidating the kernel, improving the surrounding facilities, and opening up more r&d capabilities. We want all projects to enjoy the features of the latest version, and we don’t want to see projects become fragmented over time.

Given that Webpack’s flexibility and complexity would inevitably encourage fragmentation, we decided to hide it inside Ada and let Ada take responsibility for unifying the engineering mechanism.

Ada standardized the directory structure of the project, treated the sub-directories under the specified directory as Webpack Entry, realized the support for SPA and MPA at the same time, and made it easier to support the complex view of huge magnitude.

At the same time, Ada also unified the use of Webpack Loader and plug-in, CDN address, Code Split, SourceMap, Code compression and other construction details, and automatically handled the differences between different deployment environments, standardized the construction output form of the project.

Ada also provides business teams with a more streamlined project configuration file for possible reasonable differences between projects, such as domain names, root paths, and language processors (Webpack Loaders).

Through engineering specifications and engineering profiles, we molded Ada into a “Webpack configuration engineer” who handles all Webpack related work without the business team having to worry about such details. As a result, we have more governance and evolution capabilities for engineering mechanisms, able to iterate (such as tweaking logic, fixing problems, upgrading Webpack versions, even switching to other packaging tools, and so on) without impacting the business team.

Support for multiple frameworks

To better support business-specific technology requirements and respond to emerging new frameworks and technologies, Ada made multi-framework support an important design goal from the outset.

Based on the unified engineering mechanism, Ada can adjust Webpack configuration according to the characteristics of various frames and form new scaffolds. Consistent engineering specifications and engineering profiles are used for all scaffolds to maximize a consistent development experience and reduce switching costs for frames.

We chose vue.js as the company’s main front-end framework and developed specialized scaffolding for it. The vue.js scaffolding retains the advantages of vue.js in terms of r&d efficiency, allowing developers to configure multiple CSS processors, and providing good support for server-side rendering.

Ada then provided Weex scaffolding to support rapid mobile development, helping business teams run a set of code in browsers, iOS, and Android at the same time.

For businesses that need support for older versions of IE, we have chosen knockout.js, the grandparent of the MVVM pattern, and have introduced the much-acclaimed single-file component mechanism of vue. js into the Knockout.js scaffolding, providing developers with the same experience as vue. js scaffolding.

Ada also provides node.js scaffolding for Web API development and gradually adds TypeScript support and GraphQL development capabilities to it.

The “evolvable” Ada engineering mechanism leaves ample room for expansion of the new framework and makes it easier to keep up with the release of the framework and continue to open up the full capabilities of the framework to business teams.

Server side development capability

Ada developed Web servers based on Koa, and opened up server-side development capabilities, giving front-end engineers more complete control. In addition to performing permissions verification, redirection, and server-side rendering (SSR) operations at the UI level, the Backend for Frontend (BFF) layer can be developed through Web API. Complete server-side development capabilities can move the front and back interfaces (or friction surfaces) from the complex view level to the relatively simple and controllable BFF level, achieving true separation of the front and back, and maximizing development efficiency through parallel development.

In order to further reduce the difficulty of server-side research and development, Ada further standardized the declaration way of routing function on the basis of scaffolding directory structure specification, and formed the mapping relationship from HTTP request to function. The request function is an asynchronous function to which Ada passes a context object. This is a carefully encapsulated object that contains all information about the current Request, provides full control over the Response, and unites the Web API with the SSR API.

With a request function mapping mechanism and custom context objects, Ada provides developers with a more straightforward, request-oriented approach to development, while hiding the technical details of Koa and Web servers. This design allows the business team to focus more on product iterations, and the architecture team to perform routine maintenance and continuous evolution (tweaking logic, expanding capabilities, upgrading Node.js versions, even switching to other Web server frameworks, and so on) without the business team being aware of it.

Serverless architecture

In the lower threshold of server-side development at the same time, we also hope to be able to reduce degree of difficulty of operations management server, distract front-end engineers don’t have to be in such as operating system, basic services, network, performance, capacity, availability, stability, security and other operational details, so as to put more effort into the business and professional skills. With this in mind, we introduced the Serverless architecture.

We use container technology to build a service cluster and evolve Ada into a more generic runtime that not only discovers functions and responds to URL requests by executing functions, but also guarantees the runtime itself. The Ada server has a complete request lifecycle tracking mechanism and logging API, which can automatically identify and block malicious requests and automatically recover from common Node.js failures. In addition, service clusters also have comprehensive security defense and performance monitoring facilities, and achieve flexible capacity expansion, which can save costs and better cope with traffic fluctuations.

In this way, the service is separated from the project and becomes a member of the Serverless service cluster, which is then connected to the project through the publishing process. The release process also runs in the cloud, with two phases: deployment and live. The deployment phase only does file build, upload, and register, and has no impact on the online version. Once deployed, a specific VERSION of the URL can be live in the release center and rolled back to the historical version at any time. Both publishing and rolling back will take effect immediately.

The RELEASE mode of URL granularity is more flexible and in line with the iterative habit of front-end services, and more secure and controllable than the overall release mode of individual applications. Engineering, as a form of code organization, no longer bears the responsibility of service. It can be merged and split at any time according to the need, and it can better adapt to the organizational form of virtual team.

The workbench

Like many frameworks, Ada early provided a command-line tool to aid development. The limitations of command-line tools are obvious in that they are too simple to present and interact with. With the gradual adoption of Ada, the information generated and the operation involved in the daily development process are more and more complicated. We needed a more expressive tool to further improve productivity, and we developed the Ada workbench based on Electron.

Ada Workbench is not a simple copy of command line functionality, but a bold imagination and redefinition of front-end graphical interface development tools. We have added rich functions to Ada workbench, comprehensively covering the development, debugging, release and other links in the front-end workflow, making it a real one-stop front-end development tool.

We introduced urL-level on-demand builds in the Ada workbench. After the developer selects the URL, the Ada workbench automatically launches multiple builders to perform the build, presenting the build as a legend. Any problems with the build, such as missing references or failing to pass the development specification check, are visually displayed, and clicking on the prompt leads to more detailed information. Build on demand not only speeds up builds, but also avoids some of the problems that Webpack can have when building large projects.

In addition to starting a build manually, the Ada workbench provides a more convenient way to “access as build” by listening for access to the URL, automatically starting an on-demand build, and actively refreshing the page when the build is complete. “Access as Build” quickly became the preferred build method for developers by triggering builds through natural, native debugging behavior and eliminating the need to manually select urls one by one.

Although the server-side code ultimately runs in the Serverless environment, it does not mean that the development stage can only be remote debugging, in order to facilitate debugging, Ada workbench built a development version of Ada server, this version only adaption to the local development process and function reduction, other features and Serverless version maintain a high degree of consistency. The productivity barriers that plagued developers, such as port conflicts and environmental differences, have largely been removed.

The Ada Workbench also provides an interactive log viewer to help developers navigate logs generated during native development. All logs are presented in a very simple form. You can click to browse the details. It also provides functions such as keyword search and log level filtering, so that developers can quickly find the debugging information they are interested in.

The publishing process is also seamlessly embedded into the Ada workbench and has been further enhanced to easily perform URL-level on-demand publishing.

At present, Ada workbench has become an important infrastructure of the company’s front-end technology system. New concepts continue to emerge in the field of front-end technology, and the Ada workbench is still very much in the imagination, which makes us more excited about its future role.

Mobile terminal development ability

We chose Weex as a quick development framework for mobile, helping business teams develop applications that can run in browsers, iOS, and Android using the familiar vue.js syntax.

Weex scaffolding follows the engineering mechanism of Ada, you can enjoy the development and debugging convenience provided by Ada workbench. In addition, the Ada workbench also comes with a built-in Weex debugging tool in the form of a plug-in for in-app debugging.

In terms of development mode, we retain the characteristics of Web to the maximum extent, bringing more familiar development experience to front-end engineers. Web-style URL routing is also supported in Native kernel. The Native kernel provides Weex with full support, including routing, caching, view components, interop apis, and more. In view of the differences of Native platforms left over from history, the mobile-JS-Bridge developed by us is used to encapsulate them into a consistent API.

In addition, we also provide URL-granularity publishing capability for Weex, which can be published independently of the App version, greatly improving the speed of iteration and problem response on mobile terminals.

Ada gave full play to the advantages of Weex in rapid iteration, widely used in the company’s various mobile products, has helped the business team agreed to a number of fast delivery campaigns.

Ability to expand

Ada supports the development of a special view, Widget, in addition to Web pages. As an implementation of the microfront-end architecture, widgets run in a host page and can be developed and published independently. Its design goal is to decouple code, process, and team to help business teams reuse functionality across technology stacks, products, and teams. For example, all of the company’s product lines need to use a common login and registration Widget, which is maintained by the platform team and can evolve iteratively on its own with compatibility rather than having to be released version by version across product lines. The Widget SDK is responsible for maintaining the Widget’s life cycle and provides a Web worker-like communication mechanism that makes widgets and host pages completely independent in terms of technical framework, code logic, and publishing process.

Widgets are a mechanism for reusing capabilities on the client side. On the server side, Ada provides request context extensions for reusing capabilities. A request context extension is a set of functions that can be developed and published independently, after which functions are attached to the request context for invocation by a specific scope of request functions. With request context extensions, business teams can more easily reuse server-side common capabilities such as user authentication and authorization.

In addition, the Ada server comes with multiple versions of common third-party modules such as Vue-server-Renderer, Axios, and PG. Developers can reference custom versions of these public modules through a dedicated public module API. On the one hand, the public module uniformly provided by Ada server improves the construction speed of the project and reduces the output volume. On the other hand, it also avoids the problem that Webpack cannot process Node.js Native.

After a lot of research and practice with GraphQL, we decided to provide GraphQL development capabilities in the form of toolkits. The GraphQL toolkit supports both GraphQL-JS and Apollo GraphQL implementations, and can convert schemas into Ada request functions for execution in Ada servers. The GraphQL toolkit recognizes asynchronous resolvers in the Schema and registers them with Ada Server’s performance monitoring and request tracing mechanisms to facilitate business teams in locating problems in requests that combine multiple operations.

This capability expansion is a typical example of how Ada’s “evolvability” enables us to be more robust in responding to business needs and continuously transform technology insights into new capabilities that can be delivered to business teams in a more Ada format.

Quality assurance

We have adopted a variety of technical means to ensure the quality of Ada core code and the stability of Serverless service cluster.

Ada core code follows fairly strict development specifications and covers 100% of the code and execution paths through thousands of unit test cases. In response to the possibility of “unintentional overwriting” in unit tests, we specifically designed “chaos mode” to verify the comprehensiveness of test cases by randomly deleting specific code.

To ensure that changes to the Ada server did not break downward compatibility of the API, we deployed the test version of Ada to a set of test containers during the integration test phase and requested pre-published test urls to check API functionality one by one. The Serverless service cluster is also equipped with comprehensive log analysis, performance monitoring, elastic scaling, fault recovery, and early warning mechanisms.

In addition, we have developed front-end development specifications, covering engineering specifications and code specifications for JavaScript, TypeScript, vue.js, CSS, Jest and other languages or frameworks. In addition, it develops matching inspection tools based on ESLint and StyleLint to supplement some unique rules. It was then integrated into engineering mechanisms, Ada workbenches, and continuous integration processes to help business teams find and correct problems in real time.

To further ensure users’ browsing experience, we developed a Web performance monitoring platform based on Google Chrome Lighthouse to track the performance of core products across the country over a long period of time. A Sentry-based error tracking and analysis platform is also being piloted.

Afterword.

Ada has been running stably for three years and has been evolving continuously for three years. It has gone through three stages:

  • In the stage of “building kernel”, Ada engineering mechanism and server kernel were quickly finalized and put into trial operation.
  • In the “facilities improvement” stage, the surrounding facilities of Serverless architecture tend to be improved, comprehensively improving the performance and stability;
  • In the “Rich architecture” phase, a series of peripheral extension capabilities such as Ada workbench and Widgets were introduced to explore more possibilities.

Ada will continue to embrace changing front-end technologies and respond to changing business needs in the future. The server development capability will no longer be limited to the BFF layer, but will also be open to developers full stack development capability; Widget is just a small attempt by Ada to dabble in the micro front end. We will also introduce micro front end solutions to facilitate deeper business integration. The request function mapping mechanism will evolve from faAS-like to true FaaS…

This paper introduces Ada, the big front-end architecture of Zhaopin.com, from a macro level, without too much technical details. If you are interested in a particular feature, please leave a message and tell us, and we will write a special article to introduce it in detail.

recruitment

As the front-end architecture team of Zhaopin, we are always looking for like-minded front-end architects and senior engineers. If you share our passion for technology, learning and exploration, please join us! Please send your resume to [email protected] or search WindieChai on wechat.