Edgio
Edgio

Connectors

Connector packages help build and run your app within Edgio. When you run 0 init, Edgio CLI detects the framework used by your app and installs the corresponding connector package. For example, if you use Next.js, @layer0/next will be installed. If no connector package exists for the framework that you use, you can still deploy to Edgio by implementing the connector interface directly in your app.

Writing a connector

A Edgio connector consists of four entry points:

  • init.js - Called when the user runs 0 init, adding resources to the project necessary for deploying on Edgio. May also modify existing files with the project.
  • dev.js - Called when the user runs 0 dev to run their app in development mode.
  • build.js - Called when the user runs 0 build or 0 deploy. Builds the application, copying resources into the .layer0 directory, which is ultimately zipped and uploaded to Edgio.
  • prod.js - Starts the application server in Edgio cloud’s serverless environment.

These files should be placed in the root directory of your connector package.

init.js

Called when the user runs 0 init. This entry point adds resources to the project necessary for deploying on Edgio. It may also modify existing files within the project.

Optional, if not provided, 0 init will add a default router and layer0.config.js to the user’s project.

Example:

JavaScript
1/* istanbul ignore file */
2const { join } = require('path')
3const { DeploymentBuilder } = require('@layer0/core/deploy')
4
5/**
6 * Called when the user runs 0 init.
7 */
8export default async function init() {
9 new DeploymentBuilder(process.cwd())
10 // Copy files from the default-app directory within the connector package.
11 // These typically include the routes.js file and layer0.config.js. Typescript alternatives are often provided.
12 .addDefaultAppResources(join(__dirname, 'default-app'))
13
14 // Adds 0:* scripts to package.json
15 .addDefaultEdgioScripts()
16}

The default-app directory typically contains the following files:

1/(connector-root)
2 /default-app
3 /all # resources to be added to both JavaScript and TypeScript projects
4 layer0.config.js # a default layer0.config.js file
5 /js # resources to be added to projects that do not use TypeScript
6 routes.js # a JavaScript implementation of the default routes file
7 /ts # resouces to be added to projects that use TypeScript
8 routes.ts # a TypeScript implementation of the default routes file

Additional files can be added beyond the ones listed above. They will be copied into the root directory of the user’s application.

dev.js

Called when the user runs 0 dev. This entry point is responsible for starting the user’s application in development mode. The @layer0/core library provides a createDevServer function to help with this.

Optional, if not provided, 0 dev will simply start Edgio in local development mode, but will not start a framework application server.

Example:

JavaScript
1const { createDevServer } = require('@layer0/core/dev')
2
3module.exports = function() {
4 return createDevServer({
5 // All console output from your app will be prefixed with this label
6 label: 'Sapper',
7
8 // The command to start your app in dev mode
9 command: () => 'npx sapper dev',
10
11 // Once your app's console output has matched all of the following patterns, the "Edgio ready on ..." message will be displayed
12 ready: [/listening on/i],
13
14 // A function that is called with every line of output from your app. Return true to show that line to the user, false to hide it.
15 // Many connectors use this to hide lines like "Next.js ready on http://localhost:3001", which might confuse the user as to
16 // which URL to use when testing their app behind Edgio.
17 filterOutput: line => !line.match(/some pattern/),
18 })
19}

build.js

Exports a function that is called when you run 0 build. It is responsible for constructing the bundle that is deployed to the Edgio cloud. This function typically uses @layer0/core/deploy/DeploymentBuilder to stage the exploded bundle in the .layer0 directory.

Optional, and not needed in most cases. The 0 build command automatically creates a bundle that includes all static assets referenced in your routes file as well as the prod entry point mentioned above.

Example:

JavaScript
1const { DeploymentBuilder } = require('@layer0/core/deploy')
2const FrameworkBuildError = require('@layer0/core/errors/FrameworkBuildError')
3
4export default async function build({ skipFramework }) {
5 const builder = new DeploymentBuilder(appDir)
6 builder.clearPreviousBuildOutput()
7
8 if (!skipFramework) {
9 // run the sapper build
10 try {
11 await builder.exec('npx sapper build')
12 } catch (e) {
13 // this lets the user know that the build error was within their application code, not their Edgio router or configuration.
14 throw new FrameworkBuildError('Sapper')
15 }
16 }
17
18 builder
19 // optionally add some file required by the app at runtime. This is equivalent to setting the includeFiles config in layer0.config.js
20 .addJSAsset('path/to/file/in/project')
21
22 // build the Edgio deployment bundle in the .layer0 directory
23 await builder.build()
24}

prod.js

Edgio runs your application in its serverless cloud by proxying requests to your framework’s application server, which it expects to be running on a specific port. The prod.js entry point exports a function that is called when a new serverless function is provisioned. It is responsible for starting your app on the provided port so that it can receive requests from Edgio.

Optional. This entry point is only needed if your app uses server-side rendering or calls the renderWithApp method on ResponseWriter.

For example:

JavaScript
1module.exports = async function prod(port) {
2 process.env.PORT = port.toString()
3
4 // Most frameworks export some kind of express server or other http listener. Your prod script
5 // just needs to start it and bind it to the provided port. In the case of Sapper, the way to do
6 // this is to set the PORT environment variable and run the provided server script
7 require('./__sapper__/build/server/server')
8}

Note that the prod entry point cannot have any external dependencies. If your prod entry point imports any non-native node modules, you’ll need to bundle it with something like webpack or rollup before publishing your package.

Here is an example webpack config:

JavaScript
1// webpack.config.js
2module.exports = {
3 target: 'node',
4 entry: {
5 prod: './src/prod.js',
6 },
7 mode: 'production',
8 resolve: {
9 extensions: ['.js'],
10 },
11 output: {
12 filename: '[name].js',
13 path: './dist',
14 libraryTarget: 'umd',
15 },
16}

Testing your connector locally before publishing it to NPM

To test your connector locally without publishing it to NPM:

  1. Use npm link, yarn link or yalc add to add the local connector package as a project dependency.
  2. Create an layer0.config.js file in the root directory of your project.
  3. Set the connector property to name of the connector package.

Now 0 init, 0 dev, 0 build, and 0 deploy commands will use the entry points in the connector, and your prod.js entrypoint will be used to serve requests in the Edgio cloud.

Implementing a connector directly within your project

If your project uses a framework that isn’t supported by one of the official connector packages, you can still deploy to Edgio by implementing your own connector directly within your project. To do so:

  1. Create a directory for your connector.
  2. Implement the entry points listed above.
  3. Create an layer0.config.js file in the root directory of your project.
  4. Set the connector property to the relative path to the directory containing the connector

Example project structure:

Directory
1|—— my-project
2 | layer0 # reference this directory in the connector property in layer0.config.js
3 | dev.js
4 | prod.js
5 | build.js
6 | layer0.config.js
7 ... other source files and directories ...

Example layer0.config.js:

JavaScript
1module.exports = {
2 connector: './layer0', // use the local connector located in layer0 directory
3}

Once the connector is in place, 0 dev, 0 build, and 0 deploy commands will use the entry points in the connector, and your prod.js entrypoint will be used to serve requests in the Edgio cloud.