Skip to content

Commit 55ead16

Browse files
committed
feat: allow labs auto-import
closes #315
1 parent d1b3ae7 commit 55ead16

File tree

11 files changed

+74
-30
lines changed

11 files changed

+74
-30
lines changed

packages/shared/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
"url": "git+https://github.com/vuetifyjs/vuetify-loader.git"
1616
},
1717
"scripts": {
18-
"build": "unbuild",
18+
"build": "unbuild && node ../../scripts/patchMJS.mjs",
1919
"dev": "unbuild --stub"
2020
},
2121
"author": "Kael Watts-Deuchar",

packages/shared/src/imports/generateImports.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import { getImports } from './getImports'
2+
import type { Options } from '../'
23

3-
export function generateImports (source: string, ignore: string[] = []) {
4-
const { imports, components, directives } = getImports(source, ignore)
4+
export function generateImports (source: string, options: Options) {
5+
const { imports, components, directives } = getImports(source, options)
56

67
let code = ''
78

packages/shared/src/imports/getImports.ts

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,41 @@
11
import { parseTemplate, TemplateMatch } from './parseTemplate'
2-
import * as importMap from 'vuetify/dist/json/importMap.json'
2+
import * as importMap from 'vuetify/dist/json/importMap.json' with { type: 'json' }
3+
import * as importMapLabs from 'vuetify/dist/json/importMap-labs.json' with { type: 'json' }
4+
import { isObject } from '../'
5+
import type { Options } from '../'
36

4-
export function getImports (source: string, ignore: string[] = []) {
7+
export function getImports (source: string, options: Options) {
58
const { components, directives } = parseTemplate(source)
69
const resolvedComponents: TemplateMatch[] = []
710
const resolvedDirectives: TemplateMatch[] = []
811
const imports = new Map<string, string[]>()
12+
const ignore = (isObject(options.autoImport) && options.autoImport.ignore) || null
13+
const includeLabs = isObject(options.autoImport) && options.autoImport.labs
14+
const map = includeLabs
15+
? {
16+
components: { ...importMap.components, ...importMapLabs.components },
17+
directives: importMap.directives,
18+
}
19+
: importMap
920

1021
if (components.size || directives.size) {
1122
components.forEach(component => {
12-
if (component.name in importMap.components && !ignore.includes(component.name)) {
23+
if (ignore?.includes(component.name as any)) return
24+
if (component.name in importMap.components) {
25+
resolvedComponents.push(component)
26+
} else if (includeLabs && component.name in importMapLabs.components) {
1327
resolvedComponents.push(component)
1428
}
1529
})
1630
directives.forEach(directive => {
17-
if (importMap.directives.includes(directive.name) && !ignore.includes(directive.name)) {
31+
if (importMap.directives.includes(directive.name) && !ignore?.includes(directive.name as any)) {
1832
resolvedDirectives.push(directive)
1933
}
2034
})
2135
}
2236

2337
resolvedComponents.forEach(component => {
24-
addImport(imports, component.name, component.symbol, 'vuetify/lib/' + (importMap.components as any)[component.name].from)
38+
addImport(imports, component.name, component.symbol, 'vuetify/lib/' + (map.components as any)[component.name].from)
2539
})
2640
resolvedDirectives.forEach(directive => {
2741
addImport(imports, directive.name, directive.symbol, 'vuetify/lib/directives/index.mjs')

packages/shared/src/index.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,19 @@ import type * as Components from 'vuetify/components'
33
import type * as Directives from 'vuetify/directives'
44

55
export interface Options {
6-
autoImport?: importPluginOptions,
6+
autoImport?: ImportPluginOptions,
77
styles?: true | 'none' | 'sass' | {
88
configFile: string,
99
},
1010
}
1111

1212
export interface ObjectImportPluginOptions {
13-
ignore: (keyof typeof Components | keyof typeof Directives)[]
13+
labs?: boolean
14+
ignore?: (keyof typeof Components | keyof typeof Directives)[]
1415
}
15-
export type importPluginOptions =
16+
export type ImportPluginOptions =
1617
| boolean
1718
| ObjectImportPluginOptions
18-
// | ((source: string, importer: string, isVuetify: boolean) => boolean | null | replace)
19-
// type replace = { symbol: string, from: string, as?: string }
2019

2120
export { generateImports } from './imports/generateImports'
2221
export { cacheDir, writeStyles } from './styles/writeStyles'

packages/vite-plugin/README.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,17 @@ import { createVuetify } from 'vuetify'
2626
export default createVuetify()
2727
```
2828

29+
### Include labs components
30+
```js
31+
// vite.config.js
32+
plugins: [
33+
vue(),
34+
vuetify({
35+
autoImport: { labs: true }
36+
}),
37+
]
38+
```
39+
2940
### Ignoring components or directives
3041
```js
3142
// vite.config.js

packages/vite-plugin/src/importPlugin.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { extname } from 'path'
22
import { Plugin } from 'vite'
3-
import { generateImports, importPluginOptions, isObject } from '@vuetify/loader-shared'
3+
import { generateImports, Options } from '@vuetify/loader-shared'
44
import { parse as parseUrl, URLSearchParams } from 'url'
55

66
function parseId (id: string) {
@@ -12,8 +12,7 @@ function parseId (id: string) {
1212
}
1313
}
1414

15-
export function importPlugin (_options: importPluginOptions): Plugin {
16-
const options = isObject(_options) ? _options : { ignore: [] };
15+
export function importPlugin (options: Options): Plugin {
1716
return {
1817
name: 'vuetify:import',
1918
configResolved (config) {
@@ -28,7 +27,7 @@ export function importPlugin (_options: importPluginOptions): Plugin {
2827
((!query || !('vue' in query)) && extname(path) === '.vue' && !/^import { render as _sfc_render } from ".*"$/m.test(code)) ||
2928
(query && 'vue' in query && (query.type === 'template' || (query.type === 'script' && query.setup === 'true')))
3029
) {
31-
const { code: imports, source } = generateImports(code, options.ignore)
30+
const { code: imports, source } = generateImports(code, options)
3231
return {
3332
code: source + imports,
3433
map: null,

packages/vite-plugin/src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ export default function vuetify (_options: Options = {}): Plugin[] {
1313

1414
const plugins: Plugin[] = []
1515
if (options.autoImport) {
16-
plugins.push(importPlugin(options.autoImport))
16+
plugins.push(importPlugin(options))
1717
}
1818
if (includes(['none', 'sass'], options.styles) || isObject(options.styles)) {
1919
plugins.push(stylesPlugin(options))

packages/vite-plugin/src/stylesPlugin.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import * as path from 'upath'
2-
import { resolveVuetifyBase, normalizePath } from '@vuetify/loader-shared'
2+
import { resolveVuetifyBase, normalizePath, isObject } from '@vuetify/loader-shared'
33

44
import type { Plugin } from 'vite'
55
import type { Options } from '@vuetify/loader-shared'
@@ -19,7 +19,7 @@ export function stylesPlugin (options: Options): Plugin {
1919
name: 'vuetify:styles',
2020
enforce: 'pre',
2121
configResolved (config) {
22-
if (typeof options.styles === 'object') {
22+
if (isObject(options.styles)) {
2323
if (path.isAbsolute(options.styles.configFile)) {
2424
configFile = options.styles.configFile
2525
} else {
@@ -40,7 +40,7 @@ export function stylesPlugin (options: Options): Plugin {
4040
} else if (options.styles === 'sass') {
4141
const target = source.replace(/\.css$/, '.sass')
4242
return this.resolve(target, importer, { skipSelf: true, custom })
43-
} else if (typeof options.styles === 'object') {
43+
} else if (isObject(options.styles)) {
4444
const resolution = await this.resolve(source, importer, { skipSelf: true, custom })
4545

4646
if (!resolution) return null

packages/webpack-plugin/src/plugin.ts

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,7 @@ export class VuetifyPlugin {
3434
}
3535

3636
apply (compiler: Compiler) {
37-
const autoImport = this.options.autoImport
38-
if (autoImport) {
37+
if (this.options.autoImport) {
3938
compiler.options.module.rules.unshift({
4039
resourceQuery: query => {
4140
if (!query) return false
@@ -47,7 +46,7 @@ export class VuetifyPlugin {
4746
},
4847
use: {
4948
loader: require.resolve('./scriptLoader'),
50-
options: isObject(autoImport) ? autoImport : undefined
49+
options: this.options
5150
},
5251
})
5352
}
@@ -88,9 +87,7 @@ export class VuetifyPlugin {
8887
})
8988
} else if (this.options.styles === 'sass') {
9089
hookResolve(file => file.replace(/\.css$/, '.sass'))
91-
}
92-
93-
if (isObject(this.options.styles)) {
90+
} else if (isObject(this.options.styles)) {
9491
const configFile = path.isAbsolute(this.options.styles.configFile)
9592
? this.options.styles.configFile
9693
: path.join(

packages/webpack-plugin/src/scriptLoader.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { LoaderDefinitionFunction } from 'webpack'
2-
import { generateImports, ObjectImportPluginOptions } from '@vuetify/loader-shared'
2+
import { generateImports, Options } from '@vuetify/loader-shared'
33

44
export default (function VuetifyLoader (content, sourceMap) {
55
if (this.data?.skip) {
@@ -11,10 +11,10 @@ export default (function VuetifyLoader (content, sourceMap) {
1111

1212
const options = this.getOptions()
1313

14-
const { code: imports, source } = generateImports(content, options?.ignore)
14+
const { code: imports, source } = generateImports(content, options)
1515

1616
this.callback(null, source + imports, sourceMap)
17-
} as LoaderDefinitionFunction<ObjectImportPluginOptions | undefined>)
17+
} as LoaderDefinitionFunction<Options>)
1818

1919
export const pitch = (function VuetifyLoaderPitch (remainingRequest, precedingRequest, data) {
2020
if (this.loaders.some(loader => loader.path.endsWith('vue-loader/dist/pitcher.js'))) {

0 commit comments

Comments
 (0)