Skip to content

Commit 23c7ce7

Browse files
mrstorkpieh
andauthored
fix: multiple plugin versions in a monorepo setup (#6105)
* chore(deps): update resolve package * fix: respect monorepos when determining plugin paths * test: add regression test for plugin resolutions in monorepos * test: add more test context Co-authored-by: Michal Piechowiak <[email protected]> --------- Co-authored-by: Michal Piechowiak <[email protected]>
1 parent 77b947d commit 23c7ce7

File tree

15 files changed

+78
-6
lines changed

15 files changed

+78
-6
lines changed

package-lock.json

Lines changed: 3 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/build/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@
112112
"ps-list": "^8.0.0",
113113
"read-package-up": "^11.0.0",
114114
"readdirp": "^3.4.0",
115-
"resolve": "^2.0.0-next.1",
115+
"resolve": "^2.0.0-next.5",
116116
"rfdc": "^1.3.0",
117117
"safe-json-stringify": "^1.2.0",
118118
"semver": "^7.3.8",

packages/build/src/plugins/resolve.js

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ export const resolvePluginsPath = async function ({
3737
}) {
3838
const autoPluginsDir = getAutoPluginsDir(buildDir, packagePath)
3939
const pluginsOptionsA = await Promise.all(
40-
pluginsOptions.map((pluginOptions) => resolvePluginPath({ pluginOptions, buildDir, autoPluginsDir })),
40+
pluginsOptions.map((pluginOptions) => resolvePluginPath({ pluginOptions, buildDir, packagePath, autoPluginsDir })),
4141
)
4242
const pluginsOptionsB = await addPluginsNodeVersion({
4343
featureFlags,
@@ -100,24 +100,25 @@ const resolvePluginPath = async function ({
100100
pluginOptions,
101101
pluginOptions: { packageName, loadedFrom },
102102
buildDir,
103+
packagePath,
103104
autoPluginsDir,
104105
}) {
105106
// Core plugins
106107
if (loadedFrom !== undefined) {
107108
return pluginOptions
108109
}
109110

110-
const localPackageName = normalizeLocalPackageName(packageName)
111-
112111
// Local plugins
112+
const localPackageName = normalizeLocalPackageName(packageName)
113113
if (localPackageName.startsWith('.')) {
114114
const { path: localPath, error } = await tryResolvePath(localPackageName, buildDir)
115115
validateLocalPluginPath(error, localPackageName)
116116
return { ...pluginOptions, pluginPath: localPath, loadedFrom: 'local' }
117117
}
118118

119119
// Plugin added to `package.json`
120-
const { path: manualPath } = await tryResolvePath(packageName, buildDir)
120+
const packageDir = join(buildDir, packagePath || '')
121+
const { path: manualPath } = await tryResolvePath(packageName, packageDir)
121122
if (manualPath !== undefined) {
122123
return { ...pluginOptions, pluginPath: manualPath, loadedFrom: 'package.json' }
123124
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"name": "module_plugin",
3+
"version": "0.0.1",
4+
"type": "module",
5+
"description": "test",
6+
"license": "MIT",
7+
"repository": "test",
8+
"dependencies": {
9+
"netlify-plugin-test": "8.2.0"
10+
}
11+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
[build]
2+
publish = "/"
3+
4+
[[plugins]]
5+
package = "netlify-plugin-test"

packages/build/tests/plugins/fixtures/monorepo/apps/unpinned/node_modules/netlify-plugin-test/index.js

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/build/tests/plugins/fixtures/monorepo/apps/unpinned/node_modules/netlify-plugin-test/manifest.yml

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/build/tests/plugins/fixtures/monorepo/apps/unpinned/node_modules/netlify-plugin-test/package.json

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"name": "module_plugin",
3+
"version": "0.0.1",
4+
"type": "module",
5+
"description": "test",
6+
"license": "MIT",
7+
"repository": "test",
8+
"dependencies": {
9+
"netlify-plugin-test": "^8.5.3"
10+
}
11+
}

packages/build/tests/plugins/fixtures/monorepo/node_modules/netlify-plugin-test/index.js

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/build/tests/plugins/fixtures/monorepo/node_modules/netlify-plugin-test/manifest.yml

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/build/tests/plugins/fixtures/monorepo/node_modules/netlify-plugin-test/package.json

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/build/tests/plugins/fixtures/monorepo/node_modules/unpinned

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"name": "module_multiple",
3+
"workspaces": [
4+
"apps/*"
5+
]
6+
}

packages/build/tests/plugins/tests.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,15 @@ test('Resolution is relative to the build directory', async (t) => {
8686
t.snapshot(normalizeOutput(output))
8787
})
8888

89+
test('Resolution respects monorepo node module resolution rules', async (t) => {
90+
const fixture = await new Fixture('./fixtures/monorepo')
91+
const output = await fixture.withFlags({ packagePath: 'apps/unpinned' }).runWithBuild()
92+
// fixture has 2 versions of the same build plugin used by different workspaces
93+
// this ensures version used by apps/unpinned is used instead of version that
94+
// is hoisted in shared monorepo node_modules
95+
t.assert(output.indexOf('@8.5.3') > 0)
96+
})
97+
8998
test('Non-existing plugins', async (t) => {
9099
const output = await new Fixture('./fixtures/non_existing').runWithBuild()
91100
t.snapshot(normalizeOutput(output))

0 commit comments

Comments
 (0)