Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: dirs add exportAllByFileName config (#388) #390

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
13 changes: 9 additions & 4 deletions playground/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@
import HelloWorld from './HelloWorld.vue'

ElMessage.warning('Test')
const foo = useFoo()
const bar = useBar()
const composableFoo = useFoo()
const composableBar = useBar()

const utilsFoo = foo.useFoo()
const utilsBar = bar.useBar()
</script>

<script lang="ts">
Expand All @@ -19,8 +22,10 @@ export default defineComponent({

<template>
<HelloWorld msg="hi" />
<pre>{{ foo }}</pre>
<pre>{{ bar }}</pre>
<pre>{{ composableFoo }}</pre>
<pre>{{ composableBar }}</pre>
<pre>{{ utilsFoo }}</pre>
<pre>{{ utilsBar }}</pre>
<pre>{{ FOOBAR }}</pre>
<div v-loading="false">
<ElButton>Hello</ElButton>
Expand Down
3 changes: 3 additions & 0 deletions playground/utils/foo.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export function useFoo() {
return 'foo from ./utils/'
}
3 changes: 3 additions & 0 deletions playground/utils/nested/bar.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export function useBar() {
return 'bar from ./utils/nested/'
}
5 changes: 4 additions & 1 deletion playground/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,12 @@ export default defineConfig({
],
dirs: [
'./composables/**',
{
dir: './utils/**',
exportAllByFileName: true,
},
],
vueTemplate: true,
cache: true,
}),
],
})
50 changes: 41 additions & 9 deletions src/core/ctx.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import { dirname, isAbsolute, relative, resolve } from 'node:path'
import { basename, dirname, extname, isAbsolute, relative, resolve } from 'node:path'
import { existsSync, promises as fs } from 'node:fs'
import { slash, throttle, toArray } from '@antfu/utils'
import { isString, slash, throttle, toArray } from '@antfu/utils'
import { createFilter } from '@rollup/pluginutils'
import { isPackageExists } from 'local-pkg'
import type { Import, InlinePreset } from 'unimport'
import { createUnimport, resolvePreset, scanDirExports } from 'unimport'
import type { Import, InlinePreset, ScanDirExportsOptions } from 'unimport'
import { createUnimport, resolvePreset, scanDirExports, scanFilesFromDir } from 'unimport'

// @ts-expect-error types
import { vueTemplateAddon } from 'unimport/addons'
import MagicString from 'magic-string'
import { presets } from '../presets'
import type { ESLintGlobalsPropValue, ESLintrc, ImportExtended, Options } from '../types'
import type { DirsOptions, ESLintGlobalsPropValue, ESLintrc, ImportExtended, Options } from '../types'
import { generateESLintConfigs } from './eslintrc'
import { resolversAddon } from './resolvers'

Expand All @@ -19,7 +19,19 @@ export function createContext(options: Options = {}, root = process.cwd()) {
dts: preferDTS = isPackageExists('typescript'),
} = options

const dirs = options.dirs?.map(dir => resolve(root, dir))
const dirs: DirsOptions[] | undefined = options.dirs?.map((dir) => {
if (isString(dir)) {
return {
dir: resolve(root, dir),
}
}
else {
return {
...dir,
dir: resolve(root, dir.dir),
}
}
})

const eslintrc: ESLintrc = options.eslintrc || {}
eslintrc.enabled = eslintrc.enabled === undefined ? false : eslintrc.enabled
Expand Down Expand Up @@ -164,12 +176,32 @@ ${dts}`.trim()}\n`
return Promise.all(promises)
}

async function scanExportAllByFileNameDir(dirs: string[], options: ScanDirExportsOptions): Promise<ImportExtended[]> {
const files = await scanFilesFromDir(dirs, options)

return files.map(i => ({
name: '*',
as: basename(i, extname(i)),
from: i,
}))
}

async function scanDirs() {
if (dirs?.length) {
await unimport.modifyDynamicImports(async (imports) => {
const exports_ = await scanDirExports(dirs, {
filePatterns: ['*.{tsx,jsx,ts,js,mjs,cjs,mts,cts}'],
}) as ImportExtended[]
const exportDirs = dirs.filter(i => !i.exportAllByFileName).map(i => i.dir)
const exportAllByFileNameDirs = dirs.filter(i => i.exportAllByFileName).map(i => i.dir)
const exports_: ImportExtended[] = []
if (exportDirs.length) {
exports_.push(...await scanDirExports(exportDirs, {
filePatterns: ['*.{tsx,jsx,ts,js,mjs,cjs,mts,cts}'],
}))
}
if (exportAllByFileNameDirs.length) {
exports_.push(...await scanExportAllByFileNameDir(exportAllByFileNameDirs, {
filePatterns: ['*.{tsx,jsx,ts,js,mjs,cjs,mts,cts}'],
}))
}
exports_.forEach(i => i.__source = 'dir')
return modifyDefaultExportsAlias([
...imports.filter((i: ImportExtended) => i.__source !== 'dir'),
Expand Down
4 changes: 2 additions & 2 deletions src/core/unplugin.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { minimatch } from 'minimatch'
import { slash } from '@antfu/utils'
import { isString, slash } from '@antfu/utils'
import { createUnplugin } from 'unplugin'
import type { Options } from '../types'
import { createContext } from './ctx'
Expand All @@ -23,7 +23,7 @@ export default createUnplugin<Options>((options) => {
},
vite: {
async handleHotUpdate({ file }) {
if (ctx.dirs?.some(glob => minimatch(slash(file), slash(glob))))
if (ctx.dirs?.some(glob => minimatch(slash(file), isString(glob) ? glob : glob.dir)))
await ctx.scanDirs()
},
async configResolved(config) {
Expand Down
7 changes: 6 additions & 1 deletion src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@ export type Resolver = ResolverFunction | ResolverResultObject
*/
export type ImportsMap = Record<string, (string | ImportNameAlias)[]>

export interface DirsOptions {
dir: string
exportAllByFileName?: boolean
}

export type ESLintGlobalsPropValue = boolean | 'readonly' | 'readable' | 'writable' | 'writeable'

export interface ESLintrc {
Expand Down Expand Up @@ -93,7 +98,7 @@ export interface Options {
/**
* Path for directories to be auto imported
*/
dirs?: string[]
dirs?: (string | DirsOptions)[]

/**
* Pass a custom function to resolve the component importing path from the component name.
Expand Down