Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support native esm modules. #453

Closed
dbo opened this issue Feb 18, 2022 · 10 comments
Closed

Support native esm modules. #453

dbo opened this issue Feb 18, 2022 · 10 comments

Comments

@dbo
Copy link

dbo commented Feb 18, 2022

Hi! 馃憢

Firstly, thanks for your work on this project! 馃檪

Today I used patch-package to patch micro@9.3.4 for the project I'm working on.

Here is the diff that solved my problem:

diff --git a/node_modules/micro/lib/handler.js b/node_modules/micro/lib/handler.js
index 4b8fd1c..6e6439a 100644
--- a/node_modules/micro/lib/handler.js
+++ b/node_modules/micro/lib/handler.js
@@ -1,12 +1,36 @@
 // Utilities
+const path = require('path');
+const fs = require('fs');
 const logError = require('./error');
 
 module.exports = async file => {
 	let mod;
 
 	try {
-		mod = await require(file); // Await to support exporting Promises
+		let esm = /\.mjs$/.test(file);
+		if (!esm) { // look up package.json what kind it is
+			let dir = file;
+			while (true) {
+				const pkgPath = path.join(dir, 'package.json');
+				if (fs.existsSync(pkgPath)) {
+					const pkg = JSON.parse(String(fs.readFileSync(pkgPath)));
+					esm = /module/i.test(pkg.type);
+					if (esm && dir === file) { // directory given, resolve main module for dynamic import
+						const main = pkg.main || 'index.js';
+						file = path.join(dir, ...main.split('/'));
+					}
+					break;
+				}
+				const parsed = path.parse(dir);
+				if (parsed.root === dir) {
+					break;
+				}
+				dir = parsed.dir;
+			}
+		}
+		mod = esm ? await import(file) : require(file);
 
+		mod = await mod; // Await to support exporting Promises
 		if (mod && typeof mod === 'object') {
 			mod = await mod.default; // Await to support es6 module's default export
 		}

This issue body was partially generated by patch-package.

@leerob
Copy link
Member

leerob commented Jul 7, 2022

#448

@leerob leerob closed this as completed Jul 7, 2022
@dbo
Copy link
Author

dbo commented Jul 7, 2022

@leerob The patch I submitted supports esm in a much more complete way, looking up the package's type like node.js does instead of urging to use the .mjs extension. Please consider it.

@leerob
Copy link
Member

leerob commented Jul 7, 2022

Would you be open to adding a PR with a test? Happy to review and merge it.

@pmbanugo
Copy link
Contributor

pmbanugo commented Aug 1, 2022

@leerob What do you think about reopening this and solving it after we merge #458 ?

@leerob
Copy link
Member

leerob commented Aug 4, 2022

Yeah I'm onboard.

@TooTallNate
Copy link
Member

Why not just always use await import()?

@leerob
Copy link
Member

leerob commented Aug 5, 2022

I'm good with that as well, especially since we're doing a major version bump.

@pmbanugo
Copy link
Contributor

pmbanugo commented Aug 5, 2022

Since we're using TS now, that gets transpiled to using require statements. We already use await import

mod = await import(file);

It was not a straightforward process to get that working the last time I tried. I plan to try a different solution when I get some time in the near future.

@electerious
Copy link

electerious commented Aug 11, 2022

Is it correct that I currently can't use micro together with an ES Module / "type": "module"? Is there a recommended workaround or is it better to wait as this will be resolved soon?

@pmbanugo
Copy link
Contributor

@electerious If you're not using micro programmatically then the cli will fail when processing ESM files. If you want to use ESM, then you can use it this way:

//programmatic usage

const micro = require('micro')
 
const server = micro(async (req, res) => {
  return 'Hello world'
})
 
server.listen(3000)

There would be a fix to load ESM files through the CLI in the near future.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants