Skip to content

Commit

Permalink
Merge pull request #17 from serverless/add-custom-scripts-plugin
Browse files Browse the repository at this point in the history
feat(web): add custom scripts plugin
  • Loading branch information
eahefnawy authored Oct 16, 2024
2 parents 3ce5c0a + 03e6fb9 commit 0619201
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 12 deletions.
9 changes: 1 addition & 8 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions website/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@
"name": "website",
"version": "1.0.0",
"main": "index.js",
"type": "module",
"license": "MIT",
"dependencies": {
"express": "^4.19.2",
"serverless-http": "^3.2.0"
},
"devDependencies": {
"serverless-domain-manager": "^7.4.0",
"serverless-plugin-scripts": "^1.0.2"
"serverless-domain-manager": "^7.4.0"
}
}
83 changes: 83 additions & 0 deletions website/scripts.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import { execSync } from "child_process";

/**
* This is a custom Serverless Framework Plugin that allows you to
* define and run custom scripts in your serverless.yml file, similar to npm scripts.
* For more information on creating custom plugins, see the documentation:
* https://www.serverless.com/framework/docs/guides/plugins/creating-plugins
*
* In this AI example, we need to run vite build script before deploying the website service.
* So we built this quick plugin, and loaded it in the serverless.yml file.
*/

class Scripts {
constructor(serverless, options, utils) {
this.serverless = serverless;
this.options = options; // CLI options are passed to the plugin
this.utils = utils; // Helper logging functions are passed to the plugin

this.commands = {};
this.hooks = {};

this.defineCommands();
this.defineHooks();
}

getConfig() {
const service = this.serverless.service;
return service.custom && service.custom.scripts;
}

defineCommands() {
const config = this.getConfig();
const commands = config && config.commands;
if (!commands) return;

for (const name of Object.keys(commands)) {
if (!this.commands[name]) {
this.commands[name] = { lifecycleEvents: [] };
}
this.commands[name].lifecycleEvents.push(name);

this.hooks[`${name}:${name}`] = this.runCommand.bind(this, name);
}
}

defineHooks() {
const config = this.getConfig();
const hooks = config && config.hooks;
if (!hooks) return;

for (const name of Object.keys(hooks)) {
this.hooks[name] = this.runHook.bind(this, name);
}
}

runCommand(name) {
const commands = this.getConfig().commands;
const command = commands[name];
this.execute(command);
}

runHook(name) {
const hooks = this.getConfig().hooks;
const hook = hooks[name];
this.execute(hook);
}

execute(command) {
// By default, only show stderr in the terminal
// So that you can see any build errors that may occur
let stdio = ["ignore", "ignore", "inherit"];

// But in verbose or debug mode, we show all output
if (this.options.verbose || this.options.debug) {
stdio = "inherit";
}

// Execute the command/script in a child service
execSync(command, { stdio });
}
}

export default Scripts;
6 changes: 4 additions & 2 deletions website/serverless.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ provider:
runtime: nodejs20.x

plugins:
- serverless-plugin-scripts
- serverless-domain-manager
- serverless-domain-manager # Load the community plugin for custom domains installed with npm
- ./scripts # Load our custom scripts plugin

build:
esbuild: true
Expand All @@ -25,6 +25,8 @@ custom:
apiType: http
autoDomain: true
enabled: ${param:customDomainNameEnabled}

# This property is expected by our custom scripts plugin.
scripts:
hooks:
# This hook builds the React App. It sets the environment variables for
Expand Down

0 comments on commit 0619201

Please sign in to comment.