mirror of
https://github.com/vitejs/vite.git
synced 2024-11-21 14:48:41 +00:00
wip
This commit is contained in:
parent
63f21faf2f
commit
67d2d69587
@ -1,9 +1,13 @@
|
||||
import { defineBuildConfig } from 'unbuild'
|
||||
|
||||
export default defineBuildConfig({
|
||||
entries: ['src/index.ts', 'src/postcss/index.ts'],
|
||||
entries: [
|
||||
'src/index.ts',
|
||||
'src/lightningcss/index.ts',
|
||||
'src/postcss/index.ts',
|
||||
],
|
||||
clean: true,
|
||||
declaration: true,
|
||||
declaration: 'node16',
|
||||
rollup: {
|
||||
inlineDependencies: true,
|
||||
esbuild: {
|
||||
|
@ -3,10 +3,12 @@
|
||||
"version": "1.0.0",
|
||||
"license": "MIT",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"main": "./dist/index.mjs",
|
||||
"types": "./dist/index.d.ts",
|
||||
"types": "./dist/index.d.mts",
|
||||
"exports": {
|
||||
".": "./dist/index.mjs",
|
||||
"./lightningcss": "./dist/lightningcss/index.mjs",
|
||||
"./postcss": "./dist/postcss/index.mjs"
|
||||
},
|
||||
"scripts": {
|
||||
@ -18,9 +20,13 @@
|
||||
"node": "^18.0.0 || >=20.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"lightningcss": "^1.21.0",
|
||||
"postcss": "^8.4.35"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"lightningcss": {
|
||||
"optional": true
|
||||
},
|
||||
"postcss": {
|
||||
"optional": true
|
||||
}
|
||||
@ -44,6 +50,7 @@
|
||||
"@types/postcss-modules-local-by-default": "^4.0.2",
|
||||
"@types/postcss-modules-scope": "^3.0.4",
|
||||
"@types/postcss-modules-values": "^4.0.2",
|
||||
"lightningcss": "^1.24.1",
|
||||
"postcss": "^8.4.35"
|
||||
}
|
||||
}
|
||||
|
54
packages/css-modules/src/lightningcss/compile.ts
Normal file
54
packages/css-modules/src/lightningcss/compile.ts
Normal file
@ -0,0 +1,54 @@
|
||||
import { transform } from 'lightningcss'
|
||||
import type { CSSModulesConfig } from 'lightningcss'
|
||||
import type { CSSModuleData, RawSourceMap } from '../types'
|
||||
|
||||
export interface CompileOptions {
|
||||
cssModules?: CSSModulesConfig
|
||||
sourcemap?: boolean
|
||||
}
|
||||
|
||||
export interface CompileResult {
|
||||
css: string
|
||||
map?: RawSourceMap
|
||||
data: CSSModuleData
|
||||
}
|
||||
|
||||
export async function compileCSSModule(
|
||||
css: string,
|
||||
id: string,
|
||||
options?: CompileOptions,
|
||||
): Promise<CompileResult> {
|
||||
const transformed = transform({
|
||||
filename: id,
|
||||
code: Buffer.from(css),
|
||||
cssModules: options?.cssModules ?? true,
|
||||
sourceMap: options?.sourcemap,
|
||||
})
|
||||
|
||||
/**
|
||||
* Addresses non-deterministic exports order:
|
||||
* https://github.com/parcel-bundler/lightningcss/issues/291
|
||||
*/
|
||||
const exports = Object.fromEntries(
|
||||
Object.entries(
|
||||
// `exports` is defined if cssModules is true
|
||||
transformed.exports!,
|
||||
).sort(
|
||||
// Cheap alphabetical sort (localCompare is expensive)
|
||||
([a], [b]) => (a < b ? -1 : a > b ? 1 : 0),
|
||||
),
|
||||
)
|
||||
|
||||
const map = transformed.map
|
||||
? (JSON.parse(Buffer.from(transformed.map).toString()) as RawSourceMap)
|
||||
: undefined
|
||||
|
||||
return {
|
||||
css: transformed.code.toString(),
|
||||
map,
|
||||
data: {
|
||||
exports,
|
||||
references: transformed.references,
|
||||
},
|
||||
}
|
||||
}
|
2
packages/css-modules/src/lightningcss/index.ts
Normal file
2
packages/css-modules/src/lightningcss/index.ts
Normal file
@ -0,0 +1,2 @@
|
||||
export { compileCSSModule } from './compile'
|
||||
export type { CompileOptions, CompileResult } from './compile'
|
@ -7,7 +7,8 @@ import postcss from 'postcss'
|
||||
import type { CSSModuleData, CSSModulesOptions, RawSourceMap } from '../types'
|
||||
import { postcssExtractIcss } from './postcss-extract-icss'
|
||||
|
||||
export interface CompileOptions extends CSSModulesOptions {
|
||||
export interface CompileOptions {
|
||||
cssModules?: CSSModulesOptions
|
||||
sourcemap?: boolean
|
||||
}
|
||||
|
||||
@ -37,14 +38,15 @@ export async function compileCSSModule(
|
||||
id: string,
|
||||
options?: CompileOptions,
|
||||
): Promise<CompileResult> {
|
||||
const cssModules = options?.cssModules ?? {}
|
||||
const generateScopedName =
|
||||
typeof options?.generateScopedName === 'function'
|
||||
? options.generateScopedName
|
||||
: genericNames(options?.generateScopedName ?? defaultScopedName, {
|
||||
hashPrefix: options?.hashPrefix,
|
||||
typeof cssModules.generateScopedName === 'function'
|
||||
? cssModules.generateScopedName
|
||||
: genericNames(cssModules.generateScopedName ?? defaultScopedName, {
|
||||
hashPrefix: cssModules.hashPrefix,
|
||||
})
|
||||
|
||||
const isGlobal = options?.globalModulePaths?.some((pattern) =>
|
||||
const isGlobal = cssModules.globalModulePaths?.some((pattern) =>
|
||||
pattern.test(id),
|
||||
)
|
||||
|
||||
@ -55,7 +57,7 @@ export async function compileCSSModule(
|
||||
postcssModulesValues,
|
||||
|
||||
postcssModulesLocalByDefault({
|
||||
mode: isGlobal ? 'global' : options?.scopeBehaviour,
|
||||
mode: isGlobal ? 'global' : cssModules.scopeBehaviour,
|
||||
}),
|
||||
|
||||
// Declares imports from composes
|
||||
@ -63,7 +65,7 @@ export async function compileCSSModule(
|
||||
|
||||
// Resolves & removes composes
|
||||
postcssModulesScope({
|
||||
exportGlobals: options?.exportGlobals,
|
||||
exportGlobals: cssModules.exportGlobals,
|
||||
generateScopedName: (exportName, resourceFile, rawCss) => {
|
||||
const scopedName = generateScopedName(exportName, resourceFile, rawCss)
|
||||
localClasses.push(scopedName)
|
||||
|
@ -12,8 +12,6 @@ import type {
|
||||
RollupError,
|
||||
SourceMapInput,
|
||||
} from 'rollup'
|
||||
import type { CSSModuleData, CssModuleToEsmResult } from '@vitejs/css-modules'
|
||||
import type { CompileResult as CompileCSSModuleResult } from '@vitejs/css-modules/postcss'
|
||||
import colors from 'picocolors'
|
||||
import MagicString from 'magic-string'
|
||||
import type * as PostCSS from 'postcss'
|
||||
@ -48,6 +46,7 @@ import {
|
||||
arraify,
|
||||
asyncReplace,
|
||||
combineSourcemaps,
|
||||
createCachedImport,
|
||||
createSerialPromiseQueue,
|
||||
emptyCssComments,
|
||||
generateCodeFrame,
|
||||
@ -81,7 +80,7 @@ import {
|
||||
} from './asset'
|
||||
import type { ESBuildOptions } from './esbuild'
|
||||
import { getChunkOriginalFileName } from './manifest'
|
||||
import type { TransformResult } from 'lightningcss'
|
||||
import { cssModulesCache } from './cssModules'
|
||||
|
||||
// const debug = createDebugger('vite:css')
|
||||
|
||||
@ -210,7 +209,7 @@ const enum PureCssLang {
|
||||
const enum PostCssDialectLang {
|
||||
sss = 'sugarss',
|
||||
}
|
||||
type CssLang =
|
||||
export type CssLang =
|
||||
| keyof typeof PureCssLang
|
||||
| keyof typeof PreprocessLang
|
||||
| keyof typeof PostCssDialectLang
|
||||
@ -227,18 +226,6 @@ export const isDirectCSSRequest = (request: string): boolean =>
|
||||
export const isDirectRequest = (request: string): boolean =>
|
||||
directRequestRE.test(request)
|
||||
|
||||
interface CSSModuleMetadata extends CSSModuleData {
|
||||
/**
|
||||
* Metadata after finishing processing a CSS module file
|
||||
*/
|
||||
exportsMetadata?: CssModuleToEsmResult['exportsMetadata']
|
||||
}
|
||||
|
||||
const cssModulesCache = new WeakMap<
|
||||
ResolvedConfig,
|
||||
Map<string, CSSModuleMetadata>
|
||||
>()
|
||||
|
||||
export const removedPureCssFilesCache = new WeakMap<
|
||||
ResolvedConfig,
|
||||
Map<string, RenderedChunk>
|
||||
@ -260,7 +247,6 @@ const cssUrlAssetRE = /__VITE_CSS_URL__([\da-f]+)__/g
|
||||
*/
|
||||
export function cssPlugin(config: ResolvedConfig): Plugin {
|
||||
const isBuild = config.command === 'build'
|
||||
let moduleCache: Map<string, CSSModuleMetadata>
|
||||
|
||||
const resolveUrl = config.createResolver({
|
||||
preferRelative: true,
|
||||
@ -279,10 +265,6 @@ export function cssPlugin(config: ResolvedConfig): Plugin {
|
||||
name: 'vite:css',
|
||||
|
||||
buildStart() {
|
||||
// Ensure a new cache for every build (i.e. rebuilding in watch mode)
|
||||
moduleCache = new Map<string, CSSModuleMetadata>()
|
||||
cssModulesCache.set(config, moduleCache)
|
||||
|
||||
removedPureCssFilesCache.set(config, new Map<string, RenderedChunk>())
|
||||
|
||||
preprocessorWorkerController = createPreprocessorWorkerController(
|
||||
@ -367,7 +349,6 @@ export function cssPlugin(config: ResolvedConfig): Plugin {
|
||||
|
||||
const {
|
||||
code: css,
|
||||
modules,
|
||||
deps,
|
||||
map,
|
||||
} = await compileCSS(
|
||||
@ -377,9 +358,6 @@ export function cssPlugin(config: ResolvedConfig): Plugin {
|
||||
preprocessorWorkerController!,
|
||||
urlReplacer,
|
||||
)
|
||||
if (modules) {
|
||||
moduleCache.set(id, modules)
|
||||
}
|
||||
|
||||
if (deps) {
|
||||
for (const file of deps) {
|
||||
@ -482,51 +460,11 @@ export function cssPostPlugin(config: ResolvedConfig): Plugin {
|
||||
// #6984, #7552
|
||||
// `foo.module.css` => modulesCode
|
||||
// `foo.module.css?inline` => cssContent
|
||||
const modulesCode =
|
||||
modules &&
|
||||
!inlined &&
|
||||
(await (async () => {
|
||||
const { cssModuleToEsm } = await importCssModules()
|
||||
const atImportResolvers = getAtImportResolvers(config)
|
||||
const result = await cssModuleToEsm(
|
||||
{
|
||||
css,
|
||||
id,
|
||||
exports: modules.exports,
|
||||
references: modules.references,
|
||||
resolve: async (id, importer) => {
|
||||
for (const key of getCssResolversKeys(atImportResolvers)) {
|
||||
const resolved = await atImportResolvers[key](id, importer)
|
||||
if (resolved) {
|
||||
return path.resolve(resolved)
|
||||
}
|
||||
}
|
||||
|
||||
return id
|
||||
},
|
||||
loadExports: async (resolvedId) => {
|
||||
await this.load({ id: resolvedId })
|
||||
|
||||
const modules = cssModulesCache.get(config)!.get(resolvedId)
|
||||
if (!modules || !modules.exportsMetadata) {
|
||||
throw new Error(
|
||||
`Failed to find exports from ${JSON.stringify(resolvedId)}`,
|
||||
)
|
||||
}
|
||||
return modules.exportsMetadata
|
||||
},
|
||||
},
|
||||
config.css.transformer === 'postcss' && config.css.modules !== false
|
||||
? config.css.modules
|
||||
: undefined,
|
||||
)
|
||||
|
||||
css = result.css
|
||||
// Save metadata to the modules cache so other CSS modules' `loadExports` can use it
|
||||
modules.exportsMetadata = result.exportsMetadata
|
||||
|
||||
return result.code
|
||||
})())
|
||||
let modulesCode: string | undefined
|
||||
if (modules && !inlined) {
|
||||
css = modules.css
|
||||
modulesCode = modules.code
|
||||
}
|
||||
|
||||
if (config.command === 'serve') {
|
||||
const getContentWithSourcemap = async (content: string) => {
|
||||
@ -1136,12 +1074,6 @@ function createCSSResolvers(config: ResolvedConfig): CSSAtImportResolvers {
|
||||
}
|
||||
}
|
||||
|
||||
function getCssResolversKeys(
|
||||
resolvers: CSSAtImportResolvers,
|
||||
): Array<keyof CSSAtImportResolvers> {
|
||||
return Object.keys(resolvers) as unknown as Array<keyof CSSAtImportResolvers>
|
||||
}
|
||||
|
||||
async function compileCSSPreprocessors(
|
||||
id: string,
|
||||
lang: PreprocessLang,
|
||||
@ -1213,7 +1145,9 @@ const configToAtImportResolvers = new WeakMap<
|
||||
ResolvedConfig,
|
||||
CSSAtImportResolvers
|
||||
>()
|
||||
function getAtImportResolvers(config: ResolvedConfig) {
|
||||
export function getAtImportResolvers(
|
||||
config: ResolvedConfig,
|
||||
): CSSAtImportResolvers {
|
||||
let atImportResolvers = configToAtImportResolvers.get(config)
|
||||
if (!atImportResolvers) {
|
||||
atImportResolvers = createCSSResolvers(config)
|
||||
@ -1232,7 +1166,6 @@ async function compileCSS(
|
||||
code: string
|
||||
map?: SourceMapInput
|
||||
ast?: PostCSS.Result
|
||||
modules?: CSSModuleMetadata
|
||||
deps?: Set<string>
|
||||
}> {
|
||||
if (config.css?.transformer === 'lightningcss') {
|
||||
@ -1428,22 +1361,11 @@ async function compileCSS(
|
||||
throw e
|
||||
}
|
||||
|
||||
let moduleResult: CompileCSSModuleResult | undefined
|
||||
if (isModule) {
|
||||
const { compileCSSModule } = await importCssModulesPostcss()
|
||||
moduleResult = await compileCSSModule(
|
||||
postcssResult.css,
|
||||
removeDirectQuery(id),
|
||||
{ ...modulesOptions, sourcemap: devSourcemap },
|
||||
)
|
||||
}
|
||||
|
||||
if (!devSourcemap) {
|
||||
return {
|
||||
ast: postcssResult,
|
||||
code: moduleResult?.css ?? postcssResult.css,
|
||||
code: postcssResult.css,
|
||||
map: { mappings: '' },
|
||||
modules: moduleResult?.data,
|
||||
deps,
|
||||
}
|
||||
}
|
||||
@ -1461,41 +1383,16 @@ async function compileCSS(
|
||||
|
||||
map = combineSourcemapsIfExists(cleanUrl(id), postcssMap, preprocessorMap)
|
||||
|
||||
if (moduleResult?.map) {
|
||||
map = combineSourcemapsIfExists(
|
||||
cleanUrl(id),
|
||||
map,
|
||||
moduleResult.map as ExistingRawSourceMap,
|
||||
)
|
||||
}
|
||||
|
||||
return {
|
||||
ast: postcssResult,
|
||||
code: moduleResult?.css ?? postcssResult.css,
|
||||
code: postcssResult.css,
|
||||
map,
|
||||
modules: moduleResult?.data,
|
||||
deps,
|
||||
}
|
||||
}
|
||||
|
||||
function createCachedImport<T>(imp: () => Promise<T>): () => T | Promise<T> {
|
||||
let cached: T | Promise<T>
|
||||
return () => {
|
||||
if (!cached) {
|
||||
cached = imp().then((module) => {
|
||||
cached = module
|
||||
return module
|
||||
})
|
||||
}
|
||||
return cached
|
||||
}
|
||||
}
|
||||
const importPostcssImport = createCachedImport(() => import('postcss-import'))
|
||||
const importPostcss = createCachedImport(() => import('postcss'))
|
||||
const importCssModules = createCachedImport(() => import('@vitejs/css-modules'))
|
||||
const importCssModulesPostcss = createCachedImport(
|
||||
() => import('@vitejs/css-modules/postcss'),
|
||||
)
|
||||
|
||||
const preprocessorWorkerControllerCache = new WeakMap<
|
||||
ResolvedConfig,
|
||||
@ -1508,7 +1405,6 @@ let alwaysFakeWorkerWorkerControllerCache:
|
||||
export interface PreprocessCSSResult {
|
||||
code: string
|
||||
map?: SourceMapInput
|
||||
modules?: CSSModuleMetadata
|
||||
deps?: Set<string>
|
||||
}
|
||||
|
||||
@ -2813,25 +2709,10 @@ async function compileLightningCSS(
|
||||
}
|
||||
}
|
||||
|
||||
let modules: CSSModuleMetadata | undefined
|
||||
if (!isStyleAttr && 'exports' in res && res.exports) {
|
||||
const resolved = res as TransformResult
|
||||
// https://github.com/parcel-bundler/lightningcss/issues/291
|
||||
const exports = Object.fromEntries(
|
||||
Object.entries(resolved.exports!).sort(
|
||||
// Cheap alphabetical sort (localCompare is expensive)
|
||||
([a], [b]) => (a < b ? -1 : a > b ? 1 : 0),
|
||||
),
|
||||
)
|
||||
|
||||
modules = { exports, references: resolved.references }
|
||||
}
|
||||
|
||||
return {
|
||||
code: css,
|
||||
map: 'map' in res ? res.map?.toString() : undefined,
|
||||
deps,
|
||||
modules,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,9 +1,149 @@
|
||||
import type{ Plugin } from "../plugin";
|
||||
import type { ResolvedConfig } from "../config";
|
||||
import { cssModuleToEsm } from '@vitejs/css-modules'
|
||||
import type { CSSModuleData, CssModuleToEsmResult } from '@vitejs/css-modules'
|
||||
import type { SourceMapInput } from 'rollup'
|
||||
import type { Plugin } from '../plugin'
|
||||
import type { ResolvedConfig } from '../config'
|
||||
import { createCachedImport, removeDirectQuery } from '../utils'
|
||||
import { CSS_LANGS_RE } from '../constants'
|
||||
import { type CssLang, getAtImportResolvers, isModuleCSSRequest } from './css'
|
||||
|
||||
interface CSSModuleMetadata {
|
||||
/**
|
||||
* Transformed CSS
|
||||
*/
|
||||
css: string
|
||||
/**
|
||||
* JS code for CSS module
|
||||
*/
|
||||
code: string
|
||||
data: CSSModuleData
|
||||
/**
|
||||
* Metadata after finishing processing a CSS module file
|
||||
*/
|
||||
exportsMetadata?: CssModuleToEsmResult['exportsMetadata']
|
||||
}
|
||||
|
||||
export const cssModulesCache = new WeakMap<
|
||||
ResolvedConfig,
|
||||
Map<string, CSSModuleMetadata>
|
||||
>()
|
||||
|
||||
// export function getCSSModuleResult(
|
||||
// id: string,
|
||||
// config: ResolvedConfig,
|
||||
// ): Pick<CSSModuleMetadata, 'css' | 'code'> | undefined {
|
||||
// const cache = cssModulesCache.get(config)?.get(id)
|
||||
// if (cache) {
|
||||
// return { css: cache.css, code: cache.code }
|
||||
// }
|
||||
// }
|
||||
|
||||
export function cssModulesPlugin(config: ResolvedConfig): Plugin {
|
||||
let moduleCache: Map<string, CSSModuleMetadata>
|
||||
|
||||
return {
|
||||
name: 'vite:css-modules',
|
||||
|
||||
buildStart() {
|
||||
// Ensure a new cache for every build (i.e. rebuilding in watch mode)
|
||||
moduleCache = new Map<string, CSSModuleMetadata>()
|
||||
cssModulesCache.set(config, moduleCache)
|
||||
},
|
||||
|
||||
async transform(css, id) {
|
||||
if (!isModuleCSSRequest(id)) return
|
||||
|
||||
const { css: newCss, map, data } = await compileCSSModule(css, id, config)
|
||||
|
||||
const lang = id.match(CSS_LANGS_RE)?.[1] as CssLang | undefined
|
||||
const atImportResolvers = getAtImportResolvers(config)
|
||||
const resolver =
|
||||
lang === 'sass' || lang === 'scss'
|
||||
? atImportResolvers.sass
|
||||
: lang === 'less'
|
||||
? atImportResolvers.less
|
||||
: atImportResolvers.css
|
||||
|
||||
const result = await cssModuleToEsm(
|
||||
{
|
||||
css: newCss,
|
||||
id,
|
||||
exports: data.exports,
|
||||
references: data.references,
|
||||
resolve: async (id, importer) => {
|
||||
return (await resolver(id, importer)) ?? id
|
||||
},
|
||||
loadExports: async (resolvedId) => {
|
||||
await this.load({ id: resolvedId })
|
||||
|
||||
const modules = cssModulesCache.get(config)!.get(resolvedId)
|
||||
if (!modules || !modules.exportsMetadata) {
|
||||
throw new Error(
|
||||
`Failed to find exports from ${JSON.stringify(resolvedId)}`,
|
||||
)
|
||||
}
|
||||
return modules.exportsMetadata
|
||||
},
|
||||
},
|
||||
config.css.transformer === 'postcss'
|
||||
? config.css.modules || undefined
|
||||
: undefined,
|
||||
)
|
||||
|
||||
moduleCache.set(id, {
|
||||
css: result.css,
|
||||
code: result.code,
|
||||
data,
|
||||
exportsMetadata: result.exportsMetadata,
|
||||
})
|
||||
|
||||
return {
|
||||
code: result.css,
|
||||
map,
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const importCssModulesPostcss = createCachedImport(
|
||||
() => import('@vitejs/css-modules/postcss'),
|
||||
)
|
||||
const importCssModulesLightningcss = createCachedImport(
|
||||
() => import('@vitejs/css-modules/lightningcss'),
|
||||
)
|
||||
|
||||
async function compileCSSModule(
|
||||
css: string,
|
||||
id: string,
|
||||
config: ResolvedConfig,
|
||||
): Promise<{
|
||||
css: string
|
||||
map?: SourceMapInput
|
||||
data: CSSModuleData
|
||||
}> {
|
||||
id = removeDirectQuery(id)
|
||||
|
||||
if (config.css?.transformer === 'lightningcss') {
|
||||
const { compileCSSModule: compile } = await importCssModulesLightningcss()
|
||||
const result = await compile(css, id, {
|
||||
cssModules: config.css.lightningcss?.cssModules,
|
||||
sourcemap: config.css.devSourcemap,
|
||||
})
|
||||
return {
|
||||
css: result.css,
|
||||
map: result.map as SourceMapInput,
|
||||
data: result.data,
|
||||
}
|
||||
} else {
|
||||
const { compileCSSModule: compile } = await importCssModulesPostcss()
|
||||
const result = await compile(css, id, {
|
||||
cssModules: config.css.modules || {},
|
||||
sourcemap: config.css.devSourcemap,
|
||||
})
|
||||
return {
|
||||
css: result.css,
|
||||
map: result.map as SourceMapInput,
|
||||
data: result.data,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -90,7 +90,7 @@ export async function resolvePlugins(
|
||||
...normalPlugins,
|
||||
wasmFallbackPlugin(),
|
||||
definePlugin(config),
|
||||
cssModulesPlugin(config),
|
||||
config.css.modules !== false ? cssModulesPlugin(config) : null,
|
||||
cssPostPlugin(config),
|
||||
isBuild && buildHtmlPlugin(config),
|
||||
workerImportMetaUrlPlugin(config),
|
||||
|
@ -1424,3 +1424,18 @@ export function displayTime(time: number): string {
|
||||
export function partialEncodeURI(uri: string): string {
|
||||
return uri.replaceAll('%', '%25')
|
||||
}
|
||||
|
||||
export function createCachedImport<T>(
|
||||
imp: () => Promise<T>,
|
||||
): () => T | Promise<T> {
|
||||
let cached: T | Promise<T>
|
||||
return () => {
|
||||
if (!cached) {
|
||||
cached = imp().then((module) => {
|
||||
cached = module
|
||||
return module
|
||||
})
|
||||
}
|
||||
return cached
|
||||
}
|
||||
}
|
||||
|
@ -253,6 +253,9 @@ importers:
|
||||
'@types/postcss-modules-values':
|
||||
specifier: ^4.0.2
|
||||
version: 4.0.2
|
||||
lightningcss:
|
||||
specifier: ^1.24.1
|
||||
version: 1.24.1
|
||||
postcss:
|
||||
specifier: ^8.4.35
|
||||
version: 8.4.36
|
||||
|
Loading…
Reference in New Issue
Block a user