Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 14 additions & 7 deletions lib/loader/mixin/plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -331,22 +331,29 @@ module.exports = {
}

const name = plugin.package || plugin.name;
const lookupDirs = [];
const lookupDirs = new Set();

// 尝试在以下目录找到匹配的插件
// try to locate the plugin in the following directories
// -> {APP_PATH}/node_modules
// -> {EGG_PATH}/node_modules
// -> $CWD/node_modules
lookupDirs.push(path.join(this.options.baseDir, 'node_modules'));
lookupDirs.add(path.join(this.options.baseDir, 'node_modules'));

// 到 egg 中查找,优先从外往里查找
// try to locate the plugin at framework from upper to lower
for (let i = this.eggPaths.length - 1; i >= 0; i--) {
const eggPath = this.eggPaths[i];
lookupDirs.push(path.join(eggPath, 'node_modules'));
lookupDirs.add(path.join(eggPath, 'node_modules'));

// should find the siblings directory of framework when using pnpm
// 'node_modules/.pnpm/[email protected]/node_modules/yadan/node_modules',
// 'node_modules/.pnpm/[email protected]/node_modules', <- this is the sibling directory
// 'node_modules/.pnpm/[email protected]/node_modules/egg/node_modules',
// 'node_modules/.pnpm/[email protected]/node_modules', <- this is the sibling directory
lookupDirs.add(path.dirname(eggPath));
}

// should find the $cwd/node_modules when test the plugins under npm3
lookupDirs.push(path.join(process.cwd(), 'node_modules'));
lookupDirs.add(path.join(process.cwd(), 'node_modules'));

for (let dir of lookupDirs) {
Copy link
Member Author

@atian25 atian25 Jan 7, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个地方,如果把原来的 fs.exists 改为 require.resolve(${name}/package.json, { paths: [...lookupDirs] }); 其实会更合理,使用到 require 自己的寻址机制,就不用在上面 hard code 目录。

潜在的问题:

  1. 寻址逻辑稍微复杂了一点,但基本上可以无视,后面支持 manifest 后就更没问题了。
  2. inline plugin 会存在一些问题,现在我们没有强制检测它必须有 package.json,就看这种我们是否算 break

@fengmk2 @hyj1991 @mansonchor @popomore 你们怎么看?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

原来也没有,不算 break。

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

好,我也倾向于用 resolve, 不过肯定会 break 到一些不规范的用户的,之前没这个规范,但我们也没有强制限制。

我再提个 PR

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

在这个 fn 的第一行,就会判断 plugin.path 是否存在,然后直接 return 了,所以不存在上面说的 break 的情况。
重新提交了下 #238

dir = path.join(dir, name);
Expand All @@ -355,7 +362,7 @@ module.exports = {
}
}

throw new Error(`Can not find plugin ${name} in "${lookupDirs.join(', ')}"`);
throw new Error(`Can not find plugin ${name} in "${[ ...lookupDirs ].join(', ')}"`);
},

_extendPlugins(target, plugins) {
Expand Down
10 changes: 10 additions & 0 deletions test/fixtures/plugin-pnpm/config/plugin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
'use strict';

module.exports = {
a: {
enable: true,
},
b: {
enable: true,
},
};

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions test/fixtures/plugin-pnpm/node_modules/b/package.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions test/fixtures/plugin-pnpm/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"name": "egg-plugin-pnpm"
}
39 changes: 30 additions & 9 deletions test/loader/mixin/load_plugin.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,28 @@ describe('test/load_plugin.test.js', function() {
});
});

it('should support pnpm node_modules style', () => {
class Application extends EggCore {
get [ Symbol.for('egg#loader') ]() {
return EggLoader;
}
get [ Symbol.for('egg#eggPath') ]() {
return utils.getFilepath('plugin-pnpm/node_modules/.pnpm/[email protected]/node_modules/framework');
}
}
app = utils.createApp('plugin-pnpm', {
Application,
});
const loader = app.loader;
loader.loadPlugin();
loader.loadConfig();
console.log(loader.plugins, loader.config);
assert(loader.plugins.a);
assert(loader.plugins.b);
assert(loader.config.a === 'a');
assert(loader.config.b === 'b');
});

it('should support alias', function() {
const baseDir = utils.getFilepath('plugin');
app = utils.createApp('plugin');
Expand Down Expand Up @@ -406,16 +428,15 @@ describe('test/load_plugin.test.js', function() {
assert(plugin.path === utils.getFilepath('realpath/a'));
});

class Application extends EggCore {
get [Symbol.for('egg#loader')]() {
return EggLoader;
}
get [Symbol.for('egg#eggPath')]() {
return utils.getFilepath('plugin-from/framework');
}
}

it('should get the defining plugin path in every plugin', () => {
class Application extends EggCore {
get [ Symbol.for('egg#loader') ]() {
return EggLoader;
}
get [ Symbol.for('egg#eggPath') ]() {
return utils.getFilepath('plugin-from/framework');
}
}
app = utils.createApp('plugin-from', {
Application,
});
Expand Down