-
Notifications
You must be signed in to change notification settings - Fork 19
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Feat: Import functions that are written as ES Modules (#140)
* feat: add the ability to use a function written as an ES module
- Loading branch information
1 parent
b1bafc8
commit 6ac6fff
Showing
10 changed files
with
145 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
const path = require('path'); | ||
|
||
// This is the way to import es modules inside a CJS module | ||
const dynamicImport = new Function('modulePath', 'return import(modulePath)'); | ||
|
||
async function loadFunction(filePath) { | ||
if (isESM(filePath)) { | ||
code = await dynamicImport(filePath); | ||
} else { | ||
code = require(filePath); | ||
} | ||
|
||
return code; | ||
} | ||
|
||
// https://nodejs.org/dist/latest-v18.x/docs/api/packages.html#determining-module-system | ||
// An ESM module can be determined 2 ways | ||
// 1. has the mjs file extention | ||
// 2. type=module in the package.json | ||
function isESM(filePath) { | ||
const pathParsed = path.parse(filePath); | ||
|
||
if (pathParsed.ext === '.mjs') { | ||
return true; | ||
} | ||
|
||
// find the functions package.json and see if it has a type field | ||
const functionPkg = require(path.join(pathParsed.dir, 'package.json')); | ||
if (functionPkg.type === 'module') { | ||
return true; | ||
} | ||
|
||
// Should default to CJS | ||
return false; | ||
} | ||
|
||
|
||
module.exports = exports = { loadFunction }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
module.exports = function testFunc(context) { | ||
return context; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
{ | ||
"name": "cjs-module", | ||
"version": "1.0.0" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
const handle = async (context) => { | ||
// YOUR CODE HERE | ||
context.log.info(JSON.stringify(context, null, 2)); | ||
|
||
// If the request is an HTTP POST, the context will contain the request body | ||
if (context.method === 'POST') { | ||
return { | ||
body: context.body, | ||
} | ||
// If the request is an HTTP GET, the context will include a query string, if it exists | ||
} else if (context.method === 'GET') { | ||
return { | ||
query: context.query, | ||
} | ||
} else { | ||
return { statusCode: 405, statusMessage: 'Method not allowed' }; | ||
} | ||
} | ||
|
||
// Export the function | ||
export { handle }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
{ | ||
"name": "esm-module-mjs", | ||
"version": "1.0.0" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
const handle = async context => { | ||
// YOUR CODE HERE | ||
context.log.info(JSON.stringify(context, null, 2)); | ||
|
||
// If the request is an HTTP POST, the context will contain the request body | ||
if (context.method === 'POST') { | ||
return { | ||
body: context.body, | ||
}; | ||
// If the request is an HTTP GET, the context will include a query string, if it exists | ||
} else if (context.method === 'GET') { | ||
return { | ||
query: context.query, | ||
}; | ||
} else { | ||
return { statusCode: 405, statusMessage: 'Method not allowed' }; | ||
} | ||
}; | ||
|
||
// Export the function | ||
export { handle }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
{ | ||
"name": "esm-module-type-module", | ||
"version": "1.0.0", | ||
"type": "module" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
const test = require('tape'); | ||
const path = require('path'); | ||
const { loadFunction } = require('../lib/function-loader.js'); | ||
|
||
const fixtureDir = path.join(__dirname, 'fixtures'); | ||
|
||
test('Loads a CJS function', async t => { | ||
const fn = await loadFunction(path.join(fixtureDir, 'cjs-module', 'index.js')); | ||
t.equal(typeof fn, 'function'); | ||
t.pass('CJS function loaded'); | ||
}); | ||
|
||
test('Loads an ESM function with an .mjs extension', async t => { | ||
const fn = await loadFunction(path.join(fixtureDir, 'esm-module-mjs', 'index.mjs')); | ||
t.equal(typeof fn.handle, 'function'); | ||
t.pass('ESM module with a mjs ext loaded'); | ||
}); | ||
|
||
test('Loads an ESM function with the type=module in the package.json', async t => { | ||
const fn = await loadFunction(path.join(fixtureDir, 'esm-module-type-module', 'index.js')); | ||
t.equal(typeof fn.handle, 'function'); | ||
t.pass('ESM module with a type=module in the package.json'); | ||
}); |