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

docs/issue 144 best practices and recommendations for import maps and referencing node modules #153

Next Next commit
update docs around import map implementation details and compatiblity…
… observations
thescientist13 committed Jan 27, 2025
commit b3882c3c6e8cb9ea0b68b3c3f4f8c9f6a97532e7
19 changes: 18 additions & 1 deletion src/pages/docs/introduction/web-standards.md
Original file line number Diff line number Diff line change
@@ -104,7 +104,7 @@ export async function handler(request) {

## Import Maps

During local development, Greenwood loads all assets from your browser unbundled, serving the content right off disk. [**Import maps**](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script/type/importmap) allow bare specifiers typically found when referencing packages from npm, to work natively in the browser. When installing a package as a **dependency** in your _package.json_, Greenwood will walk your dependencies and all their dependencies, to build up a map to be injected into the `<head>` of your HTML.
During local development, Greenwood loads all assets from your browser unbundled, serving the content right off disk. [**Import Maps**](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script/type/importmap) allow bare specifiers typically found when referencing packages from npm, to work natively in the browser. When installing a package as a **dependency** in your _package.json_, Greenwood will walk your dependencies and all their dependencies, to build up a map to be injected into the `<head>` of your HTML.

This is a sample of an import map that would be generated after having installed the **lit** package:

@@ -128,6 +128,23 @@ This is a sample of an import map that would be generated after having installed
</html>
```

To generate this map, Greenwood first checks for package's [**exports**](https://nodejs.org/api/packages.html#package-entry-points) field, then looks for a **module** field, and finally a **main** field. For **exports**, Greenwood resolves the following [conditions](https://nodejs.org/api/packages.html#conditional-exports) in this priority order:

1. **import**
1. **module-sync**
1. **default**

### Compatibility

It should be noted that not all packages are created equal, and Greenwood depends on packages following the standard conventions of the NodeJS entry point specification when looking up their location using `import.meta.resolve`. This means there are packages that may not behave as expected, though Greenwood will do its best to make them work. In these exceptional cases, Greenwood will output some diagnostic information that can be used when reaching out for help. Ideally, package authors would accept patches to correct any such issues.

Some known issues / examples observed so far include:

- `ERR_MODULE_NOT_FOUND` - Observed with packages like [**@types/trusted-types**](https://github.com/DefinitelyTyped/DefinitelyTyped), which has an [empty string](https://unpkg.com/browse/@types/trusted-types@2.0.7/package.json) for the **main** field, and [**font-awesome**](https://fontawesome.com/), which has [no entry point](https://unpkg.com/browse/font-awesome@4.7.0/package.json) at all, at least as of `v4.x`.
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

found another example with type-fest

- `ERR_PACKAGE_PATH_NOT_EXPORTED` - Encountered with the [**geist-font** package](https://vercel.com/font), which has [no default export](https://github.com/vercel/geist-font/issues/150) in its exports map
Copy link
Member Author

@thescientist13 thescientist13 Jan 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


In these cases where Greenwood cannot resolve these dependencies, it will fallback to assuming packages are located in a _node_modules_ folder at the root of your project. Depending on your package manager, you may need to ["hoist"](https://pnpm.io/npmrc#dependency-hoisting-settings) these dependencies, as might be the case when using PNPM.

## URL

The [`URL`](https://developer.mozilla.org/en-US/docs/Web/API/URL) constructor provides an elegant way for referencing [static assets](/docs/resources/assets/) on the client and on the server, and it works great when combined with [`URLSearchParams`](https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams) for easily interacting with search params in a request.