

Javascript Refactoring without an IDE - justinlilly
http://justin.abrah.ms/js/javascript-reafactoring-without-ides.html

======
afandian
This doesn't really look like a 'proper' refactor to me. It's a blanket 'all
strings and attributes' isn't it? How does this apply to 'real world' code?

1 - What if I'm using an external library so I have some exceptions?

2 - What if I want to keep strings with underscores in them? Can it detect
those strings that are used to reference as attributes and those that aren't?

3 - What if I'm using an external library so I have some exceptions?

4 - What if I have two entirely separate 'classes'/prototypes but they share a
common attribute name. What if I want to update one but not the other?

I've spent a lot of time writing in static and dynamic languages and I
intuitively don't believe that you can do 'proper' refactors in dynamic
languages (although it's not something I've gone out of my way to look into).

I'd love to be proved wrong.

~~~
justinlilly
Perhaps not a 'proper' refactor. For that, check out Tern, mentioned below.

If you want deeper control, my examples are rather mundane. Check out rewrite-
js linked in the post for a better example of stronger guarantees based on AST
matching.

Regarding strings, that totally works. You can see in my example I have
explicitly called out `node.type === 'String'` to catch those cases.

I agree that you can't do "proper refactoring" (to use your definition) in
dynamic languages, but that doesn't mean the answer is to do everything
manually. You could make the argument that the answer is to never use dynamic
languages, but I feel that's infeasible when it comes to browser-based work.

~~~
afandian
I did have a look at tern. It looks very interesting. But it couldn't rename
the field with this code:

    
    
        var key = "test";
        var theThing = {};
        theThing[key] = function() { return "hello"; };;
        console.log(theThing.test());
    
    

Which isn't so exotic.

To clarify, if I had a string in my source code that had nothing to do with
looking up attributes, it wouldn't be touched?

    
    
        var one = "_I_just_like_talking_like_this_";
        var two = "_two";
        var test = {};
        test[two] = "II";
        console.log(test._two);
    

The result would be

    
    
        var one = "_I_just_like_talking_like_this_";
        var two = "two";
        var test = {};
        test[two] = "II";
        console.log(test.two);
    
    
    ?

~~~
justinlilly
If you had this:

    
    
        var one = "_I_just_like_talking_like_this_";
        var two = "_two";
        var test = {_two: "II"};
    

And ran the program in the blog post, one's value, two's value and the _two
attribute in test would match.

If you removed the string stanza in the post, only the _two attribute in test
would match.

~~~
afandian
Sorry I made a mistake didn't make the point I was trying to make, updated
post.

------
bpodgursky
If you do feel like booting up an IDE... Intellij's Javscript refactoring is
really impressive.

------
justinlilly
Was discussing this in #node.js on freenode and someone suggested looking at
Tern as well. It seems to be a bigger, though more powerful, library.

Blog post that was suggested:
[http://marijnhaverbeke.nl/blog/tern.html](http://marijnhaverbeke.nl/blog/tern.html)

