ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

javascript-Webpack插件使用asm更改内容

2019-11-08 11:34:33  阅读:284  来源: 互联网

标签:webpack webpack-4 javascript


问题

嗨,我正在尝试编写一个插件,并使用ast来解析文件.但是我无法更改代码.例如,此代码不会将div更改为label.更改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更改为return块中的标签或将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插件中的抽象语法树更改某些内容.

解决方法:

如评论中所述,并在this question中的webpack代码中指出,webpack忽略了在抽头内更改解析器AST的尝试.

预计插件将使用ast作为只读映射在dependency graph中建立新的依赖关系.(这对于排序和并行执行的脆弱性较小,因为多个插件可以添加到依赖关系图中而不会通过更改参考AST彼此无效. )

基于i18n-lang和Define Plugins,使用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可能会因不同的加载器和输入更改而有很大差异.

标签:webpack,webpack-4,javascript
来源: https://codeday.me/bug/20191108/2007860.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有