Skip to content

Commit

Permalink
Add an option for this.resolve to skip the plugin calling it
Browse files Browse the repository at this point in the history
  • Loading branch information
lukastaegert committed May 12, 2019
1 parent fbf9bce commit e0ed3b9
Show file tree
Hide file tree
Showing 7 changed files with 80 additions and 9 deletions.
4 changes: 3 additions & 1 deletion docs/05-plugins.md
Original file line number Diff line number Diff line change
Expand Up @@ -386,9 +386,11 @@ or converted into an Array via `Array.from(this.moduleIds)`.

Use Rollup's internal acorn instance to parse code to an AST.

#### `this.resolve(source: string, importer: string) => Promise<{id: string, external: boolean} | null>`
#### `this.resolve(source: string, importer: string, options?: {skipSelf: boolean}) => Promise<{id: string, external: boolean} | null>`
Resolve imports to module ids (i.e. file names) using the same plugins that Rollup uses, and determine if an import should be external. If `null` is returned, the import could not be resolved by Rollup or any plugin but was not explicitly marked as external by the user.

If you pass `skipSelf: true`, then the `resolveId` hook of the plugin from which `this.resolve` is called will be skipped when resolving.

#### `this.setAssetSource(assetReferenceId: string, source: string | Buffer) => void`

Set the deferred source of an asset.
Expand Down
4 changes: 2 additions & 2 deletions src/ModuleLoader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -211,11 +211,11 @@ export class ModuleLoader {
return fileName;
}

resolveId(source: string, importer: string): Promise<ResolvedId | null> {
resolveId(source: string, importer: string, skip?: number | null): Promise<ResolvedId | null> {
return Promise.resolve(
this.isExternal(source, importer, false)
? { id: source, external: true }
: this.pluginDriver.hookFirst('resolveId', [source, importer])
: this.pluginDriver.hookFirst('resolveId', [source, importer], null, skip)
).then((result: ResolveIdResult) => this.normalizeResolveIdResult(result, importer, source));
}

Expand Down
6 changes: 5 additions & 1 deletion src/rollup/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,11 @@ export interface PluginContext extends MinimalPluginContext {
isExternal: IsExternal;
moduleIds: IterableIterator<string>;
parse: (input: string, options: any) => ESTree.Program;
resolve: (source: string, importer: string) => Promise<ResolvedId | null>;
resolve: (
source: string,
importer: string,
options?: { skipSelf: boolean }
) => Promise<ResolvedId | null>;
/** @deprecated Use `this.resolve` instead */
resolveId: (source: string, importer: string) => Promise<string | null>;
setAssetSource: (assetReferenceId: string, source: string | Buffer) => void;
Expand Down
16 changes: 11 additions & 5 deletions src/utils/pluginDriver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ export interface PluginDriver {
hookFirst<H extends keyof PluginHooks, R = ReturnType<PluginHooks[H]>>(
hook: H,
args: Args<PluginHooks[H]>,
hookContext?: HookContext
hookContext?: HookContext | null,
skip?: number
): Promise<R>;
hookFirstSync<H extends keyof PluginHooks, R = ReturnType<PluginHooks[H]>>(
hook: H,
Expand Down Expand Up @@ -194,8 +195,12 @@ export function createPluginDriver(
.resolveId(source, importer)
.then(resolveId => resolveId && resolveId.id);
},
resolve(source, importer) {
return graph.moduleLoader.resolveId(source, importer);
resolve(source, importer, options?: { skipSelf: boolean }) {
return graph.moduleLoader.resolveId(
source,
importer,
options && options.skipSelf ? pidx : null
);
},
setAssetSource,
warn(warning) {
Expand Down Expand Up @@ -265,7 +270,7 @@ export function createPluginDriver(
args: any[],
pluginIndex: number,
permitValues = false,
hookContext?: HookContext
hookContext?: HookContext | null
): Promise<T> {
const plugin = plugins[pluginIndex];
let context = pluginContexts[pluginIndex];
Expand Down Expand Up @@ -325,9 +330,10 @@ export function createPluginDriver(
},

// chains, first non-null result stops and returns
hookFirst(name, args, hookContext) {
hookFirst(name, args, hookContext, skip) {
let promise: Promise<any> = Promise.resolve();
for (let i = 0; i < plugins.length; i++) {
if (skip === i) continue;
promise = promise.then((result: any) => {
if (result != null) return result;
return runHook(name, args, i, false, hookContext);
Expand Down
42 changes: 42 additions & 0 deletions test/function/samples/context-resolve-skipself/_config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
const path = require('path');

module.exports = {
description: 'allows a plugin to skip its own resolveId hook when using this.resolve',
options: {
plugins: [
{
resolveId(id) {
if (id === 'resolutions') {
return id;
}
if (id.startsWith('test')) {
return 'own-resolution';
}
},
load(id) {
if (id === 'resolutions') {
const importer = path.resolve(__dirname, 'main.js');
return Promise.all([
this.resolve('test', importer).then(result => ({ id: result.id, text: 'all' })),
this.resolve('test', importer, { skipSelf: false }).then(result => ({
id: result.id,
text: 'unskipped'
})),
this.resolve('test', importer, { skipSelf: true }).then(result => ({
id: result.id,
text: 'skipped'
}))
]).then(result => `export default ${JSON.stringify(result)};`);
}
}
},
{
resolveId(id) {
if (id.startsWith('test')) {
return 'other-resolution';
}
}
}
]
}
};
1 change: 1 addition & 0 deletions test/function/samples/context-resolve-skipself/existing.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
console.log('existing');
16 changes: 16 additions & 0 deletions test/function/samples/context-resolve-skipself/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import resolutions from 'resolutions';

assert.deepStrictEqual(resolutions, [
{
id: 'own-resolution',
text: 'all'
},
{
id: 'own-resolution',
text: 'unskipped'
},
{
id: 'other-resolution',
text: 'skipped'
}
]);

0 comments on commit e0ed3b9

Please sign in to comment.