I haven’t gotten around to porting this code to 3.0 yet but here is some 2.x code. I’m not sure how good of an idea this is, but I have a scene that has an animation defined in it. To make it reusable I add it to an object that I want to have said animation. I then update the animation so it is wired to the new object instead. This is the code I use to update the animation. This is 2.x code, so the :transform/scale etc will be different in 3.0
onready var _player = get_node('AnimationPlayer')
...
var anim = _player.get_animation(ANIM_PHASE_OUT)
anim.track_set_path(0, new_sprite_path + ':transform/scale')
anim.track_set_path(1, new_sprite_path + ':visibility/visible')
var anim = _player.get_animation(ANIM_PHASE)
anim.track_set_path(0, new_sprite_path + ':transform/scale')
This allowed me to work in a scene, creating the animation the way I wanted and then apply it to any object I wanted. The code to update the animation went in the script for the scene that had the animation. So I just add the animation scene as a child to a scene and then call the method to wire it up by passing in new_sprite_path.
This could be a really bad practice but it worked great for applying the animation to a lot of different kinds of objects.