@adonisjs/vite 0.0.1-4 → 0.0.1-6

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 (35) hide show
  1. package/build/configure.js +3 -3
  2. package/build/index.d.ts +1 -0
  3. package/build/index.js +1 -0
  4. package/build/providers/vite_provider.d.ts +6 -2
  5. package/build/providers/vite_provider.js +21 -44
  6. package/build/src/backend/debug.d.ts +3 -0
  7. package/build/src/backend/debug.js +10 -0
  8. package/build/src/backend/define_config.d.ts +5 -0
  9. package/build/src/backend/define_config.js +18 -0
  10. package/build/src/backend/edge_plugin_vite.d.ts +7 -0
  11. package/build/src/backend/edge_plugin_vite.js +65 -0
  12. package/build/src/backend/types/main.d.ts +48 -1
  13. package/build/src/backend/utils.d.ts +4 -0
  14. package/build/src/backend/utils.js +16 -0
  15. package/build/src/backend/vite.d.ts +9 -41
  16. package/build/src/backend/vite.js +112 -176
  17. package/build/src/{vite_plugin → client}/config.d.ts +1 -1
  18. package/build/src/{vite_plugin → client}/config_resolver.d.ts +1 -1
  19. package/build/src/{vite_plugin → client}/config_resolver.js +2 -3
  20. package/build/src/client/main.d.ts +6 -0
  21. package/build/src/{vite_plugin/index.js → client/main.js} +6 -9
  22. package/build/src/{vite_plugin/types/index.d.ts → client/types.d.ts} +2 -8
  23. package/build/stubs/client_config.stub +22 -0
  24. package/build/stubs/config.stub +21 -0
  25. package/package.json +12 -13
  26. package/build/src/vite_plugin/index.d.ts +0 -6
  27. package/build/stubs/vite/vite_config.stub +0 -18
  28. package/build/src/{vite_plugin → client}/config.js +2 -2
  29. package/build/src/{vite_plugin → client}/helpers/inertia.d.ts +0 -0
  30. package/build/src/{vite_plugin → client}/helpers/inertia.js +0 -0
  31. package/build/src/{vite_plugin → client}/hot_file.d.ts +0 -0
  32. package/build/src/{vite_plugin → client}/hot_file.js +1 -1
  33. package/build/src/{vite_plugin/types/index.js → client/types.js} +0 -0
  34. package/build/src/{vite_plugin → client}/utils.d.ts +1 -1
  35. /package/build/src/{vite_plugin → client}/utils.js +0 -0
@@ -13,12 +13,12 @@ import { fileURLToPath } from 'node:url';
13
13
  */
