Change source code of a module via AST from a WebP

2019-05-27 02:15发布

问题:

I have the following JS file:

// hello-foo.js
console.log('foo')

I want to replace 'foo' with 'bar' with webpack. I have the following WebPack plugin for that:

class MyPlugin {

  constructor() {}
  apply(compiler) {

    compiler
      .hooks
      .compilation
      .tap('MyPlugin', (compilation, {normalModuleFactory}) => {

        normalModuleFactory
          .hooks
          .parser
          .for('javascript/auto')
          .tap('MyPlugin', (parser) => {

            parser
              .hooks
              .program
              .tap('MyPlugin', (ast, comments) => {

                ast.body[0].expression.arguments[0].value = 'bar'

                // ast.body[0].expression.arguments[0].raw = 'bar' // does not make any difference :(

              })

          })

      })
  }
}

I debugged webpack/lib/Parser.js, it got back the updated AST, but it just got ignored when emitting the bundle.

I know that for the above trivial example a loader might be a better option, but I am specifically interested in reusing WebPack's AST, if it is possible. In other words, I don't want to parse the module with Babel first, then have it re-parsed again by WebPack/Acorn.

There is a similar question here already, but I believe that it relates to an earlier version of WebPack.