Skip to content
This repository has been archived by the owner on May 22, 2024. It is now read-only.

Commit

Permalink
fix: limit nodeModulesWithDynamicImports to unresolved imports (#671)
Browse files Browse the repository at this point in the history
* feat: limit nodeModulesWithDynamicImports to unresolved imports

* chore: update test

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
  • Loading branch information
eduardoboucas and kodiakhq[bot] committed Sep 27, 2021
1 parent d646be2 commit ce6d1ce
Show file tree
Hide file tree
Showing 10 changed files with 59 additions and 31 deletions.
47 changes: 23 additions & 24 deletions src/runtimes/node/dynamic_imports/plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,36 +22,35 @@ const getDynamicImportsPlugin = ({ basePath, includedPaths, moduleNames, process
build.onDynamicImport({}, async (args) => {
const { expression, resolveDir } = args

await registerModuleWithDynamicImports({ cache, moduleNames, resolveDir, srcDir })

// Don't attempt to parse the expression if the base path isn't defined,
// since we won't be able to generate the globs for the included paths.
// Also don't parse the expression if we're not interested in processing
// the dynamic import expressions.
if (!basePath || !processImports) {
return
}

const { includedPathsGlob, type: expressionType } = parseExpression({ basePath, expression, resolveDir }) || {}

if (!includedPathsGlob) {
return
if (basePath && processImports) {
const { includedPathsGlob, type: expressionType } = parseExpression({ basePath, expression, resolveDir }) || {}

if (includedPathsGlob) {
// The parser has found a glob of paths that should be included in the
// bundle to make this import work, so we add it to `includedPaths`.
includedPaths.add(includedPathsGlob)

// Create the shim that will handle the import at runtime.
const contents = getShimContents({ expressionType, resolveDir, srcDir })

// This is the only branch where we actually solve a dynamic import.
// eslint-disable-next-line max-depth
if (contents) {
return {
contents,
}
}
}
}

// The parser has found a glob of paths that should be included in the
// bundle to make this import work, so we add it to `includedPaths`.
includedPaths.add(includedPathsGlob)

// Create the shim that will handle the import at runtime.
const contents = getShimContents({ expressionType, resolveDir, srcDir })

if (!contents) {
return
}

return {
contents,
}
// If we're here, it means we weren't able to solve the dynamic import.
// We add it to the list of modules with dynamic imports, which allows
// consumers like Netlify Build or CLI to advise users on how to proceed.
await registerModuleWithDynamicImports({ cache, moduleNames, resolveDir, srcDir })
})
},
})
Expand Down
6 changes: 5 additions & 1 deletion tests/fixtures/node-module-dynamic-import/function.js
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
module.exports = require('@org/test')
const test1 = require('@org/test')
const test2 = require('@org/test_2')
const test3 = require('test-three')

module.exports = [test1, test2, test3]

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.

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.

4 changes: 3 additions & 1 deletion tests/fixtures/node-module-dynamic-import/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
"name": "node-module-dynamic-import",
"version": "1.0.0",
"dependencies": {
"@org/test": "1.0.0"
"@org/test": "1.0.0",
"@org/test_2": "1.0.0",
"test-three": "1.0.0"
}
}
10 changes: 5 additions & 5 deletions tests/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -1455,13 +1455,14 @@ test('Adds `type: "functionsBundling"` to esbuild bundling errors', async (t) =>
})

test('Returns a list of all modules with dynamic imports in a `nodeModulesWithDynamicImports` property', async (t) => {
const { files } = await zipNode(t, 'node-module-dynamic-import', {
opts: { config: { '*': { nodeBundler: ESBUILD } } },
const fixtureName = 'node-module-dynamic-import'
const { files } = await zipNode(t, fixtureName, {
opts: { basePath: join(FIXTURES_DIR, fixtureName), config: { '*': { nodeBundler: ESBUILD } } },
})

t.is(files[0].nodeModulesWithDynamicImports.length, 2)
t.true(files[0].nodeModulesWithDynamicImports.includes('@org/test'))
t.true(files[0].nodeModulesWithDynamicImports.includes('test-two'))
t.true(files[0].nodeModulesWithDynamicImports.includes('test-three'))
})

test('Returns an empty list of modules with dynamic imports if the modules are missing a `package.json`', async (t) => {
Expand Down Expand Up @@ -1508,8 +1509,7 @@ test('Adds a runtime shim and includes the files needed for dynamic imports usin
// eslint-disable-next-line unicorn/new-for-builtins
t.deepEqual(values, Array(expectedLength).fill(true))
t.throws(() => func('two'))
t.is(files[0].nodeModulesWithDynamicImports.length, 1)
t.true(files[0].nodeModulesWithDynamicImports.includes('@org/test'))
t.is(files[0].nodeModulesWithDynamicImports.length, 0)
})

test('Leaves dynamic imports untouched when the files required to resolve the expression cannot be packaged at build time', async (t) => {
Expand Down

1 comment on commit ce6d1ce

@github-actions
Copy link
Contributor

Choose a reason for hiding this comment

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

⏱ Benchmark results

largeDepsZisi: 1m 14.1s

Please sign in to comment.