14
14
  export async function configure(command) {
15
15
  const stubDestination = join(fileURLToPath(command.app.appRoot), 'vite.config.js');
16
- await command.publishStub('vite/vite_config.stub', {
16
+ await command.publishStub('client_config.stub', {
17
17
  destination: stubDestination,
18
18
  });
19
+ await command.publishStub('config.stub');
19
20
  await command.updateRcFile((rcFile) => {
20
21
  rcFile.addProvider('@adonisjs/vite/vite_provider');
21
22
  });
22
- const packagesToInstall = [{ name: 'vite', isDevDependency: true }];
23
- command.listPackagesToInstall(packagesToInstall);
23
+ await command.installPackages([{ name: 'vite', isDevDependency: true }]);
24
24
  }
package/build/index.d.ts CHANGED
@@ -2,3 +2,4 @@ import './src/backend/types/extended.js';
2
2
  export { configure } from './configure.js';
3
3
  export { stubsRoot } from './stubs/index.js';
4
4
  export { Vite } from './src/backend/vite.js';
5
+ export { defineConfig } from './src/backend/define_config.js';
package/build/index.js CHANGED
@@ -10,3 +10,4 @@ import './src/backend/types/extended.js';
10
10
  export { configure } from './configure.js';
11
11
  export { stubsRoot } from './stubs/index.js';
12
12
  export { Vite } from './src/backend/vite.js';
13
+ export { defineConfig } from './src/backend/define_config.js';
@@ -1,11 +1,15 @@
1
1
  import type { ApplicationService } from '@adonisjs/core/types';
2
+ import { Edge } from 'edge.js';
2
3
  export default class ViteServiceProvider {
3
- #private;
4
4
  protected app: ApplicationService;
5
5
  constructor(app: ApplicationService);
6
+ /**
7
+ * Returns edge when it's installed
8
+ */
9
+ protected getEdge(): Promise<Edge | null>;
6
10
  register(): void;
7
11
  /**
8
- * Extend the view globals with vite tags and globals
12
+ * Extending edge
9
13
  */
10
14
  boot(): Promise<void>;
11
15
  }
@@ -6,66 +6,43 @@
6
6
  * For the full copyright and license information, please view the LICENSE
7
7
  * file that was distributed with this source code.
8
8
  */
9
- import { EdgeError } from 'edge-error';
10
9
  export default class ViteServiceProvider {
11
10
  app;
12
11
  constructor(app) {
13
12
  this.app = app;
14
13
  }
15
14
  /**
16
- * Inject the script needed for Vite HMR
15
+ * Returns edge when it's installed
17
16
  */
18
- #registerViteTag(view) {
19
- view.registerTag({
20
- tagName: 'vite',
21
- seekable: true,
22
- block: false,
23
- compile(parser, buffer, token) {
24
- /**
25
- * Ensure an argument is defined
26
- */
27
- if (!token.properties.jsArg.trim()) {
28
- throw new EdgeError('Missing entrypoint name', 'E_RUNTIME_EXCEPTION', {
29
- filename: token.filename,
30
- line: token.loc.start.line,
31
- col: token.loc.start.col,
32
- });
33
- }
34
- const parsed = parser.utils.transformAst(parser.utils.generateAST(token.properties.jsArg, token.loc, token.filename), token.filename, parser);
35
- const entrypoints = parser.utils.stringify(parsed);
36
- buffer.outputExpression(`state.vite.generateEntryPointsTags(${entrypoints})`, token.filename, token.loc.start.line, false);
37
- },
38
- });
39
- }
40
- /**
41
- * Inject a script needed for the HMR working with React
42
- */
43
- #registerViteReactTag(view) {
44
- view.registerTag({
45
- tagName: 'viteReactRefresh',
46
- seekable: true,
47
- block: false,
48
- compile(_parser, buffer, token) {
49
- buffer.outputExpression(`state.vite.getReactHmrScript()`, token.filename, token.loc.start.line, false);
50
- },
51
- });
17
+ async getEdge() {
18
+ try {
19
+ const { default: edge } = await import('edge.js');
20
+ return edge;
21
+ }
22
+ catch {
23
+ return null;
24
+ }
52
25
  }
53
26
  register() {
54
27
  this.app.container.singleton('vite', async () => {
55
28
  const { Vite } = await import('../src/backend/vite.js');
56
- return new Vite(this.app);
29
+ const config = this.app.config.get('vite');
30
+ return new Vite({
31
+ ...config,
32
+ buildDirectory: this.app.makePath(config.buildDirectory || 'public/build'),
33
+ hotFile: this.app.makePath(config.hotFile || 'public/build/hot.json'),
34
+ });
57
35
  });
58
36
  }
59
37
  /**
60
- * Extend the view globals with vite tags and globals
38
+ * Extending edge
61
39
  */
62
40
  async boot() {
63
- this.app.container.resolving('view', async (view) => {
41
+ const edge = await this.getEdge();
42
+ if (edge) {
64
43
  const vite = await this.app.container.make('vite');
65
- view.global('vite', vite);
66
- view.global('asset', vite.assetPath.bind(vite));
67
- this.#registerViteTag(view);
68
- this.#registerViteReactTag(view);
69
- });
44
+ const { edgePluginVite } = await import('../src/backend/edge_plugin_vite.js');
45
+ edge.use(edgePluginVite(vite));
46
+ }
70
47
  }
71
48
  }
@@ -0,0 +1,3 @@
1
+ /// <reference types="@types/node" resolution-mode="require"/>
2
+ declare const _default: import("util").DebugLogger;
3
+ export default _default;
@@ -0,0 +1,10 @@
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
+ import { debuglog } from 'node:util';
10
+ export default debuglog('adonisjs:vite');
@@ -0,0 +1,5 @@
1
+ import { ViteOptions } from './types/main.js';
2
+ /**
3
+ * Define the backend config for resolving vite assets
4
+ */
5
+ export declare function defineConfig(config: Partial<ViteOptions>): ViteOptions;
@@ -0,0 +1,18 @@
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
+ * Define the backend config for resolving vite assets
11
+ */
12
+ export function defineConfig(config) {
13
+ return {
14
+ buildDirectory: 'public/assets',
15
+ hotFile: 'public/assets/hot.json',
16
+ ...config,
17
+ };
18
+ }
@@ -0,0 +1,7 @@
1
+ import type { PluginFn } from 'edge.js/types';
2
+ import type { Vite } from './vite.js';
3
+ /**
4
+ * The edge plugin for vite to share vite service with edge
5
+ * and register custom tags
6
+ */
7
+ export declare const edgePluginVite: (vite: Vite) => PluginFn<undefined>;
@@ -0,0 +1,65 @@
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
+ import { EdgeError } from 'edge-error';
10
+ import debug from './debug.js';
11
+ /**
12
+ * The edge plugin for vite to share vite service with edge
13
+ * and register custom tags
14
+ */
15
+ export const edgePluginVite = (vite) => {
16
+ return (edge) => {
17
+ debug('sharing vite and asset globals with edge');
18
+ edge.global('vite', vite);
19
+ edge.global('asset', vite.assetPath.bind(vite));
20
+ debug('registering vite tags with edge');
21
+ edge.registerTag({
22
+ tagName: 'viteReactRefresh',
23
+ seekable: true,
24
+ block: false,
25
+ compile(_parser, buffer, token) {
26
+ /**
27
+ * Get HMR script
28
+ */
29
+ buffer.writeExpression(`const __vite_hmr_script = state.vite.getReactHmrScript()`, token.filename, token.loc.start.line);
30
+ /**
31
+ * Check if the script exists (only in hot mode)
32
+ */
33
+ buffer.writeStatement('if(__vite_hmr_script) {', token.filename, token.loc.start.line);
34
+ /**
35
+ * Write output
36
+ */
37
+ buffer.outputExpression(`__vite_hmr_script.toString()`, token.filename, token.loc.start.line, false);
38
+ /**
39
+ * Close if block
40
+ */
41
+ buffer.writeStatement('}', token.filename, token.loc.start.line);
42
+ },
43
+ });
44
+ edge.registerTag({
45
+ tagName: 'vite',
46
+ seekable: true,
47
+ block: false,
48
+ compile(parser, buffer, token) {
49
+ /**
50
+ * Ensure an argument is defined
51
+ */
52
+ if (!token.properties.jsArg.trim()) {
53
+ throw new EdgeError('Missing entrypoint name', 'E_RUNTIME_EXCEPTION', {
54
+ filename: token.filename,
55
+ line: token.loc.start.line,
56
+ col: token.loc.start.col,
57
+ });
58
+ }
59
+ const parsed = parser.utils.transformAst(parser.utils.generateAST(token.properties.jsArg, token.loc, token.filename), token.filename, parser);
60
+ const entrypoints = parser.utils.stringify(parsed);
61
+ buffer.outputExpression(`state.vite.generateEntryPointsTags(${entrypoints}).join('\\n')`, token.filename, token.loc.start.line, false);
62
+ },
63
+ });
64
+ };
65
+ };
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Content of the hotfile
2
+ * Contents of the hotfile
3
3
  */
4
4
  export type HotFile = {
5
5
  url: string;
@@ -16,3 +16,50 @@ export type SetAttributesCallbackParams = {
16
16
  * Can be either a record or a callback that returns a record.
17
17
  */
18
18
  export type SetAttributes = Record<string, string | boolean> | ((params: SetAttributesCallbackParams) => Record<string, string | boolean>);
19
+ /**
20
+ * Representation of an AdonisJS Vite Element returned
21
+ * by different tags generation APIs
22
+ */
23
+ export type AdonisViteElement = {
24
+ tag: 'link';
25
+ attributes: Record<string, any>;
26
+ } | {
27
+ tag: 'script';
28
+ attributes: Record<string, any>;
29
+ children: string[];
30
+ };
31
+ /**
32
+ * Vite backend integration configuration options
33
+ */
34
+ export type ViteOptions = {
35
+ /**
36
+ * Path to the hot file relative from the root of the
37
+ * application.
38
+ *
39
+ * @default public/assets/hot.json
40
+ */
41
+ hotFile: string;
42
+ /**
43
+ * Public directory where the assets will be compiled.
44
+ *
45
+ * @default 'public/assets'
46
+ */
47
+ buildDirectory: string;
48
+ /**
49
+ * The URL to prefix when generating assets URLs. For example: This
50
+ * could the CDN URL when generating the production build
51
+ *
52
+ * @default ''
53
+ */
54
+ assetsUrl?: string;
55
+ /**
56
+ * A custom set of attributes to apply on all
57
+ * script tags
58
+ */
59
+ scriptAttributes?: SetAttributes;
60
+ /**
61
+ * A custom set of attributes to apply on all
62
+ * style tags
63
+ */
64
+ styleAttributes?: SetAttributes;
65
+ };
@@ -2,3 +2,7 @@
2
2
  * Returns a new array with unique items by the given key
3
3
  */
4
4
  export declare function uniqBy<T>(array: T[], key: keyof T): T[];
5
+ /**
6
+ * Convert Record of attributes to a valid HTML string
7
+ */
8
+ export declare function makeAttributes(attributes: Record<string, string | boolean>): string;
@@ -16,3 +16,19 @@ export function uniqBy(array, key) {
16
16
  return seen.has(k) ? false : seen.add(k);
17
17
  });
18
18
  }
19
+ /**
20
+ * Convert Record of attributes to a valid HTML string
21
+ */
22
+ export function makeAttributes(attributes) {
23
+ return Object.keys(attributes)
24
+ .map((key) => {
25
+ const value = attributes[key];
26
+ if (value === true)
27
+ return key;
28
+ if (value === false)
29
+ return null;
30
+ return `${key}="${value}"`;
31
+ })
32
+ .filter((attr) => attr !== null)
33
+ .join(' ');
34
+ }
@@ -1,60 +1,28 @@
1
1
  import type { Manifest } from 'vite';
2
- import { SetAttributes } from './types/main.js';
3
- import { ApplicationService } from '@adonisjs/core/types';
2
+ import type { AdonisViteElement, ViteOptions } from './types/main.js';
3
+ /**
4
+ * Vite class exposes the APIs to generate tags and URLs for
5
+ * assets processed using vite.
6
+ */
4
7
  export declare class Vite {
5
8
  #private;
6
- private application;
7
- constructor(application: ApplicationService);
9
+ constructor(options: ViteOptions);
8
10
  /**
9
11
  * Generate tags for the entry points
10
12
  */
11
- generateEntryPointsTags(entryPoints: string[] | string): string;
13
+ generateEntryPointsTags(entryPoints: string[] | string): AdonisViteElement[];
12
14
  /**
13
15
  * Returns path to a given asset file
14
16
  */
15
17
  assetPath(asset: string): string;
16
18
  /**
17
- * Returns the manifest file content
19
+ * Returns the manifest file contents
18
20
  *
19
21
  * @throws Will throw an exception when running in hot mode
20
22
  */
21
23
  manifest(): Manifest;
22
24
  /**
23
25
  * Returns the script needed for the HMR working with React
24
- *
25
- * This method is called automatically when using edge tag `@viteReactRefresh`
26
- */
27
- getReactHmrScript(): string;
28
- /**
29
- * Set the path to the hotfile
30
- *
31
- * You must also set the `hotFile` option in the vite plugin config
32
- */
33
- setHotFilePath(path: string): this;
34
- /**
35
- * Set the manifest filename
36
- *
37
- * You must also set the `build.manifest` option in your vite configuration
38
- */
39
- setManifestFilename(name: string): this;
40
- /**
41
- * Set the build directory. Subdirectory of the AdonisJs public directory
42
- *
43
- * You must also set the `buildDirectory` option in the vite plugin config
44
- */
45
- setBuildDirectory(path: string): this;
46
- /**
47
- * Set the assets url
48
- *
49
- * You must also set the `assetsUrl` option in the vite plugin config
50
- */
51
- setAssetsUrl(url: string): this;
52
- /**
53
- * Include additional attributes to each script tag generated
54
- */
55
- setScriptAttributes(attributes: SetAttributes): this;
56
- /**
57
- * Include additional attributes to each style tag generated
58
26
  */
59
- setStyleAttributes(attributes: SetAttributes): this;
27
+ getReactHmrScript(): AdonisViteElement | null;
60
28
  }
@@ -7,54 +7,37 @@
7
7
  * file that was distributed with this source code.
8
8
  */
9
9
  import { join } from 'node:path';
10
- import { fileURLToPath } from 'node:url';
11
10
  import { existsSync, readFileSync } from 'node:fs';
12
- import { uniqBy } from './utils.js';
11
+ import debug from './debug.js';
12
+ import { makeAttributes, uniqBy } from './utils.js';
13
+ /**
14
+ * Vite class exposes the APIs to generate tags and URLs for
15
+ * assets processed using vite.
16
+ */
13
17
  export class Vite {
14
- application;
15
- /**
16
- * Path to the build directory
17
- *
18
- * @default 'public/assets'
19
- */
20
- #buildDirectory;
21
- /**
22
- * Path to the hotfile
23
- *
24
- * @default 'public/assets/hot.json'
25
- */
26
- #hotFile;
27
18
  /**
28
19
  * Manifest file name
29
20
  */
30
21
  #manifestFilename = 'manifest.json';
31
- /**
32
- * Assets URL
33
- */
34
- #assetsUrl = '';
35
22
  /**
36
23
  * We cache the manifest file content in production
37
24
  * to avoid reading the file multiple times
38
25
  */
39
26
  #manifestCache = null;
40
27
  /**
41
- * Attributes to be set on the style tags
42
- */
43
- #styleAttributes = {};
44
- /**
45
- * Attributes to be set on the script tags
28
+ * Configuration options
46
29
  */
47
- #scriptAttributes = {};
48
- constructor(application) {
49
- this.application = application;
50
- this.#buildDirectory = this.application.publicPath('assets');
51
- this.#hotFile = join(this.#buildDirectory, 'hot.json');
30
+ #options;
31
+ constructor(options) {
32
+ this.#options = options;
33
+ this.#options.assetsUrl = (this.#options.assetsUrl || '/').replace(/\/$/, '');
34
+ debug('vite config %O', this.#options);
52
35
  }
53
36
  /**
54
37
  * Checks if the application is running in hot mode
55
38
  */
56
39
  #isRunningHot() {
57
- return existsSync(this.#hotFile);
40
+ return existsSync(this.#options.hotFile);
58
41
  }
59
42
  /**
60
43
  * Reads the file contents as JSON
@@ -66,7 +49,7 @@ export class Vite {
66
49
  * Returns the parsed hot file content
67
50
  */
68
51
  #readHotFile() {
69
- return this.#readFileAsJSON(this.#hotFile);
52
+ return this.#readFileAsJSON(this.#options.hotFile);
70
53
  }
71
54
  /**
72
55
  * Get the path to an asset when running in hot mode
@@ -74,23 +57,91 @@ export class Vite {
74
57
  #hotAsset(asset) {
75
58
  return this.#readHotFile().url + '/' + asset;
76
59
  }
60
+ /**
61
+ * Unwrap attributes from the user defined function or return
62
+ * the attributes as it is
63
+ */
64
+ #unwrapAttributes(src, url, attributes) {
65
+ if (typeof attributes === 'function') {
66
+ return attributes({ src, url });
67
+ }
68
+ return attributes;
69
+ }
70
+ /**
71
+ * Create a script tag for the given path
72
+ */
73
+ #makeScriptTag(src, url) {
74
+ const customAttributes = this.#unwrapAttributes(src, url, this.#options.scriptAttributes);
75
+ const attributes = { type: 'module', ...customAttributes, src: url };
76
+ return this.#generateElement({
77
+ tag: 'script',
78
+ attributes,
79
+ children: [],
80
+ });
81
+ }
82
+ /**
83
+ * Create a style tag for the given path
84
+ */
85
+ #makeStyleTag(src, url) {
86
+ const customAttributes = this.#unwrapAttributes(src, url, this.#options.styleAttributes);
87
+ const attributes = { rel: 'stylesheet', ...customAttributes, href: url };
88
+ return this.#generateElement({
89
+ tag: 'link',
90
+ attributes,
91
+ });
92
+ }
93
+ /**
94
+ * Generate a HTML tag for the given asset
95
+ */
96
+ #generateTag(asset) {
97
+ let url = '';
98
+ if (this.#isRunningHot()) {
99
+ url = this.#hotAsset(asset);
100
+ }
101
+ else {
102
+ url = `${this.#options.assetsUrl}/${asset}`;
103
+ }
104
+ if (this.#isCssPath(asset)) {
105
+ return this.#makeStyleTag(asset, url);
106
+ }
107
+ return this.#makeScriptTag(asset, url);
108
+ }
109
+ /**
110
+ * Generates a JSON element with a custom toString implementation
111
+ */
112
+ #generateElement(element) {
113
+ return {
114
+ ...element,
115
+ toString() {
116
+ const attributes = `${makeAttributes(element.attributes)}`;
117
+ if (element.tag === 'link') {
118
+ return `<${element.tag} ${attributes}/>`;
119
+ }
120
+ return `<${element.tag} ${attributes}>${element.children.join('\n')}</${element.tag}>`;
121
+ },
122
+ };
123
+ }
77
124
  /**
78
125
  * Returns the script needed for the HMR working with Vite
79
126
  */
