Skip to content

Commit

Permalink
Add importedIdResolutions to moduleInfo
Browse files Browse the repository at this point in the history
  • Loading branch information
lukastaegert committed Jan 18, 2022
1 parent 7c2823e commit 546b2fb
Show file tree
Hide file tree
Showing 13 changed files with 318 additions and 2 deletions.
16 changes: 14 additions & 2 deletions docs/05-plugin-development.md
Expand Up @@ -122,7 +122,7 @@ This hook is called each time a module has been fully parsed by Rollup. See [`th

In contrast to the [`transform`](guide/en/#transform) hook, this hook is never cached and can be used to get information about both cached and other modules, including the final shape of the `meta` property, the `code` and the `ast`.

This hook will wait until all imports are resolved so that the information in `moduleInfo.importedIds` and `moduleInfo.dynamicallyImportedIds` is complete and accurate. Note however that information about importing modules may be incomplete as additional importers could be discovered later. If you need this information, use the [`buildEnd`](guide/en/#buildend) hook.
This hook will wait until all imports are resolved so that the information in `moduleInfo.importedIds`, `moduleInfo.dynamicallyImportedIds`, `moduleInfo.importedIdResolutions`, and `moduleInfo.dynamicallyImportedIdResolutions` is complete and accurate. Note however that information about importing modules may be incomplete as additional importers could be discovered later. If you need this information, use the [`buildEnd`](guide/en/#buildend) hook.

#### `options`

Expand Down Expand Up @@ -677,15 +677,27 @@ type ModuleInfo = {
isExternal: boolean; // for external modules that are referenced but not included in the graph
isIncluded: boolean | null; // is the module included after tree-shaking, `null` if external or not yet available
importedIds: string[]; // the module ids statically imported by this module
importedIdResolutions: ResolvedId[]; // how statically imported ids were resolved, for use with this.load
importers: string[]; // the ids of all modules that statically import this module
dynamicallyImportedIds: string[]; // the module ids imported by this module via dynamic import()
dynamicallyImportedIdResolutions: ResolvedId[]; // how ids imported via dynamic import() were resolved
dynamicImporters: string[]; // the ids of all modules that import this module via dynamic import()
implicitlyLoadedAfterOneOf: string[]; // implicit relationships, declared via this.emitFile
implicitlyLoadedBefore: string[]; // implicit relationships, declared via this.emitFile
hasModuleSideEffects: boolean | 'no-treeshake'; // are imports of this module included if nothing is imported from it
meta: { [plugin: string]: any }; // custom module meta-data
syntheticNamedExports: boolean | string; // final value of synthetic named exports
};

// TODO Lukas add comments
// TODO Lukas add new flags elsewhere in the documentation
type ResolvedId = {
id: string;
external: boolean | 'absolute';
moduleSideEffects: boolean | 'no-treeshake';
syntheticNamedExports: boolean | string;
meta: { [plugin: string]: any };
};
```
During the build, this object represents currently available information about the module. Before the [`buildEnd`](guide/en/#buildend) hook, this information may be incomplete as e.g. the `importedIds` are not yet resolved or additional `importers` are discovered.
Expand All @@ -706,7 +718,7 @@ Loads and parses the module corresponding to the given id, attaching additional
This allows you to inspect the final content of modules before deciding how to resolve them in the [`resolveId`](guide/en/#resolveid) hook and e.g. resolve to a proxy module instead. If the module becomes part of the graph later, there is no additional overhead from using this context function as the module will not be parsed again. The signature allows you to directly pass the return value of [`this.resolve`](guide/en/#thisresolve) to this function as long as it is neither `null` nor external.
The returned promise will resolve once the module has been fully transformed and parsed but before any imports have been resolved. That means that the resulting `ModuleInfo` will have empty `importedIds` and `dynamicallyImportedIds`. This helps to avoid deadlock situations when awaiting `this.load` in a `resolveId` hook. If you are interested in `importedIds` and `dynamicallyImportedIds`, you should implement a `moduleParsed` hook.
The returned promise will resolve once the module has been fully transformed and parsed but before any imports have been resolved. That means that the resulting `ModuleInfo` will have empty `importedIds`, `dynamicallyImportedIds`, `importedIdResolutions` and `dynamicallyImportedIdResolutions`. This helps to avoid deadlock situations when awaiting `this.load` in a `resolveId` hook. If you are interested in `importedIds` and `dynamicallyImportedIds`, you should implement a `moduleParsed` hook.
Note that with regard to the `moduleSideEffects`, `syntheticNamedExports` and `meta` options, the same restrictions apply as for the `resolveId` hook: Their values only have an effect if the module has not been loaded yet. Thus, it is very important to use `this.resolve` first to find out if any plugins want to set special values for these options in their `resolveId` hook, and pass these options on to `this.load` if appropriate. The example below showcases how this can be handled to add a proxy module for modules containing a special code comment:
Expand Down
2 changes: 2 additions & 0 deletions src/ExternalModule.ts
Expand Up @@ -41,6 +41,7 @@ export default class ExternalModule {
this.info = {
ast: null,
code: null,
dynamicallyImportedIdResolutions: EMPTY_ARRAY,
dynamicallyImportedIds: EMPTY_ARRAY,
get dynamicImporters() {
return dynamicImporters.sort();
Expand All @@ -49,6 +50,7 @@ export default class ExternalModule {
id,
implicitlyLoadedAfterOneOf: EMPTY_ARRAY,
implicitlyLoadedBefore: EMPTY_ARRAY,
importedIdResolutions: EMPTY_ARRAY,
importedIds: EMPTY_ARRAY,
get importers() {
return importers.sort();
Expand Down
9 changes: 9 additions & 0 deletions src/Module.ts
Expand Up @@ -38,6 +38,7 @@ import {
NormalizedInputOptions,
PartialNull,
PreserveEntrySignaturesOption,
ResolvedId,
ResolvedIdMap,
RollupError,
RollupLogProps,
Expand Down Expand Up @@ -259,6 +260,11 @@ export default class Module {
this.info = {
ast: null,
code: null,
get dynamicallyImportedIdResolutions() {
return module.dynamicImports
.map(({ argument }) => typeof argument === 'string' && module.resolvedIds[argument])
.filter(Boolean) as ResolvedId[];
},
get dynamicallyImportedIds() {
const dynamicallyImportedIds: string[] = [];
for (const { id } of module.dynamicImports) {
Expand All @@ -279,6 +285,9 @@ export default class Module {
get implicitlyLoadedBefore() {
return Array.from(module.implicitlyLoadedBefore, getId).sort();
},
get importedIdResolutions() {
return Array.from(module.sources, source => module.resolvedIds[source]).filter(Boolean);
},
get importedIds() {
return Array.from(module.sources, source => module.resolvedIds[source]?.id).filter(Boolean);
},
Expand Down
2 changes: 2 additions & 0 deletions src/rollup/types.d.ts
Expand Up @@ -160,11 +160,13 @@ interface ModuleInfo {
ast: AcornNode | null;
code: string | null;
dynamicImporters: readonly string[];
dynamicallyImportedIdResolutions: readonly ResolvedId[];
dynamicallyImportedIds: readonly string[];
hasModuleSideEffects: boolean | 'no-treeshake';
id: string;
implicitlyLoadedAfterOneOf: readonly string[];
implicitlyLoadedBefore: readonly string[];
importedIdResolutions: readonly ResolvedId[];
importedIds: readonly string[];
importers: readonly string[];
isEntry: boolean;
Expand Down
Expand Up @@ -70,12 +70,22 @@ module.exports = {
sourceType: 'module'
},
code: "import { value } from './lib';\nconsole.log(value);\n",
dynamicallyImportedIdResolutions: [],
dynamicallyImportedIds: [],
dynamicImporters: [],
hasModuleSideEffects: true,
id: ID_MAIN,
implicitlyLoadedAfterOneOf: [],
implicitlyLoadedBefore: [],
importedIdResolutions: [
{
external: false,
id: ID_LIB,
meta: {},
moduleSideEffects: true,
syntheticNamedExports: false
}
],
importedIds: [ID_LIB],
importers: [],
isEntry: true,
Expand Down Expand Up @@ -130,12 +140,22 @@ module.exports = {
sourceType: 'module'
},
code: "import { value } from './lib';\nconsole.log(value);\n",
dynamicallyImportedIdResolutions: [],
dynamicallyImportedIds: [],
dynamicImporters: [],
hasModuleSideEffects: true,
id: ID_DEP,
implicitlyLoadedAfterOneOf: [],
implicitlyLoadedBefore: [],
importedIdResolutions: [
{
external: false,
id: ID_LIB,
meta: {},
moduleSideEffects: true,
syntheticNamedExports: false
}
],
importedIds: [ID_LIB],
importers: [],
isEntry: true,
Expand Down
Expand Up @@ -66,12 +66,22 @@ module.exports = {
sourceType: 'module'
},
code: "import { value } from './lib';\nconsole.log(value);\n",
dynamicallyImportedIdResolutions: [],
dynamicallyImportedIds: [],
dynamicImporters: [],
hasModuleSideEffects: true,
id: ID_MAIN,
implicitlyLoadedAfterOneOf: [],
implicitlyLoadedBefore: [],
importedIdResolutions: [
{
external: false,
id: ID_LIB,
meta: {},
moduleSideEffects: true,
syntheticNamedExports: false
}
],
importedIds: [ID_LIB],
importers: [],
isEntry: true,
Expand Down Expand Up @@ -126,12 +136,22 @@ module.exports = {
sourceType: 'module'
},
code: "import { value } from './lib';\nconsole.log(value);\n",
dynamicallyImportedIdResolutions: [],
dynamicallyImportedIds: [],
dynamicImporters: [],
hasModuleSideEffects: true,
id: ID_DEP,
implicitlyLoadedAfterOneOf: [],
implicitlyLoadedBefore: [],
importedIdResolutions: [
{
external: false,
id: ID_LIB,
meta: {},
moduleSideEffects: true,
syntheticNamedExports: false
}
],
importedIds: [ID_LIB],
importers: [],
isEntry: true,
Expand Down
Expand Up @@ -114,12 +114,36 @@ module.exports = {
sourceType: 'module'
},
code: "import { lib1 } from './lib1';\nimport { lib1b } from './lib1b';\nimport { lib2 } from './lib2';\nconsole.log('main1', lib1, lib1b, lib2);\n",
dynamicallyImportedIdResolutions: [],
dynamicallyImportedIds: [],
dynamicImporters: [],
hasModuleSideEffects: true,
id: ID_MAIN1,
implicitlyLoadedAfterOneOf: [],
implicitlyLoadedBefore: [ID_DEP],
importedIdResolutions: [
{
external: false,
id: ID_LIB1,
meta: {},
moduleSideEffects: true,
syntheticNamedExports: false
},
{
external: false,
id: ID_LIB1B,
meta: {},
moduleSideEffects: true,
syntheticNamedExports: false
},
{
external: false,
id: ID_LIB2,
meta: {},
moduleSideEffects: true,
syntheticNamedExports: false
}
],
importedIds: [ID_LIB1, ID_LIB1B, ID_LIB2],
importers: [],
isEntry: true,
Expand Down Expand Up @@ -209,12 +233,36 @@ module.exports = {
sourceType: 'module'
},
code: "import { lib1 } from './lib1';\nimport { lib1b } from './lib1b';\nimport { lib3 } from './lib3';\nconsole.log('main2', lib1, lib1b, lib3);\n",
dynamicallyImportedIdResolutions: [],
dynamicallyImportedIds: [],
dynamicImporters: [],
hasModuleSideEffects: true,
id: ID_MAIN2,
implicitlyLoadedAfterOneOf: [],
implicitlyLoadedBefore: [ID_DEP],
importedIdResolutions: [
{
external: false,
id: ID_LIB1,
meta: {},
moduleSideEffects: true,
syntheticNamedExports: false
},
{
external: false,
id: ID_LIB1B,
meta: {},
moduleSideEffects: true,
syntheticNamedExports: false
},
{
external: false,
id: ID_LIB3,
meta: {},
moduleSideEffects: true,
syntheticNamedExports: false
}
],
importedIds: [ID_LIB1, ID_LIB1B, ID_LIB3],
importers: [],
isEntry: true,
Expand Down Expand Up @@ -303,12 +351,36 @@ module.exports = {
sourceType: 'module'
},
code: "import { lib1 } from './lib1';\nimport { lib2 } from './lib2';\nimport { lib3 } from './lib3';\nconsole.log(lib1, lib2, lib3);\n",
dynamicallyImportedIdResolutions: [],
dynamicallyImportedIds: [],
dynamicImporters: [],
hasModuleSideEffects: true,
id: ID_DEP,
implicitlyLoadedAfterOneOf: [ID_MAIN1, ID_MAIN2],
implicitlyLoadedBefore: [],
importedIdResolutions: [
{
external: false,
id: ID_LIB1,
meta: {},
moduleSideEffects: true,
syntheticNamedExports: false
},
{
external: false,
id: ID_LIB2,
meta: {},
moduleSideEffects: true,
syntheticNamedExports: false
},
{
external: false,
id: ID_LIB3,
meta: {},
moduleSideEffects: true,
syntheticNamedExports: false
}
],
importedIds: [ID_LIB1, ID_LIB2, ID_LIB3],
importers: [],
isEntry: false,
Expand Down
Expand Up @@ -65,12 +65,22 @@ module.exports = {
sourceType: 'module'
},
code: "import { value } from './lib';\nconsole.log(value);\n",
dynamicallyImportedIdResolutions: [],
dynamicallyImportedIds: [],
dynamicImporters: [],
hasModuleSideEffects: true,
id: ID_MAIN,
implicitlyLoadedAfterOneOf: [],
implicitlyLoadedBefore: [ID_DEP],
importedIdResolutions: [
{
external: false,
id: ID_LIB,
meta: {},
moduleSideEffects: true,
syntheticNamedExports: false
}
],
importedIds: [ID_LIB],
importers: [],
isEntry: true,
Expand Down Expand Up @@ -125,12 +135,22 @@ module.exports = {
sourceType: 'module'
},
code: "import { value } from './lib';\nconsole.log(value);\n",
dynamicallyImportedIdResolutions: [],
dynamicallyImportedIds: [],
dynamicImporters: [],
hasModuleSideEffects: true,
id: ID_DEP,
implicitlyLoadedAfterOneOf: [ID_MAIN],
implicitlyLoadedBefore: [],
importedIdResolutions: [
{
external: false,
id: ID_LIB,
meta: {},
moduleSideEffects: true,
syntheticNamedExports: false
}
],
importedIds: [ID_LIB],
importers: [],
isEntry: false,
Expand Down

0 comments on commit 546b2fb

Please sign in to comment.