vite-plugin-entry-shaking
Advanced tools
Comparing version 0.1.0 to 0.2.0
@@ -10,36 +10,9 @@ import { PluginOption } from 'vite'; | ||
}; | ||
/** Final plugin options. */ | ||
declare type FinalPluginOptions = Required<PluginOptions>; | ||
/** Target entry data. */ | ||
declare type EntryData = { | ||
exports: EntryExports; | ||
updatedSource: string; | ||
}; | ||
/** Target entry map. */ | ||
declare type PluginEntries = Map<TargetAbsolutePath, EntryData>; | ||
/** Import parameters. */ | ||
declare type ImportParams<T = string> = { | ||
path: T; | ||
importDefault: boolean; | ||
aliasStatement?: string; | ||
}; | ||
/** Named export. */ | ||
declare type ExportName = string; | ||
/** Resolved path of aggregated export (`export … from …`). */ | ||
declare type ExportOriginPath = string; | ||
/** Entry exports map. */ | ||
declare type EntryExports = Map<ExportName, ImportParams<ExportOriginPath>>; | ||
/** Resolved absolute path of target. */ | ||
declare type TargetAbsolutePath = string; | ||
declare type EntryPath = string; | ||
/** List of targets being processed by the plugin. */ | ||
declare type PluginTargets = TargetAbsolutePath[]; | ||
declare type PluginTargets = EntryPath[]; | ||
/** Analyzes target entry files. */ | ||
declare const analyzeEntries: (targets: PluginTargets) => Promise<PluginEntries>; | ||
/** Determines whether a given file should be transformed. */ | ||
declare const transformRequired: (id: string, options: FinalPluginOptions) => boolean; | ||
/** Merges user options with the default ones. */ | ||
declare const mergeOptions: (userOptions: PluginOptions) => FinalPluginOptions; | ||
declare function createEntryShakingPlugin(userOptions: PluginOptions): Promise<PluginOption>; | ||
export { analyzeEntries, createEntryShakingPlugin as default, mergeOptions, transformRequired }; | ||
export { createEntryShakingPlugin as default }; |
{ | ||
"name": "vite-plugin-entry-shaking", | ||
"version": "0.1.0", | ||
"version": "0.2.0", | ||
"description": "Mimic tree-shaking behaviour when importing code from an entry file in development mode.", | ||
@@ -52,3 +52,3 @@ "author": "Charles Gruenais", | ||
"unbuild": "^0.8.11", | ||
"vite": "^3.1.1", | ||
"vite": "^4.0.1", | ||
"vitest": "^0.23.2" | ||
@@ -55,0 +55,0 @@ }, |
104
src/index.ts
@@ -1,57 +0,15 @@ | ||
import type { PluginOption, ResolvedConfig, Logger } from 'vite'; | ||
import { normalizePath } from 'vite'; | ||
import { parse } from 'path'; | ||
import type { FinalPluginOptions, PluginEntries, PluginOptions, PluginTargets } from './types'; | ||
import { paint } from './logger'; | ||
import { transformImports } from './transform'; | ||
import type { PluginOption, Logger, ResolveFn } from 'vite'; | ||
import type { PluginEntries, PluginOptions } from './types'; | ||
import { configureLogger } from './logger'; | ||
import { transformIfNeeded } from './transform'; | ||
import { mergeOptions } from './options'; | ||
import EntryAnalyzer from './analyze-entry'; | ||
const logPrefix = paint('cyan', `[vite:entry-shaking]`); | ||
/** Analyzes target entry files. */ | ||
export const analyzeEntries = async ( | ||
targets: PluginTargets, | ||
): Promise<PluginEntries> => { | ||
const entries: PluginEntries = new Map([]); | ||
await Promise.all( | ||
targets.map(async (absolutePath) => { | ||
await EntryAnalyzer.analyzeEntry( | ||
entries, | ||
absolutePath, | ||
); | ||
}), | ||
); | ||
return entries; | ||
}; | ||
/** Determines whether a given file should be transformed. */ | ||
export const transformRequired = ( | ||
id: string, | ||
options: FinalPluginOptions, | ||
) => { | ||
const extension = id.split('.').pop()!; | ||
const isIgnored = options.ignorePatterns.some((pattern) => id.match(pattern)); | ||
return !isIgnored && options.extensions.includes(extension); | ||
}; | ||
/** Merges user options with the default ones. */ | ||
export const mergeOptions = ( | ||
userOptions: PluginOptions, | ||
): FinalPluginOptions => ({ | ||
extensions: ['js', 'jsx', 'mjs', 'ts', 'tsx', 'mts'], | ||
ignorePatterns: [/node_modules/, ...userOptions.ignorePatterns ?? []], | ||
debug: false, | ||
...userOptions, | ||
targets: userOptions.targets.map(normalizePath), | ||
}); | ||
export default async function createEntryShakingPlugin( | ||
userOptions: PluginOptions, | ||
): Promise<PluginOption> { | ||
const options = mergeOptions(userOptions); | ||
let logger: Logger; | ||
let config: ResolvedConfig; | ||
const options = mergeOptions(userOptions); | ||
const entries = await analyzeEntries(options.targets); | ||
let resolver: ResolveFn; | ||
let entries: PluginEntries; | ||
@@ -63,34 +21,34 @@ return { | ||
configResolved(resolvedConfig) { | ||
logger = resolvedConfig.logger; | ||
config = resolvedConfig; | ||
async configResolved({ logger: loggerConfig, createResolver }) { | ||
logger = configureLogger(loggerConfig, options.debug); | ||
resolver = createResolver(); | ||
entries = await EntryAnalyzer.analyzeEntries(options.targets, resolver); | ||
logger.info(`List of merged options: ${JSON.stringify(options)}`); | ||
logger.info(`List of parsed entries: ${JSON.stringify([...entries.keys()])}`); | ||
}, | ||
if (options.debug) { | ||
logger.info(`${logPrefix} List of merged options: ${JSON.stringify(options)}`); | ||
logger.info(`${logPrefix} List of parsed entries: Map(${JSON.stringify(Array.from(entries))})`); | ||
async handleHotUpdate({ file }) { | ||
if (entries.has(file)) { | ||
await EntryAnalyzer.doAnalyzeEntry(entries, file); | ||
} | ||
}, | ||
load(id) { | ||
const { dir, name } = parse(id); | ||
const altId = name === 'index' ? dir : id; | ||
const entryParams = entries.get(id) || entries.get(altId); | ||
if (entryParams) return entryParams.updatedSource; | ||
async transform(code, id) { | ||
return await transformIfNeeded( | ||
id, | ||
code, | ||
entries, | ||
options, | ||
resolver, | ||
logger, | ||
); | ||
}, | ||
async transform(code, id) { | ||
const requiresTransform = transformRequired(id, options); | ||
if (options.debug) { | ||
logger.info(`${logPrefix} ${requiresTransform | ||
? `[MATCHED] ${id}` | ||
: paint('gray', `[IGNORED] ${id}`)}`); | ||
load(id) { | ||
if (entries.has(id)) { | ||
logger.info(`Serving mutated entry file ${id}`); | ||
return entries.get(id)!.updatedSource; | ||
} | ||
if (requiresTransform) { | ||
const { targets } = options; | ||
const aliases = config.resolve.alias; | ||
return await transformImports(id, code, entries, targets, aliases); | ||
} | ||
}, | ||
}; | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
No README
QualityPackage does not have a README. This may indicate a failed publish or a low quality package.
Found 1 instance in 1 package
34416
7
822
0
144