80
127
  #getViteHmrScript() {
81
- if (!this.#isRunningHot()) {
82
- return '';
83
- }
84
- return `<script type="module" src="${this.#hotAsset('@vite/client')}"></script>`;
128
+ return this.#generateElement({
129
+ tag: 'script',
130
+ attributes: {
131
+ type: 'module',
132
+ src: this.#hotAsset('@vite/client'),
133
+ },
134
+ children: [],
135
+ });
85
136
  }
86
137
  /**
87
138
  * Generate style and script tags for the given entrypoints
88
- * Also add the @vite/client script
139
+ * Also adds the @vite/client script
89
140
  */
90
- #generateEntryPointsTagsForHotmode(entryPoints) {
141
+ #generateEntryPointsTagsForHotMode(entryPoints) {
91
142
  const viteHmr = this.#getViteHmrScript();
92
143
  const tags = entryPoints.map((entrypoint) => this.#generateTag(entrypoint));
93
- return [viteHmr, ...tags].join('\n');
144
+ return viteHmr ? [viteHmr].concat(tags) : tags;
94
145
  }
95
146
  /**
96
147
  * Generate style and script tags for the given entrypoints
@@ -109,8 +160,7 @@ export class Vite {
109
160
  }
110
161
  return uniqBy(tags, 'path')
111
162
  .sort((a) => (a.path.endsWith('.css') ? -1 : 1))
112
- .map((preload) => preload.tag)
113
- .join('\n');
163
+ .map((tag) => tag.tag);
114
164
  }
115
165
  /**
116
166
  * Get a chunk from the manifest file for a given file name
@@ -138,71 +188,13 @@ export class Vite {
138
188
  #isCssPath(path) {
139
189
  return path.match(/\.(css|less|sass|scss|styl|stylus|pcss|postcss)$/) !== null;
140
190
  }
141
- /**
142
- * Generate a HTML tag for the given asset
143
- */
144
- #generateTag(asset) {
145
- let url = '';
146
- if (this.#isRunningHot()) {
147
- url = this.#hotAsset(asset);
148
- }
149
- else {
150
- url = `${this.#assetsUrl}/assets/${asset}`;
151
- }
152
- if (this.#isCssPath(asset)) {
153
- return this.#makeStyleTag(asset, url);
154
- }
155
- return this.#makeScriptTag(asset, url);
156
- }
157
- /**
158
- * Unwrap attributes from the user defined function or return
159
- * the attributes as it is
160
- */
161
- #unwrapAttributes(src, url, attributes) {
162
- if (typeof attributes === 'function') {
163
- return attributes({ src, url });
164
- }
165
- return attributes;
166
- }
167
- /**
168
- * Convert Record of attributes to a valid HTML string
169
- */
170
- #makeAttributes(attributes) {
171
- return Object.keys(attributes)
172
- .map((key) => {
173
- const value = attributes[key];
174
- if (value === true)
175
- return key;
176
- if (value === false)
177
- return null;
178
- return `${key}="${value}"`;
179
- })
180
- .filter((attr) => attr !== null)
181
- .join(' ');
182
- }
183
- /**
184
- * Create a script tag for the given path
185
- */
186
- #makeScriptTag(src, url) {
187
- const customAttributes = this.#unwrapAttributes(src, url, this.#scriptAttributes);
188
- const attributes = { type: 'module', ...customAttributes };
189
- return `<script ${this.#makeAttributes(attributes)} src="${url}"></script>`;
190
- }
191
- /**
192
- * Create a style tag for the given path
193
- */
194
- #makeStyleTag(src, url) {
195
- const customAttributes = this.#unwrapAttributes(src, url, this.#styleAttributes);
196
- const attributes = { rel: 'stylesheet', ...customAttributes };
197
- return `<link ${this.#makeAttributes(attributes)} href="${url}">`;
198
- }
199
191
  /**
200
192
  * Generate tags for the entry points
201
193
  */
