>  기사  >  웹 프론트엔드  >  JavaScript 플러그인 시스템을 설계하는 것은 매우 중요합니다.

JavaScript 플러그인 시스템을 설계하는 것은 매우 중요합니다.

coldplay.xixi
coldplay.xixi앞으로
2020-09-02 17:26:372023검색

JavaScript 플러그인 시스템을 설계하는 것은 매우 중요합니다.

【관련 학습 권장사항: javascript 비디오 튜토리얼

WordPress에는 플러그인이 있고, jQuery에는 플러그인이 있으며, Gatsby, Eleventy 및 Vue도 마찬가지입니다.

플러그인은 라이브러리와 프레임워크의 일반적인 기능이며, 그럴 만한 이유가 있습니다. 플러그인을 사용하면 개발자가 안전하고 확장 가능한 방식으로 기능을 추가할 수 있습니다. 이를 통해 핵심 프로젝트의 가치가 더욱 높아지고 커뮤니티가 구축됩니다. 이 모든 것이 추가적인 유지 관리 부담 없이 이루어집니다. 매우 좋은!

그렇다면 플러그인 시스템을 구축하는 방법은 무엇일까요? 이 질문에 답하기 위해 JavaScript로 자체 플러그인을 만들어 보겠습니다.

플러그인 시스템을 구축해 봅시다

BetaCalc라는 샘플 프로젝트부터 시작해 보겠습니다. BetaCalc는 다른 개발자가 "버튼"을 추가할 수 있는 최소한의 JavaScript 계산기를 목표로 합니다. 시작하기 위한 몇 가지 기본 코드는 다음과 같습니다.

// 计算器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);
  }
};// 使用计算器betaCalc.setValue(3); // => 3betaCalc.plus(3);     // => 6betaCalc.minus(2);    // => 4复制代码

우리는 일을 단순하게 유지하기 위해 계산기를 객관적인 것으로 정의합니다. 계산기는 결과를 console.log에 인쇄하여 작동합니다. console.log 打印结果来工作。

目前功能确实很有限。我们有一个 setValue 方法,该方法接受一个数字并将其显示在“屏幕”上。我们还有加法(plus)和减法(minus)方法,它们将对当前显示的值执行一个运算。

现在该添加更多功能了。首先创建一个插件系统。

世界上最小的插件系统

我们将从创建一个注册(register)方法开始,其他开发人员可以使用该方法向BetaCalc注册插件。该方法的工作很简单:获取外部插件,获取其 exec 函数,并将其作为新方法附加到我们的计算器上:

// 计算器const betaCalc = {  // ...其他计算器代码在这里

  register(plugin) {    const { name, exec } = plugin;    this[name] = exec;
  }
};复制代码

这是一个示例插件,为我们的计算器提供了一个“平方(squared)”按钮:

// 定义插件const squaredPlugin = {  name: 'squared',  exec: function() {    this.setValue(this.currentValue * this.currentValue)
  }
};// 注册插件betaCalc.register(squaredPlugin);复制代码

在许多插件系统中,插件通常分为两个部分:

  1. 要执行的代码
  2. 元数据(例如名称,描述,版本号,依赖项等)

在我们的插件中,exec 函数包含我们的代码,name 是我们的元数据。注册插件后,exec 函数将作为一种方法直接附加到我们的 betaCalc 对象,从而可以访问BetaCalc的 this

现在,BetaCalc有一个新的“平方”按钮,可以直接调用:

betaCalc.setValue(3); // => 3betaCalc.plus(2);     // => 5betaCalc.squared();   // => 25betaCalc.squared();   // => 625复制代码

这个系统有很多优点。该插件是一种简单的对象字面量,可以传递给我们的函数。这意味着插件可以通过npm下载并作为ES6模块导入。易于分发是超级重要的!

但是我们的系统有一些缺陷。

通过为插件提供访问BetaCalc的 this 权限,他们可以对所有BetaCalc的代码进行读/写访问。虽然这对于获取和设置 currentValue 很有用,但也很危险。如果插件要重新定义内部函数(如 setValue),则它可能会为BetaCalc和其他插件产生意外的结果。这违反了开放-封闭原则,即一个软件实体应该是开放的扩展,但封闭修改。

另外,“squared”函数通过产生副作用发挥作用。这在JavaScript中并不少见,但感觉并不好——特别是当其他插件可能处在同一内部状态的情况下。一种更实用的方法将大大有助于使我们的系统更安全、更可预测。

更好的插件架构

让我们再来看看一个更好的插件架构。下一个例子同时改变了计算器和它的插件API:

// 计算器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;
  }
};  
// 我们得插件,平方插件const squaredPlugin = { 
  name: 'squared',  exec: function(currentValue) {    return currentValue * currentValue;
  }
};

betaCalc.register(squaredPlugin);// 使用计算器betaCalc.setValue(3);      // => 3betaCalc.press('plus', 2); // => 5betaCalc.press('squared'); // => 25betaCalc.press('squared'); // => 625复制代码

我们在这里做了一些值得注意的更改。

