Skip to content

Support NodeJS by adding exports key to package.json #17

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

Open
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

kylewlacy
Copy link

Currently, trying to import @mhsdesign/jit-browser/tailwindcss from a NodeJS project using ES Modules leads to a pretty cryptic error:

node:internal/modules/esm/resolve:213
  const resolvedOption = FSLegacyMainResolve(packageJsonUrlString, packageConfig.main, baseStringified);
                         ^

Error: Cannot find package '/some/project/node_modules/@mhsdesign/jit-browser-tailwindcss/package.json' imported from /some/project/index.mjs

I did some reading and found out this is because the package.json file doesn't list a NodeJS package entry point. Node either expects there to be a "main" field or "exports" field in package.json. Lots of packages have a "module" field, but Node doesn't use this (most bundlers support it though).

This PR adds the "exports" field to package.json, which is roughly equivalent to the "module" field, but is used by NodeJS.

@mhsdesign
Copy link
Owner

hi ;) Thanks for digging into it and providing a pr :D
I think to be totally on the safe side we should also export then into commonjs as esbuild target. As the current file you used may contain esm specifics (probably not right now because this thing worked?) but still ...

So duplicating

// MODULE
build({
entryPoints: {'module.esm': 'builds/module.ts'},
bundle: true,
external: [...Object.keys({ ...pkg.dependencies, ...pkg.peerDependencies }).filter(
// We only want to include tailwindcss as an external dependency for its types.
(name) => name !== 'tailwindcss',
), ...externalDependenciesHack],
logLevel: 'info',
outdir: 'dist',
sourcemap: true,
format: 'esm',
...sharedConfig
});

and changing the target / creating a new output file in cjs should do https://esbuild.github.io/api/#format-commonjs?

Also as written here https://esbuild.github.io/api/#main-fields
we should probably use main for cjs and keep the module for esm?

@kylewlacy
Copy link
Author

At least for my use case, I'm trying to specifically use ES Modules with NodeJS, but I can update this PR to support CommonJS as well if you think that's beneficial. I found this SO answer that explains it pretty well: https://stackoverflow.com/a/75348391

I'll spend some time updating this PR when I have a chance.

@kylewlacy
Copy link
Author

@mhsdesign Alright, done! I tweaked the esbuild script so it now builds a CommonJS file as well, then I tried testing it out briefly and it seemed like it worked. I also tweaked the ES Module export, since I realized TypeScript wasn't finding the module declaration unless some extra stuff was added to the exports key

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

Successfully merging this pull request may close these issues.

2 participants