Fix dynamic cache

This fixes dynamic cache by having one dynamic cache per `[path + options.external + options.debug]` combo.

It would be great if someone could review this before I merge it and make sure it looks like I haven't made too many hopeless mistakes.  It would also be good to sort out a test case if I get time.