首先,我们将插件与“核心(core)”计算器方法(如plus和minus)分开,方法是将其放入自己的插件对象中。将我们的插件存储在plugins 对象中可使我们的系统更安全。现在,访问此plugins的插件将看不到BetaCalc属性,而只能看到 betaCalc.plugins 的属性。

其次,我们实现了一个 press 方法,该方法按名称查找按钮的功能,然后调用它。现在,当我们调用插件的 exec 函数时,我们将当前的计算器值(currentValue )传递给该函数,并期望它返回新的计算器值。

本质上,这个新的 press

현재 기능은 실제로 매우 제한적입니다. 숫자를 받아 "화면"에 표시하는 setValue 메소드가 있습니다. 또한 현재 표시된 값에 대해 연산을 수행하는 덧셈(plus) 및 뺄셈(minus) 메서드도 있습니다. 🎜🎜이제 더 많은 기능을 추가할 차례입니다. 먼저 플러그인 시스템을 만듭니다. 🎜

세계에서 가장 작은 플러그인 시스템🎜🎜다른 개발자가 BetaCalc 플러그인에 등록하는 데 사용할 수 있는 등록(register) 메서드를 만드는 것부터 시작하겠습니다. . 이 메서드가 수행하는 작업은 간단합니다. 외부 플러그인을 가져와 exec 함수를 가져온 다음 이를 계산기에 새 메서드로 연결합니다. 🎜rrreee🎜다음은 계산을 위한 샘플 플러그인입니다. 브라우저는 " 제곱(제곱)" 버튼: 🎜rrreee🎜많은 플러그인 시스템에서 플러그인은 일반적으로 두 부분으로 나뉩니다: 🎜
  1. 실행할 코드
  2. 메타데이터(예: 이름, 설명, 버전 번호, 종속성 등)
🎜플러그인에서 exec 함수에는 name는 우리의 메타데이터입니다. 플러그인을 등록한 후 <code>exec 함수는 betaCalc 개체에 메서드로 직접 연결되어 BetaCalc의 this에 대한 액세스를 제공합니다. 🎜🎜이제 BetaCalc에는 직접 호출할 수 있는 새로운 "사각형" 버튼이 있습니다. 🎜rrreee🎜이 시스템에는 많은 장점이 있습니다. 플러그인은 함수에 전달될 수 있는 간단한 객체 리터럴입니다. 이는 플러그인을 npm을 통해 다운로드하고 ES6 모듈로 가져올 수 있음을 의미합니다. 배포의 용이성은 매우 중요합니다! 🎜🎜하지만 우리 시스템에는 몇 가지 결함이 있습니다. 🎜🎜플러그인에 BetaCalc의 권한에 대한 액세스 권한을 부여하면 모든 BetaCalc 코드에 대한 읽기/쓰기 액세스 권한을 가질 수 있습니다. 이는 currentValue를 가져오고 설정하는 데 유용하지만 위험할 수도 있습니다. 플러그인이 내부 기능(예: setValue)을 재정의하는 경우 BetaCalc 및 기타 플러그인에 대해 예상치 못한 결과가 발생할 수 있습니다. 이는 소프트웨어 엔터티가 확장에는 개방되어야 하지만 수정에는 폐쇄되어야 한다는 개방-폐쇄 원칙을 위반합니다. 🎜🎜또한 "제곱" 기능은 부작용을 발생시켜 작동합니다. 이는 JavaScript에서 드문 일이 아니지만 기분이 좋지 않습니다. 특히 다른 플러그인이 동일한 내부 상태에 있을 수 있는 경우에는 더욱 그렇습니다. 보다 실용적인 접근 방식은 시스템을 더욱 안전하고 예측 가능하게 만드는 데 큰 도움이 될 것입니다. 🎜

더 나은 플러그인 아키텍처🎜🎜더 나은 플러그인 아키텍처를 살펴보겠습니다. 다음 예에서는 계산기와 해당 플러그인 API를 모두 변경합니다. 🎜rrreee🎜 여기서 몇 가지 눈에 띄는 변경 사항을 적용했습니다. 🎜🎜먼저, 플러그인을 자체 플러그인 개체에 넣어 "핵심" 계산기 메서드(예: 플러스 및 마이너스)와 분리합니다. 플러그인을 plugins 개체에 저장하면 시스템이 더욱 안전해집니다. 이제 이 플러그인에 액세스하는 플러그인은 BetaCalc 속성을 볼 수 없고 betaCalc.plugins의 속성만 볼 수 있습니다. 🎜🎜둘째, 버튼의 기능을 이름으로 조회한 후 호출하는 press 메서드를 구현했습니다. 이제 플러그인의 exec 함수를 호출할 때 현재 계산기 값(currentValue)을 함수에 전달하고 함수가 새 계산기 값을 반환할 것으로 예상합니다. 🎜🎜기본적으로 이 새로운 press 메서드는 모든 계산기 버튼을 순수 함수로 변환합니다. 값을 가져와 작업을 수행하고 결과를 반환합니다. 여기에는 많은 이점이 있습니다: 🎜
  • API를 단순화합니다.
  • BetaCalc와 플러그인 자체 모두에 대해 테스트가 더 쉬워집니다.
  • 시스템의 종속성을 줄이고 더 느슨하게 결합되도록 만듭니다.

