1+ import { readFileSync } from "fs" ;
2+ import { resolve } from "path" ;
3+ import { RollupError } from "rollup" ;
4+ import { Plugin } from "vite" ;
5+
6+ interface PackageJson {
7+ name : string ;
8+ version : string ;
9+ author ?: string | { name : string } ;
10+ }
11+
12+ interface AppMetadataPluginOptions {
13+ entryPath : string ;
14+ }
15+
16+ export function appMetadataPlugin ( { entryPath } : AppMetadataPluginOptions ) : Plugin {
17+ return {
18+ name : "vite-plugin-app-metadata" ,
19+ apply : "build" ,
20+ load ( id ) {
21+ if ( ! id . includes ( entryPath ) ) return null ;
22+
23+ const rootDir = process . cwd ( ) ;
24+ const packageJsonPath = resolve ( rootDir , "package.json" ) ;
25+
26+ // Read and parse the package.json file
27+ let packageJson : PackageJson | null = null ;
28+ try {
29+ const packageJsonContent = readFileSync ( packageJsonPath , "utf-8" ) ;
30+ packageJson = JSON . parse ( packageJsonContent ) as PackageJson ;
31+ } catch ( error ) {
32+ this . error ( error as RollupError ) ;
33+ }
34+
35+ if ( ! packageJson )
36+ return null ;
37+
38+ const { name, version } = packageJson ;
39+ let { author = "Unknown" } = packageJson ;
40+
41+ if ( typeof author == "string" ) {
42+ author = author . replace ( / < [ ^ > ] * > | \( [ ^ ) ] * \) / g, "" ) . trim ( ) ;
43+ } else {
44+ author = author . name ;
45+ }
46+
47+ // Read the source file content
48+ let code : string | null = null ;
49+ try {
50+ code = readFileSync ( id , "utf-8" ) ;
51+ } catch ( error ) {
52+ this . error ( error as RollupError ) ;
53+ }
54+
55+ if ( code == null )
56+ return null ;
57+
58+ // Find instance of app class
59+ const appInstanceRegex = / c o n s t \s + ( \w + ) \s * = \s * n e w \s + A p p (?: < [ \w \s , ] + > ) ? \s * \( ( [ ^ ; ] * ) \) \s * ( \. [ \w ] + \( [ ^ ) ] * \) \s * ) * ; / ;
60+ const match = code . match ( appInstanceRegex ) ;
61+
62+ if ( match ) {
63+ const appInstanceName = match [ 1 ] ;
64+
65+ // Inject code to set metadata of app
66+ const injectCode = `\n${ appInstanceName } .setMetadata({ name: "${ name } ", version: "${ version } ", author: "${ author } " });\n` ;
67+ const modifiedCode = code . replace ( appInstanceRegex , match [ 0 ] + injectCode ) ;
68+
69+ return modifiedCode ;
70+ } else {
71+ this . warn ( "No App instance found in the entry file." ) ;
72+ return null ;
73+ }
74+ } ,
75+ } ;
76+ }
0 commit comments