vite-node 0.0.2 → 0.1.0
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/README.md +16 -7
- package/index.mjs +122 -34
- package/package.json +11 -11
package/README.md
CHANGED
|
@@ -6,9 +6,6 @@ Vite as Node runtime.
|
|
|
6
6
|
|
|
7
7
|
> **EXPERIMENTAL**
|
|
8
8
|
|
|
9
|
-
## Why?
|
|
10
|
-
|
|
11
|
-
It runs Vite's id resolving, module transforming, and most importantly, the powerful plugins system!
|
|
12
9
|
|
|
13
10
|
## Usage
|
|
14
11
|
|
|
@@ -16,19 +13,31 @@ It runs Vite's id resolving, module transforming, and most importantly, the powe
|
|
|
16
13
|
npx vite-node index.ts
|
|
17
14
|
```
|
|
18
15
|
|
|
16
|
+
Options:
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npx vite-node -h
|
|
20
|
+
```
|
|
21
|
+
|
|
19
22
|
## Features
|
|
20
23
|
|
|
21
24
|
- Out-of-box ESM & TypeScript support (possible for more with plugins)
|
|
22
25
|
- Top-level await
|
|
23
|
-
-
|
|
26
|
+
- Vite plugins, resolve, aliasing
|
|
24
27
|
- Respect `vite.config.ts`
|
|
25
|
-
-
|
|
28
|
+
- Shims for `__dirname` and `__filename` in ESM
|
|
29
|
+
- Access to native node modules like `fs`, `path`, etc.
|
|
30
|
+
- Watch mode (like `nodemon`)
|
|
26
31
|
|
|
27
32
|
## When NOT to Use
|
|
28
33
|
|
|
29
34
|
- Production, yet - in very early stage, check it later
|
|
30
|
-
- Most of the time when other tools can do that job
|
|
31
|
-
- We
|
|
35
|
+
- Most of the time, when other tools can do that job
|
|
36
|
+
- We need to start a Vite server upon each execution, which inevitably introduces some overhead. Only use it when you want the same behavior as Vite or the powerful plugins system (for example, testing components with a Vite-specific setup).
|
|
37
|
+
|
|
38
|
+
## Why?
|
|
39
|
+
|
|
40
|
+
It runs Vite's id resolving, module transforming, and most importantly, the powerful plugins system!
|
|
32
41
|
|
|
33
42
|
## How?
|
|
34
43
|
|
package/index.mjs
CHANGED
|
@@ -1,19 +1,22 @@
|
|
|
1
|
+
/* eslint-disable no-console */
|
|
1
2
|
import { builtinModules, createRequire } from 'module'
|
|
2
3
|
import { pathToFileURL } from 'url'
|
|
3
|
-
import {
|
|
4
|
+
import { dirname, resolve, relative } from 'path'
|
|
4
5
|
import { createServer } from 'vite'
|
|
5
6
|
import createDebug from 'debug'
|
|
6
7
|
import minimist from 'minimist'
|
|
7
|
-
import { red, dim } from 'kolorist'
|
|
8
|
+
import { red, dim, yellow, green, inverse, cyan } from 'kolorist'
|
|
8
9
|
|
|
9
10
|
const argv = minimist(process.argv.slice(2), {
|
|
10
11
|
alias: {
|
|
11
12
|
r: 'root',
|
|
12
13
|
c: 'config',
|
|
13
14
|
h: 'help',
|
|
15
|
+
w: 'watch',
|
|
16
|
+
s: 'silent',
|
|
14
17
|
},
|
|
15
18
|
string: ['root', 'config'],
|
|
16
|
-
boolean: ['help', 'vue'],
|
|
19
|
+
boolean: ['help', 'vue', 'watch', 'silent'],
|
|
17
20
|
unknown(name) {
|
|
18
21
|
if (name[0] === '-') {
|
|
19
22
|
console.error(red(`Unknown argument: ${name}`))
|
|
@@ -43,6 +46,8 @@ const root = argv.root || process.cwd()
|
|
|
43
46
|
process.chdir(root)
|
|
44
47
|
|
|
45
48
|
const server = await createServer({
|
|
49
|
+
logLevel: 'error',
|
|
50
|
+
clearScreen: false,
|
|
46
51
|
configFile: argv.config,
|
|
47
52
|
root,
|
|
48
53
|
resolve: argv.vue
|
|
@@ -60,28 +65,95 @@ const server = await createServer({
|
|
|
60
65
|
: {},
|
|
61
66
|
})
|
|
62
67
|
await server.pluginContainer.buildStart({})
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
68
|
+
let executing = false
|
|
69
|
+
|
|
70
|
+
async function run() {
|
|
71
|
+
process.exitCode = 0
|
|
72
|
+
executing = true
|
|
73
|
+
let err
|
|
74
|
+
try {
|
|
75
|
+
await execute(files, server, argv)
|
|
76
|
+
}
|
|
77
|
+
catch (e) {
|
|
78
|
+
console.error(e)
|
|
79
|
+
err = e
|
|
80
|
+
if (!argv.watch)
|
|
81
|
+
process.exit(1)
|
|
82
|
+
}
|
|
83
|
+
finally {
|
|
84
|
+
executing = false
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if (argv.watch) {
|
|
88
|
+
setTimeout(() => {
|
|
89
|
+
if (err || process.exitCode)
|
|
90
|
+
log(inverse(red(' vite node ')), red('program exited with error, waiting for file changes...'))
|
|
91
|
+
else
|
|
92
|
+
log(inverse(green(' vite node ')), green('program exited, waiting for file changes...'))
|
|
93
|
+
}, 10)
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
await server.close()
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if (argv.watch) {
|
|
101
|
+
log(inverse(cyan(' vite node ')), cyan('watch mode enabled\n'))
|
|
102
|
+
|
|
103
|
+
server.watcher.on('change', (file) => {
|
|
104
|
+
if (!executing) {
|
|
105
|
+
log(inverse(yellow(' vite node ')), yellow(`${file} changed, restarting...\n`))
|
|
106
|
+
run()
|
|
107
|
+
}
|
|
108
|
+
})
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
await run(files, server, argv)
|
|
66
112
|
|
|
67
113
|
// --- CLI END ---
|
|
68
114
|
|
|
115
|
+
function normalizeId(id) {
|
|
116
|
+
// Virtual modules start with `\0`
|
|
117
|
+
if (id && id.startsWith('/@id/__x00__'))
|
|
118
|
+
id = `\0${id.slice('/@id/__x00__'.length)}`
|
|
119
|
+
if (id && id.startsWith('/@id/'))
|
|
120
|
+
id = id.slice('/@id/'.length)
|
|
121
|
+
return id
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function toFilePath(id) {
|
|
125
|
+
const absolute = id.startsWith('/@fs/')
|
|
126
|
+
? id.slice(4)
|
|
127
|
+
: slash(resolve(server.config.root, id.slice(1)))
|
|
128
|
+
|
|
129
|
+
return absolute
|
|
130
|
+
}
|
|
131
|
+
|
|
69
132
|
async function execute(files, server) {
|
|
70
|
-
const
|
|
133
|
+
const __pendingModules__ = new Map()
|
|
71
134
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
if (id && id.startsWith('/@id/'))
|
|
77
|
-
id = id.slice('/@id/'.length)
|
|
135
|
+
const result = []
|
|
136
|
+
for (const file of files)
|
|
137
|
+
result.push(await cachedRequest(`/@fs/${slash(resolve(file))}`, []))
|
|
138
|
+
return result
|
|
78
139
|
|
|
79
|
-
|
|
80
|
-
|
|
140
|
+
async function directRequest(rawId, callstack) {
|
|
141
|
+
if (builtinModules.includes(rawId))
|
|
142
|
+
return import(rawId)
|
|
143
|
+
|
|
144
|
+
callstack = [...callstack, rawId]
|
|
145
|
+
const request = async(dep) => {
|
|
146
|
+
if (callstack.includes(dep)) {
|
|
147
|
+
throw new Error(`${red('Circular dependency detected')}\nStack:\n${[...callstack, dep].reverse().map((i) => {
|
|
148
|
+
const path = relative(server.config.root, toFilePath(normalizeId(i)))
|
|
149
|
+
return dim(' -> ') + (i === dep ? yellow(path) : path)
|
|
150
|
+
}).join('\n')}\n`)
|
|
151
|
+
}
|
|
152
|
+
return cachedRequest(dep, callstack)
|
|
153
|
+
}
|
|
81
154
|
|
|
82
|
-
const
|
|
83
|
-
|
|
84
|
-
: slash(join(server.config.root, id.slice(1)))
|
|
155
|
+
const id = normalizeId(rawId)
|
|
156
|
+
const absolute = toFilePath(id)
|
|
85
157
|
|
|
86
158
|
debugRequest(absolute)
|
|
87
159
|
|
|
@@ -90,7 +162,7 @@ async function execute(files, server) {
|
|
|
90
162
|
? `/${absolute}`
|
|
91
163
|
: absolute
|
|
92
164
|
|
|
93
|
-
if (
|
|
165
|
+
if (absolute.includes('/node_modules/'))
|
|
94
166
|
return import(unifiedPath)
|
|
95
167
|
|
|
96
168
|
const result = await server.transformRequest(id, { ssr: true })
|
|
@@ -100,17 +172,16 @@ async function execute(files, server) {
|
|
|
100
172
|
debugTransform(id, result.code)
|
|
101
173
|
|
|
102
174
|
const url = pathToFileURL(unifiedPath)
|
|
103
|
-
|
|
104
175
|
const exports = {}
|
|
105
176
|
|
|
106
177
|
const context = {
|
|
107
178
|
require: createRequire(url),
|
|
108
179
|
__filename: absolute,
|
|
109
180
|
__dirname: dirname(absolute),
|
|
110
|
-
__vite_ssr_import__:
|
|
111
|
-
__vite_ssr_dynamic_import__:
|
|
181
|
+
__vite_ssr_import__: request,
|
|
182
|
+
__vite_ssr_dynamic_import__: request,
|
|
112
183
|
__vite_ssr_exports__: exports,
|
|
113
|
-
__vite_ssr_exportAll__: obj =>
|
|
184
|
+
__vite_ssr_exportAll__: obj => exportAll(exports, obj),
|
|
114
185
|
__vite_ssr_import_meta__: { url },
|
|
115
186
|
}
|
|
116
187
|
|
|
@@ -120,22 +191,32 @@ async function execute(files, server) {
|
|
|
120
191
|
)
|
|
121
192
|
|
|
122
193
|
// prefetch deps
|
|
123
|
-
result.deps.forEach(dep => cachedRequest(dep))
|
|
124
|
-
|
|
125
194
|
await fn(...Object.values(context))
|
|
195
|
+
|
|
126
196
|
return exports
|
|
127
197
|
}
|
|
128
198
|
|
|
129
|
-
function cachedRequest(
|
|
130
|
-
if (!
|
|
131
|
-
|
|
132
|
-
return
|
|
199
|
+
function cachedRequest(id, callstack) {
|
|
200
|
+
if (!__pendingModules__[id])
|
|
201
|
+
__pendingModules__[id] = directRequest(id, callstack)
|
|
202
|
+
return __pendingModules__[id]
|
|
133
203
|
}
|
|
134
204
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
205
|
+
function exportAll(exports, sourceModule) {
|
|
206
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
207
|
+
for (const key in sourceModule) {
|
|
208
|
+
if (key !== 'default') {
|
|
209
|
+
try {
|
|
210
|
+
Object.defineProperty(exports, key, {
|
|
211
|
+
enumerable: true,
|
|
212
|
+
configurable: true,
|
|
213
|
+
get() { return sourceModule[key] },
|
|
214
|
+
})
|
|
215
|
+
}
|
|
216
|
+
catch (_err) { }
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
139
220
|
}
|
|
140
221
|
|
|
141
222
|
function slash(path) {
|
|
@@ -143,7 +224,6 @@ function slash(path) {
|
|
|
143
224
|
}
|
|
144
225
|
|
|
145
226
|
function help() {
|
|
146
|
-
// eslint-disable-next-line no-console
|
|
147
227
|
console.log(`
|
|
148
228
|
Usage:
|
|
149
229
|
$ vite-node [options] [files]
|
|
@@ -151,6 +231,14 @@ Usage:
|
|
|
151
231
|
Options:
|
|
152
232
|
-r, --root <path> ${dim('[string]')} use specified root directory
|
|
153
233
|
-c, --config <file> ${dim('[string]')} use specified config file
|
|
234
|
+
-w, --watch ${dim('[boolean]')} restart on file changes, similar to "nodemon"
|
|
235
|
+
-s, --silent ${dim('[boolean]')} do not emit errors and logs
|
|
154
236
|
--vue ${dim('[boolean]')} support for importing Vue component
|
|
155
237
|
`)
|
|
156
238
|
}
|
|
239
|
+
|
|
240
|
+
function log(...args) {
|
|
241
|
+
if (argv.silent)
|
|
242
|
+
return
|
|
243
|
+
console.log(...args)
|
|
244
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vite-node",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "0.1.0",
|
|
4
4
|
"description": "Vite as Node runtime",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"vite"
|
|
@@ -33,23 +33,23 @@
|
|
|
33
33
|
"bin"
|
|
34
34
|
],
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"debug": "^4.3.
|
|
36
|
+
"debug": "^4.3.3",
|
|
37
37
|
"kolorist": "^1.5.0",
|
|
38
38
|
"minimist": "^1.2.5",
|
|
39
39
|
"vite": "^2.6.5"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
|
-
"@antfu/eslint-config": "^0.
|
|
43
|
-
"@antfu/ni": "^0.
|
|
42
|
+
"@antfu/eslint-config": "^0.11.1",
|
|
43
|
+
"@antfu/ni": "^0.11.0",
|
|
44
44
|
"@types/debug": "^4.1.7",
|
|
45
|
-
"@types/node": "^16.
|
|
46
|
-
"@vitejs/plugin-vue": "^1.
|
|
45
|
+
"@types/node": "^16.11.11",
|
|
46
|
+
"@vitejs/plugin-vue": "^1.10.1",
|
|
47
47
|
"bumpp": "^7.1.1",
|
|
48
|
-
"eslint": "^
|
|
49
|
-
"esno": "^0.
|
|
50
|
-
"typescript": "^4.
|
|
51
|
-
"uvu": "^0.5.
|
|
52
|
-
"vue": "^3.2.
|
|
48
|
+
"eslint": "^8.3.0",
|
|
49
|
+
"esno": "^0.12.1",
|
|
50
|
+
"typescript": "^4.5.2",
|
|
51
|
+
"uvu": "^0.5.2",
|
|
52
|
+
"vue": "^3.2.23"
|
|
53
53
|
},
|
|
54
54
|
"engines": {
|
|
55
55
|
"node": ">=14.0.0"
|