vite-plugin-serve-static 1.2.0 → 2.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/LICENSE +1 -1
- package/README.md +21 -18
- package/dist/index.d.mts +27 -0
- package/dist/index.mjs +105 -0
- package/package.json +16 -25
- package/dist/index.d.ts +0 -11
- package/dist/index.js +0 -84
package/LICENSE
CHANGED
package/README.md
CHANGED
|
@@ -2,30 +2,33 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/vite-plugin-serve-static)
|
|
4
4
|
[](https://github.com/vitejs/vite)
|
|
5
|
-
[](https://github.com/
|
|
5
|
+
[](https://github.com/typeparameter/vite-plugin-serve-static/blob/main/LICENSE)
|
|
6
6
|
|
|
7
7
|
A simple Vite plugin for serving arbitrary static files that aren't in your `public` directory.
|
|
8
8
|
|
|
9
9
|
```typescript
|
|
10
10
|
// vite.config.ts
|
|
11
11
|
import path from "path";
|
|
12
|
+
|
|
12
13
|
import { defineConfig } from "vite";
|
|
13
14
|
import serveStatic from "vite-plugin-serve-static";
|
|
14
15
|
|
|
15
|
-
const serveStaticPlugin = serveStatic(
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
16
|
+
const serveStaticPlugin = serveStatic({
|
|
17
|
+
rules: [
|
|
18
|
+
{
|
|
19
|
+
pattern: /^\/metadata\.json/,
|
|
20
|
+
resolve: path.join(".", "metadata.json"),
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
pattern: /^\/dog-photos\/.*/,
|
|
24
|
+
resolve: ([match]) => path.join("..", "dog-photos", match),
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
pattern: /^\/author-photos\/(.*)/,
|
|
28
|
+
resolve: (groups) => path.join("..", "authors", groups[1]) + ".jpg",
|
|
29
|
+
},
|
|
30
|
+
],
|
|
31
|
+
});
|
|
29
32
|
|
|
30
33
|
export default defineConfig({
|
|
31
34
|
plugins: [serveStaticPlugin],
|
|
@@ -34,12 +37,12 @@ export default defineConfig({
|
|
|
34
37
|
|
|
35
38
|
## Config
|
|
36
39
|
|
|
37
|
-
The configuration is
|
|
40
|
+
The configuration is provided as an object with `rules`, plus an optional global `contentType`.
|
|
38
41
|
|
|
39
|
-
Each `pattern` is defined as a [regular expression]. The `resolve` property can either be a string containing the path to a single file or a function that returns a string given the result of executing the `pattern` against the request path.
|
|
42
|
+
Each rule defines which patterns to intercept and how to resolve them. Each `pattern` is defined as a [regular expression]. The `resolve` property can either be a string containing the path to a single file or a function that returns a string given the result of executing the `pattern` against the request path.
|
|
40
43
|
|
|
41
44
|
## License
|
|
42
45
|
|
|
43
|
-
Licensed under the [MIT License](https://github.com/
|
|
46
|
+
Licensed under the [MIT License](https://github.com/typeparameter/vite-plugin-serve-static/blob/main/packages/vite-plugin-serve-static/LICENSE).
|
|
44
47
|
|
|
45
48
|
[regular expression]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { Plugin } from "vite";
|
|
2
|
+
import http from "http";
|
|
3
|
+
|
|
4
|
+
//#region lib/config.d.ts
|
|
5
|
+
type ResolveFn = (match: RegExpExecArray) => string;
|
|
6
|
+
type RuleConfig = {
|
|
7
|
+
readonly pattern: RegExp;
|
|
8
|
+
readonly resolve: string | ResolveFn;
|
|
9
|
+
readonly headers?: http.OutgoingHttpHeaders;
|
|
10
|
+
};
|
|
11
|
+
type Config = RuleConfig[] | {
|
|
12
|
+
readonly rules: RuleConfig[];
|
|
13
|
+
readonly contentType?: string;
|
|
14
|
+
};
|
|
15
|
+
declare function normalizeConfig(config: Config): {
|
|
16
|
+
contentType?: string;
|
|
17
|
+
rules: {
|
|
18
|
+
headers: http.OutgoingHttpHeaders;
|
|
19
|
+
pattern: RegExp;
|
|
20
|
+
resolve: string | ResolveFn;
|
|
21
|
+
}[];
|
|
22
|
+
};
|
|
23
|
+
//#endregion
|
|
24
|
+
//#region lib/index.d.ts
|
|
25
|
+
declare function serveStatic(config: Config): Plugin;
|
|
26
|
+
//#endregion
|
|
27
|
+
export { Config, ResolveFn, serveStatic as default, normalizeConfig };
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import corsMiddleware from "cors";
|
|
4
|
+
import * as mime from "mime-types";
|
|
5
|
+
|
|
6
|
+
//#region lib/config.ts
|
|
7
|
+
function normalizeConfig(config) {
|
|
8
|
+
const { rules, ...rest } = Array.isArray(config) ? { rules: config } : config;
|
|
9
|
+
return {
|
|
10
|
+
rules: rules.map((rule) => ({
|
|
11
|
+
...rule,
|
|
12
|
+
headers: normalizeHeaders(rule.headers)
|
|
13
|
+
})),
|
|
14
|
+
...rest
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
function normalizeHeaders(headers) {
|
|
18
|
+
if (!headers) return {};
|
|
19
|
+
const entries = Object.entries(headers).filter(([, value]) => value !== void 0).map(([key, value]) => [key.toLowerCase(), value]);
|
|
20
|
+
return Object.fromEntries(entries);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
//#endregion
|
|
24
|
+
//#region lib/utils.ts
|
|
25
|
+
function isDevServer(server) {
|
|
26
|
+
return "pluginContainer" in server;
|
|
27
|
+
}
|
|
28
|
+
function setupLogger(logger) {
|
|
29
|
+
const defaultOptions = { timestamp: true };
|
|
30
|
+
function applyDefaultOptions(log) {
|
|
31
|
+
return function(msg, options) {
|
|
32
|
+
log(msg, {
|
|
33
|
+
...defaultOptions,
|
|
34
|
+
...options
|
|
35
|
+
});
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
return {
|
|
39
|
+
clearScreen: logger.clearScreen,
|
|
40
|
+
hasErrorLogged: logger.hasErrorLogged,
|
|
41
|
+
hasWarned: logger.hasWarned,
|
|
42
|
+
info: applyDefaultOptions(logger.info),
|
|
43
|
+
warn: applyDefaultOptions(logger.warn),
|
|
44
|
+
warnOnce: applyDefaultOptions(logger.warnOnce),
|
|
45
|
+
error: applyDefaultOptions(logger.error)
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
//#endregion
|
|
50
|
+
//#region lib/middleware.ts
|
|
51
|
+
function createMiddleware(pluginConfig, rawLogger) {
|
|
52
|
+
const log = setupLogger(rawLogger);
|
|
53
|
+
const config = normalizeConfig(pluginConfig);
|
|
54
|
+
return function serveStaticMiddleware(req, res, next) {
|
|
55
|
+
if (!req.url) return next();
|
|
56
|
+
for (const { pattern, resolve, headers } of config.rules) {
|
|
57
|
+
const match = pattern.exec(req.url);
|
|
58
|
+
if (match) {
|
|
59
|
+
const filePath = typeof resolve === "string" ? resolve : resolve(match);
|
|
60
|
+
const stats = fs.statSync(filePath, { throwIfNoEntry: false });
|
|
61
|
+
if (!stats || !stats.isFile()) {
|
|
62
|
+
res.writeHead(404);
|
|
63
|
+
res.end("Not found");
|
|
64
|
+
log.error(`File ${filePath} is not a file`);
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
const contentType = headers["content-type"] || config.contentType || mime.contentType(path.basename(filePath)) || "application/octet-stream";
|
|
68
|
+
res.writeHead(200, {
|
|
69
|
+
"content-length": stats.size,
|
|
70
|
+
"content-type": contentType,
|
|
71
|
+
...headers
|
|
72
|
+
});
|
|
73
|
+
fs.createReadStream(filePath).pipe(res);
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return next();
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
function applyMiddleware(server, pluginConfig) {
|
|
81
|
+
const pluginMiddleware = createMiddleware(pluginConfig, server.config.logger);
|
|
82
|
+
const corsConfig = isDevServer(server) ? server.config.server.cors : server.config.preview.cors;
|
|
83
|
+
if (corsConfig !== false) {
|
|
84
|
+
const config = typeof corsConfig === "boolean" ? {} : corsConfig;
|
|
85
|
+
server.middlewares.use(corsMiddleware(config));
|
|
86
|
+
}
|
|
87
|
+
server.middlewares.use(pluginMiddleware);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
//#endregion
|
|
91
|
+
//#region lib/index.ts
|
|
92
|
+
function serveStatic(config) {
|
|
93
|
+
return {
|
|
94
|
+
name: "serve-static",
|
|
95
|
+
configureServer(server) {
|
|
96
|
+
applyMiddleware(server, config);
|
|
97
|
+
},
|
|
98
|
+
configurePreviewServer(server) {
|
|
99
|
+
applyMiddleware(server, config);
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
//#endregion
|
|
105
|
+
export { serveStatic as default, normalizeConfig };
|
package/package.json
CHANGED
|
@@ -1,30 +1,31 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vite-plugin-serve-static",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "2.1.0",
|
|
4
4
|
"description": "A Vite plugin for serving static files during local development",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
7
|
-
"url": "git+https://github.com/
|
|
7
|
+
"url": "git+https://github.com/typeparameter/vite-plugin-serve-static.git"
|
|
8
8
|
},
|
|
9
9
|
"license": "MIT",
|
|
10
|
-
"homepage": "https://github.com/
|
|
10
|
+
"homepage": "https://github.com/typeparameter/vite-plugin-serve-static",
|
|
11
11
|
"keywords": [
|
|
12
12
|
"vite-plugin"
|
|
13
13
|
],
|
|
14
14
|
"type": "module",
|
|
15
|
+
"engines": {
|
|
16
|
+
"node": ">=20"
|
|
17
|
+
},
|
|
15
18
|
"files": [
|
|
16
19
|
"dist"
|
|
17
20
|
],
|
|
18
|
-
"main": "dist/index.
|
|
19
|
-
"types": "dist/index.d.
|
|
21
|
+
"main": "dist/index.mjs",
|
|
22
|
+
"types": "dist/index.d.mts",
|
|
20
23
|
"scripts": {
|
|
21
|
-
"build": "
|
|
24
|
+
"build": "tsdown",
|
|
22
25
|
"clean": "rimraf dist",
|
|
23
|
-
"
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
"lint:fix": "eslint --fix --cache --max-warnings=0 .",
|
|
27
|
-
"prepack": "npm-run-all build test lint format:check",
|
|
26
|
+
"lint": "tsc && eslint --cache --max-warnings=0 .",
|
|
27
|
+
"lint:fix": "tsc && eslint --fix --cache --max-warnings=0 .",
|
|
28
|
+
"prepack": "pnpm build",
|
|
28
29
|
"test": "vitest --run"
|
|
29
30
|
},
|
|
30
31
|
"peerDependencies": {
|
|
@@ -35,25 +36,15 @@
|
|
|
35
36
|
"mime-types": "^2.1.35"
|
|
36
37
|
},
|
|
37
38
|
"devDependencies": {
|
|
38
|
-
"@trivago/prettier-plugin-sort-imports": "^5.2.0",
|
|
39
39
|
"@types/cors": "^2.8.17",
|
|
40
40
|
"@types/mime-types": "^2.1.4",
|
|
41
|
-
"@typescript-eslint/eslint-plugin": "^8.18.0",
|
|
42
|
-
"@typescript-eslint/parser": "^8.18.0",
|
|
43
|
-
"conventional-changelog-conventionalcommits": "^8.0.0",
|
|
44
|
-
"eslint": "^8.57.1",
|
|
45
|
-
"eslint-config-prettier": "^9.1.0",
|
|
46
|
-
"npm-run-all": "^4.1.5",
|
|
47
|
-
"prettier": "^3.4.2",
|
|
48
41
|
"rimraf": "^6.0.1",
|
|
49
|
-
"
|
|
42
|
+
"tsdown": "^0.18.4",
|
|
50
43
|
"typescript": "~5.7.2",
|
|
51
|
-
"vitest": "^
|
|
44
|
+
"vitest": "^4.0.16"
|
|
52
45
|
},
|
|
53
46
|
"publishConfig": {
|
|
54
|
-
"access": "public"
|
|
55
|
-
|
|
56
|
-
"release": {
|
|
57
|
-
"preset": "conventionalcommits"
|
|
47
|
+
"access": "public",
|
|
48
|
+
"provenance": true
|
|
58
49
|
}
|
|
59
50
|
}
|
package/dist/index.d.ts
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { Plugin } from 'vite';
|
|
2
|
-
|
|
3
|
-
type ResolveFn = (match: RegExpExecArray) => string;
|
|
4
|
-
type Config = {
|
|
5
|
-
readonly pattern: RegExp;
|
|
6
|
-
readonly resolve: string | ResolveFn;
|
|
7
|
-
}[];
|
|
8
|
-
|
|
9
|
-
declare function serveStatic(config: Config): Plugin;
|
|
10
|
-
|
|
11
|
-
export { type Config, type ResolveFn, serveStatic as default };
|
package/dist/index.js
DELETED
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
// lib/middleware.ts
|
|
2
|
-
import * as mime from "mime-types";
|
|
3
|
-
import corsMiddleware from "cors";
|
|
4
|
-
import fs from "fs";
|
|
5
|
-
import path from "path";
|
|
6
|
-
|
|
7
|
-
// lib/utils.ts
|
|
8
|
-
function isDevServer(server) {
|
|
9
|
-
return "pluginContainer" in server;
|
|
10
|
-
}
|
|
11
|
-
function setupLogger(logger) {
|
|
12
|
-
const defaultOptions = { timestamp: true };
|
|
13
|
-
function applyDefaultOptions(log) {
|
|
14
|
-
return function(msg, options) {
|
|
15
|
-
log(msg, { ...defaultOptions, ...options });
|
|
16
|
-
};
|
|
17
|
-
}
|
|
18
|
-
return {
|
|
19
|
-
clearScreen: logger.clearScreen,
|
|
20
|
-
hasErrorLogged: logger.hasErrorLogged,
|
|
21
|
-
hasWarned: logger.hasWarned,
|
|
22
|
-
info: applyDefaultOptions(logger.info),
|
|
23
|
-
warn: applyDefaultOptions(logger.warn),
|
|
24
|
-
warnOnce: applyDefaultOptions(logger.warnOnce),
|
|
25
|
-
error: applyDefaultOptions(logger.error)
|
|
26
|
-
};
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
// lib/middleware.ts
|
|
30
|
-
function createMiddleware(config, rawLogger) {
|
|
31
|
-
const log = setupLogger(rawLogger);
|
|
32
|
-
return function serveStaticMiddleware(req, res, next) {
|
|
33
|
-
if (!req.url) {
|
|
34
|
-
return next();
|
|
35
|
-
}
|
|
36
|
-
for (const { pattern, resolve } of config) {
|
|
37
|
-
const match = pattern.exec(req.url);
|
|
38
|
-
if (match) {
|
|
39
|
-
const filePath = typeof resolve === "string" ? resolve : resolve(match);
|
|
40
|
-
const stats = fs.statSync(filePath, { throwIfNoEntry: false });
|
|
41
|
-
if (!stats || !stats.isFile()) {
|
|
42
|
-
res.writeHead(404);
|
|
43
|
-
res.end("Not found");
|
|
44
|
-
log.error(`File ${filePath} is not a file`);
|
|
45
|
-
return;
|
|
46
|
-
}
|
|
47
|
-
const type = mime.contentType(path.basename(filePath));
|
|
48
|
-
res.writeHead(200, {
|
|
49
|
-
"Content-Length": stats.size,
|
|
50
|
-
"Content-Type": type || "application/octet-stream"
|
|
51
|
-
});
|
|
52
|
-
const stream = fs.createReadStream(filePath);
|
|
53
|
-
stream.pipe(res);
|
|
54
|
-
return;
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
return next();
|
|
58
|
-
};
|
|
59
|
-
}
|
|
60
|
-
function applyMiddleware(server, pluginConfig) {
|
|
61
|
-
const pluginMiddleware = createMiddleware(pluginConfig, server.config.logger);
|
|
62
|
-
const corsConfig = isDevServer(server) ? server.config.server.cors : server.config.preview.cors;
|
|
63
|
-
if (corsConfig !== false) {
|
|
64
|
-
const config = typeof corsConfig === "boolean" ? {} : corsConfig;
|
|
65
|
-
server.middlewares.use(corsMiddleware(config));
|
|
66
|
-
}
|
|
67
|
-
server.middlewares.use(pluginMiddleware);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
// lib/index.ts
|
|
71
|
-
function serveStatic(config) {
|
|
72
|
-
return {
|
|
73
|
-
name: "serve-static",
|
|
74
|
-
configureServer(server) {
|
|
75
|
-
applyMiddleware(server, config);
|
|
76
|
-
},
|
|
77
|
-
configurePreviewServer(server) {
|
|
78
|
-
applyMiddleware(server, config);
|
|
79
|
-
}
|
|
80
|
-
};
|
|
81
|
-
}
|
|
82
|
-
export {
|
|
83
|
-
serveStatic as default
|
|
84
|
-
};
|