decisions/0001-use-npm-to-manage-npm-dependencies-for-deno-projects.md
npm to manage NPM dependencies for Deno projectsDate: 2022-05-10
Status: accepted
Deno has three ways to manage dependencies:
import {...} from "https://deno.land/x/blah"Additionally, NPM packages can be accessed as Deno modules via Deno-friendly CDNs like https://esm.sh.
Remix has some requirements around dependencies:
NODE_ENV environment variable.react and react-dom).To optimize bundle size, Remix treeshakes your app's code and dependencies. This also helps to separate browser code and server code.
Under the hood, the Remix compiler uses esbuild.
Like other bundlers, esbuild uses sideEffects in package.json to determine when it is safe to eliminate unused imports.
Unfortunately, URL imports do not have a standard mechanism for marking packages as side-effect free.
Deno-friendly CDNs set the environment via a query parameter (e.g. ?dev), not via an environment variable.
That means changing environment requires changing the URL import in the source code.
While you could use multiple import maps (dev.json, prod.json, etc...) to workaround this, import maps have other limitations:
Even if import maps were perfected, CDNs compile each dependency in isolation. That means that specifying peer dependencies becomes tedious and error-prone as the user needs to:
react (or other similar peer dependency), even if indirectly.react version works across all of these dependenciesreact as a query parameter in all of the URLs for the identified dependenciesIf any dependencies change (added, removed, version change), the user must repeat all of these steps again.
npm to manage NPM dependencies for DenoDo not use Deno-friendly CDNs for NPM dependencies in Remix projects using Deno.
Use npm and node_modules/ to manage NPM dependencies like react for Remix projects, even when using Deno with Remix.
Deno module dependencies (e.g. from https://deno.land) can still be managed via URL imports.
Remix will preserve any URL imports in the built bundles as external dependencies, letting your browser runtime and server runtime handle them accordingly. That means that you may:
For example, Node will throw errors for URL imports, while Deno will resolve URL imports as normal.
Remix will not yet support import maps.
NODE_ENV environment variable at runtime.Users may configure an import map for the Deno extension for VS Code to enable type hints for NPM-managed dependencies within their Deno editor:
.vscode/resolve_npm_imports_in_deno.json
{
"// This import map is used solely for the denoland.vscode-deno extension.": "",
"// Remix does not support import maps.": "",
"// Dependency management is done through `npm` and `node_modules/` instead.": "",
"// Deno-only dependencies may be imported via URL imports (without using import maps).": "",
"imports": {
"react": "https://esm.sh/[email protected]",
"react-dom": "https://esm.sh/[email protected]",
"react-dom/server": "https://esm.sh/[email protected]/server"
}
}
.vscode/settings.json
{
"deno.enable": true,
"deno.importMap": "./.vscode/resolve_npm_imports_in_deno.json"
}