Skip to content

Commit

Permalink
fix: multiple plugin versions in a monorepo setup (#6105)
Browse files Browse the repository at this point in the history
* 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]>
  • Loading branch information
mrstork and pieh authored Feb 27, 2025
1 parent 77b947d commit 23c7ce7
Show file tree
Hide file tree
Showing 15 changed files with 78 additions and 6 deletions.
4 changes: 3 additions & 1 deletion package-lock.json

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

2 changes: 1 addition & 1 deletion packages/build/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@
"ps-list": "^8.0.0",
"read-package-up": "^11.0.0",
"readdirp": "^3.4.0",
"resolve": "^2.0.0-next.1",
"resolve": "^2.0.0-next.5",
"rfdc": "^1.3.0",
"safe-json-stringify": "^1.2.0",
"semver": "^7.3.8",
Expand Down
9 changes: 5 additions & 4 deletions packages/build/src/plugins/resolve.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export const resolvePluginsPath = async function ({
}) {
const autoPluginsDir = getAutoPluginsDir(buildDir, packagePath)
const pluginsOptionsA = await Promise.all(
pluginsOptions.map((pluginOptions) => resolvePluginPath({ pluginOptions, buildDir, autoPluginsDir })),
pluginsOptions.map((pluginOptions) => resolvePluginPath({ pluginOptions, buildDir, packagePath, autoPluginsDir })),
)
const pluginsOptionsB = await addPluginsNodeVersion({
featureFlags,
Expand Down Expand Up @@ -100,24 +100,25 @@ const resolvePluginPath = async function ({
pluginOptions,
pluginOptions: { packageName, loadedFrom },
buildDir,
packagePath,
autoPluginsDir,
}) {
// Core plugins
if (loadedFrom !== undefined) {
return pluginOptions
}

const localPackageName = normalizeLocalPackageName(packageName)

// Local plugins
const localPackageName = normalizeLocalPackageName(packageName)
if (localPackageName.startsWith('.')) {
const { path: localPath, error } = await tryResolvePath(localPackageName, buildDir)
validateLocalPluginPath(error, localPackageName)
return { ...pluginOptions, pluginPath: localPath, loadedFrom: 'local' }
}

// Plugin added to `package.json`
const { path: manualPath } = await tryResolvePath(packageName, buildDir)
const packageDir = join(buildDir, packagePath || '')
const { path: manualPath } = await tryResolvePath(packageName, packageDir)
if (manualPath !== undefined) {
return { ...pluginOptions, pluginPath: manualPath, loadedFrom: 'package.json' }
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"name": "module_plugin",
"version": "0.0.1",
"type": "module",
"description": "test",
"license": "MIT",
"repository": "test",
"dependencies": {
"netlify-plugin-test": "8.2.0"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[build]
publish = "/"

[[plugins]]
package = "netlify-plugin-test"

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.

Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"name": "module_plugin",
"version": "0.0.1",
"type": "module",
"description": "test",
"license": "MIT",
"repository": "test",
"dependencies": {
"netlify-plugin-test": "^8.5.3"
}
}

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.

6 changes: 6 additions & 0 deletions packages/build/tests/plugins/fixtures/monorepo/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"name": "module_multiple",
"workspaces": [
"apps/*"
]
}
9 changes: 9 additions & 0 deletions packages/build/tests/plugins/tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,15 @@ test('Resolution is relative to the build directory', async (t) => {
t.snapshot(normalizeOutput(output))
})

test('Resolution respects monorepo node module resolution rules', async (t) => {
const fixture = await new Fixture('./fixtures/monorepo')
const output = await fixture.withFlags({ packagePath: 'apps/unpinned' }).runWithBuild()
// fixture has 2 versions of the same build plugin used by different workspaces
// this ensures version used by apps/unpinned is used instead of version that
// is hoisted in shared monorepo node_modules
t.assert(output.indexOf('@8.5.3') > 0)
})

test('Non-existing plugins', async (t) => {
const output = await new Fixture('./fixtures/non_existing').runWithBuild()
t.snapshot(normalizeOutput(output))
Expand Down

0 comments on commit 23c7ce7

Please sign in to comment.