Skip to content

Instantly share code, notes, and snippets.

@jschr
Last active November 20, 2017 02:10
Show Gist options
  • Select an option

  • Save jschr/fd6565792839233770648b477ac3d687 to your computer and use it in GitHub Desktop.

Select an option

Save jschr/fd6565792839233770648b477ac3d687 to your computer and use it in GitHub Desktop.
Handler step 1
import createWebpackConfig from './webpack.config'
const s3 = new AWS.S3()
// the lambda handler
// event contains information from the source of the lambda invocation
// it could be data provided by manually invoking it, a payload from
// API Gateway, an S3 putObject event or an SNS topic message.
// we are going to create a scheduled lambda function through CloudWatch
// and don't actually use the event data
export default function handler(event, context, callback) {
run()
.then((result) => callback(null, result))
.catch((err) => callback(err))
}
// for async/await
async function run() {
// create webpack config from latest props
const config = await createWebpackConfig()
// compile with webpack
const files = await compile(config)
// upload files to s3
await Promise.all(files.map(upload))
// invalidate cache
const invalidation = await invalidate()
return invalidation
}
// compiles the provided config with webpack
// returns the build files
async function compile(config) {
// initialize compiler
const compiler = webpack(config)
// initialize in-memory filestystem
const fs = new MemoryFileSystem()
// tell webpack to output to the in-memory filesystem
compiler.outputFileSystem = fs
// run the compiler
const compile = promisify(compiler.run, { context: compiler })
const stats = await compile()
// error will be visible from the Lambda function console
if (stats.hasErrors())
throw new Error(`Compiler error: ${stats.toJson().errors[0]}`)
// returns a list of file names, their content type and contents
const files = fs.readdirSync(config.output.path).map((name) => ({
name,
type: mime.lookup(name),
contents: fs.readFileSync(path.resolve(config.output.path, name))
}))
return files
}
// upload a file to the S3 bucket
async function upload(file) {
const params = {
Bucket: process.env.S3_BUCKET,
ACL: 'public-read',
Key: file.name,
ContentType: file.type,
Body: file.contents
}
return s3.putObject(params).promise()
}
// create a cloudfront invalidation
async function invalidate() {
const params = {
DistributionId: process.env.CF_DISTRIBUTION,
InvalidationBatch: {
// unique id of the invalidation
CallerReference: `${+(new Date())}`,
Paths: {
Quantity: 1,
// invalidates the entire S3 bucket
Items: ['/*']
}
}
}
return cloudfront.createInvalidation(params).promise()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment