@octohash/vite-config
Version:
A personal ready-to-use Vite configuration repository, opinionated but customizable.
1,108 lines (1,092 loc) • 42.4 kB
text/typescript
import * as vite from 'vite';
import { AliasOptions, UserConfig, PluginOption } from 'vite';
import { PluginOptions as PluginOptions$1 } from '@intlify/unplugin-vue-i18n';
import { VitePluginFederationOptions } from '@originjs/vite-plugin-federation';
import { PluginVisualizerOptions } from 'rollup-plugin-visualizer';
import { Options } from 'unplugin-auto-import/types';
import { Options as Options$1 } from 'unplugin-vue-components';
import { Options as Options$2 } from 'unplugin-vue-router';
import { PluginOptions } from 'vite-plugin-dts';
import { VitePluginVueDevToolsOptions } from 'vite-plugin-vue-devtools';
interface AppLoadingPluginOptions {
rootContainer?: string;
title?: string;
filePath?: string;
}
type Log = (type: string, message: string) => void;
interface IImportMap {
imports?: Record<string, string>;
scopes?: {
[scope: string]: Record<string, string>;
};
integrity?: {
[url: string]: string;
};
}
declare class ImportMap implements IImportMap {
imports: Record<string, string>;
scopes: Record<string, Record<string, string>>;
integrity: Record<string, string>;
/**
* The absolute URL of the import map, for determining relative resolutions
* When using file:/// URLs this allows relative modules to be co-located
*/
mapUrl: URL;
/**
* The URL to use for root-level resolutions in the import map
* If null, root resolutions are not resolved and instead left as-is
*
* By default, rootUrl is null unless the mapUrl is an http or https URL,
* in which case it is taken to be the root of the mapUrl.
*/
rootUrl: URL | null;
/**
* Create a new import map instance
*
* @param opts import map options, can be an optional bag of { map?, mapUrl?, rootUrl? } or just a direct mapUrl
*/
constructor(opts: {
map?: IImportMap;
mapUrl?: string | URL;
rootUrl?: string | URL | null;
} | string | URL);
/**
* Clones the import map
* @returns Cloned import map
*/
clone(): ImportMap;
/**
* Extends the import map mappings
* @param map Import map to extend with
* @param overrideScopes Set to true to have scopes be replacing instead of extending
* @returns ImportMap for chaining
*/
extend(map: IImportMap, overrideScopes?: boolean): this;
/**
* Performs an alphanumerical sort on the import map imports and scopes
* @returns ImportMap for chaining
*/
sort(): this;
/**
* Set a specific entry in the import map
*
* @param name Specifier to set
* @param target Target of the map
* @param parent Optional parent scope
* @returns ImportMap for chaining
*/
set(name: string, target: string, parent?: string): this;
/**
* @param target URL target
* @param integrity Integrity
*/
setIntegrity(target: string, integrity: string): void;
/**
* @param target URL target
* @param integrity Integrity
*/
getIntegrity(target: string, integrity: string): string;
/**
* Bulk replace URLs in the import map
* Provide a URL ending in "/" to perform path replacements
*
* @param url {String} The URL to replace
* @param newUrl {String} The URL to replace it with
* @returns ImportMap for chaining
*/
replace(url: string, newUrl: string): this;
/**
* Groups subpath mappings into path mappings when multiple exact subpaths
* exist under the same path.
*
* For two mappings like { "base/a.js": "/a.js", "base/b.js": "/b.js" },
* these will be replaced with a single path mapping { "base/": "/" }.
* Groupings are done throughout all import scopes individually.
*
* @returns ImportMap for chaining
*/
combineSubpaths(): this;
/**
* Groups the import map scopes to shared URLs to reduce duplicate mappings.
*
* For two given scopes, "https://site.com/x/" and "https://site.com/y/",
* a single scope will be constructed for "https://site.com/" including
* their shared mappings, only retaining the scopes if they have differences.
*
* In the case where the scope is on the same origin as the mapUrl, the grouped
* scope is determined based on determining the common baseline over all local scopes
*
* @returns ImportMap for chaining
*/
flatten(): this;
/**
* Rebase the entire import map to a new mapUrl and rootUrl
*
* If the rootUrl is not provided, it will remain null if it was
* already set to null.
*
* Otherwise, just like the constructor options, the rootUrl
* will default to the mapUrl base if it is an http: or https:
* scheme URL, and null otherwise keeping absolute URLs entirely
* in-tact.
*
* @param mapUrl The new map URL to use
* @param rootUrl The new root URL to use
* @returns ImportMap for chaining
*/
rebase(mapUrl?: URL | string, rootUrl?: URL | string | null): this;
/**
* Perform a module resolution against the import map
*
* @param specifier Specifier to resolve
* @param parentUrl Parent URL to resolve against
* @returns Resolved URL string
*/
resolve(specifier: string, parentUrl?: string | URL): string;
/**
* Get the import map JSON data
*
* @returns Import map data
*/
toJSON(): IImportMap;
}
interface Provider {
parseUrlPkg(this: ProviderContext, url: string): ExactPackage | {
pkg: ExactPackage;
subpath: `./${string}` | null;
layer: string;
} | null;
pkgToUrl(this: ProviderContext, pkg: ExactPackage, layer?: string): Promise<`${string}/`>;
resolveLatestTarget(this: ProviderContext, target: LatestPackageTarget, layer: string, parentUrl: string, resolver: Resolver): Promise<ExactPackage | null>;
ownsUrl?(this: ProviderContext, url: string): boolean;
resolveBuiltin?(this: ProviderContext, specifier: string, env: string[]): string | Install | null;
getPackageConfig?(this: ProviderContext, pkgUrl: string): Promise<PackageConfig | null>;
getFileList?(this: ProviderContext, pkgUrl: string): Promise<Set<string> | undefined>;
download?(this: ProviderContext, pkg: ExactPackage): Promise<Record<string, ArrayBuffer>>;
/**
* Publish a package to the provider
* This is an optional method that providers can implement to support package publishing
*
* @param importMap Optional import map to include with the publish
*/
publish?(this: ProviderContext, pkg: ExactPackage, files: Record<string, string | ArrayBuffer> | undefined, importMap: ImportMap | undefined, imports: string[]): Promise<PublishOutput>;
/**
* Authenticate with the provider
* This is an optional method that providers can implement to support authentication
*
* @param username Optional username for authentication
* @param verify Optional callback to verify authentication with the user
* @returns A promise resolving to an authentication token
*/
auth?(this: ProviderContext, options: {
username?: string;
verify?: (url: string, instructions: string) => void;
}): Promise<{
token: string;
}>;
supportedLayers?: string[];
configure?(this: ProviderContext, config: any): void;
}
/**
* Context provided to all provider methods
* Contains necessary services and configuration
*/
declare class ProviderContext {
#private;
/**
* Logger instance for provider operations
*/
log: Log;
/**
* Fetch options for provider operations
*/
fetchOpts: any;
/**
* Custom context object for providers
*/
context: any;
constructor(pm: ProviderManager, log: Log, fetchOpts: any);
}
/**
* Provider manager to handle provider registration, lookup and operations
*/
declare class ProviderManager {
#private;
log: Log;
fetchOpts: any;
providers: Record<string, Provider>;
contexts: Record<string, ProviderContext>;
/**
* Create a new ProviderManager with the given providers
*
* @param customProviders Custom provider definitions to add
*/
constructor(log: Log, fetchOpts: any, providerConfig?: Record<string, any>, customProviders?: Record<string, Provider>);
/**
* Add a custom provider to this provider manager
*
* @param name Name of the provider
* @param provider Provider implementation
*/
addProvider(name: string, provider: Provider): void;
/**
* Find the provider name for a given URL
*
* @param url URL to find the provider for
* @returns The name of the provider, or null if no provider handles this URL
*/
providerNameForUrl(url: string): string | null;
/**
* Parse a URL to get package information
*
* @param url URL to parse
* @returns Package information or null if URL can't be parsed
*/
parseUrlPkg(url: string): Promise<{
pkg: ExactPackage;
source: {
provider: string;
layer: string;
};
subpath: `./${string}` | null;
} | null>;
/**
* Convert a package to a URL
*
* @param pkg Package to convert
* @param provider Provider name
* @param layer Layer to use
* @returns URL for the package
*/
pkgToUrl(pkg: ExactPackage, provider: string, layer?: string): Promise<`${string}/`>;
/**
* Get the package config corresponding to a package URL
*
* @param pkgUrl URL to the package
* @returns
*/
getPackageConfig(pkgUrl: string): Promise<PackageConfig | null | undefined>;
/**
* Obtain a file listing of a package boundary if available
*/
getFileList(pkgUrl: string): Promise<Set<string> | undefined>;
/**
* Resolve a builtin module
*
* @param specifier Module specifier
* @returns Resolved string, install object, or undefined if not resolvable
*/
resolveBuiltin(specifier: string, env: string[]): string | Install | undefined;
resolveLatestTarget(target: PackageTarget, { provider, layer }: PackageProvider, parentUrl: string, resolver: Resolver): Promise<ExactPackage>;
/**
* Get the supported provider strings for all providers
*
* @returns List of provider string identifiers
*/
getProviderStrings(): string[];
/**
* Downloads the given package files into the local folder path outDir
* Does not include the import map, which must be merged separately.
*/
download(pkg: ExactPackage, providerName: string): Promise<Record<string, ArrayBuffer>>;
/**
* Publish a package using the specified provider.
* A publish operation may be an import map only, files only, or both.
*
* @param pkg Package name, version and registry to publish
* @param providerName Name of the provider to use
* @param files Package files to publish
* @param importMap Optional import map to include with the publish
*/
publish(pkg: ExactPackage, providerName: string, imports: string[], files: undefined, importMap: undefined): Promise<PublishOutput>;
publish(pkg: ExactPackage, providerName: string, imports: string[], files: Record<string, string | ArrayBuffer>, importMap: undefined): Promise<PublishOutput>;
publish(pkg: ExactPackage, providerName: string, imports: string[], files: Record<string, string | ArrayBuffer>, importMap: ImportMap): Promise<PublishOutput>;
/**
* Authenticate with a provider to obtain an authentication token
*
* @param providerName Name of the provider to authenticate with
* @param options Authentication options
* @returns Promise resolving to the authentication token
*/
auth(providerName: string, options?: {
username?: string;
verify?: (url: string, instructions: string) => void;
}): Promise<{
token: string;
}>;
}
interface PublishOutput {
packageUrl: `${string}/`;
mapUrl: string;
codeSnippet?: string;
}
interface TraceEntry {
deps: string[];
dynamicDeps: string[];
hasStaticParent: boolean;
size: number;
integrity: string;
wasCjs: boolean;
usesCjs: boolean;
cjsLazyDeps: string[];
format: 'esm' | 'commonjs' | 'system' | 'json' | 'css' | 'typescript' | 'wasm';
parseError: Error;
}
declare class Resolver {
pcfgPromises: Record<string, Promise<void>>;
analysisPromises: Record<string, Promise<void>>;
pcfgs: Record<string, PackageConfig | null>;
fetchOpts: any;
preserveSymlinks: any;
pm: ProviderManager;
traceEntries: Record<string, TraceEntry | null>;
traceEntryPromises: Record<string, Promise<void>>;
env: string[];
cjsEnv: string[];
traceCjs: boolean;
traceTs: boolean;
traceSystem: boolean;
installer: Installer;
constructor({ env, fetchOpts, providerManager, preserveSymlinks, traceCjs, traceTs, traceSystem }: {
env: string[];
fetchOpts?: any;
preserveSymlinks?: boolean;
traceCjs?: boolean;
traceTs?: boolean;
traceSystem: boolean;
providerManager: ProviderManager;
});
resolveBuiltin(specifier: string): string | Install | undefined;
getPackageBase(url: string): Promise<`${string}/`>;
getPackageConfig(pkgUrl: string): Promise<PackageConfig | null>;
getDepList(pkgUrl: string, dev?: boolean): Promise<string[]>;
checkPjson(url: string): Promise<string | false>;
exists(resolvedUrl: string): Promise<boolean>;
wasCommonJS(url: string): Promise<boolean>;
realPath(url: string): Promise<string>;
finalizeResolve(url: string, parentIsCjs: boolean, exportsResolution: boolean, pkgUrl: `${string}/`): Promise<string>;
getExportResolution(pkgUrl: `${string}/`, subpath: '.' | `./${string}`, originalSpecifier: string): Promise<'.' | `./${string}` | null>;
resolveEmpty(cjsEnv: boolean, originalSpecifier: string, parentUrl: string): Promise<string>;
resolveExport(pkgUrl: `${string}/`, subpath: `.${string}`, cjsEnv: boolean, parentIsCjs: boolean, originalSpecifier: string, parentUrl?: string): Promise<string>;
getAnalysis(resolvedUrl: string): TraceEntry | null | undefined;
analyze(resolvedUrl: string): Promise<TraceEntry | null>;
resolvePackageTarget(target: ExportsTarget, packageUrl: string, cjsEnv: boolean, subpath: string, isImport: boolean): string | null;
}
interface LockResolutions {
primary: {
[pkgName: string]: InstalledResolution;
};
secondary: {
[pkgUrl: `${string}/`]: {
[pkgName: string]: InstalledResolution;
};
};
flattened: {
[scopeUrl: `${string}/`]: {
[pkgName: string]: FlatInstalledResolution[];
};
};
}
interface PackageToTarget {
[pkgName: string]: PackageTarget | URL;
}
interface VersionConstraints {
primary: PackageToTarget;
secondary: {
[pkgUrl: `${string}/`]: PackageToTarget;
};
}
interface InstalledResolution {
installUrl: `${string}/`;
installSubpath: '.' | `./${string}` | null;
}
interface FlatInstalledResolution {
export: `.${string}`;
resolution: InstalledResolution;
}
interface PackageProvider {
provider: string;
layer: string;
}
/**
* InstallOptions configure the generator's behaviour for existing mappings
* in the import map. An existing mapping is considered "in-range" if either:
* 1. its parent package.json has no "dependencies" range for it
* 2. its semver version is within the parent's range
*
* The "latest-compatible version" of a package is the latest existing version
* within the parent's "dependencies range", or just the latest existing
* version if there is no such range.
*
* "default":
* New installs always resolve to the latest compatible version. Existing
* mappings are kept unless they are out-of-range, in which case they are
* bumped to the latest compatible version.
*
* "latest-primaries":
* Existing primary dependencies (i.e. mappings under "imports") are bumped
* to latest. Existing secondary dependencies are kept unless they are
* out-of-range, in which case they are bumped to the latest compatible
* version. New installs behave according to "default".
*
* "latest-all":
* All existing mappings are bumped to the latest compatible version. New
* installs behave according to "default".
*
* "freeze":
* No existing mappings are changed, and existing mappings are always used
* for new installs wherever possible. Completely new installs behave
* according to "default".
*/
type InstallMode = 'default' | 'latest-primaries' | 'latest-all' | 'freeze';
type InstallTarget = {
pkgTarget: PackageTarget | URL;
installSubpath: null | '.' | `./${string}`;
};
interface InstallerOptions {
mapUrl: URL;
baseUrl: URL;
rootUrl?: URL | null;
lock?: LockResolutions;
reset?: boolean;
prune?: boolean;
save?: boolean;
saveDev?: boolean;
savePeer?: boolean;
saveOptional?: boolean;
resolutions?: Record<string, string>;
defaultProvider?: string;
defaultRegistry?: string;
providers?: Record<string, string>;
}
declare class Installer {
opts: InstallerOptions;
installs: LockResolutions;
constraints: VersionConstraints;
newInstalls: boolean;
installBaseUrl: `${string}/`;
hasLock: boolean;
defaultProvider: {
provider: string;
layer: string;
};
defaultRegistry: string;
providers: Record<string, string>;
resolutions: Record<string, string>;
log: Log;
resolver: Resolver;
constructor(baseUrl: `${string}/`, opts: InstallerOptions, log: Log, resolver: Resolver);
visitInstalls(visitor: (scope: Record<string, InstalledResolution>, scopeUrl: string | null) => boolean | void): void;
getProvider(target: PackageTarget): {
provider: string;
layer: string;
};
/**
* Locks a package against the given target.
*
* @param {string} pkgName Name of the package being installed.
* @param {InstallTarget} target The installation target being installed.
* @param {`./${string}` | '.'} traceSubpath
* @param {InstallMode} mode Specifies how to interact with existing installs.
* @param {`${string}/` | null} pkgScope URL of the package scope in which this install is occurring, null if it's a top-level install.
* @param {string} parentUrl URL of the parent for this install.
* @returns {Promise<InstalledResolution>}
*/
installTarget(pkgName: string, { pkgTarget, installSubpath }: InstallTarget, traceSubpath: `./${string}` | '.', mode: InstallMode, pkgScope: `${string}/` | null, parentUrl: string): Promise<InstalledResolution>;
/**
* Installs the given package specifier.
*
* @param {string} pkgName The package specifier being installed.
* @param {InstallMode} mode Specifies how to interact with existing installs.
* @param {`${string}/` | null} pkgScope URL of the package scope in which this install is occurring, null if it's a top-level install.
* @param {`./${string}` | '.'} traceSubpath
* @param {string} parentUrl URL of the parent for this install.
* @returns {Promise<string | InstalledResolution>}
*/
install(pkgName: string, mode: InstallMode, pkgScope: `${string}/` | null, traceSubpath: `./${string}` | '.', parentUrl?: string): Promise<string | InstalledResolution>;
private get pkgUrls();
private getBestExistingMatch;
private inRange;
private tryUpgradeAllTo;
private upgradeSupportedTo;
}
/**
* ExportsTarget defines specifier mappings for the public entry points of a
* package, with support for conditionals.
* see https://nodejs.org/dist/latest-v19.x/docs/api/packages.html#exports
*/
type ExportsTarget = '.' | `./${string}` | null | {
[condition: string]: ExportsTarget;
} | ExportsTarget[];
/**
* PackageConfig is a parsed version of a package's package.json file.
* see https://nodejs.org/dist/latest-v19.x/docs/api/packages.html
*/
interface PackageConfig {
registry?: string;
name?: string;
version?: string;
main?: string;
files?: string[];
module?: string;
browser?: string | Record<string, string | false>;
imports?: Record<string, ExportsTarget>;
exports?: ExportsTarget | Record<string, ExportsTarget>;
type?: string;
dependencies?: Record<string, string>;
peerDependencies?: Record<string, string>;
optionalDependencies?: Record<string, string>;
devDependencies?: Record<string, string>;
}
/**
* ExactPackage pins down an exact version of a package on an external registry,
* such as npm or deno.
*/
interface ExactPackage {
name: string;
registry: string;
version: string;
}
/**
* PackageTarget pins down a particular version range of a package on an
* external registry, such as npm or deno.
*/
interface PackageTarget {
registry: string;
name: string;
ranges: any[];
unstable: boolean;
}
/**
* LatestPackageTarget pins down the latest version of a package on an external
* registry, such as npm or deno.
*/
interface LatestPackageTarget {
registry: string;
name: string;
range: any;
unstable: boolean;
}
/**
* @interface GeneratorOptions.
*/
interface GeneratorOptions {
/**
* The URL to use for resolutions without a parent context.
*
* Defaults to mapUrl or the process base URL.
*
* Also determines the default scoping base for the import map when flattening.
*/
baseUrl?: URL | string;
/**
* The URL of the import map itself, used to construct relative import map URLs.
*
* Defaults to the base URL.
*
* The `mapUrl` is used in order to output relative URLs for modules located on the same
* host as the import map.
*
* E.g. for `mapUrl: 'file:///path/to/project/map.importmap'`, installing local file packages
* will be output as relative URLs to their file locations from the map location, since all URLs in an import
* map are relative to the URL of the import map.
*/
mapUrl?: URL | string;
/**
* The URL to treat as the root of the serving protocol of the
* import map, used to construct absolute import map URLs.
*
* When set, `rootUrl` takes precendence over `mapUrl` and is used to normalize all import map URLs
* as absolute paths against this URL.
*
* E.g. for `rootUrl: 'file:///path/to/project/public'`, any local module `public/local/mod.js` within the `public` folder
* will be normalized to `/local/mod.js` in the output map.
*/
rootUrl?: URL | string | null;
/**
* An authoritative initial import map.
*
* An initial import map to start with - can be from a previous
* install or to provide custom mappings.
*/
inputMap?: IImportMap;
/**
* The provider to use for top-level (i.e. root package) installs if there's no context in the inputMap. This can be used to set the provider for a new import map. To use a specific provider for an install, rather than relying on context, register an override using the 'providers' option.
*
* Supports: 'jspm.io' | 'jspm.io#system' | 'nodemodules' | 'skypack' | 'jsdelivr' | 'unpkg' | 'esm.sh';
*
* Providers are responsible for resolution from abstract package names and version ranges to exact URL locations.
*
* Providers resolve package names and semver ranges to exact CDN package URL paths using provider hooks.
*
* These hooks include version resolution and converting package versions into URLs and back again.
*
* See `src/providers/[name].ts` for how to define a custom provider.
*
* New providers can be provided via the `customProviders` option. PRs to merge in providers are welcome as well.
*/
defaultProvider?: string;
/**
* The default registry to use when no registry is provided to an install.
* Defaults to 'npm:'.
*
* Registries are separated from providers because multiple providers can serve
* any public registry.
*
* Internally, the default providers for registries are handled by the providers object
*/
defaultRegistry?: string;
/**
* The conditional environment resolutions to apply.
*
* The conditions passed to the `env` option are environment conditions, as [supported by Node.js](https://nodejs.org/dist/latest-v16.x/docs/api/packages.html#packages_conditions_definitions) in the package exports field.
*
* By default the `"default"`, `"require"` and `"import"` conditions are always supported regardless of what `env` conditions are provided.
*
* In addition the default conditions applied if no `env` option is set are `"browser"`, `"development"` and `"module"`.
*
* Webpack and RollupJS support a custom `"module"` condition as a bundler-specific solution to the [dual package hazard](https://nodejs.org/dist/latest-v16.x/docs/api/packages.html#packages_dual_package_hazard), which is by default included in the JSPM resolution as well although
* can be turned off if needed.
*
* Note when providing custom conditions like setting `env: ["production"]` that the `"browser"` and `"module"` conditions still need to be
* applied as well via `env: ["production", "browser", "module"]`. Ordering does not matter though.
*
* Any other custom condition strings can also be provided.
*/
env?: string[];
/**
* Whether to use a local FS cache for fetched modules. Set to 'offline' to use the offline cache.
*
* By default a global fetch cache is maintained between runs on the file system.
*
* This caching can be disabled by setting `cache: false`.
*
* When running offline, setting `cache: 'offline'` will only use the local cache and not touch the network at all,
* making fully offline workflows possible provided the modules have been seen before.
*/
cache?: 'offline' | boolean;
/**
* User-provided fetch options for fetching modules, eg check https://github.com/npm/make-fetch-happen#extra-options for Node.js fetch
*/
fetchOptions?: Record<string, any>;
/**
* Custom provider definitions.
*
* When installing from a custom CDN it can be advisable to define a custom provider in order to be able to get version deduping against that CDN.
*
* Custom provider definitions define a provider name, and the provider instance consisting of three main hooks:
*
* * `pkgToUrl({ registry: string, name: string, version: string }, layer: string) -> String URL`: Returns the URL for a given exact package registry, name and version to use for this provider. If the provider is using layers, the `layer` string can be used to determine the URL layer (where the `defaultProvider: '[name].[layer]'` form is used to determine the layer, eg minified v unminified etc). It is important that package URLs always end in `/`, because packages must be treated as folders not files. An error will be thrown for package URLs returned not ending in `/`.
* * `parsePkgUrl(url: string) -> { { registry: string, name: string, version: string }, layer: string } | undefined`: Defines the converse operation to `pkgToUrl`, converting back from a string URL
* into the exact package registry, name and version, as well as the layer. Should always return `undefined` for unknown URLs as the first matching provider is treated as authoritative when dealing with
* multi-provider installations.
* * `resolveLatestTarget(target: { registry: string, name: string, range: SemverRange }, unstable: boolean, layer: string, parentUrl: string) -> Promise<{ registry: string, name: string, version: string } | null>`: Resolve the latest version to use for a given package target. `unstable` indicates that prerelease versions can be matched. The definition of `SemverRange` is as per the [sver package](https://www.npmjs.com/package/sver#semverrange). Returning `null` corresponds to a package not found error.
*
* The use of `pkgToUrl` and `parsePkgUrl` is what allows the JSPM Generator to dedupe package versions internally based on their unique internal identifier `[registry]:[name]@[version]` regardless of what CDN location is used. URLs that do not support `parsePkgUrl` can still be installed and used fine, they just do not participate in version deduping operations.
*
* @example
* ```js
* const unpkgUrl = 'https://unpkg.com/';
* const exactPkgRegEx = /^((?:@[^/\\%@]+\/)?[^./\\%@][^/\\%@]*)@([^\/]+)(\/.*)?$/;
*
* const generator = new Generator({
* defaultProvider: 'custom',
* customProviders: {
* custom: {
* pkgToUrl ({ registry, name, version }) {
* return `${unpkgUrl}${name}@${version}/`;
* },
* parseUrlPkg (url) {
* if (url.startsWith(unpkgUrl)) {
* const [, name, version] = url.slice(unpkgUrl.length).match(exactPkgRegEx) || [];
* return { registry: 'npm', name, version };
* }
* },
* resolveLatestTarget ({ registry, name, range }, unstable, layer, parentUrl) {
* return { registry, name, version: '3.6.0' };
* }
* }
* }
* });
*
* await generator.install('custom:jquery');
* ```
*/
customProviders?: Record<string, Provider>;
/**
* A map of custom scoped providers.
*
* The provider map allows setting custom providers for specific package names, package scopes or registries.
*
* @example
* For example, an organization with private packages with names like `npmpackage` and `@orgscope/...` can define the custom providers to reference these from a custom source:
*
* ```js
* providers: {
* 'npmpackage': 'nodemodules',
* '@orgscope': 'nodemodules',
* 'npm:': 'nodemodules'
* }
* ```
*
* Alternatively a custom provider can be referenced this way for eg private CDN / registry support.
*/
providers?: Record<string, string>;
/**
* Custom dependency resolution overrides for all installs.
*
* The resolutions option allows configuring a specific dependency version to always be used overriding all version resolution
* logic for that dependency for all nestings.
*
* It is a map from package name to package version target just like the package.json "dependencies" map, but that applies and overrides universally.
*
* @example
* ```js
* const generator = new Generator({
* resolutions: {
* dep: '1.2.3'
* }
* });
* ```
*
* It is also useful for local monorepo patterns where all local packages should be located locally.
* When referencing local paths, the baseUrl configuration option is used as the URL parent.
*
* ```js
* const generator = new Generator({
* mapUrl: new URL('./app.html', import.meta.url),
* baseUrl: new URL('../', import.meta.url),
* resolutions: {
* '@company/pkgA': `./pkgA`,
* '@company/pkgB': `./pkgB`
* '@company/pkgC': `./pkgC`
* }
* })
* ```
*
* All subpath and main resolution logic will follow the package.json definitions of the resolved package, unlike `inputMap`
* which only maps specific specifiers.
*/
resolutions?: Record<string, string>;
/**
* Allows ignoring certain module specifiers during the tracing process.
* It can be useful, for example, when you provide an `inputMap`
* that contains a mapping that can't be traced in current context,
* but you know it will work in the context where the generated map
* is going to be used.
* ```js
* const generator = new Generator({
* inputMap: {
* imports: {
* "react": "./my/own/react.js",
* }
* },
* ignore: ["react"]
* });
*
* // Even though `@react-three/fiber@7` depends upon `react`,
* // `generator` will not try to trace and resolve `react`,
* // so the mapping provided in `inputMap` will end up in the resulting import map.
* await generator.install("@react-three/fiber@7")
* ```
*/
ignore?: string[];
/**
* Lockfile data to use for resolutions
*/
lock?: LockResolutions;
/**
* Support tracing CommonJS dependencies locally. This is necessary if you
* are using the "nodemodules" provider and have CommonJS dependencies.
* Disabled by default.
*/
commonJS?: boolean;
/**
* Support tracing TypeScript dependencies when generating the import map.
* Disabled by default.
*/
typeScript?: boolean;
/**
* Support tracing SystemJS dependencies when generating the import map.
* Disabled by default.
*/
system?: boolean;
/**
* Whether to include "integrity" field in the import map
*/
integrity?: boolean;
/**
* The number of fetch retries to attempt for request failures.
* Defaults to 3.
*/
fetchRetries?: number;
/**
* The same as the Node.js `--preserve-symlinks` flag, except it will apply
* to both the main and the dependencies.
* See https://nodejs.org/api/cli.html#--preserve-symlinks.
* This is only supported for file: URLs.
* Defaults to false, like Node.js.
*/
preserveSymlinks?: boolean;
/**
* Provider configuration options
*
* @example
* ```js
* const generator = new Generator({
* mapUrl: import.meta.url,
* defaultProvider: "jspm.io",
* providerConfig: {
* "jspm.io": {
* cdnUrl: `https://jspm-mirror.com/`
* }
* }
*/
providerConfig?: {
[providerName: string]: any;
};
/**
* Custom async resolver function for intercepting resolution operations.
*
* When provided, this function will be called first for all resolution operations.
* If it returns a string URL, that will be used as the resolved module and persisted
* in the import map. If it returns undefined, normal resolution continues.
*
* @param specifier The module specifier being resolved
* @param parentUrl The URL of the parent module
* @param context Additional context including environment and other metadata
* @returns A resolved URL string or undefined to continue with default resolution
*
* @example
* ```js
* const generator = new Generator({
* customResolver: async (specifier, parentUrl, context) => {
* if (specifier === 'my-custom-lib') {
* return 'https://cdn.example.com/my-custom-lib@1.0.0/index.js';
* }
* return undefined;
* }
* });
* ```
*/
customResolver?: (specifier: string, parentUrl: string, context: {
parentPkgUrl: string;
env?: string[];
installMode: any;
toplevel: boolean;
[key: string]: any;
}) => string | undefined | Promise<string | undefined>;
/**
* @default true
*
* Whether to flatten import map scopes into domain-groupings.
* This is a lossy process, removing scoped dependencies.
* By default this is done to create a smaller import map output
* size. Set to false to retain dependency scoping information.
*
*/
flattenScopes?: boolean;
/**
* @default true
*
* Whether to combine subpaths in the final import map.
* By default, when possible, the generator will at output time
* combine similar subpaths in an imports map like:
*
* @example
* ```json
* {
* "imports": {
* "a/b.js": "./pkg/b.js",
* "a/c.js": "./pkg/c.js"
* }
* }
* ```
*
* Into a single folder mapping:
*
* ```json
* {
* "imports": {
* "a/": "./pkg/"
* }
* }
* ```
*
* Resulting in a smaller import map size. This process is done
* carefully to never break any existing mappings, but is a lossy
* import map compression as well.
*
* Set this option to false to disable this default behaviour and
* retain individual mappings.
*/
combineSubpaths?: boolean;
}
interface Install {
target: string | InstallTarget;
alias?: string;
subpath?: '.' | `./${string}`;
subpaths?: ('.' | `./${string}`)[] | true;
}
interface ImportMapPluginOptions extends GeneratorOptions {
downloadDeps?: boolean;
debug?: boolean;
defaultProvider?: 'jspm.io' | 'jsdelivr' | 'unpkg' | 'esm.sh';
include?: string[];
exclude?: string[];
}
interface LicensePluginOptions {
name?: string;
author?: string;
version?: string;
description?: string;
homepage?: string;
license?: string;
contact?: string;
copyright?: {
holder?: string;
year?: string | number;
};
}
interface MetadataPluginOptions {
extendMetadata?: Record<string, unknown>;
}
type ProjectType = 'app' | 'lib';
interface CommonPluginOptions {
/**
* https://github.com/btd/rollup-plugin-visualizer
* By default template path is: ./node_modules/.cache/visualizer/stats.html
*
* @default false
*/
visualizer?: boolean | PluginVisualizerOptions;
/**
* Inject license info to output files
* Load license file from `package.json`, if it is a monorepo project, the root `package.json` will also be merged
*
* @default true
*/
license?: boolean | LicensePluginOptions;
/**
* https://github.com/originjs/vite-plugin-federation
* Module federation
*/
federation?: VitePluginFederationOptions;
}
interface AppPluginOptions {
/**
* https://github.com/chenxch/vite-plugin-dynamic-base
* If you want to build once and deploy to multiple environments, you can enable this plugin to set publicPath at runtime
* You can set like this: `dynamicBase: 'window.__dynamic_base__'`
*/
dynamicBase?: string;
/**
* Inject app loading to `index.html`
* You can customize the root element and loading template
* Use `[app-loading-title]` as a placeholder to dynamically set the document title during loading`
*
* @default auto-detect based on `projectType === 'app'`
*/
appLoading?: boolean | AppLoadingPluginOptions;
/**
* Injects metadata using `define`, accessible via `__VITE_APP_METADATA__`.
* Includes information such as author, build time, version, and more.
*
* @default auto-detect based on `projectType === 'app'`
*/
metadata?: boolean | MetadataPluginOptions;
/**
* Generates an import map for the project.
* Based on https://github.com/jspm/vite-plugin-jspm, with extended CDN provider support and options for include/exclude.
*
* @default false
*/
importMap?: boolean | ImportMapPluginOptions;
}
interface LibPluginOptions {
/**
* https://github.com/qmhc/vite-plugin-dts
* Generates declaration files from .ts or .vue source files
*
* @default auto-detect based on `projectType === 'lib'`
*/
dts?: boolean | PluginOptions;
}
interface OptionsVue {
/**
* https://github.com/vuejs/devtools
* Enable Vue Devtools
*
* @default false
*/
devtools?: boolean | VitePluginVueDevToolsOptions;
/**
* https://github.com/intlify/bundle-tools
* Enable Vue I18n
*
* @default false
*/
i18n?: boolean | PluginOptions$1;
/**
* https://github.com/unplugin/unplugin-auto-import
* Auto-imports commonly used APIs such as `vue`, `vue-router`, `pinia`, `@vueuse/core`, etc
* Also supports auto-importing UI components from libraries like `ant-design-vue`, `element-plus`, etc
* Files from `src/composables` and `src/utils` will also be auto-imported.
*
* @default auto-detect based on `projectType === 'app'`
*/
imports?: boolean | Options;
/**
* https://github.com/unplugin/unplugin-vue-components
* Enabled by default when the project type is `app`
* The `directoryAsNamespace` option is enabled by default.
*
* @default auto-detect based on `projectType === 'app'`
*/
components?: boolean | Options$1;
/**
* https://github.com/posva/unplugin-vue-router
* Enabled by default when the project type is `app`
* Folder(s) to scan for files and generate routes. Defaults to scanning the pages directory.
*
* @default auto-detect based on `projectType === 'app'`
*/
pages?: boolean | Options$2;
}
interface OptionsConfig extends CommonPluginOptions, AppPluginOptions, LibPluginOptions {
/**
* Whether to build for production
*
* @default auto-detect based on `command === 'build'`
*/
isBuild?: boolean;
/**
* Type of the project
*
* @default auto-detect based on the `index.html` file
*/
type?: ProjectType;
/**
* Aliases used to replace values in `import` or `require` statements
* Paths are automatically resolved if needed
*
* @default { "@": "./src" }
*/
alias?: AliasOptions;
/**
* Enable Vue support
* The goal is to provide an automatic registration mechanism similar to Nuxt in app development.
*
* @default auto-detect based on the dependencies
*/
vue?: boolean | OptionsVue;
vite?: UserConfig;
}
interface ConditionPlugin {
condition?: boolean;
plugins: () => PluginOption[] | PromiseLike<PluginOption[]>;
}
type ResolvedOptions<T> = T extends boolean ? never : NonNullable<T>;
declare function defineConfig(options: OptionsConfig): vite.UserConfigFnPromise;
export { defineConfig };
export type { AppPluginOptions, CommonPluginOptions, ConditionPlugin, LibPluginOptions, OptionsConfig, OptionsVue, ProjectType, ResolvedOptions };