Skip to content

Commit

Permalink
Get rid of default plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
lukastaegert committed Mar 19, 2020
1 parent a16f3eb commit a79ac92
Show file tree
Hide file tree
Showing 11 changed files with 236 additions and 214 deletions.
8 changes: 2 additions & 6 deletions src/Graph.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,12 +126,7 @@ export default class Graph {
...this.acornOptions
});

this.pluginDriver = new PluginDriver(
this,
options.plugins!,
this.pluginCache,
options.preserveSymlinks === true
);
this.pluginDriver = new PluginDriver(this, options.plugins!, this.pluginCache);

if (watcher) {
const handleChange = (id: string) => this.pluginDriver.hookSeqSync('watchChange', [id]);
Expand Down Expand Up @@ -178,6 +173,7 @@ export default class Graph {
this,
this.moduleById,
this.pluginDriver,
options.preserveSymlinks === true,
options.external!,
(typeof options.manualChunks === 'function' && options.manualChunks) as GetManualChunk | null,
(this.treeshakingOptions ? this.treeshakingOptions.moduleSideEffects : null)!,
Expand Down
53 changes: 27 additions & 26 deletions src/ModuleLoader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
ResolveIdResult,
TransformModuleJSON
} from './rollup/types';
import { resolveId } from './utils/defaultPlugin';
import {
errBadLoader,
errCannotAssignModuleToChunk,
Expand All @@ -26,6 +27,7 @@ import {
errUnresolvedImport,
errUnresolvedImportTreatedAsExternal
} from './utils/error';
import { readFile } from './utils/fs';
import { isRelative, resolve } from './utils/path';
import { PluginDriver } from './utils/PluginDriver';
import relativeId from './utils/relativeId';
Expand Down Expand Up @@ -97,27 +99,22 @@ function getHasModuleSideEffects(
export class ModuleLoader {
readonly isExternal: IsExternal;
private readonly getManualChunk: GetManualChunk;
private readonly graph: Graph;
private readonly hasModuleSideEffects: (id: string, external: boolean) => boolean;
private readonly indexedEntryModules: { index: number; module: Module }[] = [];
private latestLoadModulesPromise: Promise<any> = Promise.resolve();
private readonly manualChunkModules: Record<string, Module[]> = {};
private readonly modulesById: Map<string, Module | ExternalModule>;
private nextEntryModuleIndex = 0;
private readonly pluginDriver: PluginDriver;

constructor(
graph: Graph,
modulesById: Map<string, Module | ExternalModule>,
pluginDriver: PluginDriver,
private readonly graph: Graph,
private readonly modulesById: Map<string, Module | ExternalModule>,
private readonly pluginDriver: PluginDriver,
private readonly preserveSymlinks: boolean,
external: ExternalOption,
getManualChunk: GetManualChunk | null,
moduleSideEffects: ModuleSideEffectsOption,
pureExternalModules: PureModulesOption
) {
this.graph = graph;
this.modulesById = modulesById;
this.pluginDriver = pluginDriver;
this.isExternal = getIdMatcher(external);
this.hasModuleSideEffects = getHasModuleSideEffects(
moduleSideEffects,
Expand Down Expand Up @@ -201,12 +198,13 @@ export class ModuleLoader {
async resolveId(
source: string,
importer: string | undefined,
skip?: number | null
skip: number | null = null
): Promise<ResolvedId | null> {
return this.normalizeResolveIdResult(
this.isExternal(source, importer, false)
? false
: await this.pluginDriver.hookFirst('resolveId', [source, importer], null, skip),
: await resolveId(source, importer, this.preserveSymlinks, this.pluginDriver, skip),

importer,
source
);
Expand Down Expand Up @@ -301,6 +299,7 @@ export class ModuleLoader {

timeStart('load modules', 3);
return Promise.resolve(this.pluginDriver.hookFirst('load', [id]))
.then(source => (source != null ? source : readFile(id)))
.catch((err: Error) => {
timeEnd('load modules', 3);
let msg = `Could not load ${id}`;
Expand Down Expand Up @@ -423,23 +422,25 @@ export class ModuleLoader {
isEntry: boolean,
importer: string | undefined
): Promise<Module> =>
this.pluginDriver.hookFirst('resolveId', [unresolvedId, importer]).then(resolveIdResult => {
if (
resolveIdResult === false ||
(resolveIdResult && typeof resolveIdResult === 'object' && resolveIdResult.external)
) {
return error(errEntryCannotBeExternal(unresolvedId));
}
const id =
resolveIdResult && typeof resolveIdResult === 'object'
? resolveIdResult.id
: resolveIdResult;
resolveId(unresolvedId, importer, this.preserveSymlinks, this.pluginDriver, null).then(
resolveIdResult => {
if (
resolveIdResult === false ||
(resolveIdResult && typeof resolveIdResult === 'object' && resolveIdResult.external)
) {
return error(errEntryCannotBeExternal(unresolvedId));
}
const id =
resolveIdResult && typeof resolveIdResult === 'object'
? resolveIdResult.id
: resolveIdResult;

if (typeof id === 'string') {
return this.fetchModule(id, undefined as any, true, false, isEntry);
if (typeof id === 'string') {
return this.fetchModule(id, undefined as any, true, false, isEntry);
}
return error(errUnresolvedEntry(unresolvedId));
}
return error(errUnresolvedEntry(unresolvedId));
});
);

private normalizeResolveIdResult(
resolveIdResult: ResolveIdResult,
Expand Down
9 changes: 8 additions & 1 deletion src/ast/nodes/ImportExpression.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,14 @@ export default class Import extends NodeBase {
}
}

private getDynamicImportMechanism(options: RenderOptions): DynamicImportMechanism | null {
private getDynamicImportMechanism(
options: RenderOptions
// pluginDriver: PluginDriver
): DynamicImportMechanism | null {
// const mechanism = pluginDriver.hookFirstSync('renderDynamicImport', [{}]);
// if (mechanism) {
// return mechanism;
// }
switch (options.format) {
case 'cjs': {
const _ = options.compact ? '' : ' ';
Expand Down
118 changes: 97 additions & 21 deletions src/ast/nodes/MetaProperty.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import MagicString from 'magic-string';
import { accessedFileUrlGlobals, accessedMetaUrlGlobals } from '../../utils/defaultPlugin';
import { dirname, normalize, relative } from '../../utils/path';
import { PluginDriver } from '../../utils/PluginDriver';
import { ObjectPathKey } from '../utils/PathTracker';
Expand Down Expand Up @@ -106,18 +105,19 @@ export default class MetaProperty extends NodeBase {
]);
}
if (!replacement) {
replacement = outputPluginDriver.hookFirstSync<'resolveFileUrl'>('resolveFileUrl', [
{
assetReferenceId,
chunkId,
chunkReferenceId,
fileName,
format,
moduleId: this.context.module.id,
referenceId: referenceId || assetReferenceId || chunkReferenceId!,
relativePath
}
]) as string;
replacement =
outputPluginDriver.hookFirstSync('resolveFileUrl', [
{
assetReferenceId,
chunkId,
chunkReferenceId,
fileName,
format,
moduleId: this.context.module.id,
referenceId: referenceId || assetReferenceId || chunkReferenceId!,
relativePath
}
]) || relativeUrlMechanisms[format](relativePath);
}

code.overwrite(
Expand All @@ -129,14 +129,16 @@ export default class MetaProperty extends NodeBase {
return;
}

const replacement = outputPluginDriver.hookFirstSync('resolveImportMeta', [
metaProperty,
{
chunkId,
format,
moduleId: this.context.module.id
}
]);
const replacement =
outputPluginDriver.hookFirstSync('resolveImportMeta', [
metaProperty,
{
chunkId,
format,
moduleId: this.context.module.id
}
]) ||
(importMetaMechanisms[format] && importMetaMechanisms[format](metaProperty, chunkId));
if (typeof replacement === 'string') {
if (parent instanceof MemberExpression) {
code.overwrite(parent.start, parent.end, replacement, { contentOnly: true });
Expand All @@ -146,3 +148,77 @@ export default class MetaProperty extends NodeBase {
}
}
}

const accessedMetaUrlGlobals = {
amd: ['document', 'module', 'URL'],
cjs: ['document', 'require', 'URL'],
iife: ['document', 'URL'],
system: ['module'],
umd: ['document', 'require', 'URL']
};

const accessedFileUrlGlobals = {
amd: ['document', 'require', 'URL'],
cjs: ['document', 'require', 'URL'],
iife: ['document', 'URL'],
system: ['module', 'URL'],
umd: ['document', 'require', 'URL']
};

const getResolveUrl = (path: string, URL = 'URL') => `new ${URL}(${path}).href`;

const getRelativeUrlFromDocument = (relativePath: string) =>
getResolveUrl(
`'${relativePath}', document.currentScript && document.currentScript.src || document.baseURI`
);

const getGenericImportMetaMechanism = (getUrl: (chunkId: string) => string) => (
prop: string | null,
chunkId: string
) => {
const urlMechanism = getUrl(chunkId);
return prop === null ? `({ url: ${urlMechanism} })` : prop === 'url' ? urlMechanism : 'undefined';
};

const getUrlFromDocument = (chunkId: string) =>
`(document.currentScript && document.currentScript.src || new URL('${chunkId}', document.baseURI).href)`;

const relativeUrlMechanisms: Record<string, (relativePath: string) => string> = {
amd: relativePath => {
if (relativePath[0] !== '.') relativePath = './' + relativePath;
return getResolveUrl(`require.toUrl('${relativePath}'), document.baseURI`);
},
cjs: relativePath =>
`(typeof document === 'undefined' ? ${getResolveUrl(
`'file:' + __dirname + '/${relativePath}'`,
`(require('u' + 'rl').URL)`
)} : ${getRelativeUrlFromDocument(relativePath)})`,
es: relativePath => getResolveUrl(`'${relativePath}', import.meta.url`),
iife: relativePath => getRelativeUrlFromDocument(relativePath),
system: relativePath => getResolveUrl(`'${relativePath}', module.meta.url`),
umd: relativePath =>
`(typeof document === 'undefined' ? ${getResolveUrl(
`'file:' + __dirname + '/${relativePath}'`,
`(require('u' + 'rl').URL)`
)} : ${getRelativeUrlFromDocument(relativePath)})`
};

const importMetaMechanisms: Record<string, (prop: string | null, chunkId: string) => string> = {
amd: getGenericImportMetaMechanism(() => getResolveUrl(`module.uri, document.baseURI`)),
cjs: getGenericImportMetaMechanism(
chunkId =>
`(typeof document === 'undefined' ? ${getResolveUrl(
`'file:' + __filename`,
`(require('u' + 'rl').URL)`
)} : ${getUrlFromDocument(chunkId)})`
),
iife: getGenericImportMetaMechanism(chunkId => getUrlFromDocument(chunkId)),
system: prop => (prop === null ? `module.meta` : `module.meta.${prop}`),
umd: getGenericImportMetaMechanism(
chunkId =>
`(typeof document === 'undefined' ? ${getResolveUrl(
`'file:' + __filename`,
`(require('u' + 'rl').URL)`
)} : ${getUrlFromDocument(chunkId)})`
)
};
29 changes: 17 additions & 12 deletions src/rollup/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,17 @@ export interface OutputBundleWithPlaceholders {
[fileName: string]: OutputAsset | OutputChunk | FilePlaceholder;
}

export interface PluginHooks extends OutputPluginHooks {
buildEnd: (this: PluginContext, err?: Error) => Promise<void> | void;
buildStart: (this: PluginContext, options: InputOptions) => Promise<void> | void;
load: LoadHook;
options: (this: MinimalPluginContext, options: InputOptions) => InputOptions | null | undefined;
resolveDynamicImport: ResolveDynamicImportHook;
resolveId: ResolveIdHook;
transform: TransformHook;
watchChange: (id: string) => void;
}

interface OutputPluginHooks {
augmentChunkHash: (this: PluginContext, chunk: PreRenderedChunk) => string | void;
generateBundle: (
Expand All @@ -326,6 +337,10 @@ interface OutputPluginHooks {
) => void | Promise<void>;
outputOptions: (this: PluginContext, options: OutputOptions) => OutputOptions | null | undefined;
renderChunk: RenderChunkHook;
// renderDynamicImport: (
// this: PluginContext,
// options: {}
// ) => { left: string; right: string } | null | undefined;
renderError: (this: PluginContext, err?: Error) => Promise<void> | void;
renderStart: (
this: PluginContext,
Expand All @@ -334,26 +349,15 @@ interface OutputPluginHooks {
) => Promise<void> | void;
/** @deprecated Use `resolveFileUrl` instead */
resolveAssetUrl: ResolveAssetUrlHook;
resolveDynamicImport: ResolveDynamicImportHook;
resolveFileUrl: ResolveFileUrlHook;
resolveImportMeta: ResolveImportMetaHook;
writeBundle: (
this: PluginContext,
options: OutputOptions,
bundle: OutputBundle
) => void | Promise<void>;
}

export interface PluginHooks extends OutputPluginHooks {
buildEnd: (this: PluginContext, err?: Error) => Promise<void> | void;
buildStart: (this: PluginContext, options: InputOptions) => Promise<void> | void;
load: LoadHook;
options: (this: MinimalPluginContext, options: InputOptions) => InputOptions | null | undefined;
resolveId: ResolveIdHook;
resolveImportMeta: ResolveImportMetaHook;
transform: TransformHook;
watchChange: (id: string) => void;
}

export type AsyncPluginHooks =
| 'buildEnd'
| 'buildStart'
Expand All @@ -373,6 +377,7 @@ export type SyncPluginHooks = Exclude<keyof PluginHooks, AsyncPluginHooks>;

export type FirstPluginHooks =
| 'load'
// | 'renderDynamicImport'
| 'resolveAssetUrl'
| 'resolveDynamicImport'
| 'resolveFileUrl'
Expand Down

0 comments on commit a79ac92

Please sign in to comment.