202
194
  generateEntryPointsTags(entryPoints) {
203
195
  entryPoints = Array.isArray(entryPoints) ? entryPoints : [entryPoints];
204
196
  if (this.#isRunningHot()) {
205
- return this.#generateEntryPointsTagsForHotmode(entryPoints);
197
+ return this.#generateEntryPointsTagsForHotMode(entryPoints);
206
198
  }
207
199
  return this.#generateEntryPointsTagsWithManifest(entryPoints);
208
200
  }
@@ -214,10 +206,10 @@ export class Vite {
214
206
  return this.#hotAsset(asset);
215
207
  }
216
208
  const chunk = this.#chunk(this.manifest(), asset);
217
- return `${this.#assetsUrl}/assets/${chunk.file}`;
209
+ return `${this.#options.assetsUrl}/${chunk.file}`;
218
210
  }
219
211
  /**
220
- * Returns the manifest file content
212
+ * Returns the manifest file contents
221
213
  *
222
214
  * @throws Will throw an exception when running in hot mode
223
215
  */
@@ -225,88 +217,32 @@ export class Vite {
225
217
  if (this.#isRunningHot()) {
226
218
  throw new Error('Cannot read the manifest file when running in hot mode');
227
219
  }
228
- /**
229
- * Use in-memory cache when available
230
- */
231
- if (this.#manifestCache) {
232
- return this.#manifestCache;
220
+ if (!this.#manifestCache) {
221
+ this.#manifestCache = this.#readFileAsJSON(join(this.#options.buildDirectory, this.#manifestFilename));
233
222
  }
234
- const manifest = this.#readFileAsJSON(join(this.#buildDirectory, this.#manifestFilename));
235
- /**
236
- * Cache the manifest in production to avoid re-reading the file from disk
237
- */
238
- if (this.application.inProduction) {
239
- this.#manifestCache = manifest;
240
- }
241
- return manifest;
223
+ return this.#manifestCache;
242
224
  }
243
225
  /**
244
226
  * Returns the script needed for the HMR working with React
245
- *
246
- * This method is called automatically when using edge tag `@viteReactRefresh`
247
227
  */
248
228
  getReactHmrScript() {
249
229
  if (!this.#isRunningHot()) {
250
- return '';
230
+ return null;
251
231
  }
252
- return `
253
- <script type="module">
254
- import RefreshRuntime from '${this.#hotAsset('@react-refresh')}'
255
- RefreshRuntime.injectIntoGlobalHook(window)
256
- window.$RefreshReg$ = () => {}
257
- window.$RefreshSig$ = () => (type) => type
258
- window.__vite_plugin_react_preamble_installed__ = true
259
- </script>
260
- `;
261
- }
262
- /**
263
- * Set the path to the hotfile
264
- *
265
- * You must also set the `hotFile` option in the vite plugin config
266
- */
267
- setHotFilePath(path) {
268
- this.#hotFile = join(fileURLToPath(this.application.appRoot), path);
269
- return this;
270
- }
271
- /**
272
- * Set the manifest filename
273
- *
274
- * You must also set the `build.manifest` option in your vite configuration
275
- */
276
- setManifestFilename(name) {
277
- this.#manifestFilename = name;
278
- return this;
279
- }
280
- /**
281
- * Set the build directory. Subdirectory of the AdonisJs public directory
282
- *
283
- * You must also set the `buildDirectory` option in the vite plugin config
284
- */
285
- setBuildDirectory(path) {
286
- this.#buildDirectory = this.application.publicPath(path);
287
- return this;
288
- }
289
- /**
290
- * Set the assets url
291
- *
292
- * You must also set the `assetsUrl` option in the vite plugin config
293
- */
294
- setAssetsUrl(url) {
295
- this.#assetsUrl = url.endsWith('/') ? url : `${url}/`;
296
- return this;
297
- }
298
- /**
299
- * Include additional attributes to each script tag generated
300
- */
301
- setScriptAttributes(attributes) {
302
- this.#scriptAttributes = attributes;
303
- return this;
304
- }
305
- /**
306
- * Include additional attributes to each style tag generated
307
- */
308
- setStyleAttributes(attributes) {
309
- this.#styleAttributes = attributes;
310
- return this;
232
+ return this.#generateElement({
233
+ tag: 'script',
234
+ attributes: {
235
+ type: 'module',
236
+ },
237
+ children: [
238
+ '',
239
+ `import RefreshRuntime from '${this.#hotAsset('@react-refresh')}'`,
240
+ `RefreshRuntime.injectIntoGlobalHook(window)`,
241
+ `window.$RefreshReg$ = () => {}`,
242
+ `window.$RefreshSig$ = () => (type) => type`,
243
+ `window.__vite_plugin_react_preamble_installed__ = true`,
244
+ '',
245
+ ],
246
+ });
311
247
  }
