UNPKG

8.31 kBMarkdownView Raw
1# node-module-import-map
2
3Generate importmap for node_modules.
4
5[![github package](https://img.shields.io/github/package-json/v/jsenv/jsenv-node-module-import-map.svg?logo=github&label=package)](https://github.com/jsenv/jsenv-node-module-import-map/packages)
6[![npm package](https://img.shields.io/npm/v/@jsenv/node-module-import-map.svg?logo=npm&label=package)](https://www.npmjs.com/package/@jsenv/node-module-import-map)
7[![github ci](https://github.com/jsenv/jsenv-node-module-import-map/workflows/ci/badge.svg)](https://github.com/jsenv/jsenv-node-module-import-map/actions?workflow=ci)
8[![codecov coverage](https://codecov.io/gh/jsenv/jsenv-node-module-import-map/branch/master/graph/badge.svg)](https://codecov.io/gh/jsenv/jsenv-node-module-import-map)
9
10# Table of contents
11
12- [Presentation](#Presentation)
13- [Installation](#installation)
14- [getImportMapFromNodeModules](#getImportMapFromNodeModules)
15 - [projectDirectoryUrl](#projectDirectoryUrl)
16 - [projectPackageDevDependenciesIncluded](#projectPackageDevDependenciesIncluded)
17 - [packagesExportsPreference](#packagesExportsPreference)
18- [Concrete example](#concrete-example)
19 - [Step 1 - Setup basic project](#step-1---setup-project)
20 - [Step 2 - Generate project importMap](#step-2---generate-project-importMap)
21- [Custom node module resolution](#custom-node-module-resolution)
22- [generateImportMapForProject](#generateImportMapForProject)
23 - [importMapFile](#importMapFile)
24 - [importMapFileRelativeUrl](#importMapFileRelativeUrl)
25 - [importMapFileLog](#importMapFileLog)
26- [getImportMapFromFile](#getImportMapFromFile)
27 - [importMapFileUrl](#importMapFileUrl)
28
29# Presentation
30
31`@jsenv/node-module-import-map` generates importMap for your project node_modules.<br />
32— see [importMap spec](https://github.com/WICG/import-maps)
33
34It reads `package.json` and recursively try to find your dependencies. Be sure node modules are on your filesystem because we'll use the filesystem structure to generate the importmap. For that reason, you must use it after `npm install` or anything that is responsible to generate the node_modules folder and its content on your filesystem.
35
36```js
37import { getImportMapFromNodeModules } from "@jsenv/node-module-import-map"
38
39getImportMapFromNodeModules({
40 projectDirectoryUrl: "file:///directory",
41})
42```
43
44`@jsenv/node-module-import-map` can also be required.
45
46```js
47const { getImportMapFromNodeModules } = require("@jsenv/node-module-import-map")
48```
49
50# Installation
51
52```console
53npm install @jsenv/node-module-import-map
54```
55
56# getImportMapFromNodeModules
57
58`getImportMapFromNodeModules` is an async function returning an importMap object computed from the content of node_modules directory.
59
60```js
61import { getImportMapFromNodeModules } from "@jsenv/node-module-import-map"
62
63const importMap = await getImportMapFromNodeModules({
64 projectDirectoryUrl: new URL("./", import.meta.url),
65 projectPackageDevDependenciesIncluded: true,
66})
67```
68
69— source code at [src/getImportMapFromNodeModules.js](./src/getImportMapFromNodeModules.js).
70
71## projectDirectoryUrl
72
73`projectDirectoryUrl` parameter is a string url leading to a folder with a `package.json`. This parameters is **required** and accepted values are documented in https://github.com/jsenv/jsenv-util#assertAndNormalizeDirectoryUrl
74
75## projectPackageDevDependenciesIncluded
76
77`projectPackageDevDependenciesIncluded` parameter is a boolean controling if devDependencies from your project `package.json` are included in the generated importMap. This parameter is optional and by default it's disabled when `process.env.NODE_ENV` is `"production"`.
78
79## packagesExportsPreference
80
81`packagesExportsPreference` parameter is an array of string representing what conditional export you prefer to pick from package.json. This parameter is optional with a default value of `["import", "node", "require"]`. It exists to support conditional exports from Node.js.
82
83— see [Conditional export documentation on Node.js](https://nodejs.org/dist/latest-v13.x/docs/api/esm.html#esm_conditional_exports)
84
85For instance if you want to favor `"browser"` conditional export use the following value.
86
87<!-- prettier-ignore -->
88```js
89["browser"]
90```
91
92Or if you prefer `"electron"` and fallback to `"browser"` use the following value.
93
94<!-- prettier-ignore -->
95```js
96["electron", "browser"]
97```
98
99When none of `packagesExportsPreference` is found in a `package.json` and if `"default"` is specified in that `package.json`, `"default"` value is read and appears in the importmap.
100
101# Concrete example
102
103This part explains how to setup a real environment to see `@jsenv/node-module-import-map` in action.
104It reuses a preconfigured project where you can generate import map file.
105
106## Step 1 - Setup basic project
107
108```console
109git clone https://github.com/jsenv/jsenv-node-module-import-map.git
110```
111
112```console
113cd ./jsenv-node-module-import-map/docs/basic-project
114```
115
116```console
117npm install
118```
119
120## Step 2 - Generate project importMap
121
122Running command below will log importMap generated for that basic project.
123
124> You need node 13+ to run this example
125
126```console
127node ./generate-import-map.js
128```
129
130# Custom node module resolution
131
132`@jsenv/node-module-import-map` uses a custom node module resolution.<br />
133— see [node module resolution on node.js](https://nodejs.org/api/modules.html#modules_all_together)
134
135It behaves as Node.js with one big change:
136
137> A node module will not be found if it is outside your project folder.
138
139We do this because importMap are used on the web where a file outside project folder would cannot be reached.
140
141In practice it does not impact you because node modules are inside your project folder. If not, write all your dependencies in your `package.json` and re-run `npm install`.
142
143# generateImportMapForProject
144
145`generateImportMapForProject` is an async function receiving an array of promise resolving to importmaps. It awaits for every importmap, compose them into one and write it into a file.
146
147> This function is meant to be responsible of generating the final importMap file that a project uses.
148
149For example code below will generate an import map from node_modules + a file + an inline importmap.
150
151```js
152import {
153 getImportMapFromNodeModules,
154 getImportMapFromFile,
155 generateImportMapForProject,
156} from "@jsenv/node-module-import-map"
157
158const projectDirectoryUrl = new URL("./", import.meta.url)
159const customImportMapFileUrl = new URL("./import-map-custom.importmap", projectDirectoryUrl)
160const importMapInputs = [
161 getImportMapFromNodeModules({
162 projectDirectoryUrl,
163 projectPackageDevDependenciesIncluded: true,
164 }),
165 getImportMapFromFile(customImportMapFileUrl),
166 {
167 imports: {
168 foo: "./bar.js",
169 },
170 },
171]
172
173await generateImportMapForProject(importMapInputs, {
174 projectDirectoryUrl,
175 importMapFileRelativeUrl: "./import-map.importmap",
176})
177```
178
179— source code at [src/generateImportMapForProject.js](./src/generateImportMapForProject.js).
180
181## importMapInputs
182
183`importMapInputs` is an array of importmap object or promise resolving to importmap objects. This parameter is optional and is an empty array by default.
184
185> When `importMapInputs` is empty a warning is emitted and `generateImportMapForProject` write an empty importmap file.
186
187## importMapFile
188
189`importMapFile` parameter is a boolean controling if importMap is written to a file. This parameters is optional and enabled by default.
190
191## importMapFileRelativeUrl
192
193`importMapFileRelativeUrl` parameter is a string controlling where importMap file is written. This parameter is optional and by default it's `"./import-map.importmap"`.
194
195## importMapFileLog
196
197`importMapFileLog` parameter a boolean controlling if there is log in the terminal when importMap file is written. This parameter is optional and by default it's enabled.
198
199# getImportMapFromFile
200
201`getImportMapFromFile` is an async function reading importmap from a file.
202
203```js
204import { getImportMapFromFile } from "@jsenv/node-module-import-map"
205
206const importMapFileUrl = new URL("./import-map.importmap", import.meta.url)
207const importMap = await getImportMapFromFile(importMapFileUrl)
208```
209
210— source code at [src/getImportMapFromFile.js](../src/getImportMapFromFile.js).
211
212## importMapFileUrl
213
214`importMapFileUrl` parameter a string or an url leading to the importmap file. This parameter is **required**.