You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
* Add hasDefaultExport to ModuleInfo
* Improve example
* Make export information available after loading, detect reexports
* Manually fix vulnerability
Copy file name to clipboardExpand all lines: docs/05-plugin-development.md
+40-16Lines changed: 40 additions & 16 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -164,27 +164,42 @@ The `importer` is the fully resolved id of the importing module. When resolving
164
164
165
165
For those cases, the `isEntry` option will tell you if we are resolving a user defined entry point, an emitted chunk, or if the `isEntry` parameter was provided for the [`this.resolve`](guide/en/#thisresolve) context function.
166
166
167
-
You can use this for instance as a mechanism to define custom proxy modules for entry points. The following plugin will only expose the default export from entry points while still keeping named exports available for internal usage:
167
+
You can use this for instance as a mechanism to define custom proxy modules for entry points. The following plugin will proxy all entry points to inject a polyfill import.
168
168
169
169
```js
170
-
functiononlyDefaultForEntriesPlugin() {
170
+
functioninjectPolyfillPlugin() {
171
171
return {
172
-
name:'only-default-for-entries',
172
+
name:'inject-polyfill',
173
173
asyncresolveId(source, importer, options) {
174
174
if (options.isEntry) {
175
175
// We need to skip this plugin to avoid an infinite loop
let code =`import 'polyfill';export * from ${JSON.stringify(entryId)};`;
197
+
// Namespace reexports do not reexport default, so we need special
198
+
// handling here
199
+
if (hasDefaultExport) {
200
+
code +=`export { default } from ${JSON.stringify(entryId)};`;
201
+
}
202
+
return code;
188
203
}
189
204
returnnull;
190
205
}
@@ -673,6 +688,7 @@ type ModuleInfo = {
673
688
id: string; // the id of the module, for convenience
674
689
code: string |null; // the source code of the module, `null` if external or not yet available
675
690
ast:ESTree.Program; // the parsed abstract syntax tree if available
691
+
hasDefaultExport: boolean |null; // is there a default export, `null` if external or not yet available
676
692
isEntry: boolean; // is this a user- or plugin-defined entry point
677
693
isExternal: boolean; // for external modules that are referenced but not included in the graph
678
694
isIncluded: boolean |null; // is the module included after tree-shaking, `null` if external or not yet available
@@ -718,7 +734,7 @@ This allows you to inspect the final content of modules before deciding how to r
718
734
719
735
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.
720
736
721
-
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:
737
+
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:
722
738
723
739
```js
724
740
exportdefaultfunctionaddProxyPlugin() {
@@ -744,7 +760,16 @@ export default function addProxyPlugin() {
744
760
load(id) {
745
761
if (id.endsWith('?proxy')) {
746
762
constimportee=id.slice(0, -'?proxy'.length);
747
-
return`console.log('proxy for ${importee}'); export * from ${JSON.stringify(importee)};`;
763
+
// Note that namespace reexports do not reexport default exports
764
+
let code =`console.log('proxy for ${importee}'); export * from ${JSON.stringify(
765
+
importee
766
+
)};`;
767
+
// We know that while resolving the proxy, importee was already fully
768
+
// loaded and parsed, so we can rely on hasDefaultExport
769
+
if (this.getModuleInfo(importee).hasDefaultExport) {
770
+
code +=`export { default } from ${JSON.stringify(importee)};`;
771
+
}
772
+
return code;
748
773
}
749
774
returnnull;
750
775
}
@@ -1142,7 +1167,7 @@ function parentPlugin() {
1142
1167
}
1143
1168
}
1144
1169
// ...plugin hooks
1145
-
}
1170
+
};
1146
1171
}
1147
1172
1148
1173
functiondependentPlugin() {
@@ -1151,20 +1176,19 @@ function dependentPlugin() {
0 commit comments