312
248
  }
@@ -1,5 +1,5 @@
1
1
  import { ConfigEnv, Plugin, UserConfig } from 'vite';
2
- import { PluginFullOptions } from './types/index.js';
2
+ import type { PluginFullOptions } from './types.js';
3
3
  /**
4
4
  * Vite config hook
5
5
  */
@@ -1,5 +1,5 @@
1
1
  import { ResolvedConfig, UserConfig, AliasOptions } from 'vite';
2
- import { PluginFullOptions } from './types/index.js';
2
+ import { PluginFullOptions } from './types.js';
3
3
  export declare class ConfigResolver {
4
4
  static resolvedConfig?: ResolvedConfig;
5
5
  /**
@@ -7,7 +7,6 @@
7
7
  * file that was distributed with this source code.
8
8
  */
9
9
  import { addTrailingSlash } from './utils.js';
10
- import { join } from 'node:path';
11
10
  export class ConfigResolver {
12
11
  static resolvedConfig;
13
12
  /**
@@ -18,7 +17,7 @@ export class ConfigResolver {
18
17
  return config.base;
19
18
  }
20
19
  if (command === 'build') {
21
- return addTrailingSlash(options.assetsUrl) + addTrailingSlash(options.buildDirectory);
20
+ return addTrailingSlash(options.assetsUrl);
22
21
  }
23
22
  return '/';
24
23
  }
@@ -42,6 +41,6 @@ export class ConfigResolver {
42
41
  * Resolve the `config.build.outDir` value
43
42
  */
44
43
  static resolveOutDir(config, options) {
45
- return config.build?.outDir ?? join(options.publicDirectory, options.buildDirectory);
44
+ return config.build?.outDir ?? options.buildDirectory;
46
45
  }
47
46
  }
@@ -0,0 +1,6 @@
1
+ import { PluginOption } from 'vite';
2
+ import type { PluginOptions } from './types.js';
3
+ /**
4
+ * Vite plugin for adonisjs
5
+ */
6
+ export default function adonisjs(options: PluginOptions): PluginOption[];
@@ -7,20 +7,17 @@
7
7
  * file that was distributed with this source code.
8
8
  */
9
9
  import { defu } from 'defu';
10
- import { config } from './config.js';
11
10
  import PluginRestart from 'vite-plugin-restart';
12
- import { join } from 'node:path';
11
+ import { config } from './config.js';
13
12
  const VitePluginRestart = PluginRestart;
14
13
  /**
15
- * Vite plugin for AdonisJS
14
+ * Vite plugin for adonisjs
16
15
  */
17
- export default function Adonis(options) {
18
- const hotfileDefaultDestination = join(options.publicDirectory || 'public', options.buildDirectory || 'assets', 'hot.json');
16
+ export default function adonisjs(options) {
19
17
  const fullOptions = defu(options, {
20
- publicDirectory: 'public',
21
- buildDirectory: 'assets',
22
- assetsUrl: '',
23
- hotFile: hotfileDefaultDestination,
18
+ buildDirectory: 'public/assets',
19
+ assetsUrl: '/assets',
20
+ hotFile: 'public/assets/hot.json',
24
21
  reload: ['./resources/views/**/*.edge'],
25
22
  });
26
23
  return [VitePluginRestart({ reload: fullOptions.reload }), config(fullOptions)];
@@ -12,12 +12,6 @@ export type PluginOptions = {
12
12
  * Paths to the entrypoints files
13
13
  */
14
14
  entrypoints: string[];
15
- /**
16
- * Path to your AdonisJS public directory
17
- *
18
- * @default 'public'
19
- */
20
- publicDirectory?: string;
21
15
  /**
22
16
  * The URL where the assets will be served. This is particularly
23
17
  * useful if you are using a CDN to deploy your assets.
@@ -26,9 +20,9 @@ export type PluginOptions = {
26
20
  */
27
21
  assetsUrl?: string;
28
22
  /**
29
- * Public subdirectory where the assets will be compiled.
23
+ * Public directory where the assets will be compiled.
30
24
  *
31
- * @default 'assets'
25
+ * @default 'public/assets'
32
26
  */
33
27
  buildDirectory?: string;
34
28
  /**
@@ -0,0 +1,22 @@
1
+ ---
2
+ to: {{ destination }}
3
+ ---
4
+ import { defineConfig } from 'vite'
5
+ import adonisjs from '@adonisjs/vite/client'
6
+
7
+ export default defineConfig({
8
+ plugins: [
9
+ adonisjs({
10
+ /**
11
+ * Entrypoints of your application. Each entrypoint will
12
+ * result in a separate bundle.
13
+ */
14
+ entrypoints: ['resources/js/app.js'],
15
+
16
+ /**
17
+ * Paths to watch and reload the browser on file change
18
+ */
19
+ reloads: ['resources/views/**/*.edge'],
20
+ }),
21
+ ],
22
+ })
@@ -0,0 +1,21 @@
1
+ ---
2
+ to: {{ app.configPath('vite.ts') }}
3
+ ---
4
+ import { defineConfig } from '@adonisjs/vite'
5
+
6
+ const viteBackendConfig = defineConfig({
7
+ /**
8
+ * The output of vite will be written inside this
9
+ * directory. The path should be relative from
10
+ * the application root.
11
+ */
12
+ buildDirectory: 'public/assets',
13
+
14
+ /**
15
+ * Feel free to change the value of the "assetsUrl" to
16
+ * point to a CDN in production.
17
+ */
18
+ assetsUrl: '/assets',
19
+ })
20
+
21
+ export default viteBackendConfig
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@adonisjs/vite",
3
3
  "description": "Vite plugin for Adonis.js",
