如何你可以在 Webpack 编译钩子中操作 AST 吗?

问题描述

对于一些内部工具,我正在尝试使用 webpack 将源文件名写入 javascript 源。我想出了下面的代码。不幸的是,虽然它确实替换了提供的 AST 中的 '[filename]',但该更改似乎被丢弃了。在这种情况下 AST 是只读的吗? (而且可能,如果不是这样,你怎么能做到这一点?)

const NAME = 'InjectFilenamePlugin'

const SOURCE_TEST = /src/i // a path to ensure node_modules are bypassed
const PLACEHOLDER = '[filename]'

class InjectFilenamePlugin {

  apply(compiler) {
    compiler.hooks.compilation.tap(NAME,(_,params) => {
      const { normalModuleFactory } = params

      function handler(parser) {
        parser.hooks.program.tap(NAME,(ast) => {
          const { resource } = parser.state.module

          if (SOURCE_TEST.test(resource) && ast) {
            replacePlaceholder(ast)
          }

          function replacePlaceholder(node) {
            if (node.value === PLACEHOLDER) {
              node.value = resource
              node.raw = `"${resource}"`
            } else {
              Object.values(node)
                .filter(node => node && typeof node === 'object')
                .forEach(replacePlaceholder)
            }
          }
        })
      }

      normalModuleFactory.hooks.parser
        .for('javascript/auto')
        .tap(NAME,handler)
      normalModuleFactory.hooks.parser
        .for('javascript/dynamic')
        .tap(NAME,handler)
      normalModuleFactory.hooks.parser
        .for('javascript/esm')
        .tap(NAME,handler)
    })

  }

}

module.exports = InjectFilenamePlugin

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)