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
27 changes: 27 additions & 0 deletions packages/edge-bundler/node/bundler.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -533,6 +533,33 @@ test('Loads npm modules which use package.json.exports', async () => {
await rm(vendorDirectory.path, { force: true, recursive: true })
})

test('Loads modules which contain cycles', async () => {
const { basePath, cleanup, distPath } = await useFixture('imports_cycle')
const sourceDirectory = join(basePath, 'functions')
const declarations: Declaration[] = [
{
function: 'func1',
path: '/func1',
},
]
const vendorDirectory = await tmp.dir()

await bundle([sourceDirectory], distPath, declarations, {
basePath,
vendorDirectory: vendorDirectory.path,
})

const manifestFile = await readFile(resolve(distPath, 'manifest.json'), 'utf8')
const manifest = JSON.parse(manifestFile)
const bundlePath = join(distPath, manifest.bundles[0].asset)
const { func1 } = await runESZIP(bundlePath, vendorDirectory.path)

expect(func1).toBe('magix')

await cleanup()
await rm(vendorDirectory.path, { force: true, recursive: true })
})

test('Loads npm modules in a monorepo setup', async () => {
const systemLogger = vi.fn()
const { basePath: rootPath, cleanup, distPath } = await useFixture('monorepo_npm_module')
Expand Down
32 changes: 28 additions & 4 deletions packages/edge-bundler/node/npm_dependencies.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,10 @@ async function parseImportsForFile(file: string, rootPath: string) {
* Parses a set of functions and returns a list of specifiers that correspond
* to npm modules.
*/
const getNPMSpecifiers = async ({ basePath, functions, importMap, environment, rootPath }: GetNPMSpecifiersOptions) => {
const getNPMSpecifiers = async (
{ basePath, functions, importMap, environment, rootPath }: GetNPMSpecifiersOptions,
alreadySeenPaths = new Set<string>(),
) => {
const baseURL = pathToFileURL(basePath)
const npmSpecifiers: { specifier: string; types?: string }[] = []
for (const func of functions) {
Expand All @@ -157,15 +160,29 @@ const getNPMSpecifiers = async ({ basePath, functions, importMap, environment, r
const specifier = i.moduleSpecifier.isConstant ? i.moduleSpecifier.value! : i.moduleSpecifier.code
switch (i.moduleSpecifier.type) {
case 'absolute': {
if (alreadySeenPaths.has(specifier)) {
break
}
alreadySeenPaths.add(specifier)
npmSpecifiers.push(
...(await getNPMSpecifiers({ basePath, functions: [specifier], importMap, environment, rootPath })),
...(await getNPMSpecifiers(
{ basePath, functions: [specifier], importMap, environment, rootPath },
alreadySeenPaths,
)),
)
break
}
case 'relative': {
const filePath = path.join(path.dirname(func), specifier)
if (alreadySeenPaths.has(filePath)) {
break
}
alreadySeenPaths.add(filePath)
npmSpecifiers.push(
...(await getNPMSpecifiers({ basePath, functions: [filePath], importMap, environment, rootPath })),
...(await getNPMSpecifiers(
{ basePath, functions: [filePath], importMap, environment, rootPath },
alreadySeenPaths,
)),
)
break
}
Expand All @@ -180,8 +197,15 @@ const getNPMSpecifiers = async ({ basePath, functions, importMap, environment, r
if (matched) {
if (resolvedImport.protocol === 'file:') {
const newSpecifier = fileURLToPath(resolvedImport).replace(/\\/g, '/')
if (alreadySeenPaths.has(newSpecifier)) {
break
}
alreadySeenPaths.add(newSpecifier)
npmSpecifiers.push(
...(await getNPMSpecifiers({ basePath, functions: [newSpecifier], importMap, environment, rootPath })),
...(await getNPMSpecifiers(
{ basePath, functions: [newSpecifier], importMap, environment, rootPath },
alreadySeenPaths,
)),
)
}
} else if (!resolvedImport?.protocol?.startsWith('http')) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import hello from '../hello.ts'

export const name = "magix"

export default async () => {
return new Response(hello())
}
5 changes: 5 additions & 0 deletions packages/edge-bundler/test/fixtures/imports_cycle/hello.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { name } from "./functions/func1.ts";

export default function hello() {
return name
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"type": "module"
}
Loading