4
- "version": "0.0.1-4",
4
+ "version": "0.0.1-6",
5
5
  "engines": {
6
6
  "node": ">=18.16.0"
7
7
  },
@@ -20,10 +20,10 @@
20
20
  "exports": {
21
21
  ".": "./build/index.js",
22
22
  "./services/main": "./build/services/vite.js",
23
- "./vite_provider": "./build/vite_provider.js",
24
- "./plugin": "./build/src/vite_plugin/index.js",
25
- "./types": "./build/src/backend/types.js",
26
- "./types/extended": "./build/src/backend/types/extended.js"
23
+ "./vite_provider": "./build/providers/vite_provider.js",
24
+ "./client": "./build/src/client/main.js",
25
+ "./plugin_edge": "./build/backend/edge_plugin_vite.js",
26
+ "./types": "./build/src/backend/types.js"
27
27
  },
28
28
  "scripts": {
29
29
  "clean": "del-cli build",
@@ -42,23 +42,22 @@
42
42
  "prepublishOnly": "npm run build"
43
43
  },
44
44
  "devDependencies": {
45
- "@adonisjs/core": "^6.1.5-11",
45
+ "@adonisjs/core": "^6.1.5-15",
46
46
  "@adonisjs/eslint-config": "^1.1.8",
47
47
  "@adonisjs/prettier-config": "^1.1.8",
48
48
  "@adonisjs/tsconfig": "^1.1.8",
49
- "@adonisjs/view": "^7.0.0-5",
50
49
  "@commitlint/cli": "^17.6.7",
51
50
  "@commitlint/config-conventional": "^17.6.7",
52
51
  "@japa/assert": "^2.0.0-1",
53
52
  "@japa/expect-type": "^2.0.0-0",
54
53
  "@japa/file-system": "^2.0.0-1",
55
54
  "@japa/runner": "^3.0.0-6",
56
- "@poppinss/dev-utils": "^2.0.3",
57
55
  "@swc/core": "^1.3.70",
58
56
  "@types/node": "^20.4.4",
59
57
  "c8": "^8.0.0",
60
58
  "copyfiles": "^2.4.1",
61
59
  "del-cli": "^5.0.0",
60
+ "edge.js": "^6.0.0-6",
62
61
  "eslint": "^8.45.0",
63
62
  "husky": "^8.0.3",
64
63
  "np": "^8.0.4",
@@ -66,16 +65,15 @@
66
65
  "rollup": "^3.26.3",
67
66
  "ts-node": "^10.9.1",
68
67
  "typescript": "^5.1.6",
69
- "vite": "^4.4.6"
68
+ "vite": "^4.4.9"
70
69
  },
