Skip to content

Commit

Permalink
add vite-monorepo-alias
Browse files Browse the repository at this point in the history
  • Loading branch information
bichikim committed Jun 23, 2023
1 parent 2ad477c commit 6c46a17
Show file tree
Hide file tree
Showing 32 changed files with 308 additions and 547 deletions.
7 changes: 6 additions & 1 deletion apps/nuxt/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
{
// https://nuxt.com/docs/guide/concepts/typescript
"extends": "./.nuxt/tsconfig.json"
"extends": "./.nuxt/tsconfig.json",
"compilerOptions": {
"paths": {
"components/*": ["components/*"]
}
}
}
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
"@typescript-eslint/parser": "^5.59.9",
"@vue/eslint-config-typescript": "^11.0.3",
"@vitejs/plugin-vue": "4.2.3",
"@byte-abc/vite-monorepo-alias": "workspace:^",
"eslint": "8.28.0",
"eslint-config-prettier": "^8.8.0",
"eslint-import-resolver-typescript": "^3.5.5",
Expand All @@ -34,7 +35,7 @@
"eslint-plugin-promise": "^6.1.1",
"eslint-plugin-sort-export-all": "^1.4.1",
"eslint-plugin-sort-keys-fix": "1.1.2",
"eslint-plugin-typescript-sort-keys": "2.1.0",
"eslint-plugin-typescript-sort-keys": "2.3.0",
"eslint-plugin-unicorn": "45.0.0",
"eslint-plugin-vue": "^9.14.1",
"histoire": "^0.16.1",
Expand Down
18 changes: 17 additions & 1 deletion packages/vite-monorepo-alias/package.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,24 @@
{
"name": "@byte-abc/vite-monorepo-alias",
"version": "1.0.0",
"exports": {
".": {
"import": "./dist/index.mjs",
"require": "./dist/index.js"
},
"./*": "./*"
},
"main": "dist/index.js",
"module": "dist/index.mjs",
"source": "src/index.ts",
"types": "dist/index.d.ts",
"files": [
"dist/*"
],
"dependencies": {
"vue": "3.3.4"
"vue": "3.3.4",
"typescript": "^5.1.3",
"glob": "^10.2.7"
},
"scripts": {
"build": "cross-env NODE_ENV=production vite build",
Expand Down
37 changes: 37 additions & 0 deletions packages/vite-monorepo-alias/src/__tests__/alias.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import {createAlias} from '../alias'
import {WorkspaceInfo} from '../types'
import {describe, expect, it} from 'vitest'

describe('alias', () => {
it('should create vite alias', () => {
const info: WorkspaceInfo[] = [
{
alias: [[/^components\//u, 'components/']],
path: /^\/foo\/bar/u,
},
]
const alias = createAlias(info)

expect(alias.replacement).toBe('$1')
expect(alias.find).toBeInstanceOf(RegExp)
if (alias.find instanceof RegExp) {
expect(alias.find.test('virtual:foo')).toBeFalsy()
expect(alias.find.test('./foo/bar')).toBeFalsy()
expect(alias.find.test('../foo/bar')).toBeFalsy()
expect(alias.find.test('/foo/bar')).toBeFalsy()
expect(alias.find.test('@vite/env')).toBeFalsy()
expect(alias.find.test('@vite/client')).toBeFalsy()
expect(alias.find.test('app/foo/bar')).toBeTruthy()
}

expect(alias.customResolver).toBeInstanceOf(Function)
if (typeof alias.customResolver === 'function') {
const customResolver: any = alias.customResolver
expect(customResolver('components/Foo.vue', undefined)).toBe(null)
expect(customResolver('store/Foo.vue', '/foo/bar/john/Bar.vue')).toBe(null)
expect(customResolver('components/Foo.vue', '/foo/bar/john/Bar.vue')).toBe(
'/foo/bar/components/Foo.vue',
)
}
})
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"compilerOptions": {
"paths": {
"src/*": ["src/*"]
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import {afterEach, describe, expect, it, vi} from 'vitest'
import {getTypescriptAlias} from '../get-typescript-alias'
import {parseWorkspacePath} from '../parse-workspace-path'
import {join} from 'node:path'

vi.mock('../parse-workspace-path')

describe('get-typescript-alias', () => {
afterEach(() => {
vi.mocked(parseWorkspacePath).mockRestore()
})
const setup = () => {
vi.mocked(parseWorkspacePath).mockImplementation((_, path) => path)

return {}
}
it('should get typescript alias', async () => {
const prepare = setup()
const alias = await getTypescriptAlias([
join(__dirname, 'packages/*'),
join(__dirname, 'apps/*'),
])

expect(alias).toEqual([
{
alias: [['src/*', 'src/']],
path: join(__dirname, 'apps', 'john'),
},
{
alias: [['components/*', 'components/']],
path: join(__dirname, 'packages', 'foo'),
},
{
alias: [['components/*', 'components/']],
path: join(__dirname, 'packages', 'bar'),
},
])

expect(parseWorkspacePath).toHaveBeenCalledWith('', join(__dirname, 'packages', 'foo'))
expect(parseWorkspacePath).toHaveBeenCalledWith('', join(__dirname, 'packages', 'bar'))
expect(parseWorkspacePath).toHaveBeenCalledWith('', join(__dirname, 'apps', 'john'))
expect(parseWorkspacePath).toHaveBeenCalledWith('', join('src/*'))
expect(parseWorkspacePath).toHaveBeenCalledWith('', join('components/*'))
})
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import {describe, expect, it, vi} from 'vitest'
import {normalizeWorkspaceInfoOptions} from '../normalize-workspace-info-options'

describe('normalize-workspace-info-options', () => {
it('should normalize workspace info options', () => {
expect(
normalizeWorkspaceInfoOptions({
root: '/foo/bar',
workspaces: ['packages/*', 'apps/*'],
}),
).toEqual({
workspaces: ['/foo/bar/packages/*', '/foo/bar/apps/*'],
})
})
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"compilerOptions": {
"paths": {
"components/*": ["components/*"]
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"compilerOptions": {
"paths": {
"components/*": ["components/*"]
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import {parseWorkspacePath} from '../parse-workspace-path'
import {describe, expect, it} from 'vitest'

describe('parse-workspace-path', () => {
it('should return regexp', () => {
const regexp = parseWorkspacePath('/foo/bar', 'packages/hello')

expect(regexp.test('/foo/bar/packages/hello/foo')).toBeTruthy()
expect(regexp.test('/foo/john/packages/hello/foo')).toBeFalsy()
expect(regexp.test('/foo/bar/apps/hello/bar')).toBeFalsy()
})

it('should return alias regexp', () => {
const regexp = parseWorkspacePath('', 'components/*')

expect('components/hello'.replace(regexp, '')).toBe('hello')
expect(regexp.test('store/hello')).toBeFalsy()
expect(regexp.test('foo/components/hello')).toBeFalsy()
})
})
37 changes: 37 additions & 0 deletions packages/vite-monorepo-alias/src/alias.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import {Alias} from 'vite'
import {WorkspaceInfo} from './types'

export const createAlias = (workspaces: WorkspaceInfo[]): Alias => {
return {
customResolver(source: string, importer: undefined | string) {
if (!importer) {
return null
}

const workspaceInfo = workspaces.find((packageInfo) => {
return packageInfo.path.test(importer)
})

if (!workspaceInfo) {
return null
}

const rootPath = importer.match(workspaceInfo.path)?.[0] ?? '/'

const alias = workspaceInfo.alias.find(([pattern]) => {
return pattern.test(source)
})

if (!alias) {
return null
}

const replacedSource = source.replace(alias[0], alias[1])

return `${rootPath}/${replacedSource}`
},
// eslint-disable-next-line prefer-named-capture-group,require-unicode-regexp
find: /^(?!virtual:|\/|\.\/|\.\.\/|@vite\/env|@vite\/client)(.*)/,
replacement: '$1',
}
}

This file was deleted.

This file was deleted.

This file was deleted.

21 changes: 0 additions & 21 deletions packages/vite-monorepo-alias/src/depub-separator/index.ts

This file was deleted.

28 changes: 28 additions & 0 deletions packages/vite-monorepo-alias/src/get-typescript-alias.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import {glob} from 'glob'
import {readFileSync} from 'node:fs'
import {join} from 'node:path'
import {WorkspaceInfo} from 'src/types'
import {readConfigFile} from 'typescript'
import {parseWorkspacePath} from './parse-workspace-path'
const WildCard = /\/\*$/u

/**
* todo finding exact alias is yet
* @param workspacePath
*/
export const getTypescriptAlias = async (workspacePath: string[]): Promise<WorkspaceInfo[]> => {
const paths = await glob(workspacePath)
return paths.map((path) => {
const {config} = readConfigFile(join(path, 'tsconfig.json'), (path) =>
readFileSync(path).toString(),
)
const configPaths: Record<string, string[]> = config.compilerOptions?.paths ?? {}

return {
alias: Object.entries(configPaths).map(([key, value]) => {
return [parseWorkspacePath('', key), value[0].replace(WildCard, '/')]
}),
path: parseWorkspacePath('', path),
}
})
}
3 changes: 2 additions & 1 deletion packages/vite-monorepo-alias/src/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export * from './vite-alias'
export * from './alias'
export * from './workspace-info'
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import {parseWorkspacePath} from './parse-workspace-path'
import {join} from 'node:path'

export interface CreateWorkspaceInfoOptions {
root?: string
workspaces: string[]
}
export interface NormalizedCreateWorkspaceInfoOptions {
workspaces: string[]
}

export const normalizeWorkspaceInfoOptions = (
options: CreateWorkspaceInfoOptions,
): NormalizedCreateWorkspaceInfoOptions => {
const {workspaces, root = process.cwd()} = options
return {
workspaces: workspaces.map((info) => {
return join(root, info)
}),
}
}
5 changes: 5 additions & 0 deletions packages/vite-monorepo-alias/src/parse-workspace-path.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import {join} from 'node:path'

export const parseWorkspacePath = (root: string, path: string) => {
return RegExp(`^${join(root, path.replace(/\/*$/u, '/'))}`, 'u')
}

This file was deleted.

Loading

0 comments on commit 6c46a17

Please sign in to comment.