diff --git a/src/Http/View/View.imba b/src/Http/View/View.imba
index d72ff7b0..24e7b27f 100644
--- a/src/Http/View/View.imba
+++ b/src/Http/View/View.imba
@@ -7,6 +7,7 @@ import isString from '../../Support/Helpers/isString'
import querystring from 'querystring'
import UndefinedDataPropException from './Exceptions/UndefinedDataPropException'
import Language from '../../Support/Language/Language'
+import viteHelper from '../../Support/Helpers/vite'
export default class View
@@ -36,6 +37,40 @@ export default class View
self
+ def vite file\string|string[]
+ if Array.isArray(file)
+ let tags = []
+
+ for asset in file
+ if !isString(asset)
+ throw TypeError "Expected string."
+
+ const jsTagExtensions = ['js', 'ts']
+ const cssTagExtensions = ['css', 'scss', 'sass', 'less', 'styl', 'stylus']
+ const imgTagExtensions = ['png', 'jpg', 'jpeg', 'gif', 'svg', 'webp', 'avif']
+ const fontTagExtensions = ['woff', 'woff2', 'eot', 'ttf', 'otf']
+
+ const extension = asset.split('.').pop!.toLowerCase!
+
+ if !isString(extension)
+ throw new Error "Could not determine file extension for: {asset}"
+
+ if jsTagExtensions.includes(extension)
+ tags.push("")
+ else if cssTagExtensions.includes(extension)
+ tags.push("")
+ else if imgTagExtensions.includes(extension)
+ tags.push("
")
+ else if fontTagExtensions.includes(extension)
+ tags.push("")
+ else
+ throw new Error "Unsupported file extension: {extension}"
+
+ if tags.length > 0
+ tags.join('\n')
+ else
+ viteHelper(file)
+
def translate key\string, default\any
self.#_language.get(key, default)
diff --git a/src/Support/Helpers/index.imba b/src/Support/Helpers/index.imba
index 00d15530..01a6a3fd 100644
--- a/src/Support/Helpers/index.imba
+++ b/src/Support/Helpers/index.imba
@@ -35,6 +35,7 @@ const { default: toBoolean } = require './toBoolean'
const { default: updateLine } = require './updateLine'
const { default: version } = require './version'
const { default: view } = require './view'
+const { default: vite } = require './vite'
const { default: wildcard } = require './wildcard'
const { default: without } = require './without'
@@ -81,6 +82,7 @@ export {
updateLine
version
view
+ vite
wildcard
without
}
diff --git a/src/Support/Helpers/vite.imba b/src/Support/Helpers/vite.imba
new file mode 100644
index 00000000..258f3cf5
--- /dev/null
+++ b/src/Support/Helpers/vite.imba
@@ -0,0 +1,4 @@
+import Repository from '../../Vite/Repository'
+
+export default def vite file\string
+ Repository.get file
diff --git a/src/Vite/Repository.imba b/src/Vite/Repository.imba
new file mode 100644
index 00000000..ab4904c6
--- /dev/null
+++ b/src/Vite/Repository.imba
@@ -0,0 +1,46 @@
+import { readFileSync, existsSync } from 'fs'
+import { join } from 'path'
+
+export default class Repository
+
+ static manifestCache\ViteManifest|null = null
+
+ static def get file\string
+ const manifest = self.getManifest!
+
+ if !manifest
+ return file
+
+ const normalizedFile = file.startsWith('/') ? file.slice(1) : file
+
+ if manifest[normalizedFile]
+ return '/build/' + manifest[normalizedFile].file
+
+ if normalizedFile == 'css/app.css'
+ for [key, value] in Object.entries(manifest)
+ if key.includes('css/app.css')
+ return '/build/' + value.file
+
+ if normalizedFile == 'js/app.js'
+ for [key, value] in Object.entries(manifest)
+ if key.includes('js/app.ts')
+ return '/build/' + value.file
+
+ file
+
+ static def getManifest\ViteManifest|null
+ if self.manifestCache != null
+ return self.manifestCache
+
+ const location = join(process.cwd!, 'public', 'build', '.vite', 'manifest.json')
+
+ try
+ if existsSync(location)
+ const content = readFileSync(location, 'utf8')
+ self.manifestCache = content ? JSON.parse(content) : null
+ else
+ self.manifestCache = null
+ catch err
+ self.manifestCache = null
+
+ self.manifestCache
diff --git a/types/Http/View/View.d.ts b/types/Http/View/View.d.ts
index 359b369b..d0fd2672 100644
--- a/types/Http/View/View.d.ts
+++ b/types/Http/View/View.d.ts
@@ -31,6 +31,14 @@ export default class View {
*/
__(key: string, default$?: string): string;
+ /**
+ * Get asset path(s) from Vite manifest.
+ *
+ * @param {string | string[]} file
+ * @returns {string}
+ */
+ vite(file: string | string[]): string;
+
/**
* Get old input.
*/
diff --git a/types/Support/Helpers/mix.d.ts b/types/Support/Helpers/mix.d.ts
index 293e0865..8c9d5d68 100644
--- a/types/Support/Helpers/mix.d.ts
+++ b/types/Support/Helpers/mix.d.ts
@@ -1,4 +1,7 @@
/**
-@param {string} file
-*/
+ * Get asset path from Laravel Mix manifest.
+ * @param {string} file
+ * @returns {string}
+ * @deprecated
+ */
export default function mix(file: string): string;
diff --git a/types/Support/Helpers/vite.d.ts b/types/Support/Helpers/vite.d.ts
new file mode 100644
index 00000000..7e06aebc
--- /dev/null
+++ b/types/Support/Helpers/vite.d.ts
@@ -0,0 +1,7 @@
+/**
+ * Get asset path(s) from Vite manifest.
+ *
+ * @param {string | string[]} file
+ * @returns {string}
+ */
+export default function vite(file: string | string[]): string;
diff --git a/types/Vite/Repository.d.ts b/types/Vite/Repository.d.ts
new file mode 100644
index 00000000..56040b83
--- /dev/null
+++ b/types/Vite/Repository.d.ts
@@ -0,0 +1,16 @@
+interface ViteManifest {
+ [key: string]: {
+ file: string;
+ src?: string;
+ isEntry?: boolean;
+ imports?: string[];
+ css?: string[];
+ assets?: string[];
+ };
+}
+
+export default class Repository {
+ static manifestCache: ViteManifest | null = null;
+ static file(file: string): string;
+ static getManifest(): ViteManifest | null;
+}