Skip to content

Instantly share code, notes, and snippets.

@cchamplin
Created March 31, 2020 19:06
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cchamplin/c55778d4a70854a5d72bab2a8c4450fe to your computer and use it in GitHub Desktop.
Save cchamplin/c55778d4a70854a5d72bab2a8c4450fe to your computer and use it in GitHub Desktop.
const HandlerRunner = require("serverless-offline/dist/lambda/handler-runner/index").default;
class OfflineInvalidate {
constructor(serverless, options) {
this.serverless = serverless;
this.hooks = {
"before:offline:start:init": (opts) => this.inject()
};
this.lastRunner = {};
}
cacheInvalidation(filePath) {
if (require.cache[require.resolve(filePath)]) {
delete require.cache[require.resolve(filePath)];
}
}
findPrivateProperty(obj, propName) {
const props = Object.getOwnPropertyNames(obj);
for (let prop of props) {
if (prop.indexOf(`_${propName}`) > 0) {
return prop;
}
}
return null;
}
inject() {
const that = this;
const oldRun = HandlerRunner.prototype.run;
let run = async function(event, context) {
const runnerPropName = that.findPrivateProperty(this, 'runner');
const funOptionsPropName = that.findPrivateProperty(this, 'funOptions');
if (!runnerPropName || !funOptionsPropName) {
return oldRun(event, context);
}
const runner = this[runnerPropName];
const funOptions = this[funOptionsPropName];
const internalRef = funOptions.handlerPath || funOptions.handler;
if (that.lastRunner[internalRef]) {
await that.lastRunner[internalRef].cleanup();
}
that.cacheInvalidation(internalRef);
const runnerInstance = this[runnerPropName] = await this._loadRunner();
that.lastRunner[internalRef] = runnerInstance;
return runnerInstance.run(event, context);
}
HandlerRunner.prototype.run = run;
}
}
module.exports = OfflineInvalidate
@crsepulv
Copy link

on first line you requiere: serverless-offline/dist/lambda/handler-runner/index
but my serverless-offline directory on node_modules does not have a dist/ folder...
do you know how can I fix it? I really need to refresh code on dile watch. regards

@lqueryvg
Copy link

@crsepulv
My guess is that it's the version of serverless-offline that you are using.
E.g. The dist folder exists with

"serverless-offline": "6.1.2"

@lucasklaassen
Copy link

I'm not sure if this covers authorizers. I can't seem to invalidate the cache for my authorizer functions to be able to have hot reloading. Anyone else?

@juliosch
Copy link

This is a life saver. Great job and thanks!

@larrybotha
Copy link

larrybotha commented May 7, 2021

A note to anyone else using this, this plugin requires that serverless is started with the start option:

$ serverless offline start

otherwise changes are not injected.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment