@evjs/webpack-plugin 0.0.1-alpha.6 → 0.0.1-alpha.7
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 +51 -16
- package/esm/index.d.ts +7 -0
- package/esm/index.d.ts.map +1 -1
- package/esm/index.js +13 -20
- package/esm/index.js.map +1 -1
- package/esm/server-fn-loader.d.ts +4 -0
- package/esm/server-fn-loader.d.ts.map +1 -1
- package/esm/server-fn-loader.js +11 -91
- package/esm/server-fn-loader.js.map +1 -1
- package/package.json +3 -4
- package/esm/version.d.ts +0 -2
- package/esm/version.d.ts.map +0 -1
- package/esm/version.js +0 -2
- package/esm/version.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,16 +1,34 @@
|
|
|
1
1
|
# @evjs/webpack-plugin
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Webpack adapter for the **ev** framework. Thin wrapper over [`@evjs/build-tools`](../build-tools) that connects bundler-agnostic build logic to Webpack's plugin and loader APIs.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Installation
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
7
|
+
```bash
|
|
8
|
+
npm install @evjs/webpack-plugin
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Exports
|
|
12
|
+
|
|
13
|
+
| Export | Description |
|
|
14
|
+
|--------|-------------|
|
|
15
|
+
| `EvWebpackPlugin` | Plugin that auto-discovers `"use server"` files and manages server builds |
|
|
16
|
+
| `server-fn-loader` | Loader that transforms `"use server"` files for client/server |
|
|
17
|
+
|
|
18
|
+
## How It Works
|
|
19
|
+
|
|
20
|
+
### EvWebpackPlugin
|
|
21
|
+
|
|
22
|
+
1. **Scans client modules** for `"use server"` files via `detectUseServer()` from build-tools.
|
|
23
|
+
2. **Generates a server entry** via `generateServerEntry()` — produces a virtual data-URI module.
|
|
24
|
+
3. **Spawns a child compiler** targeting Node.js — builds the server bundle alongside the client.
|
|
25
|
+
4. **Emits `manifest.json`** mapping function IDs to their module and export names.
|
|
26
|
+
|
|
27
|
+
### server-fn-loader
|
|
28
|
+
|
|
29
|
+
Auto-detects whether it's running in the client or server compiler and delegates to `transformServerFile()`:
|
|
30
|
+
- **Client compiler** → replaces function bodies with RPC stubs.
|
|
31
|
+
- **Server compiler** → keeps original source, appends registrations, and reports to the manifest.
|
|
14
32
|
|
|
15
33
|
## Usage
|
|
16
34
|
|
|
@@ -19,7 +37,18 @@ const { EvWebpackPlugin } = require("@evjs/webpack-plugin");
|
|
|
19
37
|
|
|
20
38
|
module.exports = {
|
|
21
39
|
plugins: [
|
|
22
|
-
new EvWebpackPlugin(
|
|
40
|
+
new EvWebpackPlugin({
|
|
41
|
+
server: {
|
|
42
|
+
// App factory (default: "@evjs/runtime/server#createApp")
|
|
43
|
+
appFactory: "@evjs/runtime/server#createApp",
|
|
44
|
+
// Runner — bake into bundle for self-starting dev server
|
|
45
|
+
runner: process.env.NODE_ENV === "development"
|
|
46
|
+
? "@evjs/runtime/server#runNodeServer"
|
|
47
|
+
: undefined,
|
|
48
|
+
// Extra imports (middleware, config, etc.)
|
|
49
|
+
setup: [],
|
|
50
|
+
},
|
|
51
|
+
}),
|
|
23
52
|
],
|
|
24
53
|
module: {
|
|
25
54
|
rules: [
|
|
@@ -28,12 +57,18 @@ module.exports = {
|
|
|
28
57
|
exclude: /node_modules/,
|
|
29
58
|
use: [
|
|
30
59
|
{ loader: "swc-loader" },
|
|
31
|
-
{ loader: "@evjs/webpack-plugin/server-fn-loader" }
|
|
32
|
-
]
|
|
33
|
-
}
|
|
34
|
-
]
|
|
35
|
-
}
|
|
60
|
+
{ loader: "@evjs/webpack-plugin/server-fn-loader" },
|
|
61
|
+
],
|
|
62
|
+
},
|
|
63
|
+
],
|
|
64
|
+
},
|
|
36
65
|
};
|
|
37
66
|
```
|
|
38
67
|
|
|
39
|
-
|
|
68
|
+
### Plugin Options
|
|
69
|
+
|
|
70
|
+
| Option | Type | Default | Description |
|
|
71
|
+
|--------|------|---------|-------------|
|
|
72
|
+
| `server.appFactory` | `string` | `"@evjs/runtime/server#createApp"` | Module ref for app factory |
|
|
73
|
+
| `server.runner` | `string?` | `undefined` | Module ref for auto-starting the server |
|
|
74
|
+
| `server.setup` | `string[]` | `[]` | Extra imports to prepend to server entry |
|
package/esm/index.d.ts
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
|
+
import { type ServerEntryConfig } from "@evjs/build-tools";
|
|
1
2
|
import type { Compiler } from "webpack";
|
|
3
|
+
export type { ServerEntryConfig };
|
|
4
|
+
export interface EvWebpackPluginOptions {
|
|
5
|
+
server?: ServerEntryConfig;
|
|
6
|
+
}
|
|
2
7
|
/**
|
|
3
8
|
* Webpack plugin for the ev framework.
|
|
4
9
|
*
|
|
@@ -6,6 +11,8 @@ import type { Compiler } from "webpack";
|
|
|
6
11
|
* and manages the server-side build via a child compiler.
|
|
7
12
|
*/
|
|
8
13
|
export declare class EvWebpackPlugin {
|
|
14
|
+
private options;
|
|
15
|
+
constructor(options?: EvWebpackPluginOptions);
|
|
9
16
|
apply(compiler: Compiler): void;
|
|
10
17
|
}
|
|
11
18
|
//# sourceMappingURL=index.d.ts.map
|
package/esm/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAGL,KAAK,iBAAiB,EACvB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAmBxC,YAAY,EAAE,iBAAiB,EAAE,CAAC;AAElC,MAAM,WAAW,sBAAsB;IACrC,MAAM,CAAC,EAAE,iBAAiB,CAAC;CAC5B;AAED;;;;;GAKG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,OAAO,CAAyB;gBAE5B,OAAO,CAAC,EAAE,sBAAsB;IAG5C,KAAK,CAAC,QAAQ,EAAE,QAAQ;CA8JzB"}
|
package/esm/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
|
+
import { detectUseServer, generateServerEntry, } from "@evjs/build-tools";
|
|
2
3
|
class ManifestCollector {
|
|
3
4
|
serverFns = {};
|
|
4
5
|
addServerFn(id, meta) {
|
|
@@ -18,6 +19,10 @@ class ManifestCollector {
|
|
|
18
19
|
* and manages the server-side build via a child compiler.
|
|
19
20
|
*/
|
|
20
21
|
export class EvWebpackPlugin {
|
|
22
|
+
options;
|
|
23
|
+
constructor(options) {
|
|
24
|
+
this.options = options ?? {};
|
|
25
|
+
}
|
|
21
26
|
apply(compiler) {
|
|
22
27
|
const collector = new ManifestCollector();
|
|
23
28
|
// Attach collector to compiler so the loader can access it
|
|
@@ -28,45 +33,34 @@ export class EvWebpackPlugin {
|
|
|
28
33
|
if (!isServer) {
|
|
29
34
|
// We are in the Client compiler.
|
|
30
35
|
compiler.hooks.make.tapAsync("EvWebpackPlugin", async (compilation, callback) => {
|
|
31
|
-
// In Webpack 5, we can use the finishModules hook to inspect all parsed modules
|
|
32
36
|
compilation.hooks.finishModules.tapAsync("EvWebpackPlugin", (modules, finishCallback) => {
|
|
33
|
-
|
|
34
|
-
const imports = [];
|
|
35
|
-
imports.push(`import { createServer } from "@evjs/runtime/server";`);
|
|
36
|
-
let id = 0;
|
|
37
|
+
const serverModulePaths = [];
|
|
37
38
|
for (const module of modules) {
|
|
38
|
-
// Determine if this is a NormalModule with a resource path
|
|
39
39
|
const resource = "resource" in module ? module.resource : null;
|
|
40
40
|
if (!resource || typeof resource !== "string")
|
|
41
41
|
continue;
|
|
42
|
-
// Ensure it's a source file (not a node_module or internal webpack file)
|
|
43
42
|
if (resource.includes("node_modules") ||
|
|
44
43
|
!/\.(ts|tsx|js|jsx)$/.test(resource)) {
|
|
45
44
|
continue;
|
|
46
45
|
}
|
|
47
46
|
try {
|
|
48
47
|
const content = fs.readFileSync(resource, "utf-8");
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
if (isServerFile) {
|
|
52
|
-
hasServer = true;
|
|
53
|
-
// Compute a relative path from the compiler context (or just use absolute path)
|
|
54
|
-
// But using absolute path avoids relative resolution issues completely.
|
|
55
|
-
imports.push(`import * as _fns_${id++} from ${JSON.stringify(resource)};`);
|
|
48
|
+
if (detectUseServer(content)) {
|
|
49
|
+
serverModulePaths.push(resource);
|
|
56
50
|
}
|
|
57
51
|
}
|
|
58
52
|
catch (_err) {
|
|
59
53
|
// Ignore read errors for dynamically generated Webpack modules
|
|
60
54
|
}
|
|
61
55
|
}
|
|
62
|
-
if (
|
|
56
|
+
if (serverModulePaths.length === 0) {
|
|
63
57
|
return finishCallback();
|
|
64
58
|
}
|
|
65
|
-
|
|
66
|
-
const serverEntryContent =
|
|
59
|
+
// Generate server entry using build-tools (bundler-agnostic)
|
|
60
|
+
const serverEntryContent = generateServerEntry(this.options.server, serverModulePaths);
|
|
67
61
|
// Use a Data URI as a virtual entry point
|
|
68
62
|
const serverEntryPath = `data:text/javascript,${encodeURIComponent(serverEntryContent)}`;
|
|
69
|
-
//
|
|
63
|
+
// Spawn the Node Server child compiler (webpack-specific)
|
|
70
64
|
const outputOptions = {
|
|
71
65
|
filename: "../server/index.js",
|
|
72
66
|
library: { type: "commonjs", name: "evServer" },
|
|
@@ -124,7 +118,7 @@ export class EvWebpackPlugin {
|
|
|
124
118
|
callback();
|
|
125
119
|
});
|
|
126
120
|
}
|
|
127
|
-
// Emit manifest using modern processAssets hook
|
|
121
|
+
// Emit manifest using modern processAssets hook
|
|
128
122
|
compiler.hooks.thisCompilation.tap("EvWebpackPlugin", (compilation) => {
|
|
129
123
|
compilation.hooks.processAssets.tap({
|
|
130
124
|
name: "EvWebpackPlugin",
|
|
@@ -135,7 +129,6 @@ export class EvWebpackPlugin {
|
|
|
135
129
|
return;
|
|
136
130
|
}
|
|
137
131
|
const content = JSON.stringify(manifest, null, 2);
|
|
138
|
-
// We place the manifest in the server folder (relative to parent output dist/client)
|
|
139
132
|
compilation.emitAsset("../server/manifest.json", new compiler.webpack.sources.RawSource(content));
|
|
140
133
|
});
|
|
141
134
|
});
|
package/esm/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -14,6 +14,10 @@ interface LoaderContext {
|
|
|
14
14
|
};
|
|
15
15
|
};
|
|
16
16
|
}
|
|
17
|
+
/**
|
|
18
|
+
* Webpack loader for "use server" files.
|
|
19
|
+
* Thin wrapper that delegates to @evjs/build-tools for the actual transformation.
|
|
20
|
+
*/
|
|
17
21
|
export default function serverFnLoader(this: LoaderContext, source: string): Promise<string>;
|
|
18
22
|
export {};
|
|
19
23
|
//# sourceMappingURL=server-fn-loader.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server-fn-loader.d.ts","sourceRoot":"","sources":["../src/server-fn-loader.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"server-fn-loader.d.ts","sourceRoot":"","sources":["../src/server-fn-loader.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAExC,UAAU,aAAa;IACrB,UAAU,IAAI;QAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IACrC,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,QAAQ,GAAG;QACrB,sBAAsB,CAAC,EAAE;YACvB,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE;gBAAE,QAAQ,EAAE,MAAM,CAAC;gBAAC,MAAM,EAAE,MAAM,CAAA;aAAE,GAAG,IAAI,CAAC;SAC3E,CAAC;KACH,CAAC;CACH;AAED;;;GAGG;AACH,wBAA8B,cAAc,CAC1C,IAAI,EAAE,aAAa,EACnB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,MAAM,CAAC,CAmBjB"}
|
package/esm/server-fn-loader.js
CHANGED
|
@@ -1,28 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { parse } from "@swc/core";
|
|
3
|
-
import path from "node:path";
|
|
1
|
+
import { transformServerFile } from "@evjs/build-tools";
|
|
4
2
|
/**
|
|
5
|
-
*
|
|
3
|
+
* Webpack loader for "use server" files.
|
|
4
|
+
* Thin wrapper that delegates to @evjs/build-tools for the actual transformation.
|
|
6
5
|
*/
|
|
7
|
-
function makeFnId(rootContext, resourcePath, exportName) {
|
|
8
|
-
const relativePath = path.relative(rootContext, resourcePath);
|
|
9
|
-
return createHash("sha256")
|
|
10
|
-
.update(`${relativePath}:${exportName}`)
|
|
11
|
-
.digest("hex")
|
|
12
|
-
.slice(0, 16);
|
|
13
|
-
}
|
|
14
|
-
/**
|
|
15
|
-
* Check whether the source starts with the "use server" directive.
|
|
16
|
-
*/
|
|
17
|
-
function hasUseServerDirective(source) {
|
|
18
|
-
const trimmed = source.replace(/^(\s|\/\/[^\n]*\n|\/\*[\s\S]*?\*\/)*/, "");
|
|
19
|
-
return /^["']use server["'];?\s/.test(trimmed);
|
|
20
|
-
}
|
|
21
6
|
export default async function serverFnLoader(source) {
|
|
22
|
-
if (!hasUseServerDirective(source)) {
|
|
23
|
-
return source;
|
|
24
|
-
}
|
|
25
|
-
// Adaptively check if we are building the server (Child Compiler) or client
|
|
26
7
|
const explicitOptions = this.getOptions() || {};
|
|
27
8
|
let isServer = explicitOptions.isServer;
|
|
28
9
|
if (typeof isServer === "undefined") {
|
|
@@ -30,75 +11,14 @@ export default async function serverFnLoader(source) {
|
|
|
30
11
|
const target = this._compiler?.options?.target;
|
|
31
12
|
isServer = compilerName === "evServer" || target === "node";
|
|
32
13
|
}
|
|
33
|
-
// Parse the source into an AST
|
|
34
|
-
const program = await parse(source, {
|
|
35
|
-
syntax: "typescript",
|
|
36
|
-
tsx: true,
|
|
37
|
-
comments: false,
|
|
38
|
-
script: false,
|
|
39
|
-
});
|
|
40
|
-
const exportNames = [];
|
|
41
|
-
// Iterate through module items to find exports
|
|
42
|
-
for (const item of program.body) {
|
|
43
|
-
if (item.type === "ExportDeclaration") {
|
|
44
|
-
const decl = item.declaration;
|
|
45
|
-
if (decl.type === "FunctionDeclaration") {
|
|
46
|
-
if (decl.identifier.value)
|
|
47
|
-
exportNames.push(decl.identifier.value);
|
|
48
|
-
}
|
|
49
|
-
else if (decl.type === "VariableDeclaration") {
|
|
50
|
-
for (const v of decl.declarations) {
|
|
51
|
-
if (v.id.type === "Identifier") {
|
|
52
|
-
exportNames.push(v.id.value);
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
else if (item.type === "ExportNamedDeclaration") {
|
|
58
|
-
for (const specifier of item.specifiers) {
|
|
59
|
-
if (specifier.type === "ExportSpecifier") {
|
|
60
|
-
if (specifier.exported?.type === "Identifier") {
|
|
61
|
-
exportNames.push(specifier.exported.value);
|
|
62
|
-
}
|
|
63
|
-
else if (specifier.orig.type === "Identifier") {
|
|
64
|
-
exportNames.push(specifier.orig.value);
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
if (exportNames.length === 0) {
|
|
71
|
-
return source;
|
|
72
|
-
}
|
|
73
14
|
const manifestCollector = this._compiler?._ev_manifest_collector;
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
.update(relativePath)
|
|
83
|
-
.digest("hex")
|
|
84
|
-
.slice(0, 16);
|
|
85
|
-
manifestCollector.addServerFn(fnId, {
|
|
86
|
-
moduleId,
|
|
87
|
-
export: name,
|
|
88
|
-
});
|
|
89
|
-
}
|
|
90
|
-
return `registerServerFn("${fnId}", ${name});`;
|
|
91
|
-
})
|
|
92
|
-
.join("\n");
|
|
93
|
-
return `import { registerServerFn } from "@evjs/runtime/server";\n${source}\n${registrations}\n`;
|
|
94
|
-
}
|
|
95
|
-
// Client build: replace with RPC stubs
|
|
96
|
-
const stubCode = exportNames
|
|
97
|
-
.map((name) => {
|
|
98
|
-
const fnId = makeFnId(this.rootContext, this.resourcePath, name);
|
|
99
|
-
return `export function ${name}(...args) {\n return __ev_rpc("${fnId}", args);\n}\n${name}.evId = "${fnId}";`;
|
|
100
|
-
})
|
|
101
|
-
.join("\n\n");
|
|
102
|
-
return `import { __ev_rpc } from "@evjs/runtime/client";\n\n${stubCode}\n`;
|
|
15
|
+
return transformServerFile(source, {
|
|
16
|
+
resourcePath: this.resourcePath,
|
|
17
|
+
rootContext: this.rootContext,
|
|
18
|
+
isServer: !!isServer,
|
|
19
|
+
onServerFn: manifestCollector
|
|
20
|
+
? (fnId, meta) => manifestCollector.addServerFn(fnId, meta)
|
|
21
|
+
: undefined,
|
|
22
|
+
});
|
|
103
23
|
}
|
|
104
24
|
//# sourceMappingURL=server-fn-loader.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server-fn-loader.js","sourceRoot":"","sources":["../src/server-fn-loader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"server-fn-loader.js","sourceRoot":"","sources":["../src/server-fn-loader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAcxD;;;GAGG;AACH,MAAM,CAAC,OAAO,CAAC,KAAK,UAAU,cAAc,CAE1C,MAAc;IAEd,MAAM,eAAe,GAAG,IAAI,CAAC,UAAU,EAAE,IAAI,EAAE,CAAC;IAChD,IAAI,QAAQ,GAAG,eAAe,CAAC,QAAQ,CAAC;IACxC,IAAI,OAAO,QAAQ,KAAK,WAAW,EAAE,CAAC;QACpC,MAAM,YAAY,GAAG,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC;QAC1C,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,EAAE,OAAO,EAAE,MAAM,CAAC;QAC/C,QAAQ,GAAG,YAAY,KAAK,UAAU,IAAI,MAAM,KAAK,MAAM,CAAC;IAC9D,CAAC;IAED,MAAM,iBAAiB,GAAG,IAAI,CAAC,SAAS,EAAE,sBAAsB,CAAC;IAEjE,OAAO,mBAAmB,CAAC,MAAM,EAAE;QACjC,YAAY,EAAE,IAAI,CAAC,YAAY;QAC/B,WAAW,EAAE,IAAI,CAAC,WAAW;QAC7B,QAAQ,EAAE,CAAC,CAAC,QAAQ;QACpB,UAAU,EAAE,iBAAiB;YAC3B,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC,iBAAiB,CAAC,WAAW,CAAC,IAAI,EAAE,IAAI,CAAC;YAC3D,CAAC,CAAC,SAAS;KACd,CAAC,CAAC;AACL,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@evjs/webpack-plugin",
|
|
3
|
-
"version": "0.0.1-alpha.
|
|
3
|
+
"version": "0.0.1-alpha.7",
|
|
4
4
|
"description": "Webpack plugin and loaders for the ev framework",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"publishConfig": {
|
|
@@ -35,9 +35,8 @@
|
|
|
35
35
|
"author": "xusd320",
|
|
36
36
|
"license": "MIT",
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@evjs/
|
|
39
|
-
"@
|
|
40
|
-
"glob": "^13.0.6"
|
|
38
|
+
"@evjs/build-tools": "0.0.1-alpha.7",
|
|
39
|
+
"@evjs/manifest": "0.0.1-alpha.7"
|
|
41
40
|
},
|
|
42
41
|
"devDependencies": {
|
|
43
42
|
"typescript": "^5.7.3",
|
package/esm/version.d.ts
DELETED
package/esm/version.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,OAAO,kBAAkB,CAAC"}
|
package/esm/version.js
DELETED
package/esm/version.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,OAAO,GAAG,eAAe,CAAC"}
|