Egg: [RFC] 插件自动开启策略

Created on 5 Jun 2018  ·  14Comments  ·  Source: eggjs/egg

问题

如果引入一个框架未内置的插件,需要两个步骤

  1. 安装模块
  2. 配置 plugin.js
exports.pluginName = {
  enable: true,
  package: 'plugin-module-name'
};

这样会有两个问题

  1. 对使用者不太友好,直观的感觉是:我安装了就自动开启了
  2. 有些新插件,暂时没有在框架内置,会让用户自己引入。后面可能插件又被框架引入了,这个时候让用户修改 plugin.js 也很难描述「你去把那个 package.json 里删掉,把 plugin.js 里的 package 删掉」

建议

一句话说:插件只要安装了,默认就会被加载,开启的话还是在 plugin.js 里,只是不用配置 package 了

具体做法:

  1. egg-loader 在加载插件的时候,先找到应用以及它涉及的框架 app -> framework a -> framework b -> egg 目录
  2. 按顺序读取应用和它的框架的 package.json -> dependencies 列表,然后 resolve 列表中的模块,找到它们的 package.json,从它们的 package.json 中找到 eggPlugin 节点,完成插件的加载,这里加载到的插件都是默认开启关闭的
  3. 根据老的插件加载策略,读取 plugin.js,用它来覆盖第二步得到的结果

风险

目前想到的一个风险就是:应用可能自己安装了一些没用的插件,默认就被开启了,但这个问题可以在开发阶段给与一些提示

新的方案,只是增加了一个 auto load 过程,对于老的方式是兼容的

discussion proposals

Most helpful comment

how about:

https://github.com/eggjs/egg/issues/808

egg-init plugin enable egg-view
egg-init plugin install nunjucks
egg-init plugin list

All 14 comments

Translation of this issue:


[RFC] Plugins Automatically Open Policy

problem

If you introduce a plugin that does not have a built-in framework, two steps are required

  1. Install the module
  2. Configure plugin.js
exports.pluginName = {
  Enable: true,
  Package: 'plugin-module-name'
};

This will have two problems

  1. It is not very user-friendly. The intuitive feeling is: I automatically turn on when I install it.
  2. Some new plugins, which are not built into the framework for the time being, will let users introduce themselves. Later, the possible plug-ins were introduced by the framework. It is very difficult for the user to modify the plugin.js.

Suggest

In a word: The plugin is installed by default. It is enabled by default (how to load it later). If you do not want to open it, the user needs to configure plugin.js enable=false.

specific methods:

  1. egg-loader When loading the plug-in, first find the application and the framework it involves app -> framework a -> framework b -> egg directory
  2. Read the package.json -> dependencies list of the application and its framework in order, then resolve the modules in the list, find their package.json, find the eggPlugin node from their package.json, and complete the plugin loading. The plugins loaded here are all enabled by default
  3. According to the old plugin loading strategy, read plugin.js and use it to overwrite the results from the second step.

Risk

One risk that comes to mind at the moment is that the application may install some useless plugins by default and it is enabled by default, but this problem can be given some hints during development.

how about:

https://github.com/eggjs/egg/issues/808

egg-init plugin enable egg-view
egg-init plugin install nunjucks
egg-init plugin list

放到 egg-bin 吧 @atian25

@gxcsoccer 自动加载的方案有点不太可控,提示用户是不会去看的。

是不是可以修改egg插件, 在post-script阶段自动修改plugin.js, 开启插件

@gxcsoccer 自动加载的方案有点不太可控,提示用户是不会去看的。

@dead-horse 或者退一步,安装以后默认不开启,但是不用用户自己去配 package 了,配 package 真的好傻啊

@gxcsoccer 改变用户的安装方式即可: egg-bin plugin install xx 自动安装并配置 plugin.js

@gxcsoccer 改变用户的安装方式即可: egg-bin plugin install xx 自动安装并配置 plugin.js

这是一个选择,和我那个不冲突,像我个人不太喜欢用这种工具,我知道该怎么配 plugin.js,我的方案只是简化了一下配置

但是不用用户自己去配 package 了,配 package 真的好傻啊

意思是在 plugin.js 里面直接写 exports.name = true;,然后自动去寻址么?

意思是在 plugin.js 里面直接写 exports.name = true;,然后自动去寻址么?

就是以前的加载逻辑是依赖 plugin.js 里的 package 或 path 配置来找 plugin,现在改成先就通过 app 和 framework 的 package.json 里的 dependencies 把 plugin 识别出来

这里是不是也要考虑一下,插件版本与框架的对应关系的检测,比如可以借鉴 peerDependencies :

{
  "eggPlugin": {
    "peerDependencies": ">= 1.5.2 < 2",
    "dependencies": [],
    "optionalDependencies": [],
    "name": "demo"
  }
}

否则的话,做到了更容易的加载,冲突也会更严重。

ping @popomore

建议顺便改为 egg.pluginegg.framework 保持同一个节点和风格

建议是默认开启,不要默认关闭,这个模式在laravel5.x的时候已经有一段时间了,社区没有任何问题。

它的处理方式如下(转换成node的模式):

  1. 模块自己在package.json里面添加自己的插件信息,如上面的egg.plugin
  2. 应用直接npm install module,在postinstall的hook上创建将自己的信息添加进去(egg可以考虑在start的时候才去创建,php需要在install就去自动发现是因为没有start过程,安装的时候会有提示有哪些包被自动发现了)
  3. 如果希望当前应用不需要加载,可以在应用自己的package.json里面增加egg.plugin.dont-discover将不希望自动发现的插件禁用掉,例如全部禁用:
{'egg.plugin.dont-discover':['*']} 
  1. 对于一些开发时候需要加载的插件只需要在生产环境上使用--production就可以了。不安装自然也应该没有自动发现的流程。

尝试在plugin.js实现了一下

  1. 启动的时候直接遍历app的node_modules加载插件
  2. 过滤掉egg内置的plugin和用户指定不加载的插件

测试同时安装egg-restegg-validate ,只自动加载egg-validate

Was this page helpful?
0 / 5 - 0 ratings

Related issues

jtyjty99999 picture jtyjty99999  ·  52Comments

andylei18 picture andylei18  ·  35Comments

popomore picture popomore  ·  59Comments

occultskyrong picture occultskyrong  ·  35Comments

fengmk2 picture fengmk2  ·  44Comments