【问题标题】:Webpack plugin change content with asmWebpack 插件使用 asm 更改内容
【发布时间】:2019-04-16 00:31:00
【问题描述】:

问题

您好,我正在尝试编写一个插件并使用 ast 来解析文件。但我无法更改代码。例如,此代码不会将 div 更改为标签。改变ast的正确方法是什么?

    apply(compiler) {
      compiler.hooks.normalModuleFactory.tap('MyPlugin', (factory) => {
        factory.hooks.parser.for('javascript/auto').tap('MyPlugin', (parser, options) => {
          parser.hooks.program.tap('MyPlugin', (ast, comments) => {

            if (parser.state &&
                parser.state.module &&
                parser.state.module.resource.indexOf('node_modules') === -1) {

            if (parser.state.module.resource.endsWith('tsx')) {
                var g = ast.body.filter(n=> n.type === 'ExportNamedDeclaration');

            for (let a of g) {
              var decl = a.declaration.declarations;

              if (decl && decl[0]) {
                decl[0].init.body.body[0].argument.arguments[0].raw = 'label';
                decl[0].init.body.body[0].argument.arguments[0].value = 'label';
              }
            }
          }
        }
      });
    });
  });
}`

我只需要将 div 更改为返回块中的标签或将 data-attr 添加到 div。我不想使用正则表达式并替换所有文件内容,我想用 ast 制作它。 MyComponent.tsx 可以如下:

import * as React from 'react';
import * as style from './MyComponent.css';

export const MyComponent = (props) => {
  return (
    <div className={style['test']}>bla bla</div>
  );
};

也许有人可以提供一个小例子来改变 webpack 插件中的抽象语法树。

【问题讨论】:

  • 您可能需要返回修改后的 ast。您可以检查 DefinePlugin 以检查它如何修改代码:github.com/webpack/webpack/blob/master/lib/…
  • 您正在测试的模块是什么样的?
  • 我更新了问题。
  • felixmosh,感谢您的回复,但我在 DefinePlugin 中找不到,他们正在修改 ast
  • 尝试添加 UseStrictPlugin: UseStrictPlugin.js

标签: javascript webpack webpack-4


【解决方案1】:

如 cmets 中所述并在 this question 中的 webpack 代码中指出,webpack 忽略在点击中更改解析器 AST 的尝试。

插件应使用 ast 作为只读映射来在 dependency graph 中构建新的依赖项。 (这在排序和并行执行方面不太脆弱,因为多个插件可以添加到依赖关系图中,而不会通过更改引用 AST 使彼此失效。)

基于 i18n-lang 和定义插件,使用 ast 为您的转换构建依赖项的示例可能如下所示:

"use strict";
const pluginName = 'MyPlugin';
const NullFactory = require('webpack/lib/NullFactory');
const ConstDependency = require("webpack/lib/dependencies/ConstDependency");

class MyPlugin {

    apply(compiler) {

        compiler.hooks.compilation.tap(
            "MyPlugin",
            (compilation, { normalModuleFactory }) => {
                compilation.dependencyFactories.set(ConstDependency, new NullFactory());
                compilation.dependencyTemplates.set(
                    ConstDependency,
                    new ConstDependency.Template()
                );
            });


        compiler.hooks.normalModuleFactory.tap('MyPlugin', (factory) => {
            factory.hooks.parser.for('javascript/auto').tap('MyPlugin', (parser, options) => {
                parser.hooks.program.tap('MyPlugin', (ast, comments) => {

                    if (parser.state &&
                        parser.state.module &&
                        parser.state.module.resource.indexOf('node_modules') === -1) {

                        if (parser.state.module.resource.endsWith('tsx')) {
                            var g = ast.body.map(n => {
                                try {
                                    let {expression:{left:{property:{name:my}}, right:{body:{body:[{argument:{arguments:[div]}}]}}}} = n
                                    return my == 'MyComponent' && div.value == 'div' ? div: false 
                                } catch(e) {
                                  return false;
                                }
                            }).filter(e=>e);
                            for (let div of g) {
                                let dep = new ConstDependency(JSON.stringify('label'), div.range);
                                    dep.loc = div.loc;
                                    parser.state.current.addDependency(dep);
                            }
                        }
                    }
                });
            });
        });
    }
}

module.exports= MyPlugin;

解析器提供的ast 可能会随着不同的加载器和输入的变化而有很大差异。

【讨论】:

  • 谢谢你,这对我帮助很大!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-03-12
  • 1970-01-01
  • 1970-01-01
  • 2012-12-07
  • 2013-04-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多