question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Provide a hook to replace module sources after visiting all sources

See original GitHub issue

Feature request

Provide a means to replace the (complete or partial) sources of a module after all sources are visited/loaders have processed all files, but before the bundling/optimization phase.

What is the expected behavior?

There should be a hook plugin developers can tap into in order to replace the sources of a module after the registered loaders have processed all files.

What is motivation or use case for adding/changing the behavior?

We are trying to make a JavaScript optimization tool available as a webpack plugin. After browsing the sources of both webpack itself and a lot of existing webpack plugins and loaders, and after a lot of trial and error, we have the impression that our tool’s requirements are impossible to fit into webpack’s plugin architecture:

  1. We need to analyze the JavaScript sources of each file after e.g. TypeScript compilation (ts-loader), but before any other optimization tools like terser, and before webpack replacements like new Foo() --> new moduleName['exportName']())
  2. We need to adjust these sources in that same unoptimized state, but we can only start adjusting after we have seen all sources.

One possible approach we thought of was to run the analysis in a custom loader that is added by the plugin, and use the gathered information in a hook later on (e.g. seal), where all module sources are available. However, we have not been able to replace the module sources in any of the hooks we tried.

How should this be implemented in your opinion?

Maybe by introducing an additional hook between loading and bundling/optimizing, or by modifying the seal hook to allow the replacement of the module sources.

Are you willing to work on this yourself? yes, if a webpack dev could provide a rough concept/hints for the implementation.

It might of course be possible that there already is a way to implement this kind of plugin functionality using the existing plugin API that we just could not figure out yet. I already asked for help on this topic on stackoverflow, which earned me the tumbleweed badge 😃

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Reactions:3
  • Comments:5 (3 by maintainers)

github_iconTop GitHub Comments

3reactions
ndreckshagecommented, Jan 30, 2020

For anyone else who comes across this issue after going down a rabbit hole (which I think is the only way you will find this issue)…

My use case:

  • Many bundles / permutations for build time translations.
  • Placeholder strings to translate from a babel plugin.
  • Hit a translations service to replace the placeholders with real translations.
  • Using an async loader (per file basis) results in 5k+ requests. Debouncing to save requests is messy.
  • Using a plugin (previously I hooked into optimizeModules) worked but resulted in the same cache buster if translations changed. Additionally, I had to handle double encoding from various sourcemap options manually.

I found this issue most helpful to help me reduce requests + still have cachebusting work, etc.

Per @sokra suggestion above, plus this implementation I found as a reference guideline…

  1. Hit loader, add whatever you need to this._module and this._compilation
  2. Hook into compilation.hooks.finishModules.tapAsync(, do whatever async work you need to do. Attach data back to module. Rebuild necessary modules.
  3. Back in loader, use that new data to update your source appropriately.

I tried a bunch of things, and this seems like simplest approach.

3reactions
sokracommented, Feb 28, 2019

One issue is that changing the source code could affect the module graph. You could add new dependencies, etc.

Anyway there is a way to achieve what you want to do. You need a combination of loader and plugin. The loader should do nothing without whole compilation information available. In the first step do the normal compilation until a hook like seal or optimizeModule. Here you have all information available from all modules. Now trigger a rebuild for all modules that should be changed (or for all) with compilation.rebuildModule. This will invoke the loader again and it has now whole compilation information available it can do additional optimizations. But you will be unable to do major changes to the module graph. You are not allowed to add new dependencies, but it’s possible to remove dependencies.

Read more comments on GitHub >

github_iconTop Results From Across the Web

How to implement an import hook that can modify the source ...
I saw that imp.modules had to be replaced this way but the documentation indicates to use module_from_spec (from importlib). I am using 3 ......
Read more >
Execute Terraform commands on multiple modules at once
Now you can go into the root folder and deploy all the modules within it by using the run-all command with apply :...
Read more >
Hooks | module.inc | Drupal 7.x
Name Location Description hook_actions_delete modules/system/system.api.php Executes code after an action is de... hook_action_info modules/system/system.api.php Declares information about actions. hook_action_info_alter modules/system/system.api.php Alters the actions declared by anot......
Read more >
Build and Use a Local Module | Terraform
Terraform treats any local directory referenced in the source argument of a module block as a module. A typical file structure for a...
Read more >
Module Federation - webpack
Control from consumer to container. Overriding modules is a one-directional operation. · Concept should be environment-independent. Usable in web, Node.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found