vite-tampermonkey 1.0.0 → 1.0.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 koyori
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,101 @@
1
+ # 🚀 vite-plugin-tampermonkey
2
+
3
+ 一个专为 Vite 设计的 Tampermonkey (油猴) 脚本构建插件。让你能以开发现代 Web 应用的体验(HMR、TypeScript、Tailwind CSS)来编写 Userscript。
4
+
5
+ ## ✨ 功能特性
6
+
7
+ - **自动元数据生成**:根据配置自动生成脚本头 (`Userscript Header`)。
8
+ - **双模式开发驱动**:
9
+ - **Dev 模式**:自动生成 `user.dev.js` 指向本地服务,支持热更新(HMR)。
10
+ - **Build 模式**:生产环境构建,支持代码压缩与混淆。
11
+ - **智能资源处理**:
12
+ - **CDN 自动映射**:自动排除 `dependencies` 中的包并替换为远程 CDN 引用。
13
+ - **资源转换**:本地 `Icon` 图片自动转为 `base64` 嵌入。
14
+ - **样式深度集成**:完美支持 `tailwindcss`,自动压缩并注入到脚本中。
15
+ - **高度可定制**:灵活配置 `external` 模块、`globals` 全局变量及 `@resource` 资源。
16
+
17
+ ---
18
+
19
+ ## 📦 安装
20
+
21
+ ```bash
22
+ pnpm add -D vite-plugin-tampermonkey
23
+ ```
24
+
25
+ ## 🛠️ 快速开始
26
+
27
+ 1. 配置 package.json
28
+
29
+ 为了配合插件的开发逻辑,建议在 `scripts` 中配置如下命令:
30
+
31
+ ```json
32
+ "scripts": {
33
+ "dev": "vite build --mode development --watch",
34
+ "build": "vite build --mode production"
35
+ }
36
+ ```
37
+
38
+ 2. 配置 vite.config.ts
39
+
40
+ ```typescript
41
+ import { defineConfig } from 'vite';
42
+ import react from '@vitejs/plugin-react';
43
+ import tailwindcss from '@theme-it/vite-plugin-tailwindcss';
44
+ import tampermonkeyPlugin from 'vite-plugin-tampermonkey';
45
+
46
+ export default defineConfig(({ mode }) => {
47
+ const isDev = mode === 'development';
48
+
49
+ return {
50
+ plugins: [
51
+ tailwindcss(),
52
+ react({
53
+ // 开发模式开启自动 Runtime,生产模式建议 classic 以减小体积
54
+ jsxRuntime: isDev ? 'automatic' : 'classic',
55
+ }),
56
+ tampermonkeyPlugin({
57
+ entry: 'src/main.tsx',
58
+ // 脚本元属性 (Userscript Header)
59
+ meta: {
60
+ name: 'My Awesome Script',
61
+ namespace: '[https://midorii.cc/](https://midorii.cc/)',
62
+ match: ['[https://www.google.com/](https://www.google.com/)*'],
63
+ grant: ['GM_addStyle', 'GM_xmlhttpRequest', 'GM_setValue', 'GM_getValue'],
64
+ },
65
+ external: {
66
+ // 排除包体,自动添加 CDN 映射
67
+ modules: {
68
+ 'react': '[https://cdn.jsdelivr.net/npm/react@18/umd/react.production.min.js](https://cdn.jsdelivr.net/npm/react@18/umd/react.production.min.js)',
69
+ 'react-dom': '[https://cdn.jsdelivr.net/npm/react-dom@18/umd/react-dom.production.min.js](https://cdn.jsdelivr.net/npm/react-dom@18/umd/react-dom.production.min.js)',
70
+ },
71
+ // 全局变量映射
72
+ globals: {
73
+ 'react': 'React',
74
+ 'react-dom': 'ReactDOM',
75
+ },
76
+ // 外部资源引用 (CSS等)
77
+ resources: {
78
+ 'animate-css': '[https://cdn.bootcdn.net/ajax/libs/animate.css/4.1.1/animate.min.css](https://cdn.bootcdn.net/ajax/libs/animate.css/4.1.1/animate.min.css)'
79
+ }
80
+ },
81
+ }),
82
+ ],
83
+ };
84
+ });
85
+ ```
86
+
87
+ ## 💡 开发工作流
88
+
89
+ 1. 启动本地服务:运行 `pnpm dev`。
90
+ 2. 安装开发脚本:插件会在 dist 目录生成 `index.dev.user.js`。将其内容复制并粘贴到 Tampermonkey 编辑器中保存。
91
+ 3. 实时调试:修改源码并保存后,受脚本控制的页面将自动应用更改或刷新,无需手动更新脚本内容。
92
+
93
+ ## 📝 配置项说明 (Options)
94
+
95
+ | 属性 | 类型 | 描述 |
96
+ | :--- | :--- | :--- |
97
+ | **entry** | `string` | **必填**。脚本入口文件路径 (例如: `src/main.tsx`)。 |
98
+ | **meta** | `UserscriptMeta` | **必填**。油猴脚本头配置,支持所有标准的 `@match`, `@grant`, `@run-at` 等。 |
99
+ | **external.modules** | `Record<string, string>` | 需要从 Bundle 中排除的依赖及其对应的 CDN 链接。 |
100
+ | **external.globals** | `Record<string, string>` | 外部依赖对应的全局变量映射 (例如: `react` -> `React`)。 |
101
+ | **external.resources** | `Record<string, string>` | 使用 `@resource` 注入的外部资源列表,自动添加至脚本头。 |
package/dist/index.cjs ADDED
@@ -0,0 +1,316 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/index.ts
31
+ var index_exports = {};
32
+ __export(index_exports, {
33
+ tampermonkeyPlugin: () => tampermonkeyPlugin
34
+ });
35
+ module.exports = __toCommonJS(index_exports);
36
+ var import_node_fs = require("fs");
37
+ var import_node_path = require("path");
38
+ var import_node_url = require("url");
39
+
40
+ // src/builder.ts
41
+ var import_crypto = __toESM(require("crypto"), 1);
42
+ var import_fs = __toESM(require("fs"), 1);
43
+ var TampermonkeyMetaBuilder = class {
44
+ lines = ["// ==UserScript=="];
45
+ add(key, value) {
46
+ if (value == null) return this;
47
+ if (key === "icon") {
48
+ if (typeof value === "string" && !value.startsWith("http")) {
49
+ const iconBase64 = import_fs.default.readFileSync(value, "base64");
50
+ value = `data:image/png;base64,${iconBase64}`;
51
+ }
52
+ }
53
+ if (Array.isArray(value)) {
54
+ const set = new Set(value);
55
+ set.forEach((v) => this.push(key, v));
56
+ } else {
57
+ this.push(key, value === true ? "" : String(value));
58
+ }
59
+ return this;
60
+ }
61
+ addRecord(record) {
62
+ if (!record) return this;
63
+ for (const [k, v] of Object.entries(record)) {
64
+ const key = k.replace(/([A-Z])/g, "-$1").toLowerCase();
65
+ if (Array.isArray(v)) {
66
+ v.forEach((val) => this.push(key, String(val)));
67
+ } else {
68
+ this.push(key, v === true ? "" : String(v));
69
+ }
70
+ }
71
+ return this;
72
+ }
73
+ push(key, value) {
74
+ const spacing = " ".repeat(Math.max(1, 12 - key.length));
75
+ this.lines.push(`// @${key}${spacing}${value}`.trimEnd());
76
+ }
77
+ build() {
78
+ return [...this.lines, "// ==/UserScript==", ""].join("\n");
79
+ }
80
+ };
81
+ var TampermonkeyBuilder = class {
82
+ cssCode = "";
83
+ jsCode = "";
84
+ meta = {};
85
+ external;
86
+ externalResources = [];
87
+ constructor(meta, external) {
88
+ this.meta = meta;
89
+ this.external = external;
90
+ this.externalResources = this.getExternalResources();
91
+ this.addCode("var global = window;\n");
92
+ }
93
+ /**
94
+ * 添加CSS代码
95
+ * @param source 源码
96
+ */
97
+ addCss(source) {
98
+ this.cssCode += typeof source === "string" ? source : Buffer.from(source).toString("utf8");
99
+ }
100
+ /**
101
+ * 添加JS代码
102
+ * @param code 代码
103
+ */
104
+ addCode(code) {
105
+ this.jsCode += code;
106
+ }
107
+ getGrant() {
108
+ let grant = this.meta.grant ?? [];
109
+ if (typeof grant === "string") {
110
+ grant = [grant];
111
+ }
112
+ return grant;
113
+ }
114
+ getExternalResources() {
115
+ const externalResources = Array.from(
116
+ new Set(Object.values(this.external?.resources ?? {}))
117
+ );
118
+ return externalResources.map((resource) => {
119
+ const md5 = import_crypto.default.createHash("md5").update(resource).digest("hex").substring(0, 8);
120
+ return {
121
+ name: md5,
122
+ url: resource
123
+ };
124
+ });
125
+ }
126
+ buildHeader(isDev = false, filename) {
127
+ const name = isDev ? `${this.meta.name} (Dev)` : this.meta.name;
128
+ const grant = this.getGrant();
129
+ if (this.cssCode.trim().length > 0) {
130
+ grant.push("GM_addStyle");
131
+ }
132
+ if (this.externalResources.length > 0 && !isDev) {
133
+ grant.push("GM_getResourceText");
134
+ }
135
+ const requires = [
136
+ ...this.meta.require ?? [],
137
+ ...isDev ? [] : Object.values(this.external?.modules ?? {}),
138
+ ...filename && isDev ? [filename] : []
139
+ ];
140
+ const resources = [
141
+ ...this.meta.resource ?? [],
142
+ ...isDev && this.externalResources.length > 0 ? [] : this.externalResources.map(
143
+ (resource) => `${resource.name} ${resource.url}`
144
+ )
145
+ ];
146
+ return new TampermonkeyMetaBuilder().add("name", name).add("namespace", this.meta.namespace).add("version", this.meta.version).add("description", this.meta.description).add("author", this.meta.author).add("match", this.meta.match).add("include", this.meta.include).add("grant", this.meta.grant).add("run-at", this.meta.runAt).add("icon", this.meta.icon).add("require", requires).add("resource", resources).addRecord(this.meta.extra).add("license", this.meta.license).add("downloadUrl", this.meta.downloadUrl).add("updateUrl", this.meta.updateUrl).build();
147
+ }
148
+ build(isDev = false) {
149
+ const header = !isDev ? this.buildHeader(isDev) : "";
150
+ if (!isDev) {
151
+ this.externalResources.forEach((resource) => {
152
+ if (resource.url.endsWith(".css")) {
153
+ this.jsCode = 'GM_addStyle(GM_getResourceText("' + resource.name + '"));\n\n' + this.jsCode;
154
+ }
155
+ });
156
+ }
157
+ const code = `${header}
158
+ GM_addStyle(${JSON.stringify(this.cssCode)});
159
+ ${this.jsCode}`;
160
+ return code;
161
+ }
162
+ };
163
+
164
+ // src/resovler.ts
165
+ function resolveMeta(pkg, userMeta) {
166
+ const grants = new Set(userMeta.grant ?? []);
167
+ return {
168
+ name: pkg.name,
169
+ version: pkg.version,
170
+ description: pkg.description,
171
+ author: pkg.author,
172
+ ...userMeta,
173
+ grant: Array.from(grants)
174
+ };
175
+ }
176
+ function createExternalResolver(external) {
177
+ if (!external)
178
+ return {
179
+ isModule: () => false,
180
+ getGlobal: () => "",
181
+ isResource: () => false
182
+ };
183
+ const modules = Object.keys(external.modules ?? {});
184
+ const globals = external.globals ?? {};
185
+ const resources = Object.keys(external.resources ?? {});
186
+ return {
187
+ isModule(id) {
188
+ return modules.some((name) => id === name || id.startsWith(`${name}/`));
189
+ },
190
+ getGlobal(id) {
191
+ return globals[id] ?? id.replace(/[^\w$]/g, "_");
192
+ },
193
+ isResource(id) {
194
+ return resources.some((name) => id.endsWith(name));
195
+ }
196
+ };
197
+ }
198
+
199
+ // src/index.ts
200
+ var DEFAULT_META = {
201
+ namespace: "https://github.com/",
202
+ runAt: "document-idle",
203
+ grant: []
204
+ };
205
+ var DEFAULT_PKG_NAME = "userscript";
206
+ function tampermonkeyPlugin(options = {}) {
207
+ const {
208
+ root = process.cwd(),
209
+ entry = "src/main.tsx",
210
+ packageJson = (0, import_node_path.resolve)(root, "package.json"),
211
+ meta: userMeta = {}
212
+ } = options;
213
+ const pkg = JSON.parse((0, import_node_fs.readFileSync)(packageJson, "utf8"));
214
+ const pkgName = pkg.name || DEFAULT_PKG_NAME;
215
+ const baseName = pkgName.replace(/^@/, "").replace(/\//g, "-");
216
+ const externalResolver = createExternalResolver(options.external);
217
+ const meta = resolveMeta(pkg, { ...DEFAULT_META, ...userMeta });
218
+ const builder = new TampermonkeyBuilder(meta, options.external);
219
+ let isDev = false;
220
+ const fileName = `user.js`;
221
+ let outDirAbs = "";
222
+ return {
223
+ name: "vite-tampermonkey-plugin",
224
+ enforce: "post",
225
+ apply: "build",
226
+ /**
227
+ * 配置
228
+ * @param mode 模式
229
+ * @returns 配置
230
+ */
231
+ config({ mode }) {
232
+ isDev = mode === "development";
233
+ return {
234
+ publicDir: false,
235
+ build: {
236
+ lib: {
237
+ entry: (0, import_node_path.resolve)(root, entry),
238
+ name: baseName.replace(/-/g, "_"),
239
+ fileName: () => fileName,
240
+ formats: ["iife"]
241
+ },
242
+ minify: false,
243
+ cssMinify: true,
244
+ sourcemap: false,
245
+ emptyOutDir: true,
246
+ cssCodeSplit: false,
247
+ rolldownOptions: isDev ? void 0 : {
248
+ external: externalResolver.isModule,
249
+ output: {
250
+ globals: externalResolver.getGlobal,
251
+ comments: false
252
+ }
253
+ }
254
+ },
255
+ define: {
256
+ "process.env.NODE_ENV": JSON.stringify(mode)
257
+ }
258
+ };
259
+ },
260
+ configResolved(config) {
261
+ outDirAbs = (0, import_node_path.resolve)(root, config.build.outDir);
262
+ },
263
+ /**
264
+ * 拦截外部资源,防止写入到输出文件,之后自定义代码注入到用户脚本中.
265
+ * @param code
266
+ * @param id
267
+ */
268
+ load(id) {
269
+ if (externalResolver.isResource(id) && !isDev) {
270
+ return {
271
+ code: "",
272
+ map: null
273
+ };
274
+ }
275
+ return null;
276
+ },
277
+ /**
278
+ * 生成打包
279
+ * @param _options 选项
280
+ * @param bundle 打包
281
+ */
282
+ generateBundle(_, bundle) {
283
+ for (const key of Object.keys(bundle)) {
284
+ const file = bundle[key];
285
+ if (file.type === "asset" && file.fileName.endsWith(".css")) {
286
+ builder.addCss(file.source);
287
+ delete bundle[key];
288
+ }
289
+ }
290
+ for (const key of Object.keys(bundle)) {
291
+ const file = bundle[key];
292
+ if (file.type !== "chunk" || !file.isEntry) continue;
293
+ builder.addCode(file.code);
294
+ if (isDev) {
295
+ const fileUrl = (0, import_node_url.pathToFileURL)((0, import_node_path.resolve)(outDirAbs, fileName)).href;
296
+ const header = builder.buildHeader(isDev, fileUrl);
297
+ this.emitFile({
298
+ type: "asset",
299
+ fileName: `user.dev.js`,
300
+ source: header
301
+ });
302
+ }
303
+ file.code = builder.build(isDev);
304
+ this.emitFile({
305
+ type: "asset",
306
+ fileName: `meta.json`,
307
+ source: JSON.stringify(meta, null, 2)
308
+ });
309
+ }
310
+ }
311
+ };
312
+ }
313
+ // Annotate the CommonJS export names for ESM import in node:
314
+ 0 && (module.exports = {
315
+ tampermonkeyPlugin
316
+ });
@@ -1,7 +1,9 @@
1
+ import { Plugin } from 'vite';
2
+
1
3
  /**
2
4
  * 油猴元数据
3
5
  */
4
- export type TampermonkeyMeta = {
6
+ type TampermonkeyMeta = {
5
7
  name?: string;
6
8
  namespace?: string;
7
9
  version?: string;
@@ -28,7 +30,7 @@ export type TampermonkeyMeta = {
28
30
  /**
29
31
  * 外部资源
30
32
  */
31
- export type ExternalResource = {
33
+ type ExternalResource = {
32
34
  /** 外部资源(JS/CSS 等),用于生成 @require/@resource */
33
35
  resources?: Record<string, string>;
34
36
  /** 外部模块(用于 rolldown external + @require) */
@@ -39,7 +41,7 @@ export type ExternalResource = {
39
41
  /**
40
42
  * 油猴插件选项
41
43
  */
42
- export type TampermonkeyPluginOptions = {
44
+ type TampermonkeyPluginOptions = {
43
45
  /** 用户脚本入口,默认 `src/userscript.tsx`(相对 root) */
44
46
  entry?: string;
45
47
  /** 工程根目录,默认 `process.cwd()` */
@@ -51,13 +53,10 @@ export type TampermonkeyPluginOptions = {
51
53
  /** 外部资源 */
52
54
  external?: ExternalResource;
53
55
  };
56
+
54
57
  /**
55
- * package.json需要包含的字段
58
+ * 油猴插件
56
59
  */
57
- export type PackageJson = {
58
- name: string;
59
- version: string;
60
- description?: string;
61
- author?: string;
62
- };
63
- //# sourceMappingURL=types.d.ts.map
60
+ declare function tampermonkeyPlugin(options?: TampermonkeyPluginOptions): Plugin;
61
+
62
+ export { tampermonkeyPlugin };
package/dist/index.d.ts CHANGED
@@ -1,7 +1,62 @@
1
- import type { Plugin } from 'vite';
2
- import type { TampermonkeyPluginOptions } from './types';
1
+ import { Plugin } from 'vite';
2
+
3
+ /**
4
+ * 油猴元数据
5
+ */
6
+ type TampermonkeyMeta = {
7
+ name?: string;
8
+ namespace?: string;
9
+ version?: string;
10
+ description?: string;
11
+ author?: string;
12
+ /** 单条或多条 @match */
13
+ match?: string | string[];
14
+ /** 单条或多条 @include */
15
+ include?: string | string[];
16
+ /** 单条或多条 @grant */
17
+ grant?: string | string[];
18
+ runAt?: 'document-start' | 'document-end' | 'document-idle';
19
+ icon?: string;
20
+ exclude?: string | string[];
21
+ require?: string | string[];
22
+ connect?: string | string[];
23
+ resource?: string | string[];
24
+ /** 其它 // @key value,如 { noframes: '' } -> // @noframes */
25
+ extra?: Record<string, string | string[] | true>;
26
+ license?: string;
27
+ downloadUrl?: string;
28
+ updateUrl?: string;
29
+ };
30
+ /**
31
+ * 外部资源
32
+ */
33
+ type ExternalResource = {
34
+ /** 外部资源(JS/CSS 等),用于生成 @require/@resource */
35
+ resources?: Record<string, string>;
36
+ /** 外部模块(用于 rolldown external + @require) */
37
+ modules?: Record<string, string>;
38
+ /** 外部全局变量映射 */
39
+ globals?: Record<string, string>;
40
+ };
41
+ /**
42
+ * 油猴插件选项
43
+ */
44
+ type TampermonkeyPluginOptions = {
45
+ /** 用户脚本入口,默认 `src/userscript.tsx`(相对 root) */
46
+ entry?: string;
47
+ /** 工程根目录,默认 `process.cwd()` */
48
+ root?: string;
49
+ /** package.json 路径,默认 `<root>/package.json` */
50
+ packageJson?: string;
51
+ /** 覆盖 / 补充 UserScript 元数据 */
52
+ meta?: TampermonkeyMeta;
53
+ /** 外部资源 */
54
+ external?: ExternalResource;
55
+ };
56
+
3
57
  /**
4
58
  * 油猴插件
5
59
  */
6
- export declare function tampermonkeyPlugin(options?: TampermonkeyPluginOptions): Plugin;
7
- //# sourceMappingURL=index.d.ts.map
60
+ declare function tampermonkeyPlugin(options?: TampermonkeyPluginOptions): Plugin;
61
+
62
+ export { tampermonkeyPlugin };
package/dist/index.js CHANGED
@@ -1,124 +1,281 @@
1
- import { readFileSync } from 'node:fs';
2
- import { resolve } from 'node:path';
3
- import { pathToFileURL } from 'node:url';
4
- import { TampermonkeyBuilder } from './builder';
5
- import { createExternalResolver, resolveMeta } from './resovler';
6
- const DEFAULT_META = {
7
- namespace: 'https://github.com/',
8
- runAt: 'document-idle',
9
- grant: [],
1
+ // src/index.ts
2
+ import { readFileSync } from "fs";
3
+ import { resolve } from "path";
4
+ import { pathToFileURL } from "url";
5
+
6
+ // src/builder.ts
7
+ import crypto from "crypto";
8
+ import fs from "fs";
9
+ var TampermonkeyMetaBuilder = class {
10
+ lines = ["// ==UserScript=="];
11
+ add(key, value) {
12
+ if (value == null) return this;
13
+ if (key === "icon") {
14
+ if (typeof value === "string" && !value.startsWith("http")) {
15
+ const iconBase64 = fs.readFileSync(value, "base64");
16
+ value = `data:image/png;base64,${iconBase64}`;
17
+ }
18
+ }
19
+ if (Array.isArray(value)) {
20
+ const set = new Set(value);
21
+ set.forEach((v) => this.push(key, v));
22
+ } else {
23
+ this.push(key, value === true ? "" : String(value));
24
+ }
25
+ return this;
26
+ }
27
+ addRecord(record) {
28
+ if (!record) return this;
29
+ for (const [k, v] of Object.entries(record)) {
30
+ const key = k.replace(/([A-Z])/g, "-$1").toLowerCase();
31
+ if (Array.isArray(v)) {
32
+ v.forEach((val) => this.push(key, String(val)));
33
+ } else {
34
+ this.push(key, v === true ? "" : String(v));
35
+ }
36
+ }
37
+ return this;
38
+ }
39
+ push(key, value) {
40
+ const spacing = " ".repeat(Math.max(1, 12 - key.length));
41
+ this.lines.push(`// @${key}${spacing}${value}`.trimEnd());
42
+ }
43
+ build() {
44
+ return [...this.lines, "// ==/UserScript==", ""].join("\n");
45
+ }
10
46
  };
11
- const DEFAULT_PKG_NAME = 'userscript';
12
- /**
13
- * 油猴插件
14
- */
15
- export function tampermonkeyPlugin(options = {}) {
16
- const { root = process.cwd(), entry = 'src/main.tsx', packageJson = resolve(root, 'package.json'), meta: userMeta = {}, } = options;
17
- // 解析package.json
18
- const pkg = JSON.parse(readFileSync(packageJson, 'utf8'));
19
- const pkgName = pkg.name || DEFAULT_PKG_NAME;
20
- const baseName = pkgName.replace(/^@/, '').replace(/\//g, '-');
21
- // 预处理外部资源
22
- const externalResolver = createExternalResolver(options.external);
23
- const meta = resolveMeta(pkg, { ...DEFAULT_META, ...userMeta });
24
- // 创建构建器
25
- const builder = new TampermonkeyBuilder(meta, options.external);
26
- let isDev = false;
27
- const fileName = `user.js`;
28
- let outDirAbs = '';
47
+ var TampermonkeyBuilder = class {
48
+ cssCode = "";
49
+ jsCode = "";
50
+ meta = {};
51
+ external;
52
+ externalResources = [];
53
+ constructor(meta, external) {
54
+ this.meta = meta;
55
+ this.external = external;
56
+ this.externalResources = this.getExternalResources();
57
+ this.addCode("var global = window;\n");
58
+ }
59
+ /**
60
+ * 添加CSS代码
61
+ * @param source 源码
62
+ */
63
+ addCss(source) {
64
+ this.cssCode += typeof source === "string" ? source : Buffer.from(source).toString("utf8");
65
+ }
66
+ /**
67
+ * 添加JS代码
68
+ * @param code 代码
69
+ */
70
+ addCode(code) {
71
+ this.jsCode += code;
72
+ }
73
+ getGrant() {
74
+ let grant = this.meta.grant ?? [];
75
+ if (typeof grant === "string") {
76
+ grant = [grant];
77
+ }
78
+ return grant;
79
+ }
80
+ getExternalResources() {
81
+ const externalResources = Array.from(
82
+ new Set(Object.values(this.external?.resources ?? {}))
83
+ );
84
+ return externalResources.map((resource) => {
85
+ const md5 = crypto.createHash("md5").update(resource).digest("hex").substring(0, 8);
86
+ return {
87
+ name: md5,
88
+ url: resource
89
+ };
90
+ });
91
+ }
92
+ buildHeader(isDev = false, filename) {
93
+ const name = isDev ? `${this.meta.name} (Dev)` : this.meta.name;
94
+ const grant = this.getGrant();
95
+ if (this.cssCode.trim().length > 0) {
96
+ grant.push("GM_addStyle");
97
+ }
98
+ if (this.externalResources.length > 0 && !isDev) {
99
+ grant.push("GM_getResourceText");
100
+ }
101
+ const requires = [
102
+ ...this.meta.require ?? [],
103
+ ...isDev ? [] : Object.values(this.external?.modules ?? {}),
104
+ ...filename && isDev ? [filename] : []
105
+ ];
106
+ const resources = [
107
+ ...this.meta.resource ?? [],
108
+ ...isDev && this.externalResources.length > 0 ? [] : this.externalResources.map(
109
+ (resource) => `${resource.name} ${resource.url}`
110
+ )
111
+ ];
112
+ return new TampermonkeyMetaBuilder().add("name", name).add("namespace", this.meta.namespace).add("version", this.meta.version).add("description", this.meta.description).add("author", this.meta.author).add("match", this.meta.match).add("include", this.meta.include).add("grant", this.meta.grant).add("run-at", this.meta.runAt).add("icon", this.meta.icon).add("require", requires).add("resource", resources).addRecord(this.meta.extra).add("license", this.meta.license).add("downloadUrl", this.meta.downloadUrl).add("updateUrl", this.meta.updateUrl).build();
113
+ }
114
+ build(isDev = false) {
115
+ const header = !isDev ? this.buildHeader(isDev) : "";
116
+ if (!isDev) {
117
+ this.externalResources.forEach((resource) => {
118
+ if (resource.url.endsWith(".css")) {
119
+ this.jsCode = 'GM_addStyle(GM_getResourceText("' + resource.name + '"));\n\n' + this.jsCode;
120
+ }
121
+ });
122
+ }
123
+ const code = `${header}
124
+ GM_addStyle(${JSON.stringify(this.cssCode)});
125
+ ${this.jsCode}`;
126
+ return code;
127
+ }
128
+ };
129
+
130
+ // src/resovler.ts
131
+ function resolveMeta(pkg, userMeta) {
132
+ const grants = new Set(userMeta.grant ?? []);
133
+ return {
134
+ name: pkg.name,
135
+ version: pkg.version,
136
+ description: pkg.description,
137
+ author: pkg.author,
138
+ ...userMeta,
139
+ grant: Array.from(grants)
140
+ };
141
+ }
142
+ function createExternalResolver(external) {
143
+ if (!external)
29
144
  return {
30
- name: 'vite-tampermonkey-plugin',
31
- enforce: 'post',
32
- apply: 'build',
33
- /**
34
- * 配置
35
- * @param mode 模式
36
- * @returns 配置
37
- */
38
- config({ mode }) {
39
- isDev = mode === 'development';
40
- return {
41
- publicDir: false,
42
- build: {
43
- lib: {
44
- entry: resolve(root, entry),
45
- name: baseName.replace(/-/g, '_'),
46
- fileName: () => fileName,
47
- formats: ['iife'],
48
- },
49
- minify: false,
50
- cssMinify: true,
51
- sourcemap: false,
52
- emptyOutDir: true,
53
- cssCodeSplit: false,
54
- rolldownOptions: isDev ? undefined : {
55
- external: externalResolver.isModule,
56
- output: {
57
- globals: externalResolver.getGlobal,
58
- comments: false,
59
- },
60
- },
61
- },
62
- define: {
63
- 'process.env.NODE_ENV': JSON.stringify(mode),
64
- },
65
- };
66
- },
67
- configResolved(config) {
68
- outDirAbs = resolve(root, config.build.outDir);
69
- },
70
- /**
71
- * 拦截外部资源,防止写入到输出文件,之后自定义代码注入到用户脚本中.
72
- * @param code
73
- * @param id
74
- */
75
- load(id) {
76
- if (externalResolver.isResource(id) && !isDev) {
77
- return {
78
- code: '',
79
- map: null,
80
- };
81
- }
82
- return null;
83
- },
84
- /**
85
- * 生成打包
86
- * @param _options 选项
87
- * @param bundle 打包
88
- */
89
- generateBundle(_, bundle) {
90
- // 先处理一次css代码
91
- for (const key of Object.keys(bundle)) {
92
- const file = bundle[key];
93
- if (file.type === 'asset' && file.fileName.endsWith('.css')) {
94
- builder.addCss(file.source);
95
- delete bundle[key];
96
- }
97
- }
98
- // 再处理js代码
99
- for (const key of Object.keys(bundle)) {
100
- const file = bundle[key];
101
- // 不是入口文件或者不是chunk,跳过
102
- if (file.type !== 'chunk' || !file.isEntry)
103
- continue;
104
- builder.addCode(file.code);
105
- if (isDev) {
106
- const fileUrl = pathToFileURL(resolve(outDirAbs, fileName)).href;
107
- const header = builder.buildHeader(isDev, fileUrl);
108
- this.emitFile({
109
- type: 'asset',
110
- fileName: `user.dev.js`,
111
- source: header,
112
- });
113
- }
114
- file.code = builder.build(isDev);
115
- // 产生一个meta.json文件
116
- this.emitFile({
117
- type: 'asset',
118
- fileName: `meta.json`,
119
- source: JSON.stringify(meta, null, 2),
120
- });
145
+ isModule: () => false,
146
+ getGlobal: () => "",
147
+ isResource: () => false
148
+ };
149
+ const modules = Object.keys(external.modules ?? {});
150
+ const globals = external.globals ?? {};
151
+ const resources = Object.keys(external.resources ?? {});
152
+ return {
153
+ isModule(id) {
154
+ return modules.some((name) => id === name || id.startsWith(`${name}/`));
155
+ },
156
+ getGlobal(id) {
157
+ return globals[id] ?? id.replace(/[^\w$]/g, "_");
158
+ },
159
+ isResource(id) {
160
+ return resources.some((name) => id.endsWith(name));
161
+ }
162
+ };
163
+ }
164
+
165
+ // src/index.ts
166
+ var DEFAULT_META = {
167
+ namespace: "https://github.com/",
168
+ runAt: "document-idle",
169
+ grant: []
170
+ };
171
+ var DEFAULT_PKG_NAME = "userscript";
172
+ function tampermonkeyPlugin(options = {}) {
173
+ const {
174
+ root = process.cwd(),
175
+ entry = "src/main.tsx",
176
+ packageJson = resolve(root, "package.json"),
177
+ meta: userMeta = {}
178
+ } = options;
179
+ const pkg = JSON.parse(readFileSync(packageJson, "utf8"));
180
+ const pkgName = pkg.name || DEFAULT_PKG_NAME;
181
+ const baseName = pkgName.replace(/^@/, "").replace(/\//g, "-");
182
+ const externalResolver = createExternalResolver(options.external);
183
+ const meta = resolveMeta(pkg, { ...DEFAULT_META, ...userMeta });
184
+ const builder = new TampermonkeyBuilder(meta, options.external);
185
+ let isDev = false;
186
+ const fileName = `user.js`;
187
+ let outDirAbs = "";
188
+ return {
189
+ name: "vite-tampermonkey-plugin",
190
+ enforce: "post",
191
+ apply: "build",
192
+ /**
193
+ * 配置
194
+ * @param mode 模式
195
+ * @returns 配置
196
+ */
197
+ config({ mode }) {
198
+ isDev = mode === "development";
199
+ return {
200
+ publicDir: false,
201
+ build: {
202
+ lib: {
203
+ entry: resolve(root, entry),
204
+ name: baseName.replace(/-/g, "_"),
205
+ fileName: () => fileName,
206
+ formats: ["iife"]
207
+ },
208
+ minify: false,
209
+ cssMinify: true,
210
+ sourcemap: false,
211
+ emptyOutDir: true,
212
+ cssCodeSplit: false,
213
+ rolldownOptions: isDev ? void 0 : {
214
+ external: externalResolver.isModule,
215
+ output: {
216
+ globals: externalResolver.getGlobal,
217
+ comments: false
121
218
  }
219
+ }
122
220
  },
123
- };
221
+ define: {
222
+ "process.env.NODE_ENV": JSON.stringify(mode)
223
+ }
224
+ };
225
+ },
226
+ configResolved(config) {
227
+ outDirAbs = resolve(root, config.build.outDir);
228
+ },
229
+ /**
230
+ * 拦截外部资源,防止写入到输出文件,之后自定义代码注入到用户脚本中.
231
+ * @param code
232
+ * @param id
233
+ */
234
+ load(id) {
235
+ if (externalResolver.isResource(id) && !isDev) {
236
+ return {
237
+ code: "",
238
+ map: null
239
+ };
240
+ }
241
+ return null;
242
+ },
243
+ /**
244
+ * 生成打包
245
+ * @param _options 选项
246
+ * @param bundle 打包
247
+ */
248
+ generateBundle(_, bundle) {
249
+ for (const key of Object.keys(bundle)) {
250
+ const file = bundle[key];
251
+ if (file.type === "asset" && file.fileName.endsWith(".css")) {
252
+ builder.addCss(file.source);
253
+ delete bundle[key];
254
+ }
255
+ }
256
+ for (const key of Object.keys(bundle)) {
257
+ const file = bundle[key];
258
+ if (file.type !== "chunk" || !file.isEntry) continue;
259
+ builder.addCode(file.code);
260
+ if (isDev) {
261
+ const fileUrl = pathToFileURL(resolve(outDirAbs, fileName)).href;
262
+ const header = builder.buildHeader(isDev, fileUrl);
263
+ this.emitFile({
264
+ type: "asset",
265
+ fileName: `user.dev.js`,
266
+ source: header
267
+ });
268
+ }
269
+ file.code = builder.build(isDev);
270
+ this.emitFile({
271
+ type: "asset",
272
+ fileName: `meta.json`,
273
+ source: JSON.stringify(meta, null, 2)
274
+ });
275
+ }
276
+ }
277
+ };
124
278
  }
279
+ export {
280
+ tampermonkeyPlugin
281
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vite-tampermonkey",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "Vite plugin for Tampermonkey / userscript builds",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -13,26 +13,21 @@
13
13
  }
14
14
  },
15
15
  "files": [
16
- "dist"
16
+ "dist",
17
+ "LICENSE"
17
18
  ],
18
19
  "scripts": {
19
- "build": "tsc -p tsconfig.json",
20
- "prepublishOnly": "npm run build",
21
- "test": "echo \"Error: no test specified\" && exit 1"
20
+ "build": "tsup src/index.ts --format esm,cjs --dts --clean",
21
+ "prepublishOnly": "npm run build"
22
22
  },
23
- "keywords": [
24
- "vite",
25
- "vite-plugin",
26
- "tampermonkey",
27
- "userscript"
28
- ],
29
- "author": "koyori",
30
- "license": "MIT",
31
23
  "peerDependencies": {
32
24
  "vite": "^8.0.0"
33
25
  },
26
+ "license": "MIT",
27
+ "author": "koyori",
34
28
  "devDependencies": {
35
29
  "@types/node": "^22.10.0",
30
+ "tsup": "^8.5.1",
36
31
  "typescript": "^5.7.0",
37
32
  "vite": "^8.0.0"
38
33
  }
package/dist/builder.d.ts DELETED
@@ -1,34 +0,0 @@
1
- import type { ExternalResource, TampermonkeyMeta } from './types';
2
- /**
3
- * 元数据构造器
4
- */
5
- export declare class TampermonkeyMetaBuilder {
6
- private lines;
7
- add(key: string, value?: string | string[] | boolean): this;
8
- addRecord(record?: Record<string, string | string[] | true>): this;
9
- private push;
10
- build(): string;
11
- }
12
- export declare class TampermonkeyBuilder {
13
- private cssCode;
14
- private jsCode;
15
- private meta;
16
- private external?;
17
- private externalResources;
18
- constructor(meta: TampermonkeyMeta, external?: ExternalResource);
19
- /**
20
- * 添加CSS代码
21
- * @param source 源码
22
- */
23
- addCss(source: any): void;
24
- /**
25
- * 添加JS代码
26
- * @param code 代码
27
- */
28
- addCode(code: string): void;
29
- private getGrant;
30
- private getExternalResources;
31
- buildHeader(isDev?: boolean, filename?: string): string;
32
- build(isDev?: boolean): string;
33
- }
34
- //# sourceMappingURL=builder.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"builder.d.ts","sourceRoot":"","sources":["../src/builder.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAClE;;GAEG;AACH,qBAAa,uBAAuB;IAClC,OAAO,CAAC,KAAK,CAAmC;IAEhD,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,OAAO;IAqBpD,SAAS,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,CAAC;IAgB3D,OAAO,CAAC,IAAI;IAKZ,KAAK;CAIN;AAOD,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,OAAO,CAAc;IAC7B,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,IAAI,CAAwB;IACpC,OAAO,CAAC,QAAQ,CAAC,CAAmB;IACpC,OAAO,CAAC,iBAAiB,CAA2B;gBAExC,IAAI,EAAE,gBAAgB,EAAE,QAAQ,CAAC,EAAE,gBAAgB;IAM/D;;;OAGG;IACH,MAAM,CAAC,MAAM,EAAE,GAAG;IAOlB;;;OAGG;IACH,OAAO,CAAC,IAAI,EAAE,MAAM;IAIpB,OAAO,CAAC,QAAQ;IAQhB,OAAO,CAAC,oBAAoB;IAkB5B,WAAW,CAAC,KAAK,GAAE,OAAe,EAAE,QAAQ,CAAC,EAAE,MAAM;IAgDrD,KAAK,CAAC,KAAK,GAAE,OAAe;CAkB7B"}
package/dist/builder.js DELETED
@@ -1,156 +0,0 @@
1
- import crypto from 'crypto';
2
- import fs from 'fs';
3
- /**
4
- * 元数据构造器
5
- */
6
- export class TampermonkeyMetaBuilder {
7
- lines = ['// ==UserScript=='];
8
- add(key, value) {
9
- if (value == null)
10
- return this;
11
- if (key === 'icon') {
12
- // 判断是否是本地文件
13
- if (typeof value === 'string' && !value.startsWith('http')) {
14
- const iconBase64 = fs.readFileSync(value, 'base64');
15
- value = `data:image/png;base64,${iconBase64}`;
16
- }
17
- }
18
- if (Array.isArray(value)) {
19
- const set = new Set(value);
20
- set.forEach((v) => this.push(key, v));
21
- }
22
- else {
23
- this.push(key, value === true ? '' : String(value));
24
- }
25
- return this;
26
- }
27
- addRecord(record) {
28
- if (!record)
29
- return this;
30
- for (const [k, v] of Object.entries(record)) {
31
- const key = k.replace(/([A-Z])/g, '-$1').toLowerCase();
32
- if (Array.isArray(v)) {
33
- v.forEach((val) => this.push(key, String(val)));
34
- }
35
- else {
36
- this.push(key, v === true ? '' : String(v));
37
- }
38
- }
39
- return this;
40
- }
41
- push(key, value) {
42
- const spacing = ' '.repeat(Math.max(1, 12 - key.length));
43
- this.lines.push(`// @${key}${spacing}${value}`.trimEnd());
44
- }
45
- build() {
46
- return [...this.lines, '// ==/UserScript==', ''].join('\n');
47
- }
48
- }
49
- export class TampermonkeyBuilder {
50
- cssCode = '';
51
- jsCode = '';
52
- meta = {};
53
- external;
54
- externalResources = [];
55
- constructor(meta, external) {
56
- this.meta = meta;
57
- this.external = external;
58
- this.externalResources = this.getExternalResources();
59
- this.addCode('var global = window;\n');
60
- }
61
- /**
62
- * 添加CSS代码
63
- * @param source 源码
64
- */
65
- addCss(source) {
66
- this.cssCode +=
67
- typeof source === 'string'
68
- ? source
69
- : Buffer.from(source).toString('utf8');
70
- }
71
- /**
72
- * 添加JS代码
73
- * @param code 代码
74
- */
75
- addCode(code) {
76
- this.jsCode += code;
77
- }
78
- getGrant() {
79
- let grant = this.meta.grant ?? [];
80
- if (typeof grant === 'string') {
81
- grant = [grant];
82
- }
83
- return grant;
84
- }
85
- getExternalResources() {
86
- const externalResources = Array.from(new Set(Object.values(this.external?.resources ?? {})));
87
- return externalResources.map((resource) => {
88
- // md5(resource)
89
- const md5 = crypto
90
- .createHash('md5')
91
- .update(resource)
92
- .digest('hex')
93
- .substring(0, 8);
94
- return {
95
- name: md5,
96
- url: resource,
97
- };
98
- });
99
- }
100
- buildHeader(isDev = false, filename) {
101
- const name = isDev ? `${this.meta.name} (Dev)` : this.meta.name;
102
- const grant = this.getGrant();
103
- if (this.cssCode.trim().length > 0) {
104
- grant.push('GM_addStyle');
105
- }
106
- if (this.externalResources.length > 0 && !isDev) {
107
- grant.push('GM_getResourceText');
108
- }
109
- const requires = [
110
- ...(this.meta.require ?? []),
111
- ...(isDev ? [] : Object.values(this.external?.modules ?? {})),
112
- ...(filename && isDev ? [filename] : []),
113
- ];
114
- // 处理外部资源
115
- const resources = [
116
- ...(this.meta.resource ?? []),
117
- ...(isDev && this.externalResources.length > 0
118
- ? []
119
- : this.externalResources.map((resource) => `${resource.name} ${resource.url}`)),
120
- ];
121
- return new TampermonkeyMetaBuilder()
122
- .add('name', name)
123
- .add('namespace', this.meta.namespace)
124
- .add('version', this.meta.version)
125
- .add('description', this.meta.description)
126
- .add('author', this.meta.author)
127
- .add('match', this.meta.match)
128
- .add('include', this.meta.include)
129
- .add('grant', this.meta.grant)
130
- .add('run-at', this.meta.runAt)
131
- .add('icon', this.meta.icon)
132
- .add('require', requires)
133
- .add('resource', resources)
134
- .addRecord(this.meta.extra)
135
- .add('license', this.meta.license)
136
- .add('downloadUrl', this.meta.downloadUrl)
137
- .add('updateUrl', this.meta.updateUrl)
138
- .build();
139
- }
140
- build(isDev = false) {
141
- const header = !isDev ? this.buildHeader(isDev) : '';
142
- if (!isDev) {
143
- this.externalResources.forEach((resource) => {
144
- if (resource.url.endsWith('.css')) {
145
- this.jsCode =
146
- 'GM_addStyle(GM_getResourceText("' +
147
- resource.name +
148
- '"));\n\n' +
149
- this.jsCode;
150
- }
151
- });
152
- }
153
- const code = `${header}\nGM_addStyle(${JSON.stringify(this.cssCode)});\n${this.jsCode}`;
154
- return code;
155
- }
156
- }
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAGnC,OAAO,KAAK,EAAoB,yBAAyB,EAAE,MAAM,SAAS,CAAC;AAU3E;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,GAAE,yBAA8B,GACtC,MAAM,CA8HR"}
@@ -1,20 +0,0 @@
1
- import type { ExternalResource, PackageJson, TampermonkeyMeta } from './types';
2
- /**
3
- * 解析元数据
4
- * @param pkg package.json
5
- * @param userMeta 用户元数据
6
- * @returns 元数据
7
- */
8
- export declare function resolveMeta(pkg: PackageJson, userMeta: TampermonkeyMeta): TampermonkeyMeta;
9
- /**
10
- * 创建外部资源解析器
11
- * @param externals 外部资源
12
- * @param globals 全局变量
13
- * @returns 外部资源解析器
14
- */
15
- export declare function createExternalResolver(external?: ExternalResource): {
16
- isModule(id: string): boolean;
17
- getGlobal(id: string): string;
18
- isResource(id: string): boolean;
19
- };
20
- //# sourceMappingURL=resovler.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"resovler.d.ts","sourceRoot":"","sources":["../src/resovler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAC/E;;;;;GAKG;AACH,wBAAgB,WAAW,CACzB,GAAG,EAAE,WAAW,EAChB,QAAQ,EAAE,gBAAgB,GACzB,gBAAgB,CAWlB;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,CAAC,EAAE,gBAAgB;iBAajD,MAAM;kBAIL,MAAM;mBAGL,MAAM;EAIxB"}
package/dist/resovler.js DELETED
@@ -1,45 +0,0 @@
1
- /**
2
- * 解析元数据
3
- * @param pkg package.json
4
- * @param userMeta 用户元数据
5
- * @returns 元数据
6
- */
7
- export function resolveMeta(pkg, userMeta) {
8
- const grants = new Set(userMeta.grant ?? []);
9
- return {
10
- name: pkg.name,
11
- version: pkg.version,
12
- description: pkg.description,
13
- author: pkg.author,
14
- ...userMeta,
15
- grant: Array.from(grants),
16
- };
17
- }
18
- /**
19
- * 创建外部资源解析器
20
- * @param externals 外部资源
21
- * @param globals 全局变量
22
- * @returns 外部资源解析器
23
- */
24
- export function createExternalResolver(external) {
25
- if (!external)
26
- return {
27
- isModule: () => false,
28
- getGlobal: () => '',
29
- isResource: () => false,
30
- };
31
- const modules = Object.keys(external.modules ?? {});
32
- const globals = external.globals ?? {};
33
- const resources = Object.keys(external.resources ?? {});
34
- return {
35
- isModule(id) {
36
- return modules.some((name) => id === name || id.startsWith(`${name}/`));
37
- },
38
- getGlobal(id) {
39
- return globals[id] ?? id.replace(/[^\w$]/g, '_');
40
- },
41
- isResource(id) {
42
- return resources.some((name) => id.endsWith(name));
43
- },
44
- };
45
- }
@@ -1 +0,0 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC7B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,mBAAmB;IACnB,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC1B,qBAAqB;IACrB,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC5B,mBAAmB;IACnB,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC1B,KAAK,CAAC,EAAE,gBAAgB,GAAG,cAAc,GAAG,eAAe,CAAC;IAC5D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC5B,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC5B,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC5B,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC7B,0DAA0D;IAC1D,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,CAAC,CAAC;IACjD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC7B,6CAA6C;IAC7C,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,4CAA4C;IAC5C,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,eAAe;IACf,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,yBAAyB,GAAG;IACtC,8CAA8C;IAC9C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,+BAA+B;IAC/B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,+CAA+C;IAC/C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,6BAA6B;IAC7B,IAAI,CAAC,EAAE,gBAAgB,CAAC;IACxB,WAAW;IACX,QAAQ,CAAC,EAAE,gBAAgB,CAAC;CAC7B,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC"}
package/dist/types.js DELETED
@@ -1 +0,0 @@
1
- export {};