In addition to @EconomiCurtis's advice, I think you just described a perfect case for a small R package with the encapsulated / reusable functionality exposed. You can even include Shiny modules in an R package, if there are "widgets" and such that you generally reuse. R packages are R's optimal way for code documentation and reuse, and are definitely recommended for larger projects where it becomes easy to forget how things interact. Think of how nice it would be to type ?myfunc for the functions you are interacting with, or to pull up docs on how to use a module that you have not utilized in a while.
If you haven't built a package before, I definitely recommend Hadley's book / website on the topic, which makes the topic very accessible.
One last thing that I have long envisioned but never actually had a case to make good on. My intent was to keep the core of the app (i.e. the app.R file) super lightweight and provide all (or most) functionality by modules. Then, I would have a lightweight version of the app.R on another git branch or in the tests folder that would allow me to test each module (and especially new modules) separately for unit / integration testing. I never really thought through what exactly this scaffolding would look like, but the functional programming paradigm makes this possible.
It certainly is advisable to not ignore unit and integration tests of your application - other frameworks certainly wouldn't. As the app scales, I think pulling reused functionality into an R package will ultimately push you in this direction and help you think deeper about best practices for app architecture.