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’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiple ESM Edition Autoloader #83

Open
balupton opened this issue Jun 26, 2020 · 1 comment
Open

Multiple ESM Edition Autoloader #83

balupton opened this issue Jun 26, 2020 · 1 comment

Comments

@balupton
Copy link
Member

balupton commented Jun 26, 2020

Here is an attempt at a multiple ESM edition autoloader to test if the foundations are possible. It seems they are not, as it returns a promise, as dynamic imports return promises, so the exports will be promises, which is inconsistent API with the CJS Autoloader.

import { readFileSync } from 'fs'
function readJSON(path) {
	const text = readFileSync(path, 'utf8')
	return JSON.parse(text)
}

import path from 'path'
import url from 'url'
const root = path.dirname(url.fileURLToPath(import.meta.url))
const pkgPath = path.join(root, 'package.json')

function load() {
	const data = readJSON(pkgPath)
	for (const edition of data.editions) {
		if (
			edition.tags &&
			edition.tags.includes('import') &&
			edition.engines &&
			edition.engines.node
		) {
			const editionPath = path.join(root, edition.directory, edition.entry)
			return import(editionPath)
		}
	}
}

const d = load()
// can't export
export default d.default || d

As such, only a single ESM edition for Node seems to be able to be supported by packages.

@balupton
Copy link
Member Author

balupton commented Sep 3, 2020

For editions v4, it can be accomplished via a index.mjs file like so:

'use strict'
// auto-generated by boundation, do not update manually
/** @type {typeof import("./compiled-types/index.d.ts") } */
import { requirePackage } from 'editions'
import filedirname from 'filedirname'
const [__filename, __dirname] = filedirname(import.meta.url)
const pkg = await requirePackage(__dirname, (path) => import(path))
export default pkg.default || pkg

However, this still suffers from the promise return, and causes incompatibilities with anything but the default export:

// doesn't work via the autoloader
// import { nullish } from './index.mjs'
// nullish(null, 'nullish worked')

// autoloader requires
import pkg from './index.mjs'
pkg.nullish(null, 'nullish worked')

// direct consumption requires
import { nullish } from './edition-esnext-esm/index.js'
nullish(null, 'nullish worked')

As such, there will need to be a way to write static exports for everything, or boundation must only generate one esm edition, and not use an esm autoloader.

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

1 participant