1
1
# esbuild Cache Plugin for Deno
2
2
3
- esbuild Cache Plugin for Deno is an esbuild plugin to resolve remote (HTTP/HTTPS) and even npm modules using Deno's cache.
3
+ The esbuild Cache Plugin for Deno is an esbuild plugin designed to resolve remote (HTTP/HTTPS) and npm modules using Deno's cache.
4
4
5
5
## Features
6
6
7
- - Resolves http/https imports to Deno's cache.
8
- - Resolves npm module imports to Deno's cache.
9
- - Of course resolving ` import ` s and ` require ` s in the npm module.
10
- - Supports polyfill for npm modules.
11
- - Resolves [ importmaps] ( https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script/type/importmap ) .
12
- - Customizing loader of remote files.
7
+ - Resolve HTTP/HTTPS imports to cached files
8
+ - Resolve npm module imports to cached files
9
+ - Resolve [ import maps] ( https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script/type/importmap )
10
+ - Customize loader patterns
13
11
14
12
## Usage
15
13
16
- ### Minimum Example
14
+ To resolve http/https/npm imports, a lock file (default to ` deno.lock ` ) file is needed.
15
+ To create this file, ensure you have ` deno.json ` in your workspace directory.
16
+
17
+ ### Quick Example
17
18
18
19
``` typescript
20
+ // build.ts
19
21
import { esbuild } from ' https://deno.land/x/esbuild' ;
20
22
import esbuildCachePlugin from ' https://deno.land/x/esbuild_plugin_cache_deno' ;
21
- import lockMap from ' ./lock.json' assert { type: ' json' };
22
23
23
- // To use deno.lock file, you should parse the file manually
24
- // const lockMap = JSON.parse(Deno.readTextFileSync('./deno.lock'));
24
+ const lockMap = JSON .parse (Deno .readTextFileSync (' ./deno.lock' ));
25
25
26
- const config: esbuild .BuildOptions = {
27
- entryPoints: [ ' src/main.ts' ],
26
+ // note that `util.getDenoDir` requires `--allow-run` permission
27
+ // due to it parses `deno info` output.
28
+ const denoDir = await esbuildCachePlugin .util .getDenoDir ();
29
+ await esbuild .build ({
30
+ entryPoints: [ ' ./src/main.ts' ],
28
31
bundle: true ,
29
32
outdir: ' ./dist' ,
30
33
platform: ' browser' ,
31
34
plugins: [
32
35
esbuildCachePlugin ({
33
36
lockMap ,
34
- denoCacheDirectory: ' /home/[user]/.cache/deno '
37
+ denoCacheDirectory: denoDir ,
35
38
}),
36
39
],
37
- };
38
-
39
- await esbuild .build (config );
40
+ });
40
41
41
42
await esbuild .stop ();
42
43
```
43
44
44
- And don't forget to cache ` src/main.ts ` with Deno:
45
-
46
- ``` shell
47
- $deno cache --lock=./test/lock.json --lock-write ./src/main.ts
48
- # or to use deno.lock:
49
- # $deno cache ./src/main.ts
50
- ```
51
-
52
- The you can use remote imports like:
45
+ Include remote imports in your code, for instance:
53
46
54
47
``` typescript
55
- // src/main.ts
48
+ // ./ src/main.ts
56
49
import * as react from " https://esm.sh/react" ;
50
+ // or
51
+ // import * as react from "npm:react";
57
52
58
53
console .log (react .version );
59
54
```
60
55
56
+ Don't forget to cache ` src/main.ts ` with Deno:
57
+
58
+ ``` shell
59
+ $ deno cache ./src/main.ts
60
+ ```
61
+
62
+ See more examples in ` /example ` directory.
63
+
61
64
### Getting Deno's Cache Path
62
65
63
- There's a utility function to get ` DENO_PATH ` from output of ` deno info ` command and you can use the pass as ` denoCacheDirectory ` .
66
+ You can retrieve Deno's cache path using ` deno info ` command:
67
+
68
+ ``` sh
69
+ $ deno info
70
+ DENO_DIR location: /home/user/.cache/deno
71
+ Remote modules cache: /home/user/.cache/deno/deps
72
+ npm modules cache: /home/user/.cache/deno/npm
73
+ Emitted modules cache: /home/user/.cache/deno/gen
74
+ Language server registries cache: /home/user/.cache/deno/registries
75
+ Origin storage: /home/user/.cache/deno/location_data
76
+ ```
77
+
78
+ Or use the utility function to extract the value:
64
79
65
80
``` typescript
66
- const denoPath = await esbuildCachePlugin .util .getDenoDir ();
81
+ const denoDir = await esbuildCachePlugin .util .getDenoDir ();
67
82
```
68
83
69
- Alternatively, you can pass them from CLI argument using shell scripts.
84
+ ## API Reference
70
85
71
- ### Using npm Modules
86
+ ### Import
72
87
73
- You can use npm modules just like using them in Deno :
88
+ Import the plugin like this :
74
89
75
90
``` typescript
76
- // src/main.ts
77
- import * as preact from " npm:preact" ;
78
- import * as preact from " npm:/preact/hooks" ;
91
+ import esbuildCachePlugin from ' https://deno.land/x/esbuild_plugin_cache_deno' ;
79
92
```
80
93
81
- You can replace or remove some modules like Node.js's core modules using import-maps and custom loader (details are in the next section).
94
+ Or,
82
95
83
96
``` typescript
84
- esbuildCachePlugin ({
85
- lockMap ,
86
- denoCacheDirectory: ' /home/[user]/.cache/deno' ,
87
- importmap: {
88
- imports: {
89
- // replace "http" module to polyfill
90
- " node:http" : " /src/polyfill/http.ts" ,
91
- },
92
- },
93
- loaderRules: [
94
- // remote "util" module
95
- { test: / ^ node:util/ , loader: ' empty' },
96
- ],
97
- }),
97
+ import { esbuildCachePlugin } from ' https://deno.land/x/esbuild_plugin_cache_deno' ;
98
98
```
99
99
100
- ### Using Import Maps
100
+ ### Options
101
101
102
- You can pass [ import maps] ( https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script/type/importmap ) with ` importmap ` option.
102
+ #### lockMap (required)
103
+
104
+ The JSON parsed content of lock file.
103
105
104
106
``` typescript
107
+ const lockMap = JSON .parse (Deno .readTextFileSync (' ./deno.lock' ));
105
108
esbuildCachePlugin ({
106
109
lockMap ,
107
- denoCacheDirectory: ' /home/[user]/.cache/deno' ,
108
- importmap: {
109
- imports: {
110
- react: " https://esm.sh/react" ,
111
- },
112
- },
113
- }),
110
+ denoCacheDirectory: denoDir ,
111
+ });
114
112
```
115
113
116
- Then you can use the module specifier like:
114
+ #### denoCacheDirectory (required)
117
115
118
- ``` typescript
119
- // src/main.ts
120
- import * as react from " react" ;
116
+ The cache directory of Deno (` DENO_DIR ` of ` deno info ` command).
121
117
122
- console .log (react .version );
118
+ ``` typescript
119
+ const denoDir = await esbuildCachePlugin .util .getDenoDir ();
120
+ esbuildCachePlugin ({
121
+ lockMap ,
122
+ denoCacheDirectory: denoDir ,
123
+ });
123
124
```
124
125
125
- Of cause you can use your import maps you're using for the intellisense:
126
+ #### importMap (optional)
126
127
127
- ``` typescript
128
- import importmap from ' ./import_map.json' assert type { type : 'json' };
129
-
130
- // ...
128
+ The import map of the project. By default, the plugin resolves the map based on cwd of the process. You can overwrite it with the ` importMapBasePath ` option.
131
129
130
+ ``` typescript
132
131
esbuildCachePlugin ({
133
132
lockMap ,
134
- denoCacheDirectory: ' /home/[user]/.cache/deno' ,
135
- importmap ,
136
- }),
133
+ denoCacheDirectory: denoDir ,
134
+ importMap: {
135
+ imports: {
136
+ ' react' : ' https://esm.sh/react'
137
+ }
138
+ }
139
+ });
137
140
```
138
141
139
- Also you can disguise import map's path for import maps not located in the CWD:
140
-
141
- ``` typescript
142
- import importmap from ' ./src/import_map.json' assert type { type : 'json' };
142
+ #### importMapBasePath
143
143
144
- // .. .
144
+ The base path to resolve import map. Default to ` Deno.cwd() ` .
145
145
146
+ ``` typescript
146
147
esbuildCachePlugin ({
147
148
lockMap ,
148
- denoCacheDirectory: ' /home/[user]/.cache/deno' ,
149
- importmap ,
150
- importmapBasePath: ' src/' ,
151
- }),
149
+ denoCacheDirectory: denoDir ,
150
+ importMap: {
151
+ imports: {
152
+ ' foo' : ' util/foo.ts'
153
+ }
154
+ },
155
+ importMapBasePath: ' ./src' ,
156
+ });
152
157
```
153
158
154
- ### Customizing loaders
159
+ #### loaderRules
155
160
156
- You can specify loaders for files with ` loaderRules ` option. The plugin uses default loader as the esbuild, you may not need to use this option.
161
+ Rules of the loaders by the module specifier to load. Default to the values below and merged with them taking higher priority.
162
+
163
+ ```
164
+ [
165
+ { test: /\.(c|m)?js$/, loader: 'js' },
166
+ { test: /\.jsx$/, loader: 'jsx' },
167
+ { test: /\.(c|m)?ts$/, loader: 'ts' },
168
+ { test: /\.tsx$/, loader: 'tsx' },
169
+ { test: /\.json$/, loader: 'json' },
170
+ { test: /\.css$/, loader: 'css' },
171
+ { test: /\.txt$/, loader: 'text' },
172
+ ]
173
+ ```
174
+
175
+ Setting loader ` empty ` makes the module ignored:
157
176
158
177
``` typescript
159
178
esbuildCachePlugin ({
160
179
lockMap ,
161
- denoCacheDirectory: ' /home/[user]/.cache/deno' ,
162
- loaderRules: [
163
- { test: / \. css$ / , loader: ' css' },
164
- ],
165
- }),
180
+ denoCacheDirectory: denoDir ,
181
+ loaderRules: [{ test: / node:util/ , loader: ' empty' }],
182
+ });
166
183
```
167
184
185
+ ## Tested packages
186
+
187
+ | Package | npm | esm.sh | jsdelivr.net |
188
+ | ------- | :---: | :----: | :----------: |
189
+ | React | ✅ | ✅ | - |
190
+ | Preact | ✅ | ✅ | - |
191
+ | Lit | ✅ | ✅ | - |
192
+ | Lodash | ✅ | - | ✅ |
193
+
168
194
## npm Module Support
169
195
170
196
Reference: [ Modules: Packages | Node.js v20.2.0 Documentation] ( https://nodejs.org/api/packages.html#exports-sugar )
@@ -183,19 +209,19 @@ Reference: [Modules: Packages | Node.js v20.2.0 Documentation](https://nodejs.or
183
209
184
210
Reference: [ Package exports | webpack] ( https://webpack.js.org/guides/package-exports/#support )
185
211
186
- | Specification | Support |
187
- | --- | :---: |
188
- | ` "." ` property | ✅ |
189
- | Normal property | ✅ |
190
- | Property ending with ` / ` | ✅ |
191
- | Property ending with ` * ` | - |
192
- | Alternatives | - |
193
- | Abbreviation only path | ✅ |
194
- | Abbreviation only conditions | ✅ |
195
- | Conditional syntax | ✅ |
196
- | Nested conditional syntax | ✅ |
197
- | Conditions order | - |
198
- | ` "default" ` condition | ✅ |
199
- | Path order | - |
200
- | Error when not mapped | - |
201
- | Error when mixind conditions and paths | ✅ |
212
+ | Specification | Support |
213
+ | -------------------------------------- | :-- ---: |
214
+ | ` "." ` property | ✅ |
215
+ | Normal property | ✅ |
216
+ | Property ending with ` / ` | ✅ |
217
+ | Property ending with ` * ` | - |
218
+ | Alternatives | - |
219
+ | Abbreviation only path | ✅ |
220
+ | Abbreviation only conditions | ✅ |
221
+ | Conditional syntax | ✅ |
222
+ | Nested conditional syntax | ✅ |
223
+ | Conditions order | - |
224
+ | ` "default" ` condition | ✅ |
225
+ | Path order | - |
226
+ | Error when not mapped | - |
227
+ | Error when mixind conditions and paths | ✅ |
0 commit comments