1 | # node-module-import-map
|
2 |
|
3 | Generate 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 |
|
34 | It 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
|
37 | import { getImportMapFromNodeModules } from "@jsenv/node-module-import-map"
|
38 |
|
39 | getImportMapFromNodeModules({
|
40 | projectDirectoryUrl: "file:///directory",
|
41 | })
|
42 | ```
|
43 |
|
44 | `@jsenv/node-module-import-map` can also be required.
|
45 |
|
46 | ```js
|
47 | const { getImportMapFromNodeModules } = require("@jsenv/node-module-import-map")
|
48 | ```
|
49 |
|
50 | # Installation
|
51 |
|
52 | ```console
|
53 | npm 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
|
61 | import { getImportMapFromNodeModules } from "@jsenv/node-module-import-map"
|
62 |
|
63 | const 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 |
|
85 | For instance if you want to favor `"browser"` conditional export use the following value.
|
86 |
|
87 |
|
88 | ```js
|
89 | ["browser"]
|
90 | ```
|
91 |
|
92 | Or if you prefer `"electron"` and fallback to `"browser"` use the following value.
|
93 |
|
94 |
|
95 | ```js
|
96 | ["electron", "browser"]
|
97 | ```
|
98 |
|
99 | When 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 |
|
103 | This part explains how to setup a real environment to see `@jsenv/node-module-import-map` in action.
|
104 | It reuses a preconfigured project where you can generate import map file.
|
105 |
|
106 | ## Step 1 - Setup basic project
|
107 |
|
108 | ```console
|
109 | git clone https://github.com/jsenv/jsenv-node-module-import-map.git
|
110 | ```
|
111 |
|
112 | ```console
|
113 | cd ./jsenv-node-module-import-map/docs/basic-project
|
114 | ```
|
115 |
|
116 | ```console
|
117 | npm install
|
118 | ```
|
119 |
|
120 | ## Step 2 - Generate project importMap
|
121 |
|
122 | Running command below will log importMap generated for that basic project.
|
123 |
|
124 | > You need node 13+ to run this example
|
125 |
|
126 | ```console
|
127 | node ./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 |
|
135 | It 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 |
|
139 | We do this because importMap are used on the web where a file outside project folder would cannot be reached.
|
140 |
|
141 | In 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 |
|
149 | For example code below will generate an import map from node_modules + a file + an inline importmap.
|
150 |
|
151 | ```js
|
152 | import {
|
153 | getImportMapFromNodeModules,
|
154 | getImportMapFromFile,
|
155 | generateImportMapForProject,
|
156 | } from "@jsenv/node-module-import-map"
|
157 |
|
158 | const projectDirectoryUrl = new URL("./", import.meta.url)
|
159 | const customImportMapFileUrl = new URL("./import-map-custom.importmap", projectDirectoryUrl)
|
160 | const importMapInputs = [
|
161 | getImportMapFromNodeModules({
|
162 | projectDirectoryUrl,
|
163 | projectPackageDevDependenciesIncluded: true,
|
164 | }),
|
165 | getImportMapFromFile(customImportMapFileUrl),
|
166 | {
|
167 | imports: {
|
168 | foo: "./bar.js",
|
169 | },
|
170 | },
|
171 | ]
|
172 |
|
173 | await 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
|
204 | import { getImportMapFromFile } from "@jsenv/node-module-import-map"
|
205 |
|
206 | const importMapFileUrl = new URL("./import-map.importmap", import.meta.url)
|
207 | const 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**.
|