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
11 changes: 11 additions & 0 deletions src/build-actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,17 @@ const prepareToBuildAction = async (action, root, dist) => {
return resolve(stats)
})
})

// Fix for IOEXT-1726: webpack emits CommonJS (libraryTarget: 'commonjs2'),
// but Node walks up the directory tree to find the closest package.json
// when deciding the module type for the bundled index.js. If the user's
// project sets "type": "module" (ESM), Node parses the CJS bundle as ESM
// and aio-cli-plugin-app-dev's require()-based loader fails with
// "action not found, or does not export main". Drop a sibling package.json
// that pins the bundle output to CommonJS regardless of the project type.
fs.writeJsonSync(path.join(tempBuildDir, 'package.json'), {
type: 'commonjs'
})
}

return {
Expand Down
24 changes: 24 additions & 0 deletions test/build.actions.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,30 @@ describe('build by bundling js action file with webpack', () => {
path.normalize('/dist/actions/sample-app-1.0.0/action.zip'))
})

test('should drop a sibling package.json with type: commonjs in the webpack temp dir (IOEXT-1726)', async () => {
await buildActions(config)

const tempDir = path.normalize('/dist/actions/sample-app-1.0.0/action-temp')

// confirm webpack was asked to emit the bundle to the expected temp dir
expect(webpack).toHaveBeenCalledWith(expect.arrayContaining([
expect.objectContaining({
output: expect.objectContaining({
path: tempDir,
filename: 'index.js'
})
})
]))

// the sibling package.json must scope the bundle as CommonJS so that Node
// does not treat it as ESM when the user's project package.json declares
// "type": "module".
const siblingPath = path.join(tempDir, 'package.json').split(path.sep).join('/')
const siblingRaw = global.fakeFileSystem.files()[siblingPath]
expect(siblingRaw).toBeDefined()
expect(JSON.parse(siblingRaw)).toEqual({ type: 'commonjs' })
})

test('should bundle a single action file using webpack and zip it with includes', async () => {
global.fakeFileSystem.reset()
global.fakeFileSystem.addJson({
Expand Down
Loading