vuetify-nuxt-module 0.0.1
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/LICENSE +21 -0
- package/README.md +93 -0
- package/configuration.d.ts +6 -0
- package/dist/module.cjs +5 -0
- package/dist/module.d.ts +46 -0
- package/dist/module.json +8 -0
- package/dist/module.mjs +326 -0
- package/dist/runtime/templates/plugin.mts +30 -0
- package/dist/types.d.ts +15 -0
- package/package.json +94 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023-PRESENT Joaquín Sánchez <https://github.com/userquin>
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
<p align='center'>
|
|
2
|
+
<img src='./hero.svg' alt="vuetify-nuxt-module - Zero-config Nuxt module for Vuetify"><br>
|
|
3
|
+
Zero-config Nuxt module for Vuetify
|
|
4
|
+
</p>
|
|
5
|
+
|
|
6
|
+
<p align='center'>
|
|
7
|
+
<a href='https://www.npmjs.com/package/vuetify-nuxt-module' target="__blank">
|
|
8
|
+
<img src='https://img.shields.io/npm/v/vuetify-nuxt-module?color=33A6B8&label=' alt="NPM version">
|
|
9
|
+
</a>
|
|
10
|
+
<a href="https://www.npmjs.com/package/vuetify-nuxt-module" target="__blank">
|
|
11
|
+
<img alt="NPM Downloads" src="https://img.shields.io/npm/dm/vuetify-nuxt-module?color=476582&label=">
|
|
12
|
+
</a>
|
|
13
|
+
<!--
|
|
14
|
+
<a href="https://vite-pwa-org.netlify.app/frameworks/nuxt" target="__blank">
|
|
15
|
+
<img src="https://img.shields.io/static/v1?label=&message=docs%20%26%20guides&color=2e859c" alt="Docs & Guides">
|
|
16
|
+
</a>
|
|
17
|
+
-->
|
|
18
|
+
<br>
|
|
19
|
+
<a href="https://github.com/userquin/vuetify-nuxt-module" target="__blank">
|
|
20
|
+
<img alt="GitHub stars" src="https://img.shields.io/github/stars/userquin/vuetify-nuxt-module?style=social">
|
|
21
|
+
</a>
|
|
22
|
+
</p>
|
|
23
|
+
|
|
24
|
+
<br>
|
|
25
|
+
|
|
26
|
+
## 🚀 Features
|
|
27
|
+
|
|
28
|
+
- 📖 [**Documentation & guides**](README.md#-features) (WIP)
|
|
29
|
+
- 👌 **Zero-Config**: sensible built-in default [Vuetify](https://vuetifyjs.com/) configuration for common use cases
|
|
30
|
+
- 🔩 **Extensible**: expose the ability to customize the Vuetify configuration via [Nuxt Plugin Hooks](https://nuxt.com/docs/guide/going-further/hooks#usage-with-plugins)
|
|
31
|
+
- ⚡ **Fully tree shakable**: by default, only the needed Vuetify components are imported
|
|
32
|
+
- 🛠️ **Versatile**: custom Vuetify [directives](https://vuetifyjs.com/en/getting-started/installation/#manual-steps) and [labs components](https://vuetifyjs.com/en/labs/introduction/) registration
|
|
33
|
+
- ✨ **Configurable styles**: configure your variables using [Vuetify SASS Variables](https://vuetifyjs.com/en/features/sass-variables/)
|
|
34
|
+
- 💥 **SSR**: automatic SSR detection and configuration
|
|
35
|
+
- 🦾 **Type Strong**: written in [TypeScript](https://www.typescriptlang.org/)
|
|
36
|
+
|
|
37
|
+
## 📦 Install
|
|
38
|
+
|
|
39
|
+
> Requires Vite 3.2.0+, will not work with Webpack
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
npm i vuetify-nuxt-module -D
|
|
43
|
+
|
|
44
|
+
# yarn
|
|
45
|
+
yarn add vuetify-nuxt-module -D
|
|
46
|
+
|
|
47
|
+
# pnpm
|
|
48
|
+
pnpm add vuetify-nuxt-module -D
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## 🦄 Usage
|
|
52
|
+
|
|
53
|
+
> `vuetify-nuxt-module` is strongly opinionated and has a built-in default configuration out of the box. You can use it without any configuration, and it will work for most use cases.
|
|
54
|
+
|
|
55
|
+
Add `vuetify-nuxt-module` module to `nuxt.config.ts` and configure it:
|
|
56
|
+
|
|
57
|
+
```ts
|
|
58
|
+
// nuxt.config.ts
|
|
59
|
+
import { defineNuxtConfig } from 'nuxt/config'
|
|
60
|
+
|
|
61
|
+
export default defineNuxtConfig({
|
|
62
|
+
modules: [
|
|
63
|
+
'vuetify-nuxt-module'
|
|
64
|
+
],
|
|
65
|
+
vuetify: {
|
|
66
|
+
moduleOptions: {
|
|
67
|
+
/* module specific options */
|
|
68
|
+
},
|
|
69
|
+
vuetifyOptions: {
|
|
70
|
+
/* vuetify options */
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
})
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
<!--
|
|
77
|
+
Read the [📖 documentation](https://vite-pwa-org.netlify.app/frameworks/nuxt) for a complete guide on how to configure and use
|
|
78
|
+
this plugin.
|
|
79
|
+
-->
|
|
80
|
+
|
|
81
|
+
## 👀 Full config
|
|
82
|
+
|
|
83
|
+
**WIP**
|
|
84
|
+
<!--
|
|
85
|
+
Check out the type declaration [src/types.ts](./src/types.ts) and the following links for more details.
|
|
86
|
+
|
|
87
|
+
- [Web app manifests](https://developer.mozilla.org/en-US/docs/Web/Manifest)
|
|
88
|
+
- [Workbox](https://developers.google.com/web/tools/workbox)
|
|
89
|
+
-->
|
|
90
|
+
|
|
91
|
+
## 📄 License
|
|
92
|
+
|
|
93
|
+
[MIT](./LICENSE) License © 2023-PRESENT [Joaquín Sánchez](https://github.com/userquin)
|
package/dist/module.cjs
ADDED
package/dist/module.d.ts
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import * as _nuxt_schema from '@nuxt/schema';
|
|
2
|
+
import { VuetifyOptions } from 'vuetify';
|
|
3
|
+
|
|
4
|
+
type BooleanOrArrayString = boolean | string[];
|
|
5
|
+
interface VOptions extends Partial<Omit<VuetifyOptions, 'ssr' | 'directives'>> {
|
|
6
|
+
/**
|
|
7
|
+
* Include the lab components?
|
|
8
|
+
*
|
|
9
|
+
* You can include all lab components configuring `labComponents: true`.
|
|
10
|
+
*
|
|
11
|
+
* You can provide an array with the names of the lab components to include.
|
|
12
|
+
*
|
|
13
|
+
* @see https://vuetifyjs.com/en/labs/introduction/
|
|
14
|
+
*
|
|
15
|
+
* @default false
|
|
16
|
+
*/
|
|
17
|
+
labComponents?: BooleanOrArrayString;
|
|
18
|
+
/**
|
|
19
|
+
* Include the directives?
|
|
20
|
+
*
|
|
21
|
+
* You can include all directives configuring `directives: true`.
|
|
22
|
+
*
|
|
23
|
+
* You can provide an array with the names of the directives to include.
|
|
24
|
+
*
|
|
25
|
+
* @default false
|
|
26
|
+
*/
|
|
27
|
+
directives?: BooleanOrArrayString;
|
|
28
|
+
}
|
|
29
|
+
interface ModuleOptions {
|
|
30
|
+
moduleOptions?: {
|
|
31
|
+
writePlugin?: boolean;
|
|
32
|
+
styles?: true | 'none' | 'expose' | 'sass' | {
|
|
33
|
+
configFile: string;
|
|
34
|
+
};
|
|
35
|
+
};
|
|
36
|
+
vuetifyOptions?: VOptions;
|
|
37
|
+
}
|
|
38
|
+
declare module '#app' {
|
|
39
|
+
interface RuntimeNuxtHooks {
|
|
40
|
+
'vuetify:configuration': (vuetifyOptions: VuetifyOptions) => void;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
declare const _default: _nuxt_schema.NuxtModule<ModuleOptions>;
|
|
45
|
+
|
|
46
|
+
export { BooleanOrArrayString, ModuleOptions, VOptions, _default as default };
|
package/dist/module.json
ADDED
package/dist/module.mjs
ADDED
|
@@ -0,0 +1,326 @@
|
|
|
1
|
+
import { useLogger, defineNuxtModule, createResolver, extendWebpackConfig, addPluginTemplate } from '@nuxt/kit';
|
|
2
|
+
import defu from 'defu';
|
|
3
|
+
import vuetify from 'vite-plugin-vuetify';
|
|
4
|
+
import { utimes } from 'node:fs/promises';
|
|
5
|
+
import { resolveVuetifyBase, normalizePath, writeStyles, cacheDir } from '@vuetify/loader-shared';
|
|
6
|
+
import * as path from 'upath';
|
|
7
|
+
import { normalizePath as normalizePath$1 } from 'vite';
|
|
8
|
+
|
|
9
|
+
const version = "0.0.1";
|
|
10
|
+
|
|
11
|
+
function isSubdir(root, test) {
|
|
12
|
+
const relative = path.relative(root, test);
|
|
13
|
+
return relative && !relative.startsWith("..") && !path.isAbsolute(relative);
|
|
14
|
+
}
|
|
15
|
+
const styleImportRegexp = /(@use |meta\.load-css\()['"](vuetify(?:\/lib)?(?:\/styles(?:\/main(?:\.sass)?)?)?)['"]/;
|
|
16
|
+
function stylesPlugin(options, logger) {
|
|
17
|
+
const vuetifyBase = resolveVuetifyBase();
|
|
18
|
+
const files = /* @__PURE__ */ new Set();
|
|
19
|
+
let server;
|
|
20
|
+
let context;
|
|
21
|
+
let resolve;
|
|
22
|
+
let promise;
|
|
23
|
+
let needsTouch = false;
|
|
24
|
+
const blockingModules = /* @__PURE__ */ new Set();
|
|
25
|
+
let pendingModules;
|
|
26
|
+
async function getPendingModules() {
|
|
27
|
+
if (!server) {
|
|
28
|
+
await new Promise((resolve2) => setTimeout(resolve2, 0));
|
|
29
|
+
const modules = Array.from(context.getModuleIds()).filter((id) => {
|
|
30
|
+
return !blockingModules.has(id) && !/\w\.(s[ac]|c)ss/.test(id);
|
|
31
|
+
}).map((id) => context.getModuleInfo(id)).filter((module) => module.code == null);
|
|
32
|
+
pendingModules = modules.map((module) => module.id);
|
|
33
|
+
if (!pendingModules.length)
|
|
34
|
+
return 0;
|
|
35
|
+
const promises = modules.map((module) => context.load(module));
|
|
36
|
+
await Promise.race(promises);
|
|
37
|
+
return promises.length;
|
|
38
|
+
} else {
|
|
39
|
+
const modules = Array.from(server.moduleGraph.urlToModuleMap.entries()).filter(([k, v]) => v.transformResult == null && !k.startsWith("/@id/") && !/\w\.(s[ac]|c)ss/.test(k) && !blockingModules.has(v.id) && !/\/node_modules\/\.vite\/deps\/(?!vuetify[._])/.test(k));
|
|
40
|
+
pendingModules = modules.map(([, v]) => v.id);
|
|
41
|
+
if (!pendingModules.length)
|
|
42
|
+
return 0;
|
|
43
|
+
const promises = modules.map(([k, v]) => server.transformRequest(k).then(() => v));
|
|
44
|
+
await Promise.race(promises);
|
|
45
|
+
return promises.length;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
let timeout;
|
|
49
|
+
async function awaitBlocking() {
|
|
50
|
+
let pending;
|
|
51
|
+
do {
|
|
52
|
+
clearTimeout(timeout);
|
|
53
|
+
timeout = setTimeout(() => {
|
|
54
|
+
console.error("vuetify:styles fallback timeout hit", {
|
|
55
|
+
blockingModules: Array.from(blockingModules.values()),
|
|
56
|
+
pendingModules,
|
|
57
|
+
// @ts-expect-error not exported?
|
|
58
|
+
pendingRequests: server?._pendingRequests.keys()
|
|
59
|
+
});
|
|
60
|
+
resolve(false);
|
|
61
|
+
}, options.stylesTimeout);
|
|
62
|
+
pending = await Promise.any([
|
|
63
|
+
promise,
|
|
64
|
+
getPendingModules()
|
|
65
|
+
]);
|
|
66
|
+
logger.info(pending, "pending modules", pendingModules);
|
|
67
|
+
} while (pending);
|
|
68
|
+
resolve(false);
|
|
69
|
+
}
|
|
70
|
+
async function awaitResolve(id) {
|
|
71
|
+
if (id)
|
|
72
|
+
blockingModules.add(id);
|
|
73
|
+
if (!promise) {
|
|
74
|
+
promise = new Promise((_resolve) => resolve = _resolve);
|
|
75
|
+
awaitBlocking();
|
|
76
|
+
await promise;
|
|
77
|
+
clearTimeout(timeout);
|
|
78
|
+
blockingModules.clear();
|
|
79
|
+
logger.info("writing styles");
|
|
80
|
+
await writeStyles(files);
|
|
81
|
+
if (server && needsTouch) {
|
|
82
|
+
const cacheFile = normalizePath$1(cacheDir("styles.scss"));
|
|
83
|
+
logger.log("cacheFile", cacheFile);
|
|
84
|
+
server.moduleGraph.getModulesByFile(cacheFile)?.forEach((module) => {
|
|
85
|
+
module.importers.forEach((module2) => {
|
|
86
|
+
if (module2.file) {
|
|
87
|
+
const now = /* @__PURE__ */ new Date();
|
|
88
|
+
logger.info(`touching ${module2.file}`);
|
|
89
|
+
utimes(module2.file, now, now);
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
needsTouch = false;
|
|
94
|
+
}
|
|
95
|
+
promise = null;
|
|
96
|
+
}
|
|
97
|
+
return promise;
|
|
98
|
+
}
|
|
99
|
+
let configFile;
|
|
100
|
+
const tempFiles = /* @__PURE__ */ new Map();
|
|
101
|
+
return {
|
|
102
|
+
name: "vuetify:styles:nuxt",
|
|
103
|
+
enforce: "pre",
|
|
104
|
+
configureServer(_server) {
|
|
105
|
+
server = _server;
|
|
106
|
+
},
|
|
107
|
+
buildStart() {
|
|
108
|
+
if (!server) {
|
|
109
|
+
context = this;
|
|
110
|
+
}
|
|
111
|
+
},
|
|
112
|
+
configResolved(config) {
|
|
113
|
+
if (typeof options.styles === "object") {
|
|
114
|
+
if (path.isAbsolute(options.styles.configFile))
|
|
115
|
+
configFile = options.styles.configFile;
|
|
116
|
+
else
|
|
117
|
+
configFile = path.join(config.root || process.cwd(), options.styles.configFile);
|
|
118
|
+
}
|
|
119
|
+
},
|
|
120
|
+
async resolveId(source, importer, { custom }) {
|
|
121
|
+
if (source === "vuetify/styles" || importer && source.endsWith(".css") && isSubdir(vuetifyBase, path.isAbsolute(source) ? source : importer)) {
|
|
122
|
+
if (options.styles === "none") {
|
|
123
|
+
return "/@plugin-vuetify/lib/__void__";
|
|
124
|
+
} else if (options.styles === "sass") {
|
|
125
|
+
const target = source.replace(/\.css$/, ".sass");
|
|
126
|
+
return this.resolve(target, importer, { skipSelf: true, custom });
|
|
127
|
+
} else if (options.styles === "expose") {
|
|
128
|
+
awaitResolve();
|
|
129
|
+
const resolution = await this.resolve(
|
|
130
|
+
source.replace(/\.css$/, ".sass"),
|
|
131
|
+
importer,
|
|
132
|
+
{ skipSelf: true, custom }
|
|
133
|
+
);
|
|
134
|
+
if (resolution) {
|
|
135
|
+
if (!files.has(resolution.id)) {
|
|
136
|
+
needsTouch = true;
|
|
137
|
+
files.add(resolution.id);
|
|
138
|
+
}
|
|
139
|
+
return "/@plugin-vuetify/lib/__void__";
|
|
140
|
+
}
|
|
141
|
+
} else if (typeof options.styles === "object") {
|
|
142
|
+
const resolution = await this.resolve(source, importer, { skipSelf: true, custom });
|
|
143
|
+
if (!resolution)
|
|
144
|
+
return null;
|
|
145
|
+
const target = resolution.id.replace(/\.css$/, ".sass");
|
|
146
|
+
const file = path.relative(path.join(vuetifyBase, "lib"), target);
|
|
147
|
+
const contents = `@use "${normalizePath(configFile)}"
|
|
148
|
+
@use "${normalizePath(target)}"`;
|
|
149
|
+
tempFiles.set(file, contents);
|
|
150
|
+
return `/@plugin-vuetify/lib/${file}`;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
return null;
|
|
154
|
+
},
|
|
155
|
+
async transform(code, id) {
|
|
156
|
+
if (options.styles === "expose" && [".scss", ".sass"].some((v) => id.endsWith(v)) && styleImportRegexp.test(code)) {
|
|
157
|
+
logger.info(`awaiting ${id}`);
|
|
158
|
+
await awaitResolve(id);
|
|
159
|
+
logger.info(`returning ${id}`);
|
|
160
|
+
return {
|
|
161
|
+
code: code.replace(styleImportRegexp, '$1".cache/vuetify/styles.scss"'),
|
|
162
|
+
map: null
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
},
|
|
166
|
+
load(id) {
|
|
167
|
+
if (/^\/@plugin-vuetify\/lib\/__void__(\?.*)?$/.test(id))
|
|
168
|
+
return "";
|
|
169
|
+
if (id.startsWith("/@plugin-vuetify/lib/")) {
|
|
170
|
+
const file = /^\/@plugin-vuetify\/lib\/(.*?)(\?.*)?$/.exec(id)[1];
|
|
171
|
+
return tempFiles.get(file);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
function vuetifyConfigurationPlugin(isDev, directives, labComponents, vuetifyAppOptions) {
|
|
178
|
+
const VIRTUAL_VUETIFY_CONFIGURATION = "virtual:vuetify-configuration";
|
|
179
|
+
const RESOLVED_VIRTUAL_VUETIFY_CONFIGURATION = `\0${VIRTUAL_VUETIFY_CONFIGURATION}`;
|
|
180
|
+
return {
|
|
181
|
+
name: "vuetify:configuration:nuxt",
|
|
182
|
+
enforce: "pre",
|
|
183
|
+
resolveId(id) {
|
|
184
|
+
if (id === VIRTUAL_VUETIFY_CONFIGURATION)
|
|
185
|
+
return RESOLVED_VIRTUAL_VUETIFY_CONFIGURATION;
|
|
186
|
+
},
|
|
187
|
+
async load(id) {
|
|
188
|
+
if (id === RESOLVED_VIRTUAL_VUETIFY_CONFIGURATION) {
|
|
189
|
+
const directivesResult = buildDirectives();
|
|
190
|
+
const labsComponentsResult = buildLabsComponents();
|
|
191
|
+
return `${directivesResult.imports}
|
|
192
|
+
${labsComponentsResult.imports}
|
|
193
|
+
|
|
194
|
+
export const isDev = ${isDev}
|
|
195
|
+
export function vuetifyConfiguration() {
|
|
196
|
+
const options = ${JSON.stringify(vuetifyAppOptions)}
|
|
197
|
+
${directivesResult.expression}
|
|
198
|
+
${labsComponentsResult.expression}
|
|
199
|
+
return options
|
|
200
|
+
}
|
|
201
|
+
`;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
};
|
|
205
|
+
function buildDirectives() {
|
|
206
|
+
if (!directives)
|
|
207
|
+
return { imports: "", expression: "" };
|
|
208
|
+
if (typeof directives === "boolean") {
|
|
209
|
+
return {
|
|
210
|
+
imports: "import * as directives from 'vuetify/directives'",
|
|
211
|
+
expression: "options.directives = directives"
|
|
212
|
+
};
|
|
213
|
+
} else {
|
|
214
|
+
return {
|
|
215
|
+
imports: `${directives.map((d) => `import { ${d} } from 'vuetify/directives/${d}'`).join("\n")}`,
|
|
216
|
+
expression: `options.directives = {${directives.join(",")}}`
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
function buildLabsComponents() {
|
|
221
|
+
if (!labComponents)
|
|
222
|
+
return { imports: "", expression: "" };
|
|
223
|
+
if (typeof labComponents === "boolean") {
|
|
224
|
+
return {
|
|
225
|
+
imports: "import * as labsComponents from 'vuetify/labs/components'",
|
|
226
|
+
expression: "options.components = labsComponents"
|
|
227
|
+
};
|
|
228
|
+
} else {
|
|
229
|
+
return {
|
|
230
|
+
imports: `${labComponents.map((d) => `import { ${d} } from 'vuetify/labs/${d}'`).join("\n")}`,
|
|
231
|
+
expression: `options.components = {${labComponents.join(",")}}`
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
const CONFIG_KEY = "vuetify";
|
|
238
|
+
const logger = useLogger(`nuxt:${CONFIG_KEY}`);
|
|
239
|
+
const module = defineNuxtModule({
|
|
240
|
+
meta: {
|
|
241
|
+
name: "vuetify-nuxt-module",
|
|
242
|
+
configKey: "vuetify",
|
|
243
|
+
compatibility: { nuxt: "^3.0.0" },
|
|
244
|
+
version
|
|
245
|
+
},
|
|
246
|
+
// Default configuration options of the Nuxt module
|
|
247
|
+
defaults: {
|
|
248
|
+
vuetifyOptions: {
|
|
249
|
+
labComponents: false,
|
|
250
|
+
directives: false
|
|
251
|
+
},
|
|
252
|
+
moduleOptions: {
|
|
253
|
+
writePlugin: true,
|
|
254
|
+
styles: true
|
|
255
|
+
}
|
|
256
|
+
},
|
|
257
|
+
setup(options, nuxt) {
|
|
258
|
+
var _a;
|
|
259
|
+
const resolver = createResolver(import.meta.url);
|
|
260
|
+
const { moduleOptions, vuetifyOptions } = options;
|
|
261
|
+
const {
|
|
262
|
+
directives = false,
|
|
263
|
+
labComponents = false,
|
|
264
|
+
...vOptions
|
|
265
|
+
} = vuetifyOptions ?? {};
|
|
266
|
+
const isSSR = nuxt.options.ssr;
|
|
267
|
+
const vuetifyAppOptions = defu(vOptions, {
|
|
268
|
+
ssr: isSSR
|
|
269
|
+
});
|
|
270
|
+
const runtimeDir = resolver.resolve("./runtime");
|
|
271
|
+
nuxt.options.build.transpile.push(runtimeDir);
|
|
272
|
+
nuxt.options.build.transpile.push(CONFIG_KEY);
|
|
273
|
+
const { styles = true, writePlugin = nuxt.options.dev } = moduleOptions ?? {};
|
|
274
|
+
nuxt.options.build.transpile.push(CONFIG_KEY);
|
|
275
|
+
(_a = nuxt.options).css ?? (_a.css = []);
|
|
276
|
+
if (typeof styles === "string" && ["sass", "expose"].includes(styles))
|
|
277
|
+
nuxt.options.css.unshift("vuetify/styles/main.sass");
|
|
278
|
+
else if (styles === true)
|
|
279
|
+
nuxt.options.css.unshift("vuetify/styles");
|
|
280
|
+
else if (typeof styles === "object" && styles?.configFile && typeof styles.configFile === "string")
|
|
281
|
+
nuxt.options.css.unshift(styles.configFile);
|
|
282
|
+
extendWebpackConfig(() => {
|
|
283
|
+
throw new Error("Webpack is not supported yet: vuetify-nuxt-module module can only be used with Vite!");
|
|
284
|
+
});
|
|
285
|
+
nuxt.hook("vite:extend", ({ config }) => checkVuetifyPlugins(config));
|
|
286
|
+
nuxt.hook("prepare:types", ({ references }) => {
|
|
287
|
+
references.push({ types: "vuetify-nuxt-module/configuration" });
|
|
288
|
+
references.push({ types: "vuetify/components" });
|
|
289
|
+
});
|
|
290
|
+
nuxt.hook("vite:extendConfig", (viteInlineConfig) => {
|
|
291
|
+
viteInlineConfig.plugins = viteInlineConfig.plugins || [];
|
|
292
|
+
checkVuetifyPlugins(viteInlineConfig);
|
|
293
|
+
viteInlineConfig.optimizeDeps = defu(viteInlineConfig.optimizeDeps, { exclude: ["vuetify"] });
|
|
294
|
+
viteInlineConfig.ssr || (viteInlineConfig.ssr = {});
|
|
295
|
+
viteInlineConfig.ssr.noExternal = [
|
|
296
|
+
...Array.isArray(viteInlineConfig.ssr.noExternal) ? viteInlineConfig.ssr.noExternal : [],
|
|
297
|
+
CONFIG_KEY
|
|
298
|
+
];
|
|
299
|
+
const autoImportPlugin = vuetify({ styles, autoImport: true }).find((p) => p && typeof p === "object" && "name" in p && p.name === "vuetify:import");
|
|
300
|
+
viteInlineConfig.plugins.push(autoImportPlugin);
|
|
301
|
+
viteInlineConfig.plugins.push(stylesPlugin({ styles }, logger));
|
|
302
|
+
viteInlineConfig.plugins.push(vuetifyConfigurationPlugin(
|
|
303
|
+
nuxt.options.dev,
|
|
304
|
+
directives,
|
|
305
|
+
labComponents,
|
|
306
|
+
vuetifyAppOptions
|
|
307
|
+
));
|
|
308
|
+
});
|
|
309
|
+
addPluginTemplate({
|
|
310
|
+
src: resolver.resolve(runtimeDir, "templates/plugin.mts"),
|
|
311
|
+
write: nuxt.options.dev || writePlugin
|
|
312
|
+
}, {
|
|
313
|
+
append: true
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
});
|
|
317
|
+
function checkVuetifyPlugins(config) {
|
|
318
|
+
let plugin = config.plugins?.find((p) => p && typeof p === "object" && "name" in p && p.name === "vuetify:import");
|
|
319
|
+
if (plugin)
|
|
320
|
+
throw new Error("Remove vite-plugin-vuetify plugin from Vite Plugins entry in Nuxt config file!");
|
|
321
|
+
plugin = config.plugins?.find((p) => p && typeof p === "object" && "name" in p && p.name === "vuetify:styles");
|
|
322
|
+
if (plugin)
|
|
323
|
+
throw new Error("Remove vite-plugin-vuetify plugin from Vite Plugins entry in Nuxt config file!");
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
export { module as default };
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { createVuetify } from 'vuetify'
|
|
2
|
+
import { isDev, vuetifyConfiguration } from 'virtual:vuetify-configuration'
|
|
3
|
+
import { defineNuxtPlugin, useNuxtApp } from '#app'
|
|
4
|
+
|
|
5
|
+
export default defineNuxtPlugin({
|
|
6
|
+
name: 'vuetify:configuration:plugin',
|
|
7
|
+
enforce: 'post',
|
|
8
|
+
parallel: false,
|
|
9
|
+
async setup() {
|
|
10
|
+
const nuxtApp = useNuxtApp()
|
|
11
|
+
const options = vuetifyConfiguration()
|
|
12
|
+
|
|
13
|
+
await nuxtApp.hooks.callHook('vuetify:configuration', options)
|
|
14
|
+
|
|
15
|
+
const vuetify = createVuetify(vuetifyConfiguration())
|
|
16
|
+
|
|
17
|
+
nuxtApp.vueApp.use(vuetify)
|
|
18
|
+
|
|
19
|
+
if (!process.server && isDev) {
|
|
20
|
+
// eslint-disable-next-line no-console
|
|
21
|
+
console.log('Vuetify 3 initialized', vuetify)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return {
|
|
25
|
+
provide: {
|
|
26
|
+
vuetify,
|
|
27
|
+
},
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
})
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
|
|
2
|
+
import { ModuleOptions } from './module'
|
|
3
|
+
|
|
4
|
+
declare module '@nuxt/schema' {
|
|
5
|
+
interface NuxtConfig { ['vuetify']?: Partial<ModuleOptions> }
|
|
6
|
+
interface NuxtOptions { ['vuetify']?: ModuleOptions }
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
declare module 'nuxt/schema' {
|
|
10
|
+
interface NuxtConfig { ['vuetify']?: Partial<ModuleOptions> }
|
|
11
|
+
interface NuxtOptions { ['vuetify']?: ModuleOptions }
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
export { BooleanOrArrayString, ModuleOptions, VOptions, default } from './module'
|
package/package.json
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "vuetify-nuxt-module",
|
|
3
|
+
"type": "module",
|
|
4
|
+
"version": "0.0.1",
|
|
5
|
+
"packageManager": "pnpm@8.6.5",
|
|
6
|
+
"description": "Zero-Config Nuxt Module for Vuetify ",
|
|
7
|
+
"author": "userquin <userquin@gmail.com>",
|
|
8
|
+
"license": "MIT",
|
|
9
|
+
"homepage": "https://github.com/userquin/vuetify-nuxt-module#readme",
|
|
10
|
+
"repository": {
|
|
11
|
+
"type": "git",
|
|
12
|
+
"url": "https://github.com/userquin/vuetify-nuxt-module.git"
|
|
13
|
+
},
|
|
14
|
+
"bugs": "https://github.com/userquin/vuetify-nuxt-module/issues",
|
|
15
|
+
"keywords": [
|
|
16
|
+
"nuxt",
|
|
17
|
+
"nuxt 3",
|
|
18
|
+
"vuetify",
|
|
19
|
+
"vuetify 3",
|
|
20
|
+
"nuxt-module"
|
|
21
|
+
],
|
|
22
|
+
"exports": {
|
|
23
|
+
".": {
|
|
24
|
+
"types": "./dist/types.d.ts",
|
|
25
|
+
"require": "./dist/module.cjs",
|
|
26
|
+
"import": "./dist/module.mjs"
|
|
27
|
+
},
|
|
28
|
+
"./configuration": {
|
|
29
|
+
"types": "./configuration.d.ts"
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
"main": "./dist/module.cjs",
|
|
33
|
+
"types": "./dist/types.d.ts",
|
|
34
|
+
"files": [
|
|
35
|
+
"dist",
|
|
36
|
+
"*.d.ts"
|
|
37
|
+
],
|
|
38
|
+
"scripts": {
|
|
39
|
+
"prepack": "nuxt-module-build",
|
|
40
|
+
"dev": "nuxi dev playground",
|
|
41
|
+
"dev:build": "nuxi build playground",
|
|
42
|
+
"dev:prepare": "nuxt-module-build --stub && nuxi prepare playground",
|
|
43
|
+
"prepublishOnly": "npm run prepack",
|
|
44
|
+
"release": "bumpp && npm publish",
|
|
45
|
+
"lint": "eslint .",
|
|
46
|
+
"lint:fix": "nr lint --fix",
|
|
47
|
+
"test": "vitest run",
|
|
48
|
+
"test:watch": "vitest watch"
|
|
49
|
+
},
|
|
50
|
+
"peerDependencies": {
|
|
51
|
+
"@nuxt/kit": "^3.5.3",
|
|
52
|
+
"vite-plugin-vuetify": "^1.0.2",
|
|
53
|
+
"vuetify": "^3.3.6"
|
|
54
|
+
},
|
|
55
|
+
"dependencies": {
|
|
56
|
+
"@nuxt/kit": "^3.6.1",
|
|
57
|
+
"defu": "^6.1.2",
|
|
58
|
+
"vite-plugin-vuetify": "^1.0.2",
|
|
59
|
+
"vuetify": "^3.3.6"
|
|
60
|
+
},
|
|
61
|
+
"devDependencies": {
|
|
62
|
+
"@antfu/eslint-config": "^0.39.6",
|
|
63
|
+
"@antfu/ni": "^0.21.4",
|
|
64
|
+
"@nuxt/devtools": "^0.6.6",
|
|
65
|
+
"@nuxt/module-builder": "^0.4.0",
|
|
66
|
+
"@nuxt/schema": "^3.6.1",
|
|
67
|
+
"@nuxt/test-utils": "^3.6.1",
|
|
68
|
+
"@parcel/watcher": "^2.1.0",
|
|
69
|
+
"@types/node": "^18",
|
|
70
|
+
"bumpp": "^9.1.1",
|
|
71
|
+
"eslint": "^8.43.0",
|
|
72
|
+
"nuxt": "^3.6.1",
|
|
73
|
+
"sass": "^1.63.6",
|
|
74
|
+
"typescript": "^5.1.6",
|
|
75
|
+
"vite": "^4.3.9",
|
|
76
|
+
"vitest": "^0.31.4"
|
|
77
|
+
},
|
|
78
|
+
"build": {
|
|
79
|
+
"externals": [
|
|
80
|
+
"@vuetify/loader-shared",
|
|
81
|
+
"node:child_process",
|
|
82
|
+
"node:fs",
|
|
83
|
+
"consola",
|
|
84
|
+
"esbuild",
|
|
85
|
+
"pathe",
|
|
86
|
+
"rollup",
|
|
87
|
+
"upath",
|
|
88
|
+
"ufo",
|
|
89
|
+
"vite",
|
|
90
|
+
"vite-plugin-vuetify",
|
|
91
|
+
"vuetify"
|
|
92
|
+
]
|
|
93
|
+
}
|
|
94
|
+
}
|