In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-15 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/03 Report--
This article introduces you how to design a JavaScript plug-in system, the content is very detailed, interested friends can refer to, hope to be helpful to you.
WordPress has plug-ins, jQuery has plug-ins, Gatsby, Eleventy and Vue, React also have plug-ins.
Plug-ins are a common feature of libraries and frameworks, and for a good reason: they allow developers to add functionality in a secure and extensible manner. This makes the core project more valuable and creates a community-all of which does not add an additional maintenance burden. Great!
So how to build a plug-in system? Let's use JavaScript to build our own plug-in to answer this question.
Let's build a plug-in system. Let's start with a sample project called BetaCalc. The goal of BetaCalc is to be a minimalist JavaScript calculator to which other developers can add "buttons". Here are some basic getting started codes:
/ Calculator const betaCalc = {currentValue: 0, setValue (newValue) {this.currentValue = newValue; console.log (this.currentValue);}, plus (addend) {this.setValue (this.currentValue + addend);}, minus (subtrahend) {this.setValue (this.currentValue-subtrahend);}}; / / use Calculator betaCalc.setValue (3); / / > 3 betaCalc.plus (3) / / > 6 betaCalc.minus (2); / / = > 4
We define a calculator as an objective thing to make things simple, and the calculator works by printing results through console.log.
The function is really limited at the moment. We have a setValue method that takes a number and displays it on the screen. We also have addition (plus) and subtraction (minus) methods, which perform an operation on the currently displayed value.
Now it's time to add more functionality, starting with creating a plug-in system.
The world's smallest plug-in system
We'll start by creating a register method that other developers can use to register plug-ins with BetaCalc. The job of this method is simple: get the external plug-in, get its exec function, and attach it to our calculator as a new method:
/ / Calculator const betaCalc = {/ /... The other calculator code is here register (plugin) {const {name, exec} = plugin; this [name] = exec;}}
This is a sample plug-in that provides a "squared" button for our calculator:
/ / define plug-in const squaredPlugin = {name: 'squared', exec: function () {this.setValue (this.currentValue * this.currentValue)}}; / / register plug-in betaCalc.register (squaredPlugin)
In many plug-in systems, plug-ins are usually divided into two parts:
Hongmeng official Strategic Cooperation to build HarmonyOS Technology Community
Code to be executed
Metadata (such as name, description, version number, dependencies, etc.)
In our plug-in, the exec function contains our code, and name is our metadata. After registering the plug-in, the exec function will be attached directly to our betaCalc object as a way to access BetaCalc's this.
Now, BetaCalc has a new "square" button that can be called directly:
BetaCalc.setValue (3); / / = > 3 betaCalc.plus (2); / / = > 5 betaCalc.squared (); / / = > 25 betaCalc.squared (); / / = > 625
This system has many advantages. The plug-in is a simple object literal that can be passed to our function. This means that the plug-in can be downloaded through npm and imported as an ES6 module. Easy distribution is super important!
But our system has some flaws.
By providing plug-ins with this access to BetaCalc, they can read / write access to all BetaCalc code. While this is useful for getting and setting currentValue, it is also dangerous. If a plug-in redefines an internal function, such as setValue, it may produce unexpected results for BetaCalc and other plug-ins. This violates the open-closed principle that a software entity should be an open extension but a closed modification.
In addition, the "squared" function works by producing side effects. This is not uncommon in JavaScript, but it doesn't feel good-- especially when other plug-ins may be in the same internal state. A more practical approach will go a long way in making our system more secure and predictable.
Better plug-in architecture
Let's take a look at a better plug-in architecture. The following example changes both the calculator and its plug-in API:
/ Calculator const betaCalc = {currentValue: 0, setValue (value) {this.currentValue = value; console.log (this.currentValue);}, core: {'plus': (currentVal, addend) = > currentVal + addend,' minus': (currentVal, subtrahend) = > currentVal-subtrahend}, plugins: {}, press (buttonName, newVal) {const func = this.core [buttonName] | this.plugins [buttonName] This.setValue (func (this.currentValue, newVal));}, register (plugin) {const {name, exec} = plugin; this.plugins [name] = exec;}}; / / our plug-in, square plug-in const squaredPlugin = {name: 'squared', exec: function (currentValue) {return currentValue * currentValue;}}; betaCalc.register (squaredPlugin); / / use calculator betaCalc.setValue (3) / / = > 3 betaCalc.press ('plus', 2); / / > 5 betaCalc.press (' squared'); / / = > 25 betaCalc.press ('squared'); / / = > 625
We have made some noteworthy changes here.
First, we separate the plug-in from the "core" calculator methods, such as plus and minus, by placing it in our own plug-in object. Storing our plug-ins in plugins objects makes our system more secure. Now, the plug-in that accesses this plugins will not see the BetaCalc property, but only the betaCalc.plugins property.
Second, we implement a press method that looks up the function of the button by name and then calls it. Now, when we call the plug-in's exec function, we pass the current currentValue to the function and expect it to return the new one.
In essence, this new press method converts all our calculator buttons into pure functions. They take a value, perform an operation, and then return the result. This has many benefits:
It simplifies API.
It makes testing easier (for BetaCalc and the plug-in itself).
It reduces the dependence of our system and makes it more loosely coupled.
This new architecture is more limited than the first example, but it works well. We basically set up a guardrail for the plug-in authors, restricting them to make only the changes we want them to make.
In fact, it may be too strict! For now, our calculator plug-in can only operate on currentValue. If plug-in authors want to add advanced features (such as the "memory" button or the way they track history), there is nothing they can do.
Maybe that's good. The ability you give plug-in authors is a delicate balance. Giving them too much power may affect the stability of your project. But giving them too little power makes it difficult for them to solve their own problems-in this case, you might as well not have plug-ins.
What else can we do?
We still have a lot of work to do to improve our system.
If the plug-in author forgets to define the name or return value, we can add error handling to notify the plug-in author. It's good to think like QA developers and imagine how our system crashes so that we can proactively deal with these situations.
We can expand the functional scope of the plug-in. Currently, a BetaCalc plug-in can add a button. But what if it can also register callbacks for certain lifecycle events (for example, when the calculator is about to display values)? Or what if there is a special place for it to store a period of state in multiple interactions? Will this open up some new use cases?
We can also extend the functionality of plug-in registration. What if a plug-in can be registered with some initial settings? Does this make plug-ins more flexible? What if a plug-in author wants to register a whole set of buttons instead of a single button-such as "BetaCalc Statistics package"? What changes need to be made to support it?
Your plug-in system
BetaCalc and its plug-in system are very simple. If your project is large, you need to explore some other plug-in architectures.
A good starting point is to look at existing projects for examples of successful plug-in systems. For JavaScript, this may mean jQuery,Gatsby,D3,CKEditor or something else. You may also want to familiarize yourself with various JavaScript design patterns, each of which provides different interfaces and coupling levels, which gives you a lot of good plug-in architecture options. Knowing these options will help you better balance the needs of everyone using your project.
In addition to the pattern itself, you can also learn from many good software development principles to make such decisions. I have mentioned some methods (such as the open-close principle and loose coupling), but other related methods include Demeter's law and dependency injection.
I know it sounds like a lot, but you have to do some research. There is nothing more painful than having everyone rewrite their plug-ins because you need to change the plug-in architecture. This is a way to quickly lose trust and make people lose confidence in their future contributions.
It is difficult to write a good plug-in architecture from scratch! You have to balance many considerations in order to build a system that meets everyone's needs. Is it simple enough? Can the work be powerful? Can it work for a long time?
But it's worth it, having a good plug-in system is helpful to everyone, and developers are free to solve their problems. End users can choose from a large number of optional features. You can build an ecosystem and community around your project. This is a win-win situation.
On how to design a JavaScript plug-in system to share here, I hope the above content can be of some help to you, can learn more knowledge. If you think the article is good, you can share it for more people to see.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.