Skip to content

Commit

Permalink
Add hasDefaultExport to ModuleInfo
Browse files Browse the repository at this point in the history
  • Loading branch information
lukastaegert committed Jan 19, 2022
1 parent fa1d934 commit 646c9a1
Show file tree
Hide file tree
Showing 13 changed files with 50 additions and 7 deletions.
23 changes: 16 additions & 7 deletions docs/05-plugin-development.md
Expand Up @@ -673,6 +673,7 @@ type ModuleInfo = {
id: string; // the id of the module, for convenience
code: string | null; // the source code of the module, `null` if external or not yet available
ast: ESTree.Program; // the parsed abstract syntax tree if available
hasDefaultExport: boolean | null; // is there a default export, `null` if external or not yet available
isEntry: boolean; // is this a user- or plugin-defined entry point
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
Expand Down Expand Up @@ -718,7 +719,7 @@ This allows you to inspect the final content of modules before deciding how to r
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:
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. Note the special handling for re-exporting the default export:
```js
export default function addProxyPlugin() {
Expand All @@ -744,7 +745,16 @@ export default function addProxyPlugin() {
load(id) {
if (id.endsWith('?proxy')) {
const importee = id.slice(0, -'?proxy'.length);
return `console.log('proxy for ${importee}'); export * from ${JSON.stringify(importee)};`;
// Note that namespace reexports do not reexport default exports
let code = `console.log('proxy for ${importee}'); export * from ${JSON.stringify(
importee
)};`;
// We know that while resolving the proxy, importee was already fully
// loaded and parsed, so we can rely on hasDefaultExport
if (this.getModuleInfo(importee).hasDefaultExport) {
code += `export { default } from ${JSON.stringify(importee)};`;
}
return code;
}
return null;
}
Expand Down Expand Up @@ -1142,7 +1152,7 @@ function parentPlugin() {
}
}
// ...plugin hooks
}
};
}

function dependentPlugin() {
Expand All @@ -1151,20 +1161,19 @@ function dependentPlugin() {
name: 'dependent',
buildStart({ plugins }) {
const parentName = 'parent';
const parentPlugin = options.plugins
.find(plugin => plugin.name === parentName);
const parentPlugin = options.plugins.find(plugin => plugin.name === parentName);
if (!parentPlugin) {
// or handle this silently if it is optional
throw new Error(`This plugin depends on the "${parentName}" plugin.`);
}
// now you can access the API methods in subsequent hooks
parentApi = parentPlugin.api;
}
},
transform(code, id) {
if (thereIsAReasonToDoSomething(id)) {
parentApi.doSomething(id);
}
}
}
};
}
```
1 change: 1 addition & 0 deletions src/ExternalModule.ts
Expand Up @@ -46,6 +46,7 @@ export default class ExternalModule {
get dynamicImporters() {
return dynamicImporters.sort();
},
hasDefaultExport: null,
hasModuleSideEffects,
id,
implicitlyLoadedAfterOneOf: EMPTY_ARRAY,
Expand Down
6 changes: 6 additions & 0 deletions src/Module.ts
Expand Up @@ -277,6 +277,12 @@ export default class Module {
get dynamicImporters() {
return module.dynamicImporters.sort();
},
get hasDefaultExport() {
if (module.graph.phase !== BuildPhase.GENERATE) {
return null;
}
return 'default' in module.exports;
},
hasModuleSideEffects,
id,
get implicitlyLoadedAfterOneOf() {
Expand Down
1 change: 1 addition & 0 deletions src/rollup/types.d.ts
Expand Up @@ -162,6 +162,7 @@ interface ModuleInfo {
dynamicImporters: readonly string[];
dynamicallyImportedIdResolutions: readonly ResolvedId[];
dynamicallyImportedIds: readonly string[];
hasDefaultExport: boolean | null;
hasModuleSideEffects: boolean | 'no-treeshake';
id: string;
implicitlyLoadedAfterOneOf: readonly string[];
Expand Down
Expand Up @@ -73,6 +73,7 @@ module.exports = {
dynamicallyImportedIdResolutions: [],
dynamicallyImportedIds: [],
dynamicImporters: [],
hasDefaultExport: false,
hasModuleSideEffects: true,
id: ID_MAIN,
implicitlyLoadedAfterOneOf: [],
Expand Down Expand Up @@ -143,6 +144,7 @@ module.exports = {
dynamicallyImportedIdResolutions: [],
dynamicallyImportedIds: [],
dynamicImporters: [],
hasDefaultExport: false,
hasModuleSideEffects: true,
id: ID_DEP,
implicitlyLoadedAfterOneOf: [],
Expand Down
Expand Up @@ -69,6 +69,7 @@ module.exports = {
dynamicallyImportedIdResolutions: [],
dynamicallyImportedIds: [],
dynamicImporters: [],
hasDefaultExport: false,
hasModuleSideEffects: true,
id: ID_MAIN,
implicitlyLoadedAfterOneOf: [],
Expand Down Expand Up @@ -139,6 +140,7 @@ module.exports = {
dynamicallyImportedIdResolutions: [],
dynamicallyImportedIds: [],
dynamicImporters: [],
hasDefaultExport: false,
hasModuleSideEffects: true,
id: ID_DEP,
implicitlyLoadedAfterOneOf: [],
Expand Down
Expand Up @@ -117,6 +117,7 @@ module.exports = {
dynamicallyImportedIdResolutions: [],
dynamicallyImportedIds: [],
dynamicImporters: [],
hasDefaultExport: false,
hasModuleSideEffects: true,
id: ID_MAIN1,
implicitlyLoadedAfterOneOf: [],
Expand Down Expand Up @@ -236,6 +237,7 @@ module.exports = {
dynamicallyImportedIdResolutions: [],
dynamicallyImportedIds: [],
dynamicImporters: [],
hasDefaultExport: false,
hasModuleSideEffects: true,
id: ID_MAIN2,
implicitlyLoadedAfterOneOf: [],
Expand Down Expand Up @@ -354,6 +356,7 @@ module.exports = {
dynamicallyImportedIdResolutions: [],
dynamicallyImportedIds: [],
dynamicImporters: [],
hasDefaultExport: false,
hasModuleSideEffects: true,
id: ID_DEP,
implicitlyLoadedAfterOneOf: [ID_MAIN1, ID_MAIN2],
Expand Down
Expand Up @@ -68,6 +68,7 @@ module.exports = {
dynamicallyImportedIdResolutions: [],
dynamicallyImportedIds: [],
dynamicImporters: [],
hasDefaultExport: false,
hasModuleSideEffects: true,
id: ID_MAIN,
implicitlyLoadedAfterOneOf: [],
Expand Down Expand Up @@ -138,6 +139,7 @@ module.exports = {
dynamicallyImportedIdResolutions: [],
dynamicallyImportedIds: [],
dynamicImporters: [],
hasDefaultExport: false,
hasModuleSideEffects: true,
id: ID_DEP,
implicitlyLoadedAfterOneOf: [ID_MAIN],
Expand Down
Expand Up @@ -111,6 +111,7 @@ module.exports = {
],
dynamicallyImportedIds: [getId('dynamic')],
dynamicImporters: [],
hasDefaultExport: false,
hasModuleSideEffects: true,
id: getId('main'),
implicitlyLoadedAfterOneOf: [],
Expand Down Expand Up @@ -145,6 +146,7 @@ module.exports = {
dynamicallyImportedIdResolutions: [],
dynamicallyImportedIds: [],
dynamicImporters: [getId('dynamic')],
hasDefaultExport: false,
hasModuleSideEffects: true,
id: 'external',
implicitlyLoadedAfterOneOf: [],
Expand Down Expand Up @@ -177,6 +179,7 @@ module.exports = {
dynamicallyImportedIdResolutions: [],
dynamicallyImportedIds: [],
dynamicImporters: [],
hasDefaultExport: true,
hasModuleSideEffects: true,
id: getId('lib'),
implicitlyLoadedAfterOneOf: [],
Expand Down Expand Up @@ -260,6 +263,7 @@ module.exports = {
],
dynamicallyImportedIds: ['external'],
dynamicImporters: [getId('main')],
hasDefaultExport: false,
hasModuleSideEffects: true,
id: getId('dynamic'),
implicitlyLoadedAfterOneOf: [],
Expand Down
4 changes: 4 additions & 0 deletions test/function/samples/manual-chunks-info/_config.js
Expand Up @@ -110,6 +110,7 @@ module.exports = {
],
dynamicallyImportedIds: [getId('dynamic')],
dynamicImporters: [],
hasDefaultExport: false,
hasModuleSideEffects: true,
id: getId('main'),
implicitlyLoadedAfterOneOf: [],
Expand Down Expand Up @@ -144,6 +145,7 @@ module.exports = {
dynamicallyImportedIdResolutions: [],
dynamicallyImportedIds: [],
dynamicImporters: [getId('dynamic')],
hasDefaultExport: false,
hasModuleSideEffects: true,
id: 'external',
implicitlyLoadedAfterOneOf: [],
Expand Down Expand Up @@ -176,6 +178,7 @@ module.exports = {
dynamicallyImportedIdResolutions: [],
dynamicallyImportedIds: [],
dynamicImporters: [],
hasDefaultExport: true,
hasModuleSideEffects: true,
id: getId('lib'),
implicitlyLoadedAfterOneOf: [],
Expand Down Expand Up @@ -259,6 +262,7 @@ module.exports = {
],
dynamicallyImportedIds: ['external'],
dynamicImporters: [getId('main')],
hasDefaultExport: false,
hasModuleSideEffects: true,
id: getId('dynamic'),
implicitlyLoadedAfterOneOf: [],
Expand Down
2 changes: 2 additions & 0 deletions test/function/samples/module-parsed-hook/_config.js
Expand Up @@ -51,6 +51,7 @@ module.exports = {
dynamicallyImportedIdResolutions: [],
dynamicallyImportedIds: [],
dynamicImporters: [],
hasDefaultExport: false,
hasModuleSideEffects: true,
id: ID_MAIN,
implicitlyLoadedAfterOneOf: [],
Expand Down Expand Up @@ -107,6 +108,7 @@ module.exports = {
dynamicallyImportedIdResolutions: [],
dynamicallyImportedIds: [],
dynamicImporters: [],
hasDefaultExport: false,
hasModuleSideEffects: true,
id: ID_DEP,
implicitlyLoadedAfterOneOf: [],
Expand Down
5 changes: 5 additions & 0 deletions test/function/samples/plugin-module-information/_config.js
Expand Up @@ -18,6 +18,7 @@ module.exports = {
ast: null,
code: null,
dynamicImporters: [],
hasDefaultExport: null,
dynamicallyImportedIdResolutions: [],
dynamicallyImportedIds: [],
hasModuleSideEffects: true,
Expand Down Expand Up @@ -183,6 +184,7 @@ module.exports = {
],
dynamicallyImportedIds: [ID_NESTED, ID_PATH],
dynamicImporters: [],
hasDefaultExport: false,
hasModuleSideEffects: true,
id: ID_MAIN,
implicitlyLoadedAfterOneOf: [],
Expand Down Expand Up @@ -270,6 +272,7 @@ module.exports = {
dynamicallyImportedIdResolutions: [],
dynamicallyImportedIds: [],
dynamicImporters: [],
hasDefaultExport: false,
hasModuleSideEffects: true,
id: ID_FOO,
implicitlyLoadedAfterOneOf: [],
Expand Down Expand Up @@ -297,6 +300,7 @@ module.exports = {
dynamicallyImportedIdResolutions: [],
dynamicallyImportedIds: [],
dynamicImporters: [ID_MAIN],
hasDefaultExport: null,
hasModuleSideEffects: true,
id: ID_PATH,
implicitlyLoadedAfterOneOf: [],
Expand Down Expand Up @@ -379,6 +383,7 @@ module.exports = {
dynamicallyImportedIdResolutions: [],
dynamicallyImportedIds: [],
dynamicImporters: [ID_MAIN],
hasDefaultExport: false,
hasModuleSideEffects: true,
id: ID_NESTED,
implicitlyLoadedAfterOneOf: [],
Expand Down
2 changes: 2 additions & 0 deletions test/function/samples/preload-module/_config.js
Expand Up @@ -33,6 +33,7 @@ module.exports = {
assert.deepStrictEqual(moduleInfo, {
code: "import './dep';\nassert.ok(true);\n",
dynamicImporters: [],
hasDefaultExport: null,
dynamicallyImportedIdResolutions: [],
dynamicallyImportedIds: [],
hasModuleSideEffects: true,
Expand Down Expand Up @@ -73,6 +74,7 @@ module.exports = {
assert.deepStrictEqual(moduleInfo, {
code: 'assert.ok(true);\n',
dynamicImporters: [],
hasDefaultExport: false,
dynamicallyImportedIdResolutions: [],
dynamicallyImportedIds: [],
hasModuleSideEffects: true,
Expand Down

0 comments on commit 646c9a1

Please sign in to comment.