@adonisjs/vite 0.0.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.
Files changed (67) hide show
  1. package/LICENSE.md +9 -0
  2. package/README.md +36 -0
  3. package/build/configure.d.ts +3 -0
  4. package/build/configure.d.ts.map +1 -0
  5. package/build/configure.js +13 -0
  6. package/build/index.d.ts +5 -0
  7. package/build/index.d.ts.map +1 -0
  8. package/build/index.js +4 -0
  9. package/build/providers/vite_provider.d.ts +10 -0
  10. package/build/providers/vite_provider.d.ts.map +1 -0
  11. package/build/providers/vite_provider.js +48 -0
  12. package/build/services/vite.d.ts +4 -0
  13. package/build/services/vite.d.ts.map +1 -0
  14. package/build/services/vite.js +6 -0
  15. package/build/src/backend/types/extended.d.ts +7 -0
  16. package/build/src/backend/types/extended.d.ts.map +1 -0
  17. package/build/src/backend/types/extended.js +1 -0
  18. package/build/src/backend/types/main.d.ts +9 -0
  19. package/build/src/backend/types/main.d.ts.map +1 -0
  20. package/build/src/backend/types/main.js +1 -0
  21. package/build/src/backend/utils.d.ts +2 -0
  22. package/build/src/backend/utils.d.ts.map +1 -0
  23. package/build/src/backend/utils.js +7 -0
  24. package/build/src/backend/vite.d.ts +19 -0
  25. package/build/src/backend/vite.d.ts.map +1 -0
  26. package/build/src/backend/vite.js +182 -0
  27. package/build/src/vite_plugin/config.d.ts +5 -0
  28. package/build/src/vite_plugin/config.d.ts.map +1 -0
  29. package/build/src/vite_plugin/config.js +47 -0
  30. package/build/src/vite_plugin/config_resolver.d.ts +9 -0
  31. package/build/src/vite_plugin/config_resolver.d.ts.map +1 -0
  32. package/build/src/vite_plugin/config_resolver.js +27 -0
  33. package/build/src/vite_plugin/helpers/inertia.d.ts +2 -0
  34. package/build/src/vite_plugin/helpers/inertia.d.ts.map +1 -0
  35. package/build/src/vite_plugin/helpers/inertia.js +11 -0
  36. package/build/src/vite_plugin/hot_file.d.ts +9 -0
  37. package/build/src/vite_plugin/hot_file.d.ts.map +1 -0
  38. package/build/src/vite_plugin/hot_file.js +30 -0
  39. package/build/src/vite_plugin/index.d.ts +4 -0
  40. package/build/src/vite_plugin/index.d.ts.map +1 -0
  41. package/build/src/vite_plugin/index.js +16 -0
  42. package/build/src/vite_plugin/types/index.d.ts +10 -0
  43. package/build/src/vite_plugin/types/index.d.ts.map +1 -0
  44. package/build/src/vite_plugin/types/index.js +1 -0
  45. package/build/src/vite_plugin/utils.d.ts +5 -0
  46. package/build/src/vite_plugin/utils.d.ts.map +1 -0
  47. package/build/src/vite_plugin/utils.js +16 -0
  48. package/build/stubs/index.d.ts +2 -0
  49. package/build/stubs/index.d.ts.map +1 -0
  50. package/build/stubs/index.js +2 -0
  51. package/build/stubs/vite/vite_config.stub +14 -0
  52. package/configure.ts +30 -0
  53. package/index.ts +15 -0
  54. package/package.json +147 -0
  55. package/providers/vite_provider.ts +89 -0
  56. package/services/vite.ts +23 -0
  57. package/src/backend/types/extended.ts +19 -0
  58. package/src/backend/types/main.ts +31 -0
  59. package/src/backend/utils.ts +19 -0
  60. package/src/backend/vite.ts +367 -0
  61. package/src/vite_plugin/config.ts +97 -0
  62. package/src/vite_plugin/config_resolver.ts +62 -0
  63. package/src/vite_plugin/helpers/inertia.ts +27 -0
  64. package/src/vite_plugin/hot_file.ts +59 -0
  65. package/src/vite_plugin/index.ts +38 -0
  66. package/src/vite_plugin/types/index.ts +56 -0
  67. package/src/vite_plugin/utils.ts +40 -0
