6

I'd like to create a Webpack loader (or plugin) which would allow to replace a call to a certain method to the result returned by this method during the compilation. For example, let's assume I have a file named transpile_time.js:

import {SomeUsefullStuff} from 'a_very_cool_lib';   //<-- this should be resolved correctly

module.exports = function{
   //let's assume that 'a_very_cool_lib' is used somewhere here
   return 'console.log(\'tralala\')';
}

And, I have another another file named App.ts:

import {default as tt} from './transpile-time';
....
function someFunc(){
  ...
  tt();      // <------ I want this code to be replaced to 
             // 'console.log(\'tralala\')'
             // during the compilation process
}

For App.js my custom loader is used. With the help of Esprima and Estraverse and Escodegen I'm able to manipulate the sources, but at some moment I need to resolve the dependency

import {default as tt} from './transpile-time';

dynamically in my loader with respect to the fact that it can have it's own dependencies as well. In the example above,

import {SomeUsefullStuff} from 'a_very_cool_lib'; 

should be resolved correctly. Webpack Loader API offers loadModule method, this gives the sources and the module object. The latter theoretically contains dependencies with their sources and I can go through them and replace every import statement with the corresponding source code and then use eval. But that is quite ugly, I would prefer to let Webpack doing this job. For example, there is a compilation object, it seems like it is possible to insert some hooks, but this is not described well. Does anyone have an idea?

P.S. I'm going to use it all for template resolving and code generation.

Update: After doing a small investigation on how Weback works internally (this article was quite helpful), I think that it would be better to use a plugin instead of a loader. And, probably, I don't need Esprima and other tools because Webpack also builds AST at some stage. But still I don't know how to use it.

Anton Pilyak
  • 1,050
  • 2
  • 15
  • 34
  • Should the import statement from `./transpile-time` be included in the resulting bundle? What if some imports from it are not used? Does `./transpile-time` need to be parsed (transpiled, or otherwise) by Webpack before it can be `require`d and used? – Gerrit0 Dec 31 '18 at 02:27
  • 1. No, import statements from ./transpile-time shouldn't end up in the resulting bundle. 2. Since such imports shouldn't be included into the resulting bundle, it doesn't matter if some of them are not used. An optimization in order to reduce memory consumption could be a next step. 3. Yes, ./transpile-time and all of it's dependencies should pass through all the loaders. – Anton Pilyak Dec 31 '18 at 12:32
  • Therefore, I want Webpack to form 2 bundles - one is the usual one, and another should exist only during the compilation. Every call to any function from such bundle should be resolved during the compilation and substituted by the returning result (always a string that contains JS code). All the corresponding dependencies should be removed from the resulting bundle. – Anton Pilyak Dec 31 '18 at 12:34

0 Answers0