From 64051e6072a807a822be07295234d356ec5b7c1f Mon Sep 17 00:00:00 2001 From: Pham Van Manh Date: Tue, 22 Nov 2022 15:22:09 +0700 Subject: [PATCH 1/2] feat: auto import react component --- .gitignore | 2 ++ examples/vite-react/src/App.tsx | 3 --- examples/vite-react/vite.config.ts | 2 ++ src/core/ctx.ts | 28 ++++++++++++++++++++++++---- src/types.ts | 7 +++++++ 5 files changed, 35 insertions(+), 7 deletions(-) diff --git a/.gitignore b/.gitignore index a5defc6..d4165a5 100644 --- a/.gitignore +++ b/.gitignore @@ -81,3 +81,5 @@ dist .idea auto-imports.d.ts .eslintrc-auto-import.json + +.vscode \ No newline at end of file diff --git a/examples/vite-react/src/App.tsx b/examples/vite-react/src/App.tsx index 609290a..1e08306 100644 --- a/examples/vite-react/src/App.tsx +++ b/examples/vite-react/src/App.tsx @@ -1,7 +1,4 @@ import React from 'react' -import MainLayout from './layouts/MainLayout' -import PageA from './views/PageA' -import PageB from './views/PageB' import './i18n' function App() { diff --git a/examples/vite-react/vite.config.ts b/examples/vite-react/vite.config.ts index 9c60ad7..454f9bc 100644 --- a/examples/vite-react/vite.config.ts +++ b/examples/vite-react/vite.config.ts @@ -15,6 +15,8 @@ export default defineConfig({ AutoImport({ imports: ['react', 'react-router-dom', 'react-i18next', 'ahooks'], dts: './src/auto-imports.d.ts', + dirs: ['src/layouts', 'src/views'], + reactComponent: true, resolvers: [ IconsResolver({ componentPrefix: 'Icon', diff --git a/src/core/ctx.ts b/src/core/ctx.ts index 60e70a3..8e563d5 100644 --- a/src/core/ctx.ts +++ b/src/core/ctx.ts @@ -66,7 +66,7 @@ export function createContext(options: Options = {}, root = process.cwd()) { return unimport.generateTypeDeclarations({ resolvePath: (i) => { if (i.from.startsWith('.') || isAbsolute(i.from)) { - const related = slash(relative(dir, i.from).replace(/\.ts$/, '')) + const related = slash(relative(dir, i.from).replace(/\.ts(x)?$/, '')) return !related.startsWith('.') ? `./${related}` : related @@ -112,12 +112,14 @@ export function createContext(options: Options = {}, root = process.cwd()) { async function scanDirs() { if (dirs?.length) { await unimport.modifyDynamicImports(async (imports) => { - const exports = await scanDirExports(dirs) as ImportExtended[] + const exports = await scanDirExports(dirs, { + filePatterns: getScanDirsFilePatterns(options), + }) as ImportExtended[] exports.forEach(i => i.__source = 'dir') - return [ + return modifyReactComponentDefaultExports([ ...imports.filter((i: ImportExtended) => i.__source !== 'dir'), ...exports, - ] as Import[] + ], options) }) } writeConfigFilesThrottled() @@ -192,3 +194,21 @@ export function flattenImports(map: Options['imports'], overriding = false): Imp return Object.values(flat) } + +function getScanDirsFilePatterns(options: Options) { + if (options.reactComponent) + return ['*.{tsx,jsx,ts,js,mjs,cjs,mts,cts}'] + + return ['*.{ts,js,mjs,cjs,mts,cts}'] +} + +function modifyReactComponentDefaultExports(imports: ImportExtended[], options: Options): Import[] { + if (options.reactComponent) { + imports.forEach((i) => { + if (/(t|j)sx$/.test(i.from) && i.name === 'default') + i.as = i.from.split('/').pop()?.split('.')?.shift() + }) + } + + return imports as Import[] +} diff --git a/src/types.ts b/src/types.ts index f2cc865..22af680 100644 --- a/src/types.ts +++ b/src/types.ts @@ -113,6 +113,13 @@ export interface Options { */ vueTemplate?: boolean + /** + * Auto import React Component + * + * @default false + */ + reactComponent?: boolean + /** * Allow overriding imports sources from multiple presets. * From 52188d23945e55b5efd2afb344eb9dfa9245d8df Mon Sep 17 00:00:00 2001 From: Pham Van Manh Date: Wed, 23 Nov 2022 08:46:57 +0700 Subject: [PATCH 2/2] feat: add support tsx, jsx by default and add option defaultExportByFilename --- examples/vite-react/vite.config.ts | 5 ++++- src/core/ctx.ts | 19 ++++++------------- src/types.ts | 4 ++-- 3 files changed, 12 insertions(+), 16 deletions(-) diff --git a/examples/vite-react/vite.config.ts b/examples/vite-react/vite.config.ts index 454f9bc..e4c8441 100644 --- a/examples/vite-react/vite.config.ts +++ b/examples/vite-react/vite.config.ts @@ -16,7 +16,10 @@ export default defineConfig({ imports: ['react', 'react-router-dom', 'react-i18next', 'ahooks'], dts: './src/auto-imports.d.ts', dirs: ['src/layouts', 'src/views'], - reactComponent: true, + eslintrc: { + enabled: true, + }, + defaultExportByFilename: true, resolvers: [ IconsResolver({ componentPrefix: 'Icon', diff --git a/src/core/ctx.ts b/src/core/ctx.ts index 8e563d5..b9a0a7c 100644 --- a/src/core/ctx.ts +++ b/src/core/ctx.ts @@ -113,10 +113,10 @@ export function createContext(options: Options = {}, root = process.cwd()) { if (dirs?.length) { await unimport.modifyDynamicImports(async (imports) => { const exports = await scanDirExports(dirs, { - filePatterns: getScanDirsFilePatterns(options), + filePatterns: ['*.{tsx,jsx,ts,js,mjs,cjs,mts,cts}'], }) as ImportExtended[] exports.forEach(i => i.__source = 'dir') - return modifyReactComponentDefaultExports([ + return modifyDefaultExportsAlias([ ...imports.filter((i: ImportExtended) => i.__source !== 'dir'), ...exports, ], options) @@ -195,18 +195,11 @@ export function flattenImports(map: Options['imports'], overriding = false): Imp return Object.values(flat) } -function getScanDirsFilePatterns(options: Options) { - if (options.reactComponent) - return ['*.{tsx,jsx,ts,js,mjs,cjs,mts,cts}'] - - return ['*.{ts,js,mjs,cjs,mts,cts}'] -} - -function modifyReactComponentDefaultExports(imports: ImportExtended[], options: Options): Import[] { - if (options.reactComponent) { +function modifyDefaultExportsAlias(imports: ImportExtended[], options: Options): Import[] { + if (options.defaultExportByFilename) { imports.forEach((i) => { - if (/(t|j)sx$/.test(i.from) && i.name === 'default') - i.as = i.from.split('/').pop()?.split('.')?.shift() + if (i.name === 'default') + i.as = i.from.split('/').pop()?.split('.')?.shift() ?? i.as }) } diff --git a/src/types.ts b/src/types.ts index 22af680..62a24a5 100644 --- a/src/types.ts +++ b/src/types.ts @@ -114,11 +114,11 @@ export interface Options { vueTemplate?: boolean /** - * Auto import React Component + * Set default export alias by file name * * @default false */ - reactComponent?: boolean + defaultExportByFilename?: boolean /** * Allow overriding imports sources from multiple presets.