@@ -0,0 +1,367 @@
1
+ /*
2
+ * @adonisjs/vite
3
+ *
4
+ * (c) AdonisJS
5
+ *
6
+ * For the full copyright and license information, please view the LICENSE
7
+ * file that was distributed with this source code.
8
+ */
9
+
10
+ import { join } from 'node:path'
11
+ import type { Manifest } from 'vite'
12
+ import { fileURLToPath } from 'node:url'
13
+ import { HotFile, SetAttributes } from './types/main.js'
14
+ import { existsSync, readFileSync } from 'node:fs'
15
+ import { ApplicationService } from '@adonisjs/core/types'
16
+ import { uniqBy } from './utils.js'
17
+
18
+ export class Vite {
19
+ /**
20
+ * Path to the build directory
21
+ *
22
+ * @default 'public/assets'
23
+ */
24
+ #buildDirectory: string
25
+
26
+ /**
27
+ * Path to the hotfile
28
+ *
29
+ * @default 'public/assets/hot.json'
30
+ */
31
+ #hotFile: string
32
+
33
+ /**
34
+ * Manifest file name
35
+ */
36
+ #manifestFilename = 'manifest.json'
37
+
38
+ /**
39
+ * Assets URL
40
+ */
41
+ #assetsUrl = ''
42
+
43
+ /**
44
+ * We cache the manifest file content in production
45
+ * to avoid reading the file multiple times
46
+ */
47
+ #manifestCache: Manifest | null = null
48
+
49
+ /**
50
+ * Attributes to be set on the style tags
51
+ */
52
+ #styleAttributes: SetAttributes = {}
53
+
54
+ /**
55
+ * Attributes to be set on the script tags
56
+ */
57
+ #scriptAttributes: SetAttributes = {}
58
+
59
+ constructor(private application: ApplicationService) {
60
+ this.#buildDirectory = this.application.publicPath('assets')
61
+ this.#hotFile = join(this.#buildDirectory, 'hot.json')
62
+ }
63
+
64
+ /**
65
+ * Checks if the application is running in hot mode
66
+ */
67
+ #isRunningHot(): boolean {
68
+ return existsSync(this.#hotFile)
69
+ }
70
+
71
+ /**
72
+ * Reads the file contents as JSON
73
+ */
74
+ #readFileAsJSON(filePath: string) {
75
+ return JSON.parse(readFileSync(filePath, 'utf-8'))
76
+ }
77
+
78
+ /**
79
+ * Returns the parsed hot file content
80
+ */
81
+ #readHotFile(): HotFile {
82
+ return this.#readFileAsJSON(this.#hotFile)
83
+ }
84
+
85
+ /**
86
+ * Get the path to an asset when running in hot mode
87
+ */
88
+ #hotAsset(asset: string) {
89
+ return this.#readHotFile().url + '/' + asset
90
+ }
91
+
92
+ /**
93
+ * Returns the script needed for the HMR working with Vite
94
+ */
95
+ #getViteHmrScript(): string {
96
+ if (!this.#isRunningHot()) {
97
+ return ''
98
+ }
99
+
100
+ return `<script type="module" src="${this.#hotAsset('@vite/client')}"></script>`
101
+ }
102
+
103
+ /**
104
+ * Generate style and script tags for the given entrypoints
105
+ * Also add the @vite/client script
106
+ */
107
+ #generateEntryPointsTagsForHotmode(entryPoints: string[]): string {
108
+ const viteHmr = this.#getViteHmrScript()
109
+ const tags = entryPoints.map((entrypoint) => this.#generateTag(entrypoint))
110
+
111
+ return [viteHmr, ...tags].join('\n')
112
+ }
113
+
114
+ /**
115
+ * Generate style and script tags for the given entrypoints
116
+ * using the manifest file
117
+ */
118
+ #generateEntryPointsTagsWithManifest(entryPoints: string[]): string {
119
+ const manifest = this.manifest()
120
+ const tags: { path: string; tag: string }[] = []
121
+
122
+ for (const entryPoint of entryPoints) {
123
+ const chunk = this.#chunk(manifest, entryPoint)
124
+ tags.push({ path: chunk.file, tag: this.#generateTag(chunk.file) })
125
+
126
+ for (const css of chunk.css || []) {
127
+ const cssChunk = this.#chunkByFile(manifest, css)
128
+ tags.push({ path: cssChunk.file, tag: this.#generateTag(cssChunk.file) })
129
+ }
130
+ }
131
+
132
+ return uniqBy(tags, 'path')
133
+ .sort((a) => (a.path.endsWith('.css') ? -1 : 1))
134
+ .map((preload) => preload.tag)
135
+ .join('\n')
136
+ }
137
+
138
+ /**
139
+ * Generate tags for the entry points
140
+ */
141
+ generateEntryPointsTags(entryPoints: string[] | string): string {
142
+ entryPoints = Array.isArray(entryPoints) ? entryPoints : [entryPoints]
143
+
144
+ if (this.#isRunningHot()) {
145
+ return this.#generateEntryPointsTagsForHotmode(entryPoints)
146
+ }
147
+
148
+ return this.#generateEntryPointsTagsWithManifest(entryPoints)
149
+ }
150
+
151
+ /**
152
+ * Get a chunk from the manifest file for a given file name
153
+ */
154
+ #chunk(manifest: Manifest, fileName: string) {
155
+ const chunk = manifest[fileName]
156
+
157
+ if (!chunk) {
158
+ throw new Error(`Cannot find "${fileName}" chunk in the manifest file`)
159
+ }
160
+
161
+ return chunk
162
+ }
163
+
164
+ /**
165
+ * Get a chunk from the manifest file for a given hashed file name
166
+ */
167
+ #chunkByFile(manifest: Manifest, fileName: string) {
168
+ const chunk = Object.values(manifest).find((c) => c.file === fileName)
169
+
170
+ if (!chunk) {
171
+ throw new Error(`Cannot find "${fileName}" chunk in the manifest file`)
172
+ }
173
+
174
+ return chunk
175
+ }
176
+
177
+ /**
178
+ * Check if the given path is a CSS path
179
+ */
180
+ #isCssPath(path: string) {
181
+ return path.match(/\.(css|less|sass|scss|styl|stylus|pcss|postcss)$/) !== null
182
+ }
183
+
184
+ /**
185
+ * Generate a HTML tag for the given asset
186
+ */
187
+ #generateTag(asset: string): string {
188
+ let url = ''
189
+ if (this.#isRunningHot()) {
190
+ url = this.#hotAsset(asset)
191
+ } else {
192
+ url = `${this.#assetsUrl}/assets/${asset}`
193
+ }
194
+
195
+ if (this.#isCssPath(asset)) {
196
+ return this.#makeStyleTag(asset, url)
197
+ }
198
+
199
+ return this.#makeScriptTag(asset, url)
200
+ }
201
+
202
+ /**
203
+ * Unwrap attributes from the user defined function or return
204
+ * the attributes as it is
205
+ */
206
+ #unwrapAttributes(src: string, url: string, attributes: SetAttributes) {
207
+ if (typeof attributes === 'function') {
208
+ return attributes({ src, url })
209
+ }
210
+
211
+ return attributes
212
+ }
213
+
214
+ /**
215
+ * Convert Record of attributes to a valid HTML string
216
+ */
217
+ #makeAttributes(attributes: Record<string, string | boolean>) {
218
+ return Object.keys(attributes)
219
+ .map((key) => {
220
+ const value = attributes[key]
221
+ if (value === true) return key
222
+ if (value === false) return null
223
+
224
+ return `${key}="${value}"`
225
+ })
226
+ .filter((attr) => attr !== null)
227
+ .join(' ')
228
+ }
229
+
230
+ /**
231
+ * Create a script tag for the given path
232
+ */
233
+ #makeScriptTag(src: string, url: string) {
234
+ const customAttributes = this.#unwrapAttributes(src, url, this.#scriptAttributes)
235
+ const attributes = { type: 'module', ...customAttributes }
236
+
237
+ return `<script ${this.#makeAttributes(attributes)} src="${url}"></script>`
238
+ }
239
+
240
+ /**
241
+ * Create a style tag for the given path
242
+ */
243
+ #makeStyleTag(src: string, url: string) {
244
+ const customAttributes = this.#unwrapAttributes(src, url, this.#styleAttributes)
245
+ const attributes = { rel: 'stylesheet', ...customAttributes }
246
+
247
+ return `<link ${this.#makeAttributes(attributes)} href="${url}">`
248
+ }
249
+
250
+ /**
251
+ * Returns path to a given asset file
252
+ */
253
+ assetPath(asset: string) {
254
+ if (this.#isRunningHot()) {
255
+ return this.#hotAsset(asset)
256
+ }
257
+
258
+ const chunk = this.#chunk(this.manifest(), asset)
259
+ return `${this.#assetsUrl}/assets/${chunk.file}`
260
+ }
261
+
262
+ /**
263
+ * Returns the manifest file content
264
+ *
265
+ * @throws Will throw an exception when running in hot mode
266
+ */
267
+ manifest(): Manifest {
268
+ if (this.#isRunningHot()) {
269
+ throw new Error('Cannot read the manifest file when running in hot mode')
270
+ }
271
+
272
+ /**
273
+ * Use in-memory cache when available
274
+ */
275
+ if (this.#manifestCache) {
276
+ return this.#manifestCache
277
+ }
278
+
279
+ const manifest = this.#readFileAsJSON(join(this.#buildDirectory, this.#manifestFilename))
280
+
281
+ /**
282
+ * Cache the manifest in production to avoid re-reading the file from disk
283
+ */
284
+ if (this.application.inProduction) {
285
+ this.#manifestCache = manifest
286
+ }
287
+
288
+ return manifest
289
+ }
290
+
291
+ /**
292
+ * Returns the script needed for the HMR working with React
293
+ *
294
+ * This method is called automatically when using edge tag `@viteReactRefresh`
295
+ */
296
+ getReactHmrScript(): string {
297
+ if (!this.#isRunningHot()) {
298
+ return ''
299
+ }
300
+
301
+ return `
302
+ <script type="module">
303
+ import RefreshRuntime from '${this.#hotAsset('@react-refresh')}'
304
+ RefreshRuntime.injectIntoGlobalHook(window)
305
+ window.$RefreshReg$ = () => {}
306
+ window.$RefreshSig$ = () => (type) => type
307
+ window.__vite_plugin_react_preamble_installed__ = true
308
+ </script>
309
+ `
310
+ }
311
+
312
+ /**
313
+ * Set the path to the hotfile
314
+ *
315
+ * You must also set the `hotFile` option in the vite plugin config
316
+ */
317
+ setHotFilePath(path: string) {
318
+ this.#hotFile = join(fileURLToPath(this.application.appRoot), path)
319
+ return this
320
+ }
321
+
322
+ /**
323
+ * Set the manifest filename
324
+ *
325
+ * You must also set the `build.manifest` option in your vite configuration
326
+ */
327
+ setManifestFilename(name: string) {
328
+ this.#manifestFilename = name
329
+ return this
330
+ }
331
+
332
+ /**
333
+ * Set the build directory. Subdirectory of the AdonisJs public directory
334
+ *
335
+ * You must also set the `buildDirectory` option in the vite plugin config
336
+ */
337
+ setBuildDirectory(path: string) {
338
+ this.#buildDirectory = this.application.publicPath(path)
339
+ return this
340
+ }
341
+
342
+ /**
343
+ * Set the assets url
344
+ *
345
+ * You must also set the `assetsUrl` option in the vite plugin config
346
+ */
347
+ setAssetsUrl(url: string) {
348
+ this.#assetsUrl = url.endsWith('/') ? url : `${url}/`
349
+ return this
350
+ }
351
+
352
+ /**
353
+ * Include additional attributes to each script tag generated
354
+ */
355
+ setScriptAttributes(attributes: SetAttributes) {
356
+ this.#scriptAttributes = attributes
357
+ return this
358
+ }
359
+
360
+ /**
361
+ * Include additional attributes to each style tag generated
362
+ */
363
+ setStyleAttributes(attributes: SetAttributes) {
364
+ this.#styleAttributes = attributes
365
+ return this
366
+ }
367
+ }
@@ -0,0 +1,97 @@
1
+ /*
2
+ * @adonisjs/vite
3
+ *
4
+ * (c) AdonisJS
5
+ *
6
+ * For the full copyright and license information, please view the LICENSE
7
+ * file that was distributed with this source code.
8
+ */
9
+
10
+ import { defu } from 'defu'
11
+ import { AddressInfo } from 'node:net'
12
+ import { ConfigEnv, Plugin, UserConfig } from 'vite'
13
+ import { PluginFullOptions } from './types/index.js'
14
+ import { resolveDevServerUrl } from './utils.js'
15
+ import { HotFile } from './hot_file.js'
16
+ import { ConfigResolver } from './config_resolver.js'
17
+ import { join } from 'node:path'
18
+
19
+ /**
20
+ * Vite config hook
21
+ */
22
+ export const configHook = (
23
+ options: PluginFullOptions,
24
+ userConfig: UserConfig,
25
+ { command }: ConfigEnv
26
+ ): UserConfig => {
27
+ const config: UserConfig = {
28
+ publicDir: userConfig.publicDir ?? false,
29
+ base: ConfigResolver.resolveBase(userConfig, options, command),
30
+ resolve: { alias: ConfigResolver.resolveAlias(userConfig) },
31
+
32
+ server: {
33
+ /**
34
+ * Will allow to rewrite the URL to the public path
35
+ * in dev mode
36
+ */
37
+ origin: '__adonis_vite__',
38
+ },
39
+
40
+ build: {
41
+ assetsDir: '',
42
+ manifest: userConfig.build?.manifest ?? true,
43
+ emptyOutDir: true,
44
+ outDir: ConfigResolver.resolveOutDir(userConfig, options),
45
+
46
+ rollupOptions: {
47
+ input: options.entrypoints.map((entrypoint) => join(userConfig.root || '', entrypoint)),
48
+ },
49
+ },
50
+ }
51
+
52
+ return defu(config, userConfig)
53
+ }
54
+
55
+ /**
56
+ * Update the user vite config to match the Adonis requirements
57
+ */
58
+ export const config = (options: PluginFullOptions): Plugin => {
59
+ let devServerUrl: string
60
+
61
+ return {
62
+ name: 'vite-plugin-adonis:config',
63
+ config: configHook.bind(null, options),
64
+
65
+ /**
66
+ * Store the dev server url for further usage when rewriting URLs
67
+ */
68
+ configureServer(server) {
69
+ const hotfile = new HotFile(options.hotFile)
70
+
71
+ server.httpServer?.once('listening', async () => {
72
+ devServerUrl = resolveDevServerUrl(
73
+ server.httpServer!.address() as AddressInfo,
74
+ server.config
75
+ )
76
+
77
+ await hotfile.write({ url: devServerUrl })
78
+ })
79
+
80
+ server.httpServer?.on('close', () => hotfile.clean())
81
+ },
82
+
83
+ /**
84
+ * Rewrite URL to the public path in dev mode
85
+ *
86
+ * See : https://nystudio107.com/blog/using-vite-js-next-generation-frontend-tooling-with-craft-cms#vite-processed-assets
87
+ */
88
+ transform: (code) => ({
89
+ code: code.replace(/__adonis_vite__/g, devServerUrl),
90
+ map: null,
91
+ }),
92
+
93
+ configResolved: async (resolvedConfig) => {
94
+ ConfigResolver.resolvedConfig = resolvedConfig
95
+ },
96
+ }
97
+ }
@@ -0,0 +1,62 @@
1
+ /*
2
+ * @adonisjs/vite
3
+ *
4
+ * (c) AdonisJS
5
+ *
6
+ * For the full copyright and license information, please view the LICENSE
7
+ * file that was distributed with this source code.
8
+ */
9
+
10
+ import { ResolvedConfig, UserConfig, AliasOptions } from 'vite'
11
+ import { addTrailingSlash } from './utils.js'
12
+ import { PluginFullOptions } from './types/index.js'
13
+ import { join } from 'node:path'
14
+
15
+ export class ConfigResolver {
16
+ static resolvedConfig?: ResolvedConfig
17
+
18
+ /**
19
+ * Resolve the `config.base` value
20
+ */
21
+ static resolveBase(
22
+ config: UserConfig,
23
+ options: PluginFullOptions,
24
+ command: 'build' | 'serve'
25
+ ): string {
26
+ if (config.base) {
27
+ return config.base
28
+ }
29
+
30
+ if (command === 'build') {
31
+ return addTrailingSlash(options.assetsUrl) + addTrailingSlash(options.buildDirectory)
32
+ }
33
+
34
+ return '/'
35
+ }
36
+
37
+ /**
38
+ * Resolve the `config.resolve.alias` value
39
+ *
40
+ * Basically we are merging the user defined alias with the
41
+ * default alias.
42
+ */
43
+ static resolveAlias(config: UserConfig): AliasOptions {
44
+ const defaultAlias = { '@/': `/resources/js/` }
45
+
46
+ if (Array.isArray(config.resolve?.alias)) {
47
+ return [
48
+ ...(config.resolve?.alias ?? []),
49
+ Object.entries(defaultAlias).map(([find, replacement]) => ({ find, replacement })),
50
+ ]
51
+ }
52
+
53
+ return { ...defaultAlias, ...config.resolve?.alias }
54
+ }
55
+
56
+ /**
57
+ * Resolve the `config.build.outDir` value
58
+ */
59
+ static resolveOutDir(config: UserConfig, options: PluginFullOptions): string {
60
+ return config.build?.outDir ?? join(options.publicDirectory, options.buildDirectory)
61
+ }
62
+ }
@@ -0,0 +1,27 @@
1
+ /*
2
+ * @adonisjs/vite
3
+ *
4
+ * (c) AdonisJS
5
+ *
6
+ * For the full copyright and license information, please view the LICENSE
7
+ * file that was distributed with this source code.
8
+ */
9
+
10
+ /**
11
+ * Resolves a page component.
12
+ */
13
+ export async function resolvePageComponent(name: string, pages: Record<string, any>) {
14
+ const path = Object.keys(pages)
15
+ .sort((a, b) => a.length - b.length)
16
+ .find((filepath) => filepath.endsWith(name))
17
+
18
+ if (!path) {
19
+ throw new Error(`Page component "${name}" could not be found.`)
20
+ }
21
+
22
+ let component = typeof pages[path] === 'function' ? await pages[path]() : pages[path]
23
+
24
+ component = component.default ?? component
25
+
26
+ return component
27
+ }
@@ -0,0 +1,59 @@
1
+ /*
2
+ * @adonisjs/vite
3
+ *
4
+ * (c) AdonisJS
5
+ *
6
+ * For the full copyright and license information, please view the LICENSE
7
+ * file that was distributed with this source code.
8
+ */
9
+
10
+ import { existsSync, rmSync } from 'node:fs'
11
+ import { mkdir, writeFile } from 'node:fs/promises'
12
+ import { dirname, join } from 'node:path'
13
+ import { ConfigResolver } from './config_resolver.js'
14
+
15
+ export class HotFile {
16
+ /**
17
+ * Path to the hot file
18
+ */
19
+ #path: string
20
+
21
+ /**
22
+ * Register hooks to clean the hot file on exit
23
+ */
24
+ #cleanHotFileOnExit() {
25
+ const clean = this.clean.bind(this)
26
+
27
+ process.on('exit', clean)
28
+
29
+ process.on('SIGINT', process.exit)
30
+ process.on('SIGTERM', process.exit)
31
+ process.on('SIGHUP', process.exit)
32
+ process.on('SIGBREAK', process.exit)
33
+ process.on('SIGKILL', process.exit)
34
+ }
35
+
36
+ constructor(path: string) {
37
+ this.#path = join(ConfigResolver.resolvedConfig!.root, path)
38
+ this.#cleanHotFileOnExit()
39
+ }
40
+
41
+ /**
42
+ * Write the hot file
43
+ */
44
+ async write(data: { url: string }) {
45
+ await mkdir(dirname(this.#path), { recursive: true })
46
+ await writeFile(this.#path, JSON.stringify(data, null, 2))
47
+ }
48
+
49
+ /**
50
+ * Delete the hot file
51
+ */
52
+ clean() {
53
+ if (!existsSync(this.#path)) {
54
+ return
55
+ }
56
+
57
+ rmSync(this.#path)
58
+ }
59
+ }
@@ -0,0 +1,38 @@
1
+ /*
2
+ * @adonisjs/vite
3
+ *
4
+ * (c) AdonisJS
5
+ *
6
+ * For the full copyright and license information, please view the LICENSE
7
+ * file that was distributed with this source code.
8
+ */
9
+
10
+ import { defu } from 'defu'
11
+ import { PluginOption } from 'vite'
12
+ import { config } from './config.js'
13
+ import { PluginFullOptions, PluginOptions } from './types/index.js'
14
+ import PluginRestart from 'vite-plugin-restart'
15
+ import { join } from 'node:path'
16
+
17
+ const VitePluginRestart = PluginRestart as any as typeof PluginRestart.default
18
+
19
+ /**
20
+ * Vite plugin for AdonisJS
21
+ */
22
+ export default function Adonis(options: PluginOptions): PluginOption[] {
23
+ const hotfileDefaultDestination = join(
24
+ options.publicDirectory || 'public',
25
+ options.buildDirectory || 'assets',
26
+ 'hot.json'
27
+ )
28
+
29
+ const fullOptions = defu<PluginFullOptions, [Partial<PluginOptions>]>(options, {
30
+ publicDirectory: 'public',
31
+ buildDirectory: 'assets',
32
+ assetsUrl: '',
33
+ hotFile: hotfileDefaultDestination,
34
+ reload: ['./resources/views/**/*.edge'],
35
+ })
36
+
37
+ return [VitePluginRestart({ reload: fullOptions.reload }), config(fullOptions)]
38
+ }
@@ -0,0 +1,56 @@
1
+ /*
2
+ * @adonisjs/vite
3
+ *
4
+ * (c) AdonisJS
5
+ *
6
+ * For the full copyright and license information, please view the LICENSE
7
+ * file that was distributed with this source code.
8
+ */
9
+
10
+ /**
11
+ * Possible plugin options
12
+ */
13
+ export type PluginOptions = {
14
+ /**
15
+ * Path to the hot file
16
+ *
17
+ * @default public/hot.json
18
+ */
19
+ hotFile?: string
20
+
21
+ /**
22
+ * Paths to the entrypoints files
23
+ */
24
+ entrypoints: string[]
25
+
26
+ /**
27
+ * Path to your AdonisJS public directory
28
+ *
29
+ * @default 'public'
30
+ */
31
+ publicDirectory?: string
32
+
33
+ /**
34
+ * The URL where the assets will be served. This is particularly
35
+ * useful if you are using a CDN to deploy your assets.
36
+ *
37
+ * @default ''
38
+ */
39
+ assetsUrl?: string
40
+
41
+ /**
42
+ * Public subdirectory where the assets will be compiled.
43
+ *
44
+ * @default 'assets'
45
+ */
46
+ buildDirectory?: string
47
+
48
+ /**
49
+ * Files that should trigger a page reload when changed.
50
+ *
51
+ * @default ['./resources/views/** /*.edge']
52
+ */
53
+ reload?: string[]
54
+ }
55
+
56
+ export type PluginFullOptions = Required<PluginOptions>