71
70
  "dependencies": {
72
71
  "defu": "^6.1.2",
73
- "edge-error": "^3.0.0",
72
+ "edge-error": "^4.0.0-0",
74
73
  "vite-plugin-restart": "^0.3.1"
75
74
  },
76
75
  "peerDependencies": {
77
- "@adonisjs/core": "^6.1.5-11",
78
- "@adonisjs/view": "^7.0.0-5"
76
+ "@adonisjs/core": "^6.1.5-15"
79
77
  },
80
78
  "author": "Julien Ripouteau <julien@ripouteau.com>",
81
79
  "license": "MIT",
@@ -120,7 +118,8 @@
120
118
  "html"
121
119
  ],
122
120
  "exclude": [
123
- "tests/**"
121
+ "tests/**",
122
+ "tests_helpers/**"
124
123
  ]
125
124
  },
126
125
  "directories": {
@@ -1,6 +0,0 @@
1
- import { PluginOption } from 'vite';
2
- import { PluginOptions } from './types/index.js';
3
- /**
4
- * Vite plugin for AdonisJS
5
- */
6
- export default function Adonis(options: PluginOptions): PluginOption[];
@@ -1,18 +0,0 @@
1
- ---
2
- to: {{ destination }}
3
- ---
4
-
5
- import { defineConfig } from "vite";
6
- import Adonis from "@adonisjs/vite/plugin";
7
-
8
- export default defineConfig({
9
- plugins: [
10
- Adonis({
11
- /**
12
- * Entrypoints of your application. Each entrypoint will
13
- * result in a separate bundle.
14
- */
15
- entrypoints: ["resources/js/app.js"],
16
- }),
17
- ],
18
- });
@@ -7,10 +7,10 @@
7
7
  * file that was distributed with this source code.
8
8
  */
9
9
  import { defu } from 'defu';
10
- import { resolveDevServerUrl } from './utils.js';
10
+ import { join } from 'node:path';
11
11
  import { HotFile } from './hot_file.js';
12
+ import { resolveDevServerUrl } from './utils.js';
12
13
  import { ConfigResolver } from './config_resolver.js';
13
- import { join } from 'node:path';
14
14
  /**
15
15
  * Vite config hook
16
16
  */
File without changes
@@ -6,9 +6,9 @@
6
6
  * For the full copyright and license information, please view the LICENSE
7
7
  * file that was distributed with this source code.
8
8
  */
9
+ import { dirname, join } from 'node:path';
9
10
  import { existsSync, rmSync } from 'node:fs';
10
11
  import { mkdir, writeFile } from 'node:fs/promises';
11
- import { dirname, join } from 'node:path';
12
12
  import { ConfigResolver } from './config_resolver.js';
13
13
  export class HotFile {
14
14
  /**
@@ -1,5 +1,5 @@
1
- import { AddressInfo } from 'node:net';
2
1
  import { ResolvedConfig } from 'vite';
2
+ import { AddressInfo } from 'node:net';
3
3
  /**
4
4
  * Resolve the dev server URL from the server address and configuration.
5
5
  */
File without changes