diff --git a/migration-v2.0.0.md b/migration-v2.0.0.md index 939bd2d..d912cc4 100644 --- a/migration-v2.0.0.md +++ b/migration-v2.0.0.md @@ -1,5 +1,13 @@ # v2.0.0 升级指南 + +## 新功能 + +- 支持自定义base,默认取vite config 中的 base +- 支持 cacheDir,默认 `node_modules/.vite-plugin-public-typescript`。如果是非vite项目,可以指定为跟 `inputDir` 同名 + +**喜大普奔,再也不用看到manifest.json文件啦~** + ## vite项目 1. 删除manifest.json文件 diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e8fdadd..6519f63 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -5939,7 +5939,7 @@ packages: dependencies: find-up: 6.3.0 read-pkg: 8.1.0 - type-fest: 4.3.1 + type-fest: 4.6.0 dev: true /read-pkg-up@7.0.1: @@ -5977,7 +5977,7 @@ packages: '@types/normalize-package-data': 2.4.2 normalize-package-data: 6.0.0 parse-json: 7.1.0 - type-fest: 4.3.1 + type-fest: 4.6.0 dev: true /readable-stream@3.6.2: @@ -6843,8 +6843,8 @@ packages: engines: {node: '>=14.16'} dev: true - /type-fest@4.3.1: - resolution: {integrity: sha512-pphNW/msgOUSkJbH58x8sqpq8uQj6b0ZKGxEsLKMUnGorRcDjrUaLS+39+/ub41JNTwrrMyJcUB8+YZs3mbwqw==} + /type-fest@4.6.0: + resolution: {integrity: sha512-rLjWJzQFOq4xw7MgJrCZ6T1jIOvvYElXT12r+y0CC6u67hegDHaxcPqb2fZHOGlqxugGQPNB1EnTezjBetkwkw==} engines: {node: '>=16'} dev: true diff --git a/src/node/global-config/GlobalConfigBuilder.ts b/src/node/global-config/GlobalConfigBuilder.ts index 3e00447..b9f2ce1 100644 --- a/src/node/global-config/GlobalConfigBuilder.ts +++ b/src/node/global-config/GlobalConfigBuilder.ts @@ -18,6 +18,7 @@ export type GlobalConfig = UserConfig & { } export class GlobalConfigBuilder { + private _inited = false private _globalConfig: GlobalConfig constructor() { @@ -25,7 +26,12 @@ export class GlobalConfigBuilder { } init(c: UserConfig) { - const root = c.viteConfig.root || process.cwd() + if (this._inited) { + // only initialize once + return this + } + + const root = c.viteConfig?.root || process.cwd() const absOutputDir = path.join(root, c.outputDir) const absInputDir = path.join(root, c.inputDir) @@ -35,18 +41,30 @@ export class GlobalConfigBuilder { absOutputDir, } + this._inited = true + return this } - get() { - return this._globalConfig + test | readonly string[]>(path: Path) { + return path as any } - set(c: UserConfig) { - this._globalConfig = { - ...this.get(), - ...c, + get>(keys: Selected[]): Pick, Selected> + get>(key: Selected): GlobalConfig[Selected] + get>(key: any): any { + const result = {} as Pick, Selected> + if (Array.isArray(key)) { + ;(key as Selected[]).forEach((k) => { + result[k] = this._globalConfig[k] + }) + return result + } else { + return this._globalConfig[key as Selected] } - return this + } + + get all() { + return this._globalConfig } } diff --git a/src/node/helper/build.ts b/src/node/helper/build.ts index 60fa17d..acfa424 100644 --- a/src/node/helper/build.ts +++ b/src/node/helper/build.ts @@ -100,7 +100,7 @@ export async function esbuildTypescript(buildOptions: IBuildOptions) { export async function build(options: { filePath: string }, onBuildEnd?: BaseCacheProcessor['onTsBuildEnd']) { const { filePath } = options - const getGlobalConfig = globalConfig.get() + const getGlobalConfig = globalConfig.all const originFileName = path.basename(filePath, path.extname(filePath)) @@ -114,7 +114,7 @@ export async function build(options: { filePath: string }, onBuildEnd?: BaseCach compiledFileName = `${originFileName}.${contentHash}` } - debug('before onBuildEnd manifest-cache:', getGlobalConfig.manifestCache.get()) + debug('before onBuildEnd manifest-cache:', getGlobalConfig.manifestCache.all) await onBuildEnd?.( { @@ -125,11 +125,11 @@ export async function build(options: { filePath: string }, onBuildEnd?: BaseCach { code, contentHash, originFileName, silent: false }, ) - debug('after onBuildEnd manifest-cache:', getGlobalConfig.manifestCache.get()) + debug('after onBuildEnd manifest-cache:', getGlobalConfig.manifestCache.all) } export async function buildAllOnce(tsFilesGlob: string[]) { - const { cacheProcessor } = globalConfig.get() + const cacheProcessor = globalConfig.get('cacheProcessor') const toBuildList: (() => Promise)[] = [] diff --git a/src/node/helper/file-watcher.ts b/src/node/helper/file-watcher.ts index 855b87f..29e4265 100644 --- a/src/node/helper/file-watcher.ts +++ b/src/node/helper/file-watcher.ts @@ -13,7 +13,7 @@ export async function handleUnlink(filePath: string, cb?: () => void) { if (_isPublicTypescript(filePath)) { const fileName = path.parse(filePath).name debug('unlink:', fileName) - await globalConfig.get().cacheProcessor.deleteOldJs({ originFileName: fileName }) + await globalConfig.get('cacheProcessor').deleteOldJs({ originFileName: fileName }) cb?.() } } @@ -21,7 +21,7 @@ export async function handleUnlink(filePath: string, cb?: () => void) { export async function handleFileAdded(filePath: string, cb?: () => void) { if (_isPublicTypescript(filePath)) { debug('file added:', filePath) - await build({ filePath }, (...args) => globalConfig.get().cacheProcessor.onTsBuildEnd(...args)) + await build({ filePath }, (...args) => globalConfig.get('cacheProcessor').onTsBuildEnd(...args)) cb?.() } } @@ -41,7 +41,7 @@ async function handleFileChange(filePath: string, cb?: () => void) { export function initWatcher(cb: (file: HmrFile) => void) { try { - const watcher = new Watcher(globalConfig.get().absInputDir, { + const watcher = new Watcher(globalConfig.get('absInputDir'), { debounce: 0, ignoreInitial: true, recursive: true, diff --git a/src/node/helper/io.ts b/src/node/helper/io.ts index 8fb3f7b..a624230 100644 --- a/src/node/helper/io.ts +++ b/src/node/helper/io.ts @@ -44,7 +44,7 @@ export function writeFile(filename: string, content: string, hash = true): void if (fs.existsSync(filename)) { if (hash) { - const _hash = globalConfig.get().hash + const _hash = globalConfig.get('hash') if (extractHashFromFileName(filename, _hash)) { // if filename has hash, skip write file debug('skip writeFile, filename has hash') diff --git a/src/node/helper/server.ts b/src/node/helper/server.ts index 8570923..9c237c0 100644 --- a/src/node/helper/server.ts +++ b/src/node/helper/server.ts @@ -12,7 +12,7 @@ export type HmrFile = { event: string } export function reloadPage(ws: WebSocketServer, file: HmrFile) { - const { logger } = globalConfig.get() + const logger = globalConfig.get('logger') if (!isInTest()) { logger.info( diff --git a/src/node/helper/utils.ts b/src/node/helper/utils.ts index db6d7d2..9b1bf0e 100644 --- a/src/node/helper/utils.ts +++ b/src/node/helper/utils.ts @@ -28,7 +28,7 @@ export function createInternalLogger(allowClearScreen?: boolean) { } export function fileRelativeRootPath(filePath: string) { - return normalizePath(`/${path.relative(globalConfig.get().viteConfig.root, filePath)}`) + return normalizePath(`/${path.relative(globalConfig.get('viteConfig')!.root, filePath)}`) } export function isInTest() { @@ -47,8 +47,8 @@ export function isPublicTypescript(args: { filePath: string; inputDir: string; r export function _isPublicTypescript(filePath: string) { return isPublicTypescript({ filePath, - inputDir: globalConfig.get().inputDir, - root: globalConfig.get().viteConfig.root, + inputDir: globalConfig.get('inputDir'), + root: globalConfig.get('viteConfig')!.root, }) } @@ -136,7 +136,7 @@ export function validateOptions(options: OptionsTypeWithDefault) { options.inputDir = inputDir.replace(/\/$/, '') } - if (options.sideEffects !== undefined) { + if (options.sideEffects !== undefined && !isInTest()) { console.warn( colors.yellow( `${colors.bold('(warning!)')} [${pkgName}]: sideEffects option is ${colors.bold( @@ -212,7 +212,7 @@ export async function setupGlobalConfig(viteConfig: ResolvedConfig, opts: Option ...(opts as Required), }) - return globalConfig.get() + return globalConfig } export async function setupManifestCache(viteConfig: ResolvedConfig, opts: OptionsTypeWithDefault) { diff --git a/src/node/index.ts b/src/node/index.ts index b47e96e..cf5bb90 100644 --- a/src/node/index.ts +++ b/src/node/index.ts @@ -132,7 +132,7 @@ export default function publicTypescript(options: VPPTPluginOptions = {}) { manifestCache.writeManifestJSON() } - const { originFilesGlob } = globalConfig.get() + const originFilesGlob = globalConfig.get('originFilesGlob') const originFilesName = originFilesGlob.map((file) => path.parse(file).name) @@ -161,7 +161,7 @@ export default function publicTypescript(options: VPPTPluginOptions = {}) { }, generateBundle() { if (opts.destination === 'memory') { - const c = manifestCache.get() + const c = manifestCache.all Object.keys(c).forEach((key) => { this.emitFile({ fileName: normalizeAssetsDirPath(`${c[key]._pathToDisk}`), diff --git a/src/node/manifest-cache/ManifestCache.ts b/src/node/manifest-cache/ManifestCache.ts index 9cb6344..8f7b53c 100644 --- a/src/node/manifest-cache/ManifestCache.ts +++ b/src/node/manifest-cache/ManifestCache.ts @@ -25,7 +25,7 @@ export type CacheValue = { path: string } & Partial<{ [_key: string]: string }> -export type CacheObject = { +export type CacheManifest = { [fileName in string]: V } @@ -33,7 +33,7 @@ const DEFAULT_OPTIONS: ManifestConstructor = { writable: true, } -export class ManifestCache = CacheObject> { +export class ManifestCache = CacheManifest> { private _cache: U private _manifestPath = '' @@ -57,10 +57,24 @@ export class ManifestCache(keys: Selected[]): Pick + get(key: Selected): U[Selected] + get(key: any): any { + const result = {} as Pick + if (Array.isArray(key)) { + ;(key as Selected[]).forEach((k) => { + result[k] = this._cache[k] + }) + return result + } else { + return this._cache[key as Selected] + } + } + // NOTE: the only way to set cache set(c: U, opts?: { silent?: boolean }) { const keys = Object.keys(c) @@ -124,7 +138,7 @@ export class ManifestCache 0) { for (const f of oldFiles) { @@ -66,11 +66,9 @@ export class FileCacheProcessor extends ManifestCacheProcessor { async addNewJs(args: AddFileArgs): Promise { const { code = '' } = args - const { - viteConfig: { publicDir }, - } = globalConfig.get() + const { publicDir } = globalConfig.get('viteConfig') - const pathToDisk = this.setCache(args, globalConfig.get()) + const pathToDisk = this.setCache(args, globalConfig.all) const jsFilePath = normalizePath(path.join(publicDir, pathToDisk)) diff --git a/src/node/processor/ManifestCacheProcessor.ts b/src/node/processor/ManifestCacheProcessor.ts index b91c206..a091e22 100644 --- a/src/node/processor/ManifestCacheProcessor.ts +++ b/src/node/processor/ManifestCacheProcessor.ts @@ -48,6 +48,6 @@ export abstract class ManifestCacheProcessor extends BaseCacheProcessor { - this.setCache(args, globalConfig.get()) + this.setCache(args, globalConfig.all) } } diff --git a/tests/utils.test.ts b/tests/utils.test.ts index 9816f88..c02a1cd 100644 --- a/tests/utils.test.ts +++ b/tests/utils.test.ts @@ -71,7 +71,7 @@ describe('unit test', () => { }) test('should get globalConfig', () => { - expect(() => globalConfig.get()).not.toThrowError() + expect(() => globalConfig.all).not.toThrowError() }) test('should extract hash', () => { @@ -104,6 +104,6 @@ describe('globalConfig related', () => { }) test('global config should be same', ({ _globalConfig }) => { - expect(_globalConfig).toBe(globalConfig.get()) + expect(_globalConfig).toBe(globalConfig.all) }) }) diff --git a/tests/vitestSetup.ts b/tests/vitestSetup.ts index 95e2f78..526831a 100644 --- a/tests/vitestSetup.ts +++ b/tests/vitestSetup.ts @@ -20,5 +20,5 @@ declare module 'vitest' { beforeEach(async (ctx) => { const c = await setupGlobalConfig(viteConfig, DEFAULT_OPTIONS) - ctx._globalConfig = c + ctx._globalConfig = c.all })