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

fix: limit nodeModulesWithDynamicImports to unresolved imports #671

Merged
merged 3 commits into from
Sep 27, 2021
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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