Programming Element javascript - code modification Code

Programming Element javascript - code modification Code

introduction

Refactoring code is a manual labor, especially in determining the reconstruction program, and the rest is adjusted by program code and then test it.

How to have a good and fast adjustment in place code, which is not an easy thing.

Simple code, may be used for the regular expression shown, if the code is slightly more complex, the regular expression shown on the powerless.

As I talked about in previous modification method javascript meta-programming of method_missing , I can be modified in a project, if you want to modify the interface it 50 times? I have got to think this reconstruction is worthwhile.

I can not allow arbitrary code to write. . .

So I found a jscodeshift , so I can use my tool code refactoring code.

jscodeshift let me have the tools-source operating code.

achieve

I use the example of method_missing item in my last article, I want to interface calls (with url) I project, are adjusted to method_missing invocation.

as follows:


// old
$.ajax('/api/web/project/content/target/mod', {
  type: 'post',
  dataType: 'json',
  data: {
    tid: it.targetId,
    targetImgId: img.objectId,
    pid: pid
  }
}).done(function (data, status, jqXhr) {
  self.hideLoading();
  if (data && data.code === 200 && data.data) {
    it.target = data.data
    // self.paginationConf.onChange()
  }
}).fail(() => {

}).always(() => {

})

// new
this.$api.update_project_content_target_mod({
    tid: it.targetId,
    targetImgId: img.objectId,
    pid: pid
}).then(function (data, status, jqXhr) {
  self.hideLoading();
  if (data && data.code === 200 && data.data) {
    it.target = data.data
    // self.paginationConf.onChange()
  }
}).catch(() => {

}).finally(() => {

})

As can be seen in the new code, the old code $ .ajax replaced this. $ Api, and then generates a call to the method name parameter.

Finally, not only adjusted the number of parameters, but also to adjust the value of the parameter.

Think about how to write regular?

Regular should do nothing.

Then jscodeshift to play, it can parse the code to ast, and then we modify ast, ast then into code.

My code is as follows:


const adapt = require('vue-jscodeshift-adapter');

// 修改 $.ajax
function transform(fileInfo, api) {
  const j = api.jscodeshift

  return j(fileInfo.source)
    .find(j.CallExpression, { callee: { object: { name: '$' }, property: { name: 'ajax' } } })
    .replaceWith(p => {
      const url = p.node.arguments[0]
      const setting = p.node.arguments[1]
      const urlStr = url.value.replace('/api/web/', '').split('/')
      let method = 'get'
      let newSetting

      setting.properties.forEach(i => {
        if (i.key.name.toLowerCase() === 'type') {
          if (i.value.value.toLowerCase() === 'post') {
            method = 'update'
          }
        } else if (i.key.name.toLowerCase() === 'data') {
          newSetting = i.value
        }
      });

      urlStr.unshift(method);

      return j.callExpression(
        j.memberExpression(
          j.memberExpression(j.identifier('this'), j.identifier('$api'), false),
          j.identifier(urlStr.join('_')), false
        ), [newSetting])
    })
    .toSource();
}

// 修改 done
function transform1(fileInfo, api) {
  const j = api.jscodeshift

  return j(fileInfo.source)
    .find(j.MemberExpression, { property: { name: 'done' } })
    .replaceWith(p => {
      p.node.property.name = 'then'
      return p.node
    })
    .toSource();
}

// 修改 fail
function transform2(fileInfo, api) {
  const j = api.jscodeshift

  return j(fileInfo.source)
    .find(j.MemberExpression, { property: { name: 'fail' } })
    .replaceWith(p => {
      p.node.property.name = 'catch'
      return p.node
    })
    .toSource();
}

// 修改 always
function transform3(fileInfo, api) {
  const j = api.jscodeshift

  return j(fileInfo.source)
    .find(j.MemberExpression, { property: { name: 'always' } })
    .replaceWith(p => {
      p.node.property.name = 'finally'
      return p.node
    })
    .toSource();
}

module.exports = adapt(transform);
// module.exports = adapt(transform1);
// module.exports = adapt(transform2);
// module.exports = adapt(transform3);

how to use


# 使用 bash 循环调用
jscodeshift -t src/myTransforms.js filepath

Because my code is vue single file module, so I use a third-party plug-vue-jscodeshift-adapter.

to sum up

jscodeshift is remodeling is very helpful for large projects. It allows you to quickly rewrite a lot of code, but also easy to test.

Reference links

  1. view-jscodeshift-fit
  2. write-code-to-rewrite-your-code
  3. jscodeshift
  4. astexplorer

Guess you like

Origin www.cnblogs.com/htoooth/p/11370474.html