If I want to "require" another custom Lua file, I know that I can place the command to do so at the top of one of the "on___.lua" files within the EventsFiles folder, and that works fine to make my separate module (consisting of multiple local variables and functions) available in that file. But if I want my code to be available to several such files, and I place a separate "require" statement at the top of each corresponding file, this is basically re-reading my file each time, and -- here's my issue -- creating a separate instance of it in memory. This means the contents of the local variables I'm defining there have limited scope -- they aren't being broadly shared.
That's not how require works. Require only runs the file once, then checks package.loaded[module_name] for the table that is returned after that (or rather, if there is nothing in package.loaded, it runs the file). See here. You can also check this by using a civ.ui.text call in a file that you require by multiple files. That message will only be shown once, since the file is only read once.
The local variables will have adequate scope. For example, in the General Library, I provide a function gen.getState() which provides a way to access the state table (in the template, it actually links to a subtable, I believe), and gen.linkState(stateTable) to store the stateTable in a local variable. gen.linkState is called in the discreteEventsRegistrar.lua file, while gen.getState is called in whatever file is needed, and they work.
I think this means that using require('customModule') at the top of any relevant file actually does what you want.