A method, system, device, and medium for supporting the customization of SaaS application interfaces
By generating slot identifiers (IDs) and custom rendering functions in React applications, and using Babel plugins to obtain variables and dynamically load customized code, the problem of frequent modifications to customization requirements in SaaS applications is solved, improving the stability and maintainability of the application.
Patent Information
- Authority / Receiving Office
- CN · China
- Patent Type
- Patents(China)
- Current Assignee / Owner
- SUZHOU GAIYA INFORMATION TECH
- Filing Date
- 2025-04-07
- Publication Date
- 2026-05-26
Smart Images

Figure CN120353461B_ABST
Abstract
Description
Technical Field
[0001] This application relates to the field of application software technology, specifically to a method, system, device, and medium that supports the customization of SaaS application interfaces. Background Technology
[0002] SaaS (Software as a Service) applications typically provide services through a multi-tenant architecture, meaning the same application shares resources and functionality among different tenants (users). To support diverse business needs and personalized user requirements, SaaS applications usually need to offer a certain degree of customization. More and more enterprises are choosing to use SaaS applications to support their business operations. In SaaS applications, multiple tenants share the same set of application code; this multi-tenant architecture can significantly reduce operating costs and improve resource utilization.
[0003] In existing technologies, SaaS applications combining React and Babel provide a solid technical foundation for multi-tenancy. Within the React framework, Babel compiles and transpiles JavaScript, allowing developers to modularize the application's core logic and UI components. Different components or styles are loaded based on specific logic. However, dealing with increasingly complex customization needs often requires frequent code modifications and releases, with each update potentially impacting the business of multiple tenants. As user demands grow, especially in environments with frequent updates and iterations, maintaining such code becomes difficult and risky, leading to poor stability in SaaS applications. Summary of the Invention
[0004] This application provides a method, system, device, and medium that supports the customization of SaaS application interfaces, thereby improving code maintainability and the stability of SaaS applications.
[0005] Firstly, this application provides a method for supporting the customization of SaaS application interfaces, the method including:
[0006] Scan the original React element nodes in the React application, generate slot identifier IDs corresponding to each original React element node, and add the slot identifier IDs to the corresponding original React element nodes to obtain the React element nodes after addition;
[0007] By traversing each React element node using the Babel plugin, the available variables in the scope chain of each React element node are obtained, and a variable collection object is generated.
[0008] A custom rendering function is generated based on the React element node. The input parameters of the custom rendering function include the original React element node, the variable collection object, and the corresponding slot identifier ID.
[0009] In response to a tenant's customization request, a customized code file for the tenant's corresponding slot identifier ID is generated based on the customization request;
[0010] During interface rendering, the corresponding customized code file is loaded based on the tenant's identity detection, so that the custom rendering function calls the corresponding customized code to perform interface rendering based on the slot identifier ID.
[0011] By adopting the above technical solution, and scanning the original React element nodes in the React application to generate slot identifier IDs, combined with Babel plugins to traverse and obtain available variables in the scope chain, the customized code is decoupled from the original business code. A custom rendering function receives the original React element nodes, variable collection objects, and slot identifier IDs as input parameters, enabling the customized code to accurately locate the UI elements that need modification and obtain the necessary variable information. When a tenant submits a customization request, the system generates the corresponding customized code file based on the slot identifier ID and dynamically loads these code files based on the tenant's identity during UI rendering, ensuring that the customized code of different tenants is isolated from each other. This slot identifier-based and dynamic loading approach avoids the frequent code modification and release issues of traditional solutions, reduces the complexity of code maintenance, and, due to the independent storage and on-demand loading of customized code, reduces the impact of code updates on other tenants, thereby improving the overall stability of the SaaS application.
[0012] A second aspect of this application provides a system that supports the customization of SaaS application interfaces, the system comprising:
[0013] The slot identifier determination module is used to scan the original React element nodes in the React application, generate slot identifier IDs corresponding to each original React element node, and add the slot identifier IDs to the corresponding original React element nodes to obtain the added React element nodes.
[0014] The variable collection generation module is used to traverse each React element node through the Babel plugin, obtain the available variables in the scope chain of each React element node, and generate a variable collection object.
[0015] The rendering function determination module is used to generate a custom rendering function based on the React element node. The input parameters of the custom rendering function include the original React element node, the variable collection object, and the corresponding slot identifier ID.
[0016] The code file generation module is used to respond to a tenant's customization request and generate a customized code file with the corresponding slot identifier ID of the tenant according to the customization request;
[0017] The interface rendering module is used to detect the identity of the tenant and load the corresponding customized code file when rendering the interface, so that the custom rendering function calls the corresponding customized code to render the interface according to the slot identifier ID.
[0018] A third aspect of this application provides a computer storage medium storing a plurality of instructions adapted for loading by a processor and executing the method steps described above.
[0019] A fourth aspect of this application provides an electronic device, comprising: a processor and a memory; wherein the memory stores a computer program adapted to be loaded by the processor and to execute the above-described method steps.
[0020] In summary, one or more technical solutions provided in the embodiments of this application have at least the following technical effects or advantages:
[0021] This application achieves decoupling between customized code and original business code by scanning the original React element nodes in the React application and generating slot identifier IDs. Combined with a Babel plugin to traverse and retrieve available variables in the scope chain, this decouples customized code from the original business code. A custom rendering function receives the original React element nodes, a variable collection object, and the slot identifier IDs as input parameters, enabling the customized code to accurately locate the UI elements that need modification and obtain the necessary variable information. When a tenant submits a customization request, the system generates the corresponding customized code file based on the slot identifier ID and dynamically loads these code files based on the tenant's identity during UI rendering, ensuring that customized code from different tenants is isolated. This slot identifier-based and dynamically loaded approach avoids the frequent code modification and release issues of traditional solutions, reducing code maintenance complexity. Furthermore, the independent storage and on-demand loading of customized code minimizes the impact of code updates on other tenants, thereby improving the overall stability of the SaaS application. Attached Figure Description
[0022] Figure 1 This is a flowchart illustrating a method for supporting the customization of SaaS application interfaces provided in an embodiment of this application;
[0023] Figure 2 This is a schematic diagram of a system module that supports the customization of SaaS application interfaces, provided in an embodiment of this application.
[0024] Figure 3 This is a schematic diagram of the structure of an electronic device provided in an embodiment of this application.
[0025] Explanation of reference numerals in the attached drawings: 300, electronic device; 301, processor; 302, communication bus; 303, user interface; 304, network interface; 305, memory. Detailed Implementation
[0026] To enable those skilled in the art to better understand the technical solutions in this specification, the technical solutions in the embodiments of this specification will be clearly and completely described below with reference to the accompanying drawings. Obviously, the described embodiments are only some embodiments of this application, and not all embodiments.
[0027] In the description of the embodiments of this application, the words "for example" or "for instance" are used to indicate examples, illustrations, or explanations. Any embodiment or design that is described as "for example" or "for instance" in the embodiments of this application should not be construed as being more preferred or advantageous than other embodiments or design options. Rather, the use of the words "for example" or "for instance" is intended to present the relevant concepts in a specific manner.
[0028] In the description of the embodiments of this application, the term "multiple" means two or more. For example, multiple systems means two or more systems, and multiple screen terminals means two or more screen terminals. Furthermore, the terms "first" and "second" are used for descriptive purposes only and should not be construed as indicating or implying relative importance or implicitly specifying the indicated technical features. Thus, a feature defined with "first" or "second" may explicitly or implicitly include one or more of that feature. The terms "comprising," "including," "having," and variations thereof all mean "including but not limited to," unless otherwise specifically emphasized.
[0029] The technical solutions in the embodiments of this application will be clearly and completely described below with reference to the accompanying drawings. Obviously, the described embodiments are only some embodiments of this application, and not all embodiments.
[0030] Please refer to Figure 1This paper presents a flowchart illustrating a method for supporting the customization of SaaS application interfaces. This method can be implemented using a computer program, a microcontroller, or run on a system that supports SaaS application interface customization. The computer program can be integrated into a computer device or run as a standalone utility application. Specifically, the method includes steps 10 to 50, as follows:
[0031] Step 10: Scan the original React element nodes in the React application, generate slot identifier IDs corresponding to each original React element node, and add the slot identifier IDs to the corresponding original React element nodes to obtain the React element nodes after addition.
[0032] In this embodiment of the application, a React application refers to a web application developed based on the React framework, containing multiple React components. These components describe user interface elements using JSX syntax and are converted into JavaScript code for execution by the Babel compiler. Each component may contain multiple React element nodes, which together constitute the application's interface structure.
[0033] In this embodiment of the application, a raw React element node refers to a code snippet describing an interface element that is directly written using JSX syntax in the JSX code of a React application. It can be an HTML tag element (such as div, span, etc.) or a custom React component.
[0034] In this embodiment of the application, the slot identifier ID refers to a string identifier used to uniquely identify customizable interface elements in a React application. It is generated by analyzing and calculating the node type, node attributes, and parent node information of the React element node.
[0035] Specifically, before scanning the React application to generate slot identifier IDs, the system first checks if the "data-slot-id" attribute exists in the attribute list of the original React element node. This checking mechanism avoids consistency issues caused by duplicate ID generation. In practice, by traversing the node's props object, when a slot identifier ID already exists, it directly uses that ID value for subsequent customization processing, ensuring that the same UI element maintains the same identifier during multiple compilations or updates. If the node does not contain a slot identifier ID, a new ID is generated based on the node's characteristics. This reuse mechanism not only improves system performance but also ensures that customized code can still correctly match the target element after application updates, especially in incremental compilation scenarios, maintaining the stability of existing customized configurations.
[0036] Furthermore, the type (e.g., "div", "span"), key attributes (e.g., "className", "id"), and their hierarchical path in the component tree of the original React element node are obtained. This information is concatenated into a string (e.g., "div-header-nav-0"), and then the slot identifier ID is calculated using the SHA-256 hash algorithm. This ID is added to the original React element node as the "data-slot-id" attribute. This approach ensures that each customizable UI element has a unique identifier, facilitating precise location of target elements in subsequent customization code, while maintaining code maintainability through property injection.
[0037] Based on the above embodiments, as an optional embodiment, the step of scanning the original React element nodes in the React application and generating the slot identifier ID corresponding to each original React element node may further include the following steps:
[0038] Step 101: Obtain the node type, node attributes, and parent node information of the original React element node.
[0039] Specifically, the process of generating slot identifier IDs first requires collecting complete information about the React element nodes. The system obtains the node type by accessing the node's `type` attribute, which could be an HTML tag name in string form (such as "div" or "span") or a reference to a React component. Next, it iterates through the node's `props` object to obtain node attributes, focusing on extracting unique attributes such as `id`, `name`, and `key`, while also recording critical attributes that may affect rendering, such as `className` and `style`. For parent node information, the system obtains the parent component instance by accessing the node's `_owner` attribute, extracts the component name, and then obtains its location information in the source code through the node's `source` attribute, including file path and line number. This comprehensive information collection ensures that the subsequently generated slot identifier ID accurately reflects the node's position and characteristics within the component tree.
[0040] Step 102: Generate a path string based on node type, node attributes, and parent node information.
[0041] Specifically, based on the collected node information, the system constructs a unique path string. First, the node type is used as the beginning of the string; for HTML tags, the tag name is used directly, and for React components, the component's displayName or name is used. Then, a separator (such as "#") is added, and key node attributes are concatenated, combining attribute names and values alphabetically (e.g., "id=header") and connecting them with separators. Finally, parent node information is added, including the name of the component it belongs to and its position index within the component, forming a structure similar to...
[0042] The path string is "div#id=header#className=nav#ParentComponent-0". This structured string format ensures the uniqueness of the identifier and facilitates debugging and problem localization.
[0043] Step 103: Perform a hash calculation on the path string to obtain a hash value, and use the hash value as the slot identifier ID.
[0044] Specifically, to generate a compact and unique slot identifier ID, the generated path string is hashed. First, the path string is converted into a byte array using UTF-8 encoding, and then a fixed-length hash value is calculated using the SHA-256 hash algorithm. Considering practical use cases, the system truncates the first 8 bytes of the hash value and performs Base64 encoding, resulting in a shorter string as the final slot identifier ID. When a hash collision occurs, it is resolved by adding an incrementing counter to the end of the path string. This hashing mechanism not only guarantees the uniqueness of the identifier but also optimizes storage and transmission efficiency through fixed-length output, while Base64 encoding ensures that the identifier can be safely used as a DOM attribute value.
[0045] Step 20: Use the Babel plugin to traverse each React element node, obtain the available variables in the scope chain of each React element node, and generate a variable collection object.
[0046] In this embodiment of the application, the Babel plugin refers to a custom Babel transformation plugin used to analyze and process the source code of a React application. This plugin works during the code compilation phase, traversing the abstract syntax tree (AST) using the visitor pattern to identify and collect variable declarations, scope information, and context in React components.
[0047] In this embodiment of the application, available variables refer to all variables that can be accessed in the execution context of a React component, including but not limited to the component's props properties, state, local variables, values passed by upper-level components through the Context, and functions declared within the component's scope.
[0048] In this embodiment of the application, the variable collection object refers to a structured data object that describes all available variables in a React component, obtained through analysis by the Babel plugin.
[0049] Specifically, variable collection is implemented through a custom Babel plugin. When traversing the AST, the plugin creates a scope chain tracker for each React element node. Starting from the current node, the tracker searches upwards along the scope chain, checking the BlockStatement, FunctionDeclaration, and Program nodes in sequence. At each scope level, it collects variables declared by the VariableDeclarator node, functions defined by the FunctionDeclaration, and modules imported by the ImportDeclaration. For class components, class properties and methods are also collected. This information is organized into a variable collection object, where the key is the variable name and the value contains information such as variable type, declaration location, and scope level. This implementation ensures that customized code can accurately access available variables in the component while maintaining the safety of variable access.
[0050] Based on the above embodiments, as another optional embodiment, the step of traversing each React element node through the Babel plugin to obtain the available variables in the scope chain of each React element node and generating a variable collection object may also include the following steps:
[0051] Step 201: Use the Babel plugin to identify the parent path type of the React element node, recursively traverse upwards until a node of the preset type is identified, and then determine the insertion position. The preset types include export declarations, variable declarations, expression statements, return statements, or conditional statements.
[0052] Specifically, in the Babel plugin, to determine the correct scope for variable collection, the appropriate insertion point must first be determined. When the plugin accesses a React element node via the visitor pattern, it obtains its path object and retrieves the parent path using `path.parentPath`. It then iterates upwards using a `while` loop and `path.parentPath.type` until it encounters a predefined node type. Specifically, it stops iterating when it encounters an `ExportDeclaration`, `VariableDeclaration`, `ExpressionStatement`, `ReturnStatement`, or `IfStatement`. This implementation ensures that variable collection begins at a valid statement block level, avoiding collection at excessively high or low scope levels. For example, for a React element in a function component's return statement, the iteration stops at the return statement, thus correctly including all variables within the function's scope.
[0053] Step 202: Call the Babel plugin's node iterator, and based on the insertion position, it iterates backward from the current statement, obtaining the variable and function definitions during the traversal process and generating a variable queue.
[0054] Specifically, Babel's node iterator is used for variable collection. First, all bindings in the current scope are retrieved using `path.scope.bindings`, and a queue data structure `variableQueue` is created to store the collected variable information. Then, the array of statements in the scope is retrieved using `path.scope.path.node.body`, and each statement is traversed backwards from its current index. For nodes of type `VariableDeclaration`, their declared variables are added to the queue, including variable name, type, and initial value. For nodes of type `FunctionDeclaration`, the function name and parameter information are added to the queue. During traversal, the variable reference relationships are checked using `path.scope.getBinding(variableName)` to ensure that only variables actually used by React elements are collected. This implementation method guarantees the completeness and accuracy of variable collection.
[0055] Step 203: Based on the variable queue, declare a variable collection object in the current scope, retrieve the available variables in each scope level by level, and generate a variable collection object for each available variable in a preset order.
[0056] Specifically, after obtaining the variable queue, the variable collection object is constructed. First, an empty object `scopeVariables` is declared in the current scope. Each variable in the `variableQueue` is traversed, and its information is added to `scopeVariables` according to a predefined format. Variable information includes fields such as `type` (variable type), `source` (variable origin), `references` (reference location), and `value` (current value). Then, the parent scope is recursively accessed via `path.scope.parent`, repeating the variable collection process at each scope level. For variables in higher scopes, it is necessary to check if they are shadowed by the current scope. Finally, the variable collection objects from all scopes are merged according to the proximity principle, prioritizing the variable definitions of inner scopes. This implementation ensures the correctness of variable access and maintains JavaScript's scope rules. The merging process uses a depth-first strategy; for each variable name, the definition of the innermost scope is used first, while recording the variable's hierarchical relationship in the scope chain to facilitate correct access to these variables in subsequent customized code.
[0057] Step 30: Generate a custom rendering function based on the React element node. The input parameters of the custom rendering function include the original React element node, the variable collection object, and the corresponding slot identifier ID.
[0058] In this embodiment of the application, a custom rendering function refers to a function used to implement customized rendering of React components. This function receives the original React element node information and variable collection object as input parameters and can dynamically modify or replace the rendering content of the original node.
[0059] Specifically, this embodiment generates a custom rendering function using a higher-order function. First, a closure function is created to encapsulate the original React element node. This function accepts three parameters: `originalElement` (the original node), `scopeVariables` (a collection of variables), and `slotId` (a slot identifier ID). Internally, the function first checks the node's type and properties, then constructs an execution context based on the collection of variables. A proxy mechanism is used to wrap the collection of variables, ensuring that customized code can safely access variables within the component's scope. The function returns a new React element that inherits the original node's properties and supports property overriding and event handler binding. This implementation ensures the independence and reusability of the rendering function.
[0060] Based on the above embodiments, as another optional embodiment, the step of generating a custom rendering function based on React element nodes may further include the following steps:
[0061] Step 301: Use the Babel plugin to parse the structure of React element nodes and obtain attribute information and child node information.
[0062] Specifically, in the visitor pattern of the Babel plugin, React element structure parsing is achieved by accessing nodes of type JSXElement. First, the node object is obtained from `path.node`, and the start tag information is retrieved through the `openingElement` property. The `attributes` array within the start tag is traversed, converting each JSXAttribute node into key-value pairs and extracting the attribute name and value. For attribute values of type JSXExpressionContainer, the `expression` property needs further parsing to obtain the actual value. Simultaneously, the array of child nodes is obtained through the `children` property, and each child node is recursively processed, converting child nodes of types JSXText, JSXElement, and JSXExpressionContainer into standard formats. Finally, a node description object containing a complete property map (`propsMap`) and a list of child nodes (`childrenList`) is generated, accurately reflecting the structural characteristics of the React element.
[0063] Step 302: Based on attribute information and child node information, construct a function parameter structure containing the original React element node, variable collection object, and corresponding slot identifier ID.
[0064] Specifically, a function parameter template object is created, containing three key fields: `originalElement`, `scopeVariables`, and `slotId`. The `originalElement` field stores complete information about the original node, including the previously parsed attribute map and list of child nodes; the `scopeVariables` field is reserved as a placeholder for a variable collection object, which will be filled with the actual variable collection at runtime; the `slotId` field uses a node-specific attribute (such as `data-slot-id`) or a generated unique identifier. This parameter structure is converted into an AST node using Babel's template syntax (`template.expression`), ensuring that the generated code structure conforms to JavaScript syntax specifications. This parameter structure design allows custom rendering functions to accurately access the required context information.
[0065] Step 303: Generate conditional judgment code to determine whether customized logic exists based on the function parameter structure, and assemble the conditional judgment code with the original React element node to generate a custom rendering function. Custom rendering is executed when customized logic exists, otherwise the original React element node is returned.
[0066] Specifically, after obtaining the function parameter structure, a complete implementation of the custom rendering function is generated. First, a conditional expression is created to check if customized logic matching the current slotId exists in the global customization configuration object. Specifically, a ternary operator is created using Babel's `template.expression`. The condition part checks if `customizationConfig[slotId]` exists; the `true` branch calls the customized rendering logic, and the `false` branch returns the original node. This conditional expression is embedded in the return statement, which is then wrapped within the function body. The function body also includes parameter destructuring and variable declarations to ensure the customized logic can access the necessary context. Finally, Babel's `generateCode` method converts the AST into executable JavaScript code.
[0067] Step 40: In response to the tenant's customization request, generate a customized code file with the corresponding slot identifier ID of the tenant based on the customization request.
[0068] Specifically, the system receives a customization request from a tenant, which includes the target slot identifier ID and the desired rendering logic. Based on the request content, the system first verifies the tenant's permissions, then creates a unique customized configuration object, using the slot identifier ID as the key and the customized logic as the value. According to a preset code template, the system converts the configuration object into a JavaScript module file, which exports a rendering function that can access raw node attributes and scoped variables. The generated code file is stored in the tenant's dedicated code repository and integrated into the application runtime through a dynamic loading mechanism. This implementation ensures the isolation and maintainability of the customized code.
[0069] Based on the above embodiments, as another optional embodiment, the step of generating a customized code file for the tenant's corresponding slot identifier ID according to the customization request may further include the following steps:
[0070] Step 401: Parse the slot identifier ID and customization code content in the customization request.
[0071] Specifically, upon receiving a customization request, the system first parses the request body into JSON format. From the JSON object, a `customizationRequest` object is extracted, containing fields such as `slotId` (slot identifier ID), `customCode` (customization code content), and `tenantId` (tenant identifier). For the `customCode` field, the system performs preliminary formatting, removing unnecessary whitespace and comments, and standardizing code indentation. Regular expressions are used to validate whether the `slotId` format conforms to preset rules (e.g., "component-name:slot-name"). The system also parses the dependency declarations in `customCode`, constructing a dependency graph to ensure that all required external modules are allowed. This parsing process ensures the accuracy and completeness of data in subsequent processing.
[0072] Step 402: Generate a customized code file containing tenant identifier and version information based on the slot identifier ID and customized code content.
[0073] Specifically, based on the parsed data, the system begins generating standardized, customized code files. First, a file template is created, including header comments (containing metadata such as tenant identifier, creation time, and version number). The system automatically assigns a version number to the current customized code, using semantic versioning rules (e.g., 1.0.0). The `customCode` is encapsulated in a explicitly named function that accepts standardized parameters (`originalElement`, `scopeVariables`, etc.). The system also injects runtime checking code to verify the execution permissions and runtime environment of the customized code. The final generated code file uses a unified module format (e.g., ES Module), and the filename follows the format "tenantId_slotId_version.js", ensuring the code file's standardization and traceability.
[0074] Step 403: Perform syntax validation and security checks on the customized code files, store the customized code files that pass the validation in the code repository corresponding to the tenant, and establish a mapping relationship between slot identifier ID and customized code files.
[0075] Specifically, the generated customized code files undergo multi-layered validation. First, ESLint is used for syntax checking, applying a pre-defined rule set to ensure the code conforms to specifications. Then, AST analysis tools are used to check the code's security, including disabling the use of `eval`, prohibiting access to global objects, and restricting network requests. The system also performs sandbox testing, executing the code in an isolated environment to verify its behavior meets expectations. After successful validation, the system stores the code files in a distributed file system, establishing a directory structure with `tenantId` as the primary key. Simultaneously, a mapping record is created in the database, containing fields such as `slotId`, file path, and version information, supporting fast querying and version control. The system also maintains a memory cache to store customized code for hot slots, improving access performance.
[0076] Step 50: During interface rendering, detect the tenant's identity and load the corresponding customized code file so that the custom rendering function can call the corresponding customized code to render the interface based on the slot identifier ID.
[0077] Specifically, a dynamic module loading approach is used to load customized code on demand. During application initialization, the tenant identifier (tenantId) is obtained from the user session. A `CustomizationManager` class is created to handle code loading and cache management; this class maintains a `WeakMap` to store loaded customized code. When a component renders, the custom rendering function queries the `CustomizationManager` using the `slotId`. If the code is not loaded, the file path is constructed based on the `tenantId` and `slotId`, and the customized code file is dynamically loaded using `import()`. After loading, the code is injected into the runtime context, enabling the custom rendering function to access the customized logic.
[0078] Based on the above embodiments, as another optional embodiment, the step of detecting the tenant's identity and loading the corresponding customized code file so that the custom rendering function calls the corresponding customized code to render the interface according to the slot identifier ID may further include the following steps:
[0079] Step 501: Obtain the identity identifier of the currently accessing tenant, and obtain the corresponding customized code file path from the tenant configuration information based on the identity identifier.
[0080] Specifically, the system retrieves the tenantId of the currently accessing user. First, it reads the cached identity information from localStorage or session storage; if not found, it retrieves it by calling the authentication service. After obtaining the tenantId, the system accesses the TenantConfigurationService, which maintains a tenant configuration database storing a customized file mapping table for each tenant. The system queries the configuration database using the tenantId to obtain a set of all customized code file paths for that tenant. This set is stored in a Map structure, with the key being the slotId and the value being the corresponding file path. The system caches the query results in memory to avoid repeated database queries.
[0081] Step 502: Based on the customized code file path, asynchronously load the tenant's customized code file and parse the loaded customized code into an executable JavaScript function.
[0082] Specifically, to achieve asynchronous loading and parsing of customized code files, the system first creates the `CodeLoadManager` class to uniformly manage the loading process. This class maintains a `loadingQueue` to store file paths to be loaded and implements a request throttling mechanism to control the number of concurrent loads. For each customized code file path, the system uses the dynamic `import()` method for asynchronous loading, returning a `Promise` object. After loading, the file content is read using the `AsyncFileReader` class, which supports reading large files in chunks to avoid excessive memory consumption. After obtaining the code content, the `CodeParser` class is used for parsing. This class first uses tools such as Acorn to parse the code into an `AST` (Abstract Syntax Tree) for syntax checking and dependency analysis. Then, the `CodeTransformer` class is used to transform the `AST`, injecting runtime context variables and adding error boundary handling code. Finally, the `Function` constructor converts the processed code string into an executable JavaScript function, which accepts a standardized parameter structure (`originalElement`, `scopeVariables`, etc.). The entire process is managed through Promise chaining to ensure the orderly execution of asynchronous operations and error handling.
[0083] Step 503: Establish a mapping relationship between JavaScript functions and their corresponding slot identifier IDs, and generate a customized code runtime environment.
[0084] Specifically, to establish the mapping between slot identifiers (IDs) and JavaScript functions and generate the runtime environment, the system implements the `RuntimeEnvironmentManager` class. This class uses a Map data structure to create a `slotFunctionMap`, using `slotId` as the key and the corresponding JavaScript function as the value. It also implements a memory management mechanism: when the number of mapping relationships exceeds a threshold, it uses the LRU (Least Recently Used) algorithm to clean up infrequently used function caches. Regarding the runtime environment, the system creates the `SandboxEnvironment` class, which uses a Proxy to implement sandbox isolation, restricting customized code's access to global objects. The sandbox environment provides the `StandardAPI` class, which encapsulates predefined utility functions and component libraries, ensuring that customized code can safely access necessary functionalities. It also implements the `ContextInjector` class, responsible for injecting component props, state, and other context data at runtime. The system also implements a hot update mechanism through `EventEmitter`, automatically updating the corresponding function mappings and runtime environment when updates to customized code are detected. This implementation method ensures both the isolation and security of customized code while providing necessary functional support and update mechanisms.
[0085] Step 504: Respond to the call request of the custom rendering function, obtain and execute the corresponding JavaScript function from the customized code runtime environment according to the slot identifier ID in the call request, and return the execution result for interface rendering.
[0086] Specifically, when a custom rendering function initiates a request, the system first processes the request through the RequestHandler class. The RequestHandler parses the slotId and context parameters from the request, and then accesses the RuntimeManager to obtain the corresponding JavaScript function. Before executing the function, the system creates a new execution scope, injecting the component's props, state, and other context data into the scope. A try-catch block is used to wrap the function execution process, catching and handling any possible errors. After execution, the returned result undergoes format validation and type checking to ensure it conforms to React element specifications. Finally, the processed result is returned to the rendering function to update the UI display.
[0087] Please see Figure 2 This is a schematic diagram of a system that supports the customization of SaaS application interfaces, provided in an embodiment of this application. The system includes:
[0088] The slot identifier determination module is used to scan the original React element nodes in the React application, generate slot identifier IDs corresponding to each original React element node, and add the slot identifier IDs to the corresponding original React element nodes to obtain the added React element nodes.
[0089] The variable collection generation module is used to traverse each React element node through the Babel plugin, obtain the available variables in the scope chain of each React element node, and generate a variable collection object.
[0090] The rendering function determination module is used to generate a custom rendering function based on the React element node. The input parameters of the custom rendering function include the original React element node, the variable collection object, and the corresponding slot identifier ID.
[0091] The code file generation module is used to respond to a tenant's customization request and generate a customized code file with the corresponding slot identifier ID of the tenant according to the customization request;
[0092] The interface rendering module is used to detect the identity of the tenant and load the corresponding customized code file when rendering the interface, so that the custom rendering function calls the corresponding customized code to render the interface according to the slot identifier ID.
[0093] Optionally, the slot identifier determination module is also used to obtain the node type, node attributes, and parent node information of the original React element node;
[0094] Generate a path string based on the node type, node attributes, and parent node information;
[0095] The path string is hashed to obtain a hash value, and the hash value is used as the slot identifier ID.
[0096] Optionally, the slot identifier determination module is also used to detect whether each of the original React element nodes already contains a slot identifier ID;
[0097] If the original React element node already contains a slot identifier ID, then the existing slot identifier ID will be used as the slot identifier ID of the corresponding original React element node.
[0098] If the original React element node does not contain a slot identifier ID, then the step of generating the slot identifier ID corresponding to each of the original React element nodes is performed.
[0099] Optionally, the variable set generation module is also used to identify the parent path type of the React element node through the Babel plugin, recursively traverse upwards until a node of a preset type is identified, and then determine the insertion position. The preset type includes export declarations, variable declarations, expression statements, return statements, or conditional statements.
[0100] The Babel plugin's node iterator is invoked to iterate backward from the current statement based on the insertion position, obtaining variable and function definitions during the iteration process and generating a variable queue.
[0101] According to the variable queue, a variable collection object is declared in the current scope, and the available variables in each scope are obtained level by level. The available variables are then generated into a variable collection object in a preset order.
[0102] Optionally, the rendering function determination module is also used to parse the structure of the React element node through the Babel plugin to obtain attribute information and child node information;
[0103] Based on the attribute information and child node information, construct a function parameter structure that includes the original React element node, the variable collection object, and the corresponding slot identifier ID;
[0104] Based on the function parameter structure, conditional judgment code is generated to determine whether customized logic exists. The conditional judgment code is then assembled with the original React element node to generate a custom rendering function. Customized rendering is executed when customized logic exists; otherwise, the original React element node is returned.
[0105] Optionally, the code file generation module is also used to parse the slot identifier ID and customized code content in the customization request;
[0106] Based on the slot identifier ID and the customized code content, a customized code file containing tenant identifier and version information is generated;
[0107] The customized code file is subjected to syntax validation and security checks. Customized code files that pass the validation are stored in the code repository corresponding to the tenant, and a mapping relationship is established between the slot identifier ID and the customized code file.
[0108] Optionally, the interface rendering module is also used to obtain the identity identifier of the currently accessing tenant, and obtain the corresponding customized code file path from the tenant configuration information based on the identity identifier;
[0109] Based on the customized code file path, the tenant's customized code file is loaded asynchronously, and the loaded customized code is parsed into an executable JavaScript function;
[0110] Establish a calling mapping relationship between the JavaScript function and the corresponding slot identifier ID, and generate a customized code runtime environment;
[0111] In response to a call request for a custom rendering function, the corresponding JavaScript function is retrieved from the customized code runtime environment based on the slot identifier ID in the call request, and the execution result is returned for UI rendering.
[0112] It should be noted that the system provided in the above embodiments is only illustrated by the division of the above functional modules. In actual applications, the above functions can be assigned to different functional modules as needed, that is, the internal structure of the device can be divided into different functional modules to complete all or part of the functions described above. In addition, the system and method embodiments provided in the above embodiments belong to the same concept, and the specific implementation process can be found in the method embodiments, which will not be repeated here.
[0113] This application also provides a computer storage medium that can store multiple instructions. The instructions are adapted to be loaded and executed by a processor as described in the above embodiments to support the customization of SaaS application interfaces. For the specific execution process, please refer to the detailed description of the above embodiments, which will not be repeated here.
[0114] Please refer to Figure 3 This application also discloses an electronic device. Figure 3 This is a schematic diagram of the structure of an electronic device disclosed in an embodiment of this application. The electronic device 300 may include: at least one processor 301, at least one network interface 304, a user interface 303, a memory 305, and at least one communication bus 302.
[0115] The communication bus 302 is used to enable communication between these components.
[0116] The user interface 303 may include a display screen and a camera. Optionally, the user interface 303 may also include a standard wired interface and a wireless interface.
[0117] The network interface 304 may optionally include a standard wired interface or a wireless interface (such as a Wi-Fi interface).
[0118] The processor 301 may include one or more processing cores. The processor 301 connects to various parts of the server using various interfaces and lines, and performs various server functions and processes data by running or executing instructions, programs, code sets, or instruction sets stored in memory 305, and by calling data stored in memory 305. Optionally, the processor 301 may be implemented using at least one hardware form of Digital Signal Processing (DSP), Field-Programmable Gate Array (FPGA), or Programmable Logic Array (PLA). The processor 301 may integrate one or a combination of several of the following: Central Processing Unit (CPU), Graphics Processing Unit (GPU), and modem. The CPU primarily handles the operating system, user interface, and applications; the GPU is responsible for rendering and drawing the content required for display; and the modem handles wireless communication. It is understood that the modem may also not be integrated into the processor 301 and may be implemented as a separate chip.
[0119] The memory 305 may include random access memory (RAM) or read-only memory. Optionally, the memory 305 may include a non-transitory computer-readable storage medium. The memory 305 may be used to store instructions, programs, code, code sets, or instruction sets. The memory 305 may include a program storage area and a data storage area, wherein the program storage area may store instructions for implementing an operating system, instructions for at least one function (such as touch function, sound playback function, image playback function, etc.), instructions for implementing the above-described method embodiments, etc.; the data storage area may store data involved in the above-described method embodiments, etc. Optionally, the memory 305 may also be at least one storage device located remotely from the aforementioned processor 301. (Refer to...) Figure 3 The memory 305, which serves as a computer storage medium, may include an operating system, a network communication module, a user interface module, and an application that supports a method for customizing SaaS application interfaces.
[0120] exist Figure 3In the illustrated electronic device 300, the user interface 303 is mainly used to provide an input interface for the user and acquire user input data; while the processor 301 can be used to call an application stored in the memory 305 that supports a method for customizing the SaaS application interface. When executed by one or more processors 301, the electronic device 300 executes one or more methods as described in the above embodiments. It should be noted that, for the foregoing method embodiments, for the sake of simplicity, they are all described as a series of actions. However, those skilled in the art should understand that this application is not limited to the described order of actions, because according to this application, some steps can be performed in other orders or simultaneously. Secondly, those skilled in the art should also understand that the embodiments described in the specification are all preferred embodiments, and the actions and modules involved are not necessarily essential to this application.
[0121] In the above embodiments, the descriptions of each embodiment have different focuses. For parts not described in detail in a certain embodiment, please refer to the relevant descriptions in other embodiments.
[0122] In the various embodiments provided in this application, it should be understood that the disclosed apparatus can be implemented in other ways. For example, the apparatus embodiments described above are merely illustrative; for instance, the division of units is only a logical functional division, and in actual implementation, there may be other division methods. For example, multiple units or components may be combined or integrated into another system, or some features may be ignored or not executed. Furthermore, the coupling or direct coupling or communication connection shown or discussed may be through some service interface; the indirect coupling or communication connection between apparatuses or units may be electrical or other forms.
[0123] The units described as separate components may or may not be physically separate. The components shown as units may or may not be physical units; that is, they may be located in one place or distributed across multiple network units. Some or all of the units can be selected to achieve the purpose of this embodiment according to actual needs.
[0124] Furthermore, the functional units in the various embodiments of this application can be integrated into one processing unit, or each unit can exist physically separately, or two or more units can be integrated into one unit. The integrated unit can be implemented in hardware or as a software functional unit.
[0125] If the integrated unit is implemented as a software functional unit and sold or used as an independent product, it can be stored in a computer-readable storage device (CMD). Based on this understanding, the technical solution of this application, in essence, or the part that contributes to the prior art, or all or part of the technical solution, can be embodied in the form of a software product. This computer software product is stored in a memory and includes several instructions to cause a computer device (which may be a personal computer, server, or network device, etc.) to execute all or part of the steps of the methods of the various embodiments of this application. The aforementioned memory includes various media capable of storing program code, such as USB flash drives, portable hard drives, magnetic disks, or optical disks.
[0126] The above are merely exemplary embodiments of this disclosure and should not be construed as limiting the scope of this disclosure. Any equivalent changes and modifications made in accordance with the teachings of this disclosure shall still fall within the scope of this disclosure. Other embodiments of this disclosure will readily conceive of those skilled in the art upon consideration of the specification and the disclosure of practical truths.
[0127] This application is intended to cover any variations, uses, or adaptations of this disclosure that follow the general principles of this disclosure and include common knowledge or customary techniques in the art not described in this disclosure. The specification and embodiments are to be considered exemplary only, and the scope and spirit of this disclosure are defined by the claims.
Claims
1. A method for supporting the customization of SaaS application interfaces, characterized in that, The method includes: Scan the original React element nodes in the React application, generate slot identifier IDs corresponding to each original React element node, and add the slot identifier IDs to the corresponding original React element nodes to obtain the React element nodes after addition; By traversing each React element node using the Babel plugin, the available variables in the scope chain of each React element node are obtained, and a variable collection object is generated. A custom rendering function is generated based on the React element node. The input parameters of the custom rendering function include the original React element node, the variable collection object, and the corresponding slot identifier ID. In response to a tenant's customization request, a customized code file for the slot identifier ID corresponding to the tenant is generated based on the customization request; During interface rendering, the tenant's identity is detected and the corresponding customized code file is loaded, so that the custom rendering function calls the corresponding customized code to perform interface rendering based on the slot identifier ID; Specifically, the Babel plugin iterates through each React element node to obtain the available variables in the scope chain of each React element node, generating a variable collection object, including: The parent path type of the React element node is identified by the Babel plugin, and the node is recursively traversed upwards until a node of a preset type is identified. The insertion position is then determined. The preset type includes export declarations, variable declarations, expression statements, return statements, or conditional statements. The Babel plugin's node iterator is invoked to iterate backward from the current statement based on the insertion position, obtaining variable and function definitions during the iteration process and generating a variable queue. According to the variable queue, a variable collection object is declared in the current scope, and the available variables in each scope are obtained level by level. The available variables are then generated into a variable collection object in a preset order.
2. The method for supporting SaaS application interface customization according to claim 1, characterized in that, The process of scanning the original React element nodes in the React application and generating slot identifier IDs corresponding to each original React element node includes: Obtain the node type, node attributes, and parent node information of the original React element node; Generate a path string based on the node type, node attributes, and parent node information; The path string is hashed to obtain a hash value, and the hash value is used as the slot identifier ID.
3. The method for supporting SaaS application interface customization according to claim 1, characterized in that, Before scanning the original React element nodes in the React application and generating the slot identifier ID corresponding to each original React element node, the process further includes: Detect whether each of the original React element nodes already contains a slot identifier ID; If the original React element node already contains a slot identifier ID, then the existing slot identifier ID will be used as the slot identifier ID of the corresponding original React element node. If the original React element node does not contain a slot identifier ID, then the step of generating the slot identifier ID corresponding to each of the original React element nodes is performed.
4. The method for supporting SaaS application interface customization according to claim 1, characterized in that, The process of generating a custom rendering function based on the React element node includes: The Babel plugin parses the structure of the React element node to obtain attribute information and child node information; Based on the attribute information and child node information, construct a function parameter structure that includes the original React element node, the variable collection object, and the corresponding slot identifier ID; Based on the function parameter structure, conditional judgment code is generated to determine whether customized logic exists. The conditional judgment code is then assembled with the original React element node to generate a custom rendering function. Customized rendering is executed when customized logic exists; otherwise, the original React element node is returned.
5. The method for supporting SaaS application interface customization according to claim 1, characterized in that, The step of generating the customized code file for the slot identifier ID corresponding to the tenant based on the customization request includes: Parse the slot identifier ID and customization code content in the customization request; Based on the slot identifier ID and the customized code content, a customized code file containing tenant identifier and version information is generated; The customized code file is subjected to syntax validation and security checks. Customized code files that pass the validation are stored in the code repository corresponding to the tenant, and a mapping relationship is established between the slot identifier ID and the customized code file.
6. The method for supporting SaaS application interface customization according to claim 1, characterized in that, The step of detecting the tenant's identity and loading the corresponding customized code file, so that the custom rendering function calls the corresponding customized code to render the interface based on the slot identifier ID, includes: Obtain the identity identifier of the currently accessing tenant, and retrieve the corresponding customized code file path from the tenant configuration information based on the identity identifier; Based on the customized code file path, the tenant's customized code file is loaded asynchronously, and the loaded customized code is parsed into an executable JavaScript function; Establish a calling mapping relationship between the JavaScript function and the corresponding slot identifier ID, and generate a customized code runtime environment; In response to a call request for a custom rendering function, the corresponding JavaScript function is retrieved from the customized code runtime environment based on the slot identifier ID in the call request, and the execution result is returned for UI rendering.
7. A system that supports the customization of SaaS application interfaces, characterized in that, The system for performing the method for supporting SaaS application interface customization as described in claim 1 includes: The slot identifier determination module is used to scan the original React element nodes in the React application, generate slot identifier IDs corresponding to each original React element node, and add the slot identifier IDs to the corresponding original React element nodes to obtain the added React element nodes. The variable collection generation module is used to traverse each React element node through the Babel plugin, obtain the available variables in the scope chain of each React element node, and generate a variable collection object. The rendering function determination module is used to generate a custom rendering function based on the React element node. The input parameters of the custom rendering function include the original React element node, the variable collection object, and the corresponding slot identifier ID. The code file generation module is used to respond to a tenant's customization request and generate a customized code file with the corresponding slot identifier ID of the tenant according to the customization request; The interface rendering module is used to detect the identity of the tenant and load the corresponding customized code file when rendering the interface, so that the custom rendering function calls the corresponding customized code to render the interface according to the slot identifier ID.
8. A computer-readable storage medium, characterized in that, The computer-readable storage medium stores multiple instructions suitable for being loaded by a processor and executed as described in any one of claims 1-6.
9. An electronic device, characterized in that, It includes a processor, a memory, a user interface, and a network interface. The memory is used to store instructions, the user interface and the network interface are used to communicate with other devices, and the processor is used to execute the instructions stored in the memory to cause the electronic device to perform the method as described in any one of claims 1-6.