이 새로운 아키텍처는 첫 번째 예보다 제한적이지만 잘 작동합니다. 우리는 기본적으로 플러그인 작성자를 위한 가드레일을 배치하여 그들이 원하는 변경을 수행하지 못하도록 제한합니다.

사실 너무 엄격할 수도 있어요! 현재 계산기 플러그인은 currentValue에서만 작동합니다. 플러그인 작성자가 고급 기능(예: "기억" 버튼 또는 기록 추적 방법)을 추가하려는 경우 할 수 있는 일이 많지 않습니다.

아마도 이게 좋을 것 같아요. 플러그인 작성자에게 부여하는 힘은 섬세한 균형입니다. 너무 많은 권한을 부여하면 프로젝트의 안정성에 영향을 미칠 수 있습니다. 그러나 그들에게 너무 적은 전력을 주면 그들 자신의 문제를 해결하기 어려울 것입니다. 이 경우에는 플러그를 연결하지 않는 것이 좋습니다.

또 무엇을 할 수 있나요?

시스템을 개선하려면 아직 해야 할 일이 많습니다.

플러그인 작성자가 이름이나 반환 값 정의를 잊어버린 경우 이를 알리기 위해 오류 처리를 추가할 수 있습니다. QA 개발자처럼 생각하고 이러한 상황을 사전에 처리할 수 있도록 시스템이 어떻게 손상될 수 있는지 상상해 보는 것이 좋습니다.

플러그인의 기능을 확장할 수 있습니다. 현재 BetaCalc 플러그인은 버튼을 추가할 수 있습니다. 하지만 특정 수명 주기 이벤트(예: 계산기가 값을 표시하려고 하는 경우)에 대한 콜백도 등록할 수 있다면 어떻게 될까요? 아니면 여러 상호 작용에 걸쳐 상태를 저장할 특별한 장소가 있다면 어떨까요? 이로 인해 새로운 사용 사례가 열릴까요?

플러그인 등록 기능도 확장할 수 있습니다. 초기 설정을 통해 플러그인을 등록할 수 있다면 어떨까요? 이로 인해 플러그인이 더 유연해졌나요? 플러그인 작성자가 "BetaCalc Stats Package"와 같은 단일 버튼 대신 전체 버튼 세트를 등록하고 싶다면 어떻게 해야 할까요? 이를 지원하려면 어떤 변경이 필요합니까?

플러그인 시스템

BetaCalc와 플러그인 시스템은 매우 간단합니다. 프로젝트 규모가 더 크다면 다른 플러그인 아키텍처를 살펴보는 것이 좋습니다.

좋은 출발점은 성공적인 플러그인 시스템의 예를 찾기 위해 기존 프로젝트를 살펴보는 것입니다. JavaScript의 경우 이는 jQuery, Gatsby, D3, CKEditor 등을 의미할 수 있습니다. 또한 다양한 JavaScript 디자인 패턴에 익숙해지고 싶을 수도 있습니다. 각 디자인 패턴은 서로 다른 인터페이스와 결합 정도를 제공하여 여러 가지 좋은 플러그인 아키텍처 선택을 제공합니다. 이러한 옵션을 이해하면 프로젝트를 사용하는 모든 사람의 요구 사항의 균형을 더 잘 맞추는 데 도움이 됩니다.

패턴 자체 외에도 그러한 결정을 내리기 위해 활용할 수 있는 좋은 소프트웨어 개발 원칙이 많이 있습니다. 나는 이미 몇 가지 접근 방식(개방-폐쇄 원칙 및 느슨한 결합 등)을 언급했지만 다른 관련 접근 방식에는 디미터 법칙 및 종속성 주입이 포함됩니다.

많이 들리겠지만 조사를 해봐야 합니다. 플러그인 아키텍처를 변경해야 하기 때문에 모든 사람이 플러그인을 다시 작성하도록 하는 것보다 더 고통스러운 것은 없습니다. 이는 신뢰를 잃고 사람들이 미래 기여에 대한 신뢰를 잃게 만드는 빠른 방법입니다.

요약

좋은 플러그인 아키텍처를 처음부터 작성하는 것은 어렵습니다! 모든 사람의 요구 사항을 충족하는 시스템을 구축하려면 많은 고려 사항의 균형을 맞춰야 합니다. 충분히 간단합니까? 기능이 강력할 수 있나요? 장기적으로 효과가 있을까요?

하지만 좋은 플러그인 시스템을 갖는 것은 모든 사람에게 도움이 되고 개발자는 문제를 자유롭게 해결할 수 있다는 점에서 그만한 가치가 있습니다. 최종 사용자가 선택할 수 있는 옵션 기능이 많이 있습니다. 프로젝트를 중심으로 생태계와 커뮤니티를 구축할 수 있습니다. 그것은 윈윈(win-win) 상황이다.

위 내용은 JavaScript 플러그인 시스템을 설계하는 것은 매우 중요합니다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 juejin.im에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제