vite-import-maps 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +45 -0
- package/LICENSE +21 -0
- package/README.md +343 -0
- package/dist/index.d.mts +125 -0
- package/dist/index.mjs +364 -0
- package/package.json +61 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# vite-plugin-native-import-maps
|
|
2
|
+
|
|
3
|
+
## 0.1.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 2490e79: Improve importMapHtmlTransformer signature
|
|
8
|
+
|
|
9
|
+
## 0.1.1
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- 9bd2ce2: Fix missing types in published package
|
|
14
|
+
|
|
15
|
+
## 0.1.0
|
|
16
|
+
|
|
17
|
+
### Minor Changes
|
|
18
|
+
|
|
19
|
+
- d8d4a14: Add support for vite7. SSR improvements
|
|
20
|
+
- 9f40567: Add support for import maps `integrity` field
|
|
21
|
+
|
|
22
|
+
## 0.0.4
|
|
23
|
+
|
|
24
|
+
### Patch Changes
|
|
25
|
+
|
|
26
|
+
- 4016f08: add support to output import maps as a file
|
|
27
|
+
- 91389f1: Add `virtual-modules` strategy in build mode. Add support to local entries as import maps
|
|
28
|
+
|
|
29
|
+
## 0.0.3
|
|
30
|
+
|
|
31
|
+
### Patch Changes
|
|
32
|
+
|
|
33
|
+
- add repository information to npm
|
|
34
|
+
|
|
35
|
+
## 0.0.2
|
|
36
|
+
|
|
37
|
+
### Patch Changes
|
|
38
|
+
|
|
39
|
+
- publish dist folder
|
|
40
|
+
|
|
41
|
+
## 0.0.1
|
|
42
|
+
|
|
43
|
+
### Patch Changes
|
|
44
|
+
|
|
45
|
+
- ac41be4: First release
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Riccardo Perra
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,343 @@
|
|
|
1
|
+
<h1 align="center">vite-import-maps</h1>
|
|
2
|
+
<br/>
|
|
3
|
+
<p align="center">
|
|
4
|
+
<a href="https://npmjs.com/package/vite-plugin-native-import-maps"><img src="https://img.shields.io/npm/v/vite-plugin-native-import-maps.svg" alt="npm package"></a>
|
|
5
|
+
<a href="https://github.com/riccardoperra/vite-plugin-import-maps/actions/workflows/ci.yml"><img src="https://github.com/riccardoperra/vite-plugin-import-maps/actions/workflows/release.yml/badge.svg?branch=main" alt="build status"></a>
|
|
6
|
+
</p>
|
|
7
|
+
|
|
8
|
+
A Vite plugin that generates and keeps **browser import maps** in sync with your Vite dev server and production build.
|
|
9
|
+
|
|
10
|
+
It's aimed at **micro-frontends**, **plugin systems**, and any setup where you load ESM modules at runtime and want to:
|
|
11
|
+
|
|
12
|
+
- Share dependencies (React, Solid, etc.) **without relying on CDNs**
|
|
13
|
+
- Avoid bundling multiple copies of the same library
|
|
14
|
+
- Expose npm packages or **your own local entry modules** through an import map
|
|
15
|
+
- Keep **remote modules truly "native"**: remotes can be plain ESM files **without requiring you** to setup build step or use other plugins.
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Table of Contents
|
|
20
|
+
|
|
21
|
+
- [Install](#install)
|
|
22
|
+
- [Setup](#setup)
|
|
23
|
+
- [Configuration](#configuration)
|
|
24
|
+
- [Do You Need This Plugin?](#do-you-need-this-plugin)
|
|
25
|
+
- [Recipes](#recipes)
|
|
26
|
+
- [Troubleshooting](#troubleshooting)
|
|
27
|
+
- [How It Works](#how-it-works)
|
|
28
|
+
- [Examples](#examples)
|
|
29
|
+
- [License](#license)
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## Install
|
|
34
|
+
|
|
35
|
+
```shell
|
|
36
|
+
# pnpm
|
|
37
|
+
pnpm i -D vite-import-maps
|
|
38
|
+
|
|
39
|
+
# npm
|
|
40
|
+
npm i -D vite-import-maps
|
|
41
|
+
|
|
42
|
+
# yarn
|
|
43
|
+
yarn add -D vite-import-maps
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Setup
|
|
47
|
+
|
|
48
|
+
```ts
|
|
49
|
+
import { defineConfig } from "vite";
|
|
50
|
+
import { vitePluginNativeImportMaps } from "vite-plugin-native-import-maps";
|
|
51
|
+
|
|
52
|
+
// Host app configuration
|
|
53
|
+
export default defineConfig({
|
|
54
|
+
plugins: [
|
|
55
|
+
vitePluginNativeImportMaps({
|
|
56
|
+
// Add SRI hashes to verify module integrity in build
|
|
57
|
+
integrity: 'sha-384',
|
|
58
|
+
log: true,
|
|
59
|
+
imports: [
|
|
60
|
+
// Wanna expose react with import maps?
|
|
61
|
+
"react",
|
|
62
|
+
"react-dom",
|
|
63
|
+
// Expose a custom/local entry under a public specifier
|
|
64
|
+
{ name: "react/jsx-runtime", entry: "./src/custom-jsx-runtime.ts" },
|
|
65
|
+
{ name: "my-app-shared-lib", entry: "./src/my-app-shared-oib.ts" },
|
|
66
|
+
],
|
|
67
|
+
}),
|
|
68
|
+
],
|
|
69
|
+
});
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## Configuration
|
|
75
|
+
|
|
76
|
+
### Options
|
|
77
|
+
|
|
78
|
+
- `imports` — List of modules to expose via the import map. Each entry can be a string (the specifier to expose, e.g.
|
|
79
|
+
`"react"`) or an object with `name` (the specifier), `entry` (the local path or package to resolve), and optionally
|
|
80
|
+
`integrity` (enable SRI hash).
|
|
81
|
+
|
|
82
|
+
- `modulesOutDir` — Directory prefix for emitted shared chunks in production. Defaults to `""` (root of output
|
|
83
|
+
directory).
|
|
84
|
+
|
|
85
|
+
- `integrity` —
|
|
86
|
+
Enable [Subresource Integrity](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/script/type/importmap#integrity_metadata_map)
|
|
87
|
+
for all shared dependencies. Set to `true`, `"sha256"`, `"sha384"`, or `"sha512"`. This adds an `integrity` map to the
|
|
88
|
+
import map so browsers can verify module contents. Can also be configured per-dependency via the object form in
|
|
89
|
+
`imports`.
|
|
90
|
+
|
|
91
|
+
- `log` — Enable debug logging. Defaults to `false`.
|
|
92
|
+
|
|
93
|
+
- `injectImportMapsToHtml` — Automatically inject a `<script type="importmap">` into the HTML `<head>`. Defaults to
|
|
94
|
+
`true`. Set to `false` for SSR apps and use the `virtual:importmap` module instead.
|
|
95
|
+
|
|
96
|
+
- `importMapHtmlTransformer` — A function to transform the resolved `imports` object before injecting into HTML. Useful
|
|
97
|
+
for adding a base path prefix, rewriting URLs to a CDN, or filtering entries.
|
|
98
|
+
|
|
99
|
+
- `outputAsFile` — Emit the import map as a standalone JSON file. Set to `true` for `/import-map.json`, or provide a
|
|
100
|
+
custom name (e.g. `"my-map"` → `/my-map.json`). The file is served by Vite in dev and emitted as an asset in build.
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
## Do You Need This Plugin?
|
|
105
|
+
|
|
106
|
+
If you're considering [import maps](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script/type/importmap),
|
|
107
|
+
you're likely building one of the following:
|
|
108
|
+
|
|
109
|
+
- **Micro-frontend architecture** — A host app loads remote modules at runtime, and all parts need to share the same dependency instances (React, Solid, etc.)
|
|
110
|
+
- **Plugin system** — Your app dynamically loads user-provided or third-party modules that rely on shared libraries
|
|
111
|
+
- **Self-hosted dependency sharing** — You want to share dependencies across apps without relying on external CDN services like esm.sh or jspm.io
|
|
112
|
+
|
|
113
|
+
### Why Not Third-Party Services?
|
|
114
|
+
|
|
115
|
+
Services like [esm.sh](https://esm.sh) or [jspm.io](https://jspm.io) are convenient, but they come with trade-offs:
|
|
116
|
+
|
|
117
|
+
- **External dependency** — Your app relies on a third-party service you don't control. If it goes down or changes, your app breaks.
|
|
118
|
+
- **Network restrictions** — Many corporate environments, VPNs, and air-gapped networks block connections to public services. Your app simply won't work.
|
|
119
|
+
- **Version alignment** — Ensuring host and remotes use the exact same dependency version from an external source can be error-prone.
|
|
120
|
+
- **Limited flexibility** — You can't easily expose modified builds, subsets of exports, or local wrapper modules.
|
|
121
|
+
|
|
122
|
+
With this plugin, **your host app becomes the source of truth**. Shared dependencies are built and served from your own infrastructure.
|
|
123
|
+
|
|
124
|
+
### Why This Plugin?
|
|
125
|
+
|
|
126
|
+
**Works in both development and production**
|
|
127
|
+
|
|
128
|
+
Most import map solutions only work at build time. This plugin keeps the import map in sync with Vite's dev server _and_ production builds. During development, it resolves to Vite's optimized deps; in production, it points to the correct hashed chunk filenames. No manual updates, no mismatches.
|
|
129
|
+
|
|
130
|
+
**No build step required for remotes**
|
|
131
|
+
|
|
132
|
+
Remote modules can be plain ESM files—no bundler, no plugins, no special conventions. They just `import "your-lib"` and the browser resolves it via the import map provided by the host.
|
|
133
|
+
|
|
134
|
+
**Single dependency instance**
|
|
135
|
+
|
|
136
|
+
Host and all remotes share the exact same module instances.
|
|
137
|
+
|
|
138
|
+
**Full control over what you share**
|
|
139
|
+
|
|
140
|
+
Expose npm packages as-is, or provide custom wrapper modules, modified builds, or local files. You decide exactly what each specifier resolves to.
|
|
141
|
+
|
|
142
|
+
> **Note:** If a remote _does_ use a bundler, shared dependencies must be marked as **external**.
|
|
143
|
+
> Otherwise the remote bundles its own copy and you lose the single-instance benefit.
|
|
144
|
+
|
|
145
|
+
Import maps are simple in concept, but keeping them in sync with your build is tedious:
|
|
146
|
+
|
|
147
|
+
- In dev, Vite serves optimized deps from `node_modules/.vite/deps` with cache-busting hashes
|
|
148
|
+
- In production, chunks have content hashes in their filenames
|
|
149
|
+
- Manually updating the import map every time something changes is error-prone
|
|
150
|
+
|
|
151
|
+
This plugin handles all of that. You declare what to share, and it generates the correct import map for both dev and build—automatically.
|
|
152
|
+
|
|
153
|
+
**Example output:**
|
|
154
|
+
|
|
155
|
+
```html
|
|
156
|
+
<script type="importmap">
|
|
157
|
+
{
|
|
158
|
+
"imports": {
|
|
159
|
+
"react": "/shared/react-DyndEn3u.js",
|
|
160
|
+
"react/jsx-runtime": "/shared/react_jsx-runtime-CAvv468t.js"
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
</script>
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
## Recipes
|
|
169
|
+
|
|
170
|
+
### Expose Local Entry Points (Custom ESM Wrappers)
|
|
171
|
+
|
|
172
|
+
Expose a local file that re-exports a dependency, giving you full control over what gets shared:
|
|
173
|
+
|
|
174
|
+
```ts
|
|
175
|
+
vitePluginNativeImportMaps({
|
|
176
|
+
imports: [
|
|
177
|
+
{ name: "react", entry: "./src/react-esm.ts" },
|
|
178
|
+
{ name: "react/jsx-runtime", entry: "./src/react-jsx-runtime.ts" },
|
|
179
|
+
"react-dom",
|
|
180
|
+
],
|
|
181
|
+
modulesOutDir: "shared",
|
|
182
|
+
});
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
---
|
|
186
|
+
|
|
187
|
+
### Enable Integrity Checks
|
|
188
|
+
|
|
189
|
+
Add SRI hashes to verify module integrity:
|
|
190
|
+
|
|
191
|
+
```ts
|
|
192
|
+
vitePluginNativeImportMaps({
|
|
193
|
+
imports: ["react", "react-dom"],
|
|
194
|
+
integrity: "sha384", // applies to all
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
// Or per-dependency:
|
|
198
|
+
vitePluginNativeImportMaps({
|
|
199
|
+
imports: [
|
|
200
|
+
{ name: "react", entry: "react", integrity: "sha384" },
|
|
201
|
+
{ name: "react-dom", entry: "react-dom", integrity: false },
|
|
202
|
+
],
|
|
203
|
+
});
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
---
|
|
207
|
+
|
|
208
|
+
### Mark Shared Deps as `external` in Remote Builds
|
|
209
|
+
|
|
210
|
+
If a remote module uses a bundler, configure shared dependencies as `external` to prevent bundling them:
|
|
211
|
+
|
|
212
|
+
**tsdown example:**
|
|
213
|
+
|
|
214
|
+
```ts
|
|
215
|
+
import { defineConfig } from "tsdown";
|
|
216
|
+
|
|
217
|
+
export default defineConfig({
|
|
218
|
+
external: ["react", "react-dom", "react/jsx-runtime"],
|
|
219
|
+
});
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
**Vite (library mode) example:**
|
|
223
|
+
|
|
224
|
+
```ts
|
|
225
|
+
import { defineConfig } from "vite";
|
|
226
|
+
|
|
227
|
+
export default defineConfig({
|
|
228
|
+
build: {
|
|
229
|
+
lib: {
|
|
230
|
+
entry: "./src/index.ts",
|
|
231
|
+
formats: ["es"],
|
|
232
|
+
},
|
|
233
|
+
rollupOptions: {
|
|
234
|
+
external: ["react", "react-dom", "react/jsx-runtime"],
|
|
235
|
+
},
|
|
236
|
+
},
|
|
237
|
+
});
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
---
|
|
241
|
+
|
|
242
|
+
### Serve Import Map as JSON File
|
|
243
|
+
|
|
244
|
+
```ts
|
|
245
|
+
vitePluginNativeImportMaps({
|
|
246
|
+
imports: ["react"],
|
|
247
|
+
outputAsFile: true, // /import-map.json
|
|
248
|
+
});
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
---
|
|
252
|
+
|
|
253
|
+
## Troubleshooting
|
|
254
|
+
|
|
255
|
+
### SSR App Doesn't Show the Import Map
|
|
256
|
+
|
|
257
|
+
Set `injectImportMapsToHtml: false` and inject the import map yourself using `virtual:importmap`:
|
|
258
|
+
|
|
259
|
+
```ts
|
|
260
|
+
import importMap from "virtual:importmap";
|
|
261
|
+
// Inject into your SSR HTML template
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
---
|
|
265
|
+
|
|
266
|
+
### Specifier Resolves to the Wrong Module
|
|
267
|
+
|
|
268
|
+
Ensure the specifier matches exactly what your code imports:
|
|
269
|
+
|
|
270
|
+
- `react/jsx-runtime` ≠ `react`
|
|
271
|
+
- `solid-js/web` ≠ `solid-js`
|
|
272
|
+
|
|
273
|
+
---
|
|
274
|
+
|
|
275
|
+
### Import Maps Not Supported in Target Browser
|
|
276
|
+
|
|
277
|
+
Import maps require modern browsers. For broader support, use a polyfill
|
|
278
|
+
like [es-module-shims](https://github.com/guybedford/es-module-shims).
|
|
279
|
+
|
|
280
|
+
See the example: [`./examples/react-host-es-module-shims`](./examples/react-host-es-module-shims)
|
|
281
|
+
|
|
282
|
+
### Integrate with es-module-shims (dynamic import maps)
|
|
283
|
+
|
|
284
|
+
You can integrate this plugin with **es-module-shims** in two common ways depending on how you want import maps applied at runtime:
|
|
285
|
+
|
|
286
|
+
- **Apply import maps dynamically at runtime** — If you prefer the plugin to emit a JSON file (use `outputAsFile: true`) or to use the `virtual:importmap` module, you can fetch or import the map and pass it to the es-module-shims runtime via the global `importShim` API (it exposes helpers like `addImportMap` and `import`).
|
|
287
|
+
|
|
288
|
+
```ts
|
|
289
|
+
import "es-module-shims";
|
|
290
|
+
|
|
291
|
+
// When using outputAsFile: true (e.g. /import-map.json)
|
|
292
|
+
fetch("/import-map.json")
|
|
293
|
+
.then((r) => r.json())
|
|
294
|
+
.then((map) => importShim.addImportMap(map))
|
|
295
|
+
.then(() => importShim.import("/your/entry.js"));
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
Example (virtual module):
|
|
299
|
+
|
|
300
|
+
```js
|
|
301
|
+
import "es-module-shims";
|
|
302
|
+
import importMap from "virtual:importmap";
|
|
303
|
+
|
|
304
|
+
importShim.addImportMap(importMap).then(() => {
|
|
305
|
+
// now safe to dynamically import shimmed modules
|
|
306
|
+
});
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
---
|
|
310
|
+
|
|
311
|
+
## How It Works
|
|
312
|
+
|
|
313
|
+
1. **Collects** the `shared` entries from your config
|
|
314
|
+
2. **In dev:** Resolves corresponding Vite dev-server URLs
|
|
315
|
+
3. **In build:** Adds extra Rollup inputs so shared deps get dedicated output chunks, then records the final chunk URLs
|
|
316
|
+
4. **Exposes** the mapping via:
|
|
317
|
+
- HTML injection (optional)
|
|
318
|
+
- `virtual:importmap` module (always)
|
|
319
|
+
- JSON file (optional)
|
|
320
|
+
|
|
321
|
+
**Build snapshot:**
|
|
322
|
+
|
|
323
|
+
- [`./test/fixture/basic`](./test/fixture/basic)
|
|
324
|
+
- [`./test/__snapshot__/build-project-with-right-import-maps`](./test/__snapshot__/build-project-with-right-import-maps)
|
|
325
|
+
|
|
326
|
+
---
|
|
327
|
+
|
|
328
|
+
## Examples
|
|
329
|
+
|
|
330
|
+
| Example | Description |
|
|
331
|
+
| --------------------------------------------------------------------- | ---------------------------------------- |
|
|
332
|
+
| [`solidjs-host`](./examples/solidjs-host) | Solid.js host app |
|
|
333
|
+
| [`solidjs-remote-counter`](./examples/solidjs-remote-counter) | Solid.js remote module |
|
|
334
|
+
| [`react-host-custom`](./examples/react-host-custom) | React host with custom ESM wrappers |
|
|
335
|
+
| [`react-host-es-module-shims`](./examples/react-host-es-module-shims) | React host with es-module-shims polyfill |
|
|
336
|
+
| [`react-remote-counter`](./examples/react-remote-counter) | React remote module |
|
|
337
|
+
| [`react-tanstack-start-ssr`](./examples/react-tanstack-start-ssr) | SSR example with TanStack Start |
|
|
338
|
+
|
|
339
|
+
---
|
|
340
|
+
|
|
341
|
+
## License
|
|
342
|
+
|
|
343
|
+
MIT. See [LICENSE](./LICENSE).
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { Plugin } from "vite";
|
|
2
|
+
|
|
3
|
+
//#region src/store.d.ts
|
|
4
|
+
interface RegisteredDependency {
|
|
5
|
+
packageName: string;
|
|
6
|
+
url: string;
|
|
7
|
+
integrity?: string;
|
|
8
|
+
}
|
|
9
|
+
interface NormalizedDependencyInput {
|
|
10
|
+
name: string;
|
|
11
|
+
entry: string;
|
|
12
|
+
localFile: boolean;
|
|
13
|
+
integrity: DependencyIntegrityCheck | boolean;
|
|
14
|
+
}
|
|
15
|
+
declare class VitePluginImportMapsStore {
|
|
16
|
+
readonly defaultIntegrity: boolean | DependencyIntegrityCheck;
|
|
17
|
+
readonly sharedDependencies: ReadonlyArray<NormalizedDependencyInput>;
|
|
18
|
+
readonly modulesOutDir: string;
|
|
19
|
+
readonly log: boolean;
|
|
20
|
+
readonly importMapHtmlTransformer: ImportMapTransformerFn;
|
|
21
|
+
readonly importMapDependencies: Map<string, RegisteredDependency>;
|
|
22
|
+
readonly inputs: Array<ImportMapBuildChunkEntrypoint>;
|
|
23
|
+
constructor(options: VitePluginImportMapsConfig);
|
|
24
|
+
private normalizeDependencyInput;
|
|
25
|
+
clearDependencies(): void;
|
|
26
|
+
addDependency(dependency: RegisteredDependency): void;
|
|
27
|
+
getNormalizedDependencyName(dependency: string): string;
|
|
28
|
+
getEntrypointPath(entrypoint: string): string;
|
|
29
|
+
addInput(input: NormalizedDependencyInput): ImportMapBuildChunkEntrypoint;
|
|
30
|
+
getImportMapAsJson(): Record<string, any>;
|
|
31
|
+
}
|
|
32
|
+
interface ImportMapBuildChunkEntrypoint {
|
|
33
|
+
originalDependencyName: string;
|
|
34
|
+
normalizedDependencyName: string;
|
|
35
|
+
entrypoint: string;
|
|
36
|
+
idToResolve: string;
|
|
37
|
+
localFile: boolean;
|
|
38
|
+
integrity: DependencyIntegrityCheck | boolean;
|
|
39
|
+
}
|
|
40
|
+
//#endregion
|
|
41
|
+
//#region src/config.d.ts
|
|
42
|
+
interface ImportMapSignature {
|
|
43
|
+
/**
|
|
44
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/script/type/importmap#imports
|
|
45
|
+
*/
|
|
46
|
+
imports?: Record<string, any>;
|
|
47
|
+
/**
|
|
48
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/script/type/importmap#integrity
|
|
49
|
+
*/
|
|
50
|
+
integrity?: Record<string, string>;
|
|
51
|
+
/**
|
|
52
|
+
* @see @see https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/script/type/importmap#scopes
|
|
53
|
+
*/
|
|
54
|
+
scopes?: Record<string, any>;
|
|
55
|
+
}
|
|
56
|
+
type ImportMapTransformerFn = (importMap: ImportMapSignature, meta: {
|
|
57
|
+
entries: Map<string, RegisteredDependency>;
|
|
58
|
+
store: VitePluginImportMapsStore;
|
|
59
|
+
}) => ImportMapSignature;
|
|
60
|
+
type DependencyIntegrityCheck = "sha256" | "sha384" | "sha512";
|
|
61
|
+
interface SharedDependencyObjectConfig {
|
|
62
|
+
/**
|
|
63
|
+
* The name of the dependency that will be resolved
|
|
64
|
+
*/
|
|
65
|
+
name: string;
|
|
66
|
+
/**
|
|
67
|
+
* Local path to the entry file, or the dependency name (e.g., react)
|
|
68
|
+
*/
|
|
69
|
+
entry: string;
|
|
70
|
+
/**
|
|
71
|
+
* Enable integrity check for the dependency (only in build)
|
|
72
|
+
*
|
|
73
|
+
* https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/script/type/importmap#integrity_metadata_map
|
|
74
|
+
*/
|
|
75
|
+
integrity?: boolean | DependencyIntegrityCheck;
|
|
76
|
+
}
|
|
77
|
+
type SharedDependencyConfig = Array<string | SharedDependencyObjectConfig>;
|
|
78
|
+
interface VitePluginImportMapsConfig {
|
|
79
|
+
/**
|
|
80
|
+
* Dependencies shared by modules
|
|
81
|
+
*/
|
|
82
|
+
imports: SharedDependencyConfig;
|
|
83
|
+
/**
|
|
84
|
+
* Directory where the shared chunks are stored
|
|
85
|
+
*
|
|
86
|
+
* @default ""
|
|
87
|
+
*/
|
|
88
|
+
modulesOutDir?: string;
|
|
89
|
+
/**
|
|
90
|
+
* Default `integrity` value for entries.
|
|
91
|
+
* Can be customized per dependency through {@link SharedDependencyObjectConfig#integrity}
|
|
92
|
+
*
|
|
93
|
+
* https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/script/type/importmap#integrity_metadata_map
|
|
94
|
+
*/
|
|
95
|
+
integrity?: boolean | DependencyIntegrityCheck;
|
|
96
|
+
/**
|
|
97
|
+
* Enable logging
|
|
98
|
+
*/
|
|
99
|
+
log?: boolean;
|
|
100
|
+
/**
|
|
101
|
+
* Whether to inject the import map in to the main HTML file. Defaults to true.
|
|
102
|
+
*
|
|
103
|
+
* NOTE: You probably have to set `false` in apps with SSR enabled,
|
|
104
|
+
* and use the `virtual:importmap` dynamic import instead.
|
|
105
|
+
*/
|
|
106
|
+
injectImportMapsToHtml?: boolean;
|
|
107
|
+
/**
|
|
108
|
+
* Transform the resolved import map `imports` before writing it to the HTML file
|
|
109
|
+
*/
|
|
110
|
+
importMapHtmlTransformer?: ImportMapTransformerFn;
|
|
111
|
+
/**
|
|
112
|
+
* Whether to generate an import file.
|
|
113
|
+
*
|
|
114
|
+
* If a string is provided, it will be used as the output file name. Default as 'import-map.json'.
|
|
115
|
+
*
|
|
116
|
+
* Output file will be generated in the root directory of your generated bundle and will be
|
|
117
|
+
* available also in development mode via the Vite Dev Server.
|
|
118
|
+
*/
|
|
119
|
+
outputAsFile?: boolean | string;
|
|
120
|
+
}
|
|
121
|
+
//#endregion
|
|
122
|
+
//#region src/index.d.ts
|
|
123
|
+
declare function vitePluginNativeImportMaps(options: VitePluginImportMapsConfig): Array<Plugin>;
|
|
124
|
+
//#endregion
|
|
125
|
+
export { vitePluginNativeImportMaps };
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,364 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { normalizePath } from "vite";
|
|
3
|
+
import { createHash } from "node:crypto";
|
|
4
|
+
|
|
5
|
+
//#region src/utils.ts
|
|
6
|
+
/**
|
|
7
|
+
* Normalize a dependency name to be used as an entrypoint input
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```
|
|
11
|
+
* @scope/package-name -> @scope_package-name
|
|
12
|
+
* package-name/sub-entrypoint -> package-name_sub-entrypoint
|
|
13
|
+
* ```
|
|
14
|
+
*/
|
|
15
|
+
function normalizeDependencyName(dep) {
|
|
16
|
+
return dep.replace(/\//g, "_");
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Prefix for resolved fs paths, since windows paths may not be valid as URLs.
|
|
20
|
+
*
|
|
21
|
+
* @see https://github.com/vitejs/vite/blob/fd38d076fe2455aac1e00a7b15cd51159bf12bb5/packages/vite/src/node/constants.ts#L108
|
|
22
|
+
*/
|
|
23
|
+
const FS_PREFIX = `/@fs/`;
|
|
24
|
+
function fileToUrl(file, root) {
|
|
25
|
+
const url = path.relative(root, file);
|
|
26
|
+
if (url[0] === ".") return path.posix.join(FS_PREFIX, normalizePath(file));
|
|
27
|
+
return "/" + normalizePath(url);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
//#endregion
|
|
31
|
+
//#region src/store.ts
|
|
32
|
+
var VitePluginImportMapsStore = class {
|
|
33
|
+
defaultIntegrity;
|
|
34
|
+
sharedDependencies = [];
|
|
35
|
+
modulesOutDir = "";
|
|
36
|
+
log;
|
|
37
|
+
importMapHtmlTransformer = (importMap) => importMap;
|
|
38
|
+
importMapDependencies = /* @__PURE__ */ new Map();
|
|
39
|
+
inputs = [];
|
|
40
|
+
constructor(options) {
|
|
41
|
+
this.defaultIntegrity = options.integrity || false;
|
|
42
|
+
this.sharedDependencies = [...options.imports.map(this.normalizeDependencyInput)];
|
|
43
|
+
this.log = options.log || false;
|
|
44
|
+
if (options.modulesOutDir) this.modulesOutDir = options.modulesOutDir;
|
|
45
|
+
if (options.importMapHtmlTransformer) this.importMapHtmlTransformer = options.importMapHtmlTransformer;
|
|
46
|
+
}
|
|
47
|
+
normalizeDependencyInput = (entry) => {
|
|
48
|
+
if (typeof entry === "string") return {
|
|
49
|
+
name: entry,
|
|
50
|
+
entry,
|
|
51
|
+
localFile: false,
|
|
52
|
+
integrity: this.defaultIntegrity
|
|
53
|
+
};
|
|
54
|
+
return {
|
|
55
|
+
name: entry.name,
|
|
56
|
+
entry: entry.entry,
|
|
57
|
+
localFile: entry.entry.startsWith("./") || entry.entry.startsWith("../"),
|
|
58
|
+
integrity: entry.integrity ?? this.defaultIntegrity
|
|
59
|
+
};
|
|
60
|
+
};
|
|
61
|
+
clearDependencies() {
|
|
62
|
+
this.importMapDependencies.clear();
|
|
63
|
+
}
|
|
64
|
+
addDependency(dependency) {
|
|
65
|
+
this.importMapDependencies.set(dependency.packageName, dependency);
|
|
66
|
+
}
|
|
67
|
+
getNormalizedDependencyName(dependency) {
|
|
68
|
+
return normalizeDependencyName(dependency);
|
|
69
|
+
}
|
|
70
|
+
getEntrypointPath(entrypoint) {
|
|
71
|
+
return path.join(this.modulesOutDir, entrypoint);
|
|
72
|
+
}
|
|
73
|
+
addInput(input) {
|
|
74
|
+
const dependency = input.name;
|
|
75
|
+
const normalizedDepName = this.getNormalizedDependencyName(dependency);
|
|
76
|
+
const meta = {
|
|
77
|
+
originalDependencyName: dependency,
|
|
78
|
+
entrypoint: this.getEntrypointPath(normalizedDepName),
|
|
79
|
+
normalizedDependencyName: normalizedDepName,
|
|
80
|
+
idToResolve: input.entry,
|
|
81
|
+
localFile: input.localFile,
|
|
82
|
+
integrity: input.integrity
|
|
83
|
+
};
|
|
84
|
+
this.inputs.push(meta);
|
|
85
|
+
return meta;
|
|
86
|
+
}
|
|
87
|
+
getImportMapAsJson() {
|
|
88
|
+
const imports = {};
|
|
89
|
+
const integrity = {};
|
|
90
|
+
this.importMapDependencies.forEach((dep) => {
|
|
91
|
+
imports[dep.packageName] = dep.url;
|
|
92
|
+
if (dep.integrity) integrity[dep.url] = dep.integrity;
|
|
93
|
+
});
|
|
94
|
+
const importMap = { imports };
|
|
95
|
+
if (Object.keys(integrity).length > 0) importMap.integrity = integrity;
|
|
96
|
+
return this.importMapHtmlTransformer(importMap, {
|
|
97
|
+
store: this,
|
|
98
|
+
entries: this.importMapDependencies
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
//#endregion
|
|
104
|
+
//#region src/config.ts
|
|
105
|
+
const PLUGIN_NAME = "vite-plugin-import-maps";
|
|
106
|
+
function pluginName(name) {
|
|
107
|
+
return `${PLUGIN_NAME}:${name}`;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
//#endregion
|
|
111
|
+
//#region src/build-only/virtual-chunk-resolver.ts
|
|
112
|
+
const VIRTUAL_ID_PREFIX = `\0virtual:import-map-chunk`;
|
|
113
|
+
function getVirtualFileName(name) {
|
|
114
|
+
return `${VIRTUAL_ID_PREFIX}/${name}`;
|
|
115
|
+
}
|
|
116
|
+
function virtualChunksResolverPlugin(store) {
|
|
117
|
+
return {
|
|
118
|
+
name: pluginName("build:virtual-chunks-loader"),
|
|
119
|
+
apply: "build",
|
|
120
|
+
resolveId(id) {
|
|
121
|
+
if (this.environment.name === "ssr") return;
|
|
122
|
+
if (id.startsWith(VIRTUAL_ID_PREFIX)) {
|
|
123
|
+
const normalizedId = id.slice(VIRTUAL_ID_PREFIX.length + 1);
|
|
124
|
+
return {
|
|
125
|
+
id,
|
|
126
|
+
meta: { info: store.inputs.find((input) => input.normalizedDependencyName === normalizedId) }
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
},
|
|
130
|
+
async load(id) {
|
|
131
|
+
if (this.environment.name === "ssr") return;
|
|
132
|
+
if (!id.startsWith(VIRTUAL_ID_PREFIX)) return;
|
|
133
|
+
const virtualModuleInfo = this.getModuleInfo(id);
|
|
134
|
+
if (!virtualModuleInfo) return;
|
|
135
|
+
const chunk = virtualModuleInfo.meta["info"];
|
|
136
|
+
const resolvedId = await this.resolve(chunk.idToResolve);
|
|
137
|
+
if (!resolvedId) return;
|
|
138
|
+
let hasDefaultExport = false;
|
|
139
|
+
const [fileName] = resolvedId.id.split("?");
|
|
140
|
+
const moduleInfo = this.getModuleInfo(fileName);
|
|
141
|
+
if (moduleInfo) {
|
|
142
|
+
hasDefaultExport = moduleInfo.hasDefaultExport ?? false;
|
|
143
|
+
if (!hasDefaultExport) {
|
|
144
|
+
if ("commonjs" in moduleInfo.meta && moduleInfo.meta.commonjs.isCommonJS) {
|
|
145
|
+
const requires = moduleInfo.meta.commonjs.requires;
|
|
146
|
+
if (Array.isArray(requires)) {
|
|
147
|
+
for (const require of requires) if (require.resolved) {
|
|
148
|
+
const innerResolvedId = this.getModuleInfo(require.resolved.id);
|
|
149
|
+
if (!innerResolvedId) break;
|
|
150
|
+
hasDefaultExport = innerResolvedId.hasDefaultExport || false;
|
|
151
|
+
if (hasDefaultExport) break;
|
|
152
|
+
if (innerResolvedId.exports?.includes("__require")) {
|
|
153
|
+
hasDefaultExport = true;
|
|
154
|
+
break;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
let code = `export * from "${chunk.originalDependencyName}"`;
|
|
162
|
+
if (hasDefaultExport) code += `\nexport { default } from '${chunk.originalDependencyName}'`;
|
|
163
|
+
return {
|
|
164
|
+
moduleSideEffects: "no-treeshake",
|
|
165
|
+
code
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
//#endregion
|
|
172
|
+
//#region src/build-only/virtual-chunk-generator.ts
|
|
173
|
+
function virtualChunksGeneratorPlugin(store) {
|
|
174
|
+
const name = pluginName("build:virtual");
|
|
175
|
+
const virtualModules = /* @__PURE__ */ new Map();
|
|
176
|
+
const localModules = /* @__PURE__ */ new Map();
|
|
177
|
+
let config;
|
|
178
|
+
return {
|
|
179
|
+
name,
|
|
180
|
+
apply: "build",
|
|
181
|
+
configResolved(resolvedConfig) {
|
|
182
|
+
config = resolvedConfig;
|
|
183
|
+
},
|
|
184
|
+
buildStart() {
|
|
185
|
+
for (const input of store.inputs) if (input.localFile) {
|
|
186
|
+
const id = path.resolve(input.idToResolve);
|
|
187
|
+
if (!localModules.has(id)) this.emitFile({
|
|
188
|
+
type: "chunk",
|
|
189
|
+
name: input.entrypoint,
|
|
190
|
+
id,
|
|
191
|
+
preserveSignature: "strict"
|
|
192
|
+
});
|
|
193
|
+
localModules.set(id, input);
|
|
194
|
+
} else {
|
|
195
|
+
const id = getVirtualFileName(input.normalizedDependencyName);
|
|
196
|
+
if (!virtualModules.has(id)) this.emitFile({
|
|
197
|
+
type: "chunk",
|
|
198
|
+
name: input.entrypoint,
|
|
199
|
+
id,
|
|
200
|
+
preserveSignature: "strict"
|
|
201
|
+
});
|
|
202
|
+
virtualModules.set(id, input);
|
|
203
|
+
}
|
|
204
|
+
},
|
|
205
|
+
generateBundle(_, bundle) {
|
|
206
|
+
store.clearDependencies();
|
|
207
|
+
const keys = Object.keys(bundle);
|
|
208
|
+
for (const key of keys) {
|
|
209
|
+
const entry = bundle[key];
|
|
210
|
+
if (entry.type !== "chunk") continue;
|
|
211
|
+
const handledModules = new Map([...virtualModules.entries(), ...localModules.entries()]);
|
|
212
|
+
if (entry.facadeModuleId && (entry.facadeModuleId.startsWith(VIRTUAL_ID_PREFIX) || path.isAbsolute(entry.facadeModuleId))) {
|
|
213
|
+
const entryImportMap = handledModules.get(entry.facadeModuleId);
|
|
214
|
+
if (!entryImportMap) continue;
|
|
215
|
+
entry.isEntry = false;
|
|
216
|
+
let integrity;
|
|
217
|
+
if (entryImportMap.integrity !== false) {
|
|
218
|
+
const algorithm = typeof entryImportMap.integrity === "string" ? entryImportMap.integrity : "sha384";
|
|
219
|
+
integrity = `${algorithm}-${createHash(algorithm).update(entry.code).digest("base64")}`;
|
|
220
|
+
}
|
|
221
|
+
const url = `./${entry.fileName}`, packageName = entryImportMap.originalDependencyName;
|
|
222
|
+
store.addDependency({
|
|
223
|
+
url,
|
|
224
|
+
packageName,
|
|
225
|
+
integrity
|
|
226
|
+
});
|
|
227
|
+
store.log && config.logger.info(`[${name}] Added ${packageName}: ${url}`, { timestamp: true });
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
//#endregion
|
|
235
|
+
//#region src/build-only/build-plugin.ts
|
|
236
|
+
function pluginImportMapsBuildEnv(store) {
|
|
237
|
+
const plugins = [];
|
|
238
|
+
for (const dep of store.sharedDependencies) store.addInput(dep);
|
|
239
|
+
plugins.push(virtualChunksGeneratorPlugin(store));
|
|
240
|
+
plugins.push(virtualChunksResolverPlugin(store));
|
|
241
|
+
return plugins;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
//#endregion
|
|
245
|
+
//#region src/import-map-html.ts
|
|
246
|
+
function pluginImportMapsInject(store) {
|
|
247
|
+
return {
|
|
248
|
+
name: pluginName("inject-html-import-map"),
|
|
249
|
+
transformIndexHtml(source) {
|
|
250
|
+
const importMap = store.getImportMapAsJson();
|
|
251
|
+
return {
|
|
252
|
+
html: source,
|
|
253
|
+
tags: [{
|
|
254
|
+
tag: "script",
|
|
255
|
+
attrs: { type: "importmap" },
|
|
256
|
+
children: JSON.stringify(importMap),
|
|
257
|
+
injectTo: "head-prepend"
|
|
258
|
+
}]
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
//#endregion
|
|
265
|
+
//#region src/dev/dev-plugin.ts
|
|
266
|
+
function pluginImportMapsDevelopmentEnv(store) {
|
|
267
|
+
const name = pluginName("development");
|
|
268
|
+
let latestBrowserHash = void 0;
|
|
269
|
+
let cachedResolvedModules = [];
|
|
270
|
+
return {
|
|
271
|
+
name,
|
|
272
|
+
apply: "serve",
|
|
273
|
+
async transformIndexHtml(_, { server }) {
|
|
274
|
+
if (!server) return;
|
|
275
|
+
const { pluginContainer, config } = server, devOptimizer = server.environments["client"].depsOptimizer;
|
|
276
|
+
let resolvedModules;
|
|
277
|
+
if (devOptimizer.metadata.browserHash === latestBrowserHash) resolvedModules = cachedResolvedModules;
|
|
278
|
+
else resolvedModules = (await Promise.all(store.sharedDependencies.map(async (dependency) => {
|
|
279
|
+
const resolvedId = await pluginContainer.resolveId(dependency.entry);
|
|
280
|
+
if (!resolvedId) return null;
|
|
281
|
+
const path = fileToUrl(resolvedId.id, config.root);
|
|
282
|
+
store.log && server.config.logger.info(`[${name}] Added ${dependency.entry}: ${path}`, { timestamp: true });
|
|
283
|
+
return {
|
|
284
|
+
name: dependency.name,
|
|
285
|
+
path
|
|
286
|
+
};
|
|
287
|
+
}))).filter((value) => !!value);
|
|
288
|
+
cachedResolvedModules = resolvedModules;
|
|
289
|
+
latestBrowserHash = devOptimizer.metadata.browserHash;
|
|
290
|
+
for (const { path: url, name: packageName } of resolvedModules) store.addDependency({
|
|
291
|
+
packageName,
|
|
292
|
+
url
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
};
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
//#endregion
|
|
299
|
+
//#region src/import-map-file.ts
|
|
300
|
+
function pluginImportMapsAsFile(store, options) {
|
|
301
|
+
const { name = "import-map" } = options;
|
|
302
|
+
return {
|
|
303
|
+
name: pluginName("import-maps-as-file"),
|
|
304
|
+
configureServer(server) {
|
|
305
|
+
server.middlewares.use((req, res, next) => {
|
|
306
|
+
if (req.url === `/${name}.json`) {
|
|
307
|
+
res.setHeader("Content-Type", "application/json");
|
|
308
|
+
res.end(JSON.stringify(store.getImportMapAsJson()));
|
|
309
|
+
} else next();
|
|
310
|
+
});
|
|
311
|
+
},
|
|
312
|
+
generateBundle() {
|
|
313
|
+
const json = store.getImportMapAsJson();
|
|
314
|
+
this.emitFile({
|
|
315
|
+
type: "asset",
|
|
316
|
+
fileName: `/${name}.json`,
|
|
317
|
+
source: JSON.stringify(json, null, 2)
|
|
318
|
+
});
|
|
319
|
+
}
|
|
320
|
+
};
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
//#endregion
|
|
324
|
+
//#region src/import-map-module.ts
|
|
325
|
+
const virtualImportMapId = "virtual:importmap";
|
|
326
|
+
const resolvedVirtualImportMapId = "\0" + virtualImportMapId;
|
|
327
|
+
function pluginImportMapsAsModule(store) {
|
|
328
|
+
return {
|
|
329
|
+
name: pluginName("virtual-module-import-map"),
|
|
330
|
+
resolveId(id) {
|
|
331
|
+
if (id === virtualImportMapId) return resolvedVirtualImportMapId;
|
|
332
|
+
},
|
|
333
|
+
load(id) {
|
|
334
|
+
if (id === resolvedVirtualImportMapId) {
|
|
335
|
+
const content = JSON.stringify(store.getImportMapAsJson());
|
|
336
|
+
return `
|
|
337
|
+
export const importMapRaw = '${content}';
|
|
338
|
+
export const importMap = ${content};
|
|
339
|
+
export default importMap;
|
|
340
|
+
`;
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
};
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
//#endregion
|
|
347
|
+
//#region src/index.ts
|
|
348
|
+
function vitePluginNativeImportMaps(options) {
|
|
349
|
+
const { injectImportMapsToHtml = true, outputAsFile } = options;
|
|
350
|
+
const plugins = [];
|
|
351
|
+
const store = new VitePluginImportMapsStore(options);
|
|
352
|
+
plugins.push(...pluginImportMapsBuildEnv(store));
|
|
353
|
+
plugins.push(pluginImportMapsDevelopmentEnv(store));
|
|
354
|
+
if (injectImportMapsToHtml) plugins.push(pluginImportMapsInject(store));
|
|
355
|
+
plugins.push(pluginImportMapsAsModule(store));
|
|
356
|
+
if (outputAsFile) {
|
|
357
|
+
const name = typeof outputAsFile === "string" ? outputAsFile : void 0;
|
|
358
|
+
plugins.push(pluginImportMapsAsFile(store, { name }));
|
|
359
|
+
}
|
|
360
|
+
return plugins;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
//#endregion
|
|
364
|
+
export { vitePluginNativeImportMaps };
|
package/package.json
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "vite-import-maps",
|
|
3
|
+
"version": "0.1.2",
|
|
4
|
+
"description": "A Vite plugin that manages import maps for shared dependencies in your Vite applications.",
|
|
5
|
+
"main": "./dist/index.mjs",
|
|
6
|
+
"module ": "./dist/index.mjs",
|
|
7
|
+
"types": "./dist/index.d.mts",
|
|
8
|
+
"type": "module",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.mts",
|
|
12
|
+
"default": "./dist/index.mjs"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist",
|
|
17
|
+
"CHANGELOG.md",
|
|
18
|
+
"LICENSE"
|
|
19
|
+
],
|
|
20
|
+
"keywords": [
|
|
21
|
+
"vite",
|
|
22
|
+
"vite-plugin",
|
|
23
|
+
"import-maps",
|
|
24
|
+
"mfe",
|
|
25
|
+
"import maps",
|
|
26
|
+
"microfrontend",
|
|
27
|
+
"plugin"
|
|
28
|
+
],
|
|
29
|
+
"repository": "https://github.com/riccardoperra/vite-plugin-import-maps",
|
|
30
|
+
"homepage": "https://github.com/riccardoperra/vite-plugin-import-maps",
|
|
31
|
+
"author": {
|
|
32
|
+
"name": "Riccardo Perra",
|
|
33
|
+
"email": "riccardo.perra@icloud.com",
|
|
34
|
+
"url": "https://github.com/riccardoperra"
|
|
35
|
+
},
|
|
36
|
+
"license": "MIT",
|
|
37
|
+
"dependencies": {
|
|
38
|
+
"vite": "^7.3.1"
|
|
39
|
+
},
|
|
40
|
+
"devDependencies": {
|
|
41
|
+
"@changesets/cli": "^2.29.8",
|
|
42
|
+
"@tanstack/eslint-config": "^0.3.4",
|
|
43
|
+
"@types/node": "^25.2.0",
|
|
44
|
+
"eslint": "^9.39.2",
|
|
45
|
+
"prettier": "^3.8.1",
|
|
46
|
+
"rollup": "^4.57.1",
|
|
47
|
+
"tsdown": "^0.20.1",
|
|
48
|
+
"typescript": "^5.9.3",
|
|
49
|
+
"vitest": "^4.0.18"
|
|
50
|
+
},
|
|
51
|
+
"peerDependencies": {
|
|
52
|
+
"vite": ">=7.0.0"
|
|
53
|
+
},
|
|
54
|
+
"scripts": {
|
|
55
|
+
"test": "vitest --config ./vitest.config.ts",
|
|
56
|
+
"build": "tsdown",
|
|
57
|
+
"format": "prettier --write .",
|
|
58
|
+
"ci:publish": "changeset publish",
|
|
59
|
+
"ci:version": "changeset version"
|
|
60
|
+
}
|
|
61
|
+
}
|