Skip to content

Commit ccc0a33

Browse files
committed
feat: 提取常用字符串/数组工具到 shared,并在相关包中复用
1 parent 366027a commit ccc0a33

File tree

9 files changed

+98
-40
lines changed

9 files changed

+98
-40
lines changed

.changeset/shared-utils-extract.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
"@weapp-tailwindcss/shared": patch
3+
"weapp-style-injector": patch
4+
"wetw": patch
5+
---
6+
7+
提取常用字符串/数组工具到 shared,并在相关包中复用。

packages/shared/src/index.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,47 @@ export { getValue, setValue }
66

77
export { defu } from 'defu'
88

9+
const HTTP_PATTERN = /^https?:\/\//i
10+
const CLEAN_URL_REGEXP = /[?#].*$/
11+
912
export function isRegexp(value: unknown): value is RegExp {
1013
return value instanceof RegExp
1114
}
1215

1316
export function isMap<T = unknown, K = unknown>(value: unknown): value is Map<T, K> {
1417
return value instanceof Map
1518
}
19+
20+
export function isHttp(target: string) {
21+
return HTTP_PATTERN.test(target)
22+
}
23+
24+
export function cleanUrl(url: string): string {
25+
return url.replace(CLEAN_URL_REGEXP, '')
26+
}
27+
28+
export function toArray<T>(value: T | T[] | null | undefined): Array<NonNullable<T>> {
29+
if (value == null) {
30+
return []
31+
}
32+
return (Array.isArray(value) ? value : [value]) as Array<NonNullable<T>>
33+
}
34+
35+
export function ensurePosix(value: string): string {
36+
return value.replace(/\\/g, '/')
37+
}
38+
39+
export function normalizeRoot(root: string): string {
40+
const trimmed = root.trim().replace(/^[./\\]+/, '').replace(/\\+/g, '/')
41+
return trimmed.endsWith('/') ? trimmed.slice(0, -1) : trimmed
42+
}
43+
44+
export function normalizeRelativeImport(target: string): string {
45+
if (target.startsWith('.') || target.startsWith('/')) {
46+
return target
47+
}
48+
return `./${target}`
49+
}
1650
export function regExpTest(arr: (string | RegExp)[], str: string, options?: { exact?: boolean }) {
1751
if (!Array.isArray(arr)) {
1852
throw new TypeError('paramater \'arr\' should be an Array of Regexp | String')

packages/shared/test/index.test.ts

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,19 @@
11
import { describe, expect, it } from 'vitest'
2-
import { defuOverrideArray, groupBy, isMap, isRegexp, noop, regExpTest, removeExt } from '@/index'
2+
import {
3+
cleanUrl,
4+
defuOverrideArray,
5+
ensurePosix,
6+
groupBy,
7+
isHttp,
8+
isMap,
9+
isRegexp,
10+
noop,
11+
normalizeRelativeImport,
12+
normalizeRoot,
13+
regExpTest,
14+
removeExt,
15+
toArray,
16+
} from '@/index'
317

418
describe('shared utils', () => {
519
it('isRegexp correctly detects regular expressions', () => {
@@ -94,4 +108,35 @@ describe('shared utils', () => {
94108
it('noop returns undefined without side effects', () => {
95109
expect(noop()).toBeUndefined()
96110
})
111+
112+
it('toArray normalizes values to arrays', () => {
113+
expect(toArray(null)).toEqual([])
114+
expect(toArray('a')).toEqual(['a'])
115+
expect(toArray(['a', 'b'])).toEqual(['a', 'b'])
116+
})
117+
118+
it('ensurePosix normalizes windows separators', () => {
119+
expect(ensurePosix('C:\\Users\\file.css')).toBe('C:/Users/file.css')
120+
})
121+
122+
it('normalizeRoot trims and normalizes root paths', () => {
123+
expect(normalizeRoot('./src/')).toBe('src')
124+
expect(normalizeRoot(' /src/app ')).toBe('src/app')
125+
})
126+
127+
it('normalizeRelativeImport prepends dot for bare paths', () => {
128+
expect(normalizeRelativeImport('styles/index.css')).toBe('./styles/index.css')
129+
expect(normalizeRelativeImport('./styles/index.css')).toBe('./styles/index.css')
130+
expect(normalizeRelativeImport('/styles/index.css')).toBe('/styles/index.css')
131+
})
132+
133+
it('cleanUrl strips query and hash', () => {
134+
expect(cleanUrl('style.css?inline#hash')).toBe('style.css')
135+
})
136+
137+
it('isHttp detects http/https urls', () => {
138+
expect(isHttp('http://example.com')).toBe(true)
139+
expect(isHttp('https://example.com')).toBe(true)
140+
expect(isHttp('ftp://example.com')).toBe(false)
141+
})
97142
})

packages/weapp-style-injector/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@
8181
"lint:fix": "eslint . --fix"
8282
},
8383
"dependencies": {
84+
"@weapp-tailwindcss/shared": "workspace:*",
8485
"micromatch": "^4.0.8"
8586
},
8687
"publishConfig": {}
Lines changed: 2 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,7 @@
11
import type { PerFileImportResolver } from './core'
2+
import { toArray } from '@weapp-tailwindcss/shared'
23

3-
export function toArray<T>(value: T | T[] | null | undefined): Array<NonNullable<T>> {
4-
if (value == null) {
5-
return []
6-
}
7-
return (Array.isArray(value) ? value : [value]) as Array<NonNullable<T>>
8-
}
4+
export { ensurePosix, normalizeRelativeImport, normalizeRoot, toArray } from '@weapp-tailwindcss/shared'
95

106
export function mergePerFileResolvers(
117
resolvers: Array<PerFileImportResolver | null | undefined>,
@@ -18,19 +14,3 @@ export function mergePerFileResolvers(
1814

1915
return (fileName: string) => activeResolvers.flatMap(resolver => toArray(resolver(fileName)))
2016
}
21-
22-
export function ensurePosix(value: string): string {
23-
return value.replace(/\\/g, '/')
24-
}
25-
26-
export function normalizeRoot(root: string): string {
27-
const trimmed = root.trim().replace(/^[./\\]+/, '').replace(/\\+/g, '/')
28-
return trimmed.endsWith('/') ? trimmed.slice(0, -1) : trimmed
29-
}
30-
31-
export function normalizeRelativeImport(target: string): string {
32-
if (target.startsWith('.') || target.startsWith('/')) {
33-
return target
34-
}
35-
return `./${target}`
36-
}

packages/weapp-tailwindcss/src/bundlers/vite/utils.ts

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import type { ExistingRawSourceMap } from 'rollup'
22
import path from 'node:path'
33
import process from 'node:process'
4+
import { cleanUrl, ensurePosix } from '@weapp-tailwindcss/shared'
45

56
export function slash(p: string): string {
6-
return p.replace(/\\/g, '/')
7+
return ensurePosix(p)
78
}
89

910
export const isWindows = process.platform === 'win32'
@@ -15,13 +16,9 @@ export function isCSSRequest(request: string): boolean {
1516
}
1617

1718
export function normalizePath(id: string): string {
18-
return path.posix.normalize(isWindows ? slash(id) : id)
19-
}
20-
21-
const postfixRE = /[?#].*$/
22-
export function cleanUrl(url: string): string {
23-
return url.replace(postfixRE, '')
19+
return path.posix.normalize(isWindows ? ensurePosix(id) : id)
2420
}
21+
export { cleanUrl }
2522

2623
export async function formatPostcssSourceMap(
2724
rawMap: ExistingRawSourceMap,

packages/weapp-tailwindcss/src/bundlers/webpack/loaders/weapp-tw-css-import-rewrite-loader.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import type { Buffer } from 'node:buffer'
33
import type webpack from 'webpack'
44
import type { AppType } from '@/types'
55
import process from 'node:process'
6+
import { ensurePosix } from '@weapp-tailwindcss/shared'
67
import loaderUtils from 'loader-utils'
78
import { rewriteTailwindcssImportsInCode } from '@/bundlers/shared/css-imports'
89

@@ -13,10 +14,6 @@ interface CssImportRewriteLoaderOptions {
1314
}
1415
}
1516

16-
function slash(p: string): string {
17-
return p.replace(/\\/g, '/')
18-
}
19-
2017
function joinPosixPath(base: string, subpath: string) {
2118
if (base.endsWith('/')) {
2219
return `${base}${subpath}`
@@ -32,7 +29,7 @@ function applyCssImportRewrite(source: string, options: CssImportRewriteLoaderOp
3229
}
3330
const rewritten = rewriteTailwindcssImportsInCode(
3431
source,
35-
slash(pkgDir),
32+
ensurePosix(pkgDir),
3633
{
3734
join: joinPosixPath,
3835
appType: rewriteOptions.appType,

packages/wetw/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
"publishConfig": {},
5353
"dependencies": {
5454
"@inquirer/prompts": "^8.2.0",
55+
"@weapp-tailwindcss/shared": "workspace:*",
5556
"c12": "^3.3.3",
5657
"cac": "^6.7.14"
5758
}

packages/wetw/src/utils.ts

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1 @@
1-
const HTTP_PATTERN = /^https?:\/\//i
2-
3-
export function isHttp(target: string) {
4-
return HTTP_PATTERN.test(target)
5-
}
1+
export { isHttp } from '@weapp-tailwindcss/shared'

0 commit comments

Comments
 (0)