docts
DigitalOcean Cli Typescript Serverless (docts
) is a
community-led CLI library which enhances the development experience of
DigitalOcean doctl serverless
when working with Typescript function projects.
Serverless is awesome. The ability to deploy app without worrying about server management and scaling is a massive relief for individuals and small teams.
With serverless, we get the following benefits:
We've seen serverless from other cloud providers:
doctl
is the command-line
tool used to interact with DigitalOcean's APIs including serverless, but after
using it for a while, I find it ... somewhat lacking.
doctl serverless function
When working with Typescript, there is a transpilation step to Javascript
which other supported languages don't have and aside initializing the Typescript
project, the doctl serverless function
interface does not do much locally.
The transpilation of TS to JS makes things a bit tricky for working with Typescript projects. Here's three of the major issues (in my opinion) I've identified:
When you add new functions to your serverless project, you need to manually
add a function
entry your project.yml
.
doctl
sets up Typescript projects, treating each function as independent
projects with package.json
files.
This approach keep functions independent, however in a project with multiple functions which use the same libraries, you have to manage these dependencies independently across all functions.
You can see how this compounds as the number of functions in your serverless project grows.
The nature of the setup means, each function folder must be opened as
a separate folder in your IDE else dependencies will be installed in the
project's package.json
instead of the function's package.json
Owing to the above issues, docts
CLI has the following objectives:
project.yml
.import
statements,
building a dependency graph. From this graph, automatically pick out the
function's dependencies and save in the function's package.json
packages
from src
and generate package.json
with correct
dependencies for each packageInstall the latest version of docts
globally by running the following command
in your terminal.
yarn global add docts-cli
Here's the various features that docts
provides
docts init <project name>
To start a new Digital serverless, run the command above. You'll be asked for the project description, name of author and version number.
docts
uses this information to create the project directory and copy the
template files.
docts fn new <function name>
When you want to add a new serverless function to your project, run the command
above. The function name must be of the
format <package name>/<function name>
.
As an example, to create a function called create
in package todo
, you'd
run docts fn new todo/create
.
docts
automatically updates yourproject.yml
with the function entry
docts fn remove <function name>
To remove a new serverless function to your project, run the command above. You can either remove a single function or an entire package and all its functions.
As an example, for a project structure shown below,
running docts fn remove todo/list
would delete the src/todo/list
folder.
However, running docts fn remove todo
would delete the src/todo
folder.
| src
| todo
| create
- index.ts
| list
- index.ts
docts
automatically updates yourproject.yml
, removing the function or package entry
docts scan
Scans the src/
directory and prints out a map of packages and functions.
# Build project, marking all dependencies as external
docts build
# To include dependencies in bundle, use --include-dependencies, -d option
docts build --include-dependencies dayjs @acme/core
#or
docts build -d dayjs @acme/core
Builds the packages/
directory from src/
which can be deployed
to DigitalOcean's App Platform
app or a Function Namespace
via doctl.
After probing the inner workings of functions and extensive documentation reading, I discovered the constraints that a serverless project needs to meet in order to be deployable on App Platform.
Each function folder under packages/
must have all its import dependencies
within itself.
If a function file imports a module outside the function folder in
src/
, our build process must include all dependencies in the final folder underpackages/
The function folder can contain a single file which exports a name main()
function. If the folder has multiple files, or has dependencies, it must have
a package.json
indicating the entry file as well as dependencies.
With this information, we can kinda see how our build process should look like. Let's see what we need to do here:
node_modules
imports in the function file as well
as all its dependenciespackage.json
which contains the entry
file and its dependenciesAfter shopping around, the module bundler I settled on was Rollup. It's fast, lightweight and has a powerful JS API which handles all our needs.
Ok, now we know how to go about it and what tool to use. Let's outline the build
process of docts
:
packages/
directorysrc/<package-name>/<function-name>/index.ts
index.ts
node_modules/
packages/<package-name>/<function-name>/index.js
package.json
to get their
versionspackage.json
at
packages/<package-name>/<function-name>/package.json
src/
And we are done! At this point we have an App Platform compatible packages/
directory that can be deployed.
The test/
folder contains the unit tests for each CLI functions. The tests are
written with Mocha and Chai
Clone the project and run them using the following command:
yarn test
I created this project to improve the development experience for myself and other devs in the DigitalOcean community. I believe we can collectively improve and extend the project features.
The next major feature is to include a way of testing functions offline before deployment. Any and all contributions from the community are greatly welcome.
1.2.0 (Current)
http
object to DoFunctionArgs
interface (Docs)__ow_*
fields in DoFunctionArgs
interfaceproject.yml
template to '18' instead of '
default' (14)1.1.1
/src/sample/hello/hello.ts
/src/sample/hello/index.ts
1.1.0
Added --include-dependencies
, -d
switch to build
command. This is a
list of dependencies to include in the bundle instead of marking them as
external.
E.g. docts build --include-dependencies dayjs @acme/core