Skip to main content

Frontend Runtime Environment

You can deploy frontend apps (like websites) to Cloud Engine. For apps built with frameworks like React and Vue, their build processes can be run on Cloud Engine so you don’t have to clutter your Git repositories with production builds or set up additional CI environments. With Cloud Engine, you can easily bind custom domains to your app, set up auto-renewal for SSL certificates, and enable HTTPS redirects. These features help you reduce the time spent on deploying and maintaining your app.

info

This article serves as an introduction to Cloud Engine’s frontend runtime environment. For features provided by the Cloud Engine platform, see Cloud Engine Platform Features.

If your project has a file named static.json or index.html under its root directory, Cloud Engine will identify it as a frontend project. When you deploy your project, Cloud Engine will build it with the Node.js runtime environment and automatically start an HTTP server with serve.

Getting Started

Most frontend scaffolds can be deployed to Cloud Engine with little to no configurations. Consider using them if you plan to create a new project.

create-react-app provides out-of-the-box toolchains that automatically set up build tools for your React project so you can focus on development:

npx create-react-app react-for-engine --use-npm

Then navigate to the project’s directory (react-for-engine in the example above) and create a configuration file named static.json that rewrites non-existing URLs to index.html. This allows your single-page application to use its own frontend router (like react-router):

static.json
{
"public": "build",
"rewrites": [{ "source": "**", "destination": "/index.html" }]
}

Then create a file named leanengine.yaml and specify the build command in it:

leanengine.yaml
build: npm run build

The build process can be run on Cloud Engine so you don’t have to include a production build in your Git repository or set up additional CI environments.

Deploy to Cloud Engine

Run the following command to deploy your project to the production environment:

lean deploy --prod

Configure Node.js Version

You can specify the version of Node.js by setting engines.node in package.json:

package.json
{
"engines": {
"node": "16.x"
}
}

You can set it to * to stick to the latest (current) version.

note
For newly created apps, if you don’t specify a Node.js version, the latest stable (LTS) version will be used. For apps created before 9/2/2021, Node.js `0.12` will be used by default to ensure compatibility.

Install Dependencies (package.json)

Cloud Engine will automatically install dependencies according to the package.json in your project:

package.json
{
"dependencies": {
"leancloud-storage": "^3.11.0",
"leanengine": "^3.3.2"
},
"devDependencies": {
"nodemon": "^1.18.7"
}
}

While installing dependencies, Cloud Engine will trigger the life cycle scripts of npm, such as postinstall and prepare.

note

If your project contains package-lock.json, Cloud Engine will install dependencies with npm ci (requires Node.js 10 or higher). Otherwise, Cloud Engine will install dependencies with npm install --production, which means that dependencies listed under devDependencies will not be installed.

note

If your project contains yarn.lock, Cloud Engine will install dependencies with yarn (requires Node.js 4.8 or higher). To use npm instead of Yarn, add yarn.lock into .gitignore (if deploying with Git) or .leanignore (if deploying with the CLI). Since yarn.lock contains the URLs for downloading dependencies, please carefully choose the registry for your project, or you may experience increased build time.

Since Cloud Engine installs dependencies on the server side, the CLI won’t upload node_modules by default. If you’re deploying with Git, you should include node_modules in .gitignore so it won’t be tracked by Git.

Configure serve

To customize the behavior of serve, create a file named static.json under the root directory of your project.

static.json
{
"public": "build", // Start the website from the `build` directory rather than the root directory
"rewrites": [
{ "source": "**", "destination": "/index.html" } // Redirect all non-existing URLs to `index.html` (applicable to most single-page applications)
]
}

See serve-handler · Options for more options and usages of serve.

Customize Build Process

Cloud Engine uses the default commands of each language to complete the build process. You can override these commands by editing leanengine.yaml.

Overriding Command for Execution With run

leanengine.yaml
run: $(npm bin)/serve -c static.json -l ${LEANCLOUD_APP_PORT}

You can use shell syntax here for purposes like accessing environment variables.

Overriding Command for Installing Dependencies With install

You can override the default command for installing dependencies (like npm install) or run additional commands before or after installing dependencies.

leanengine.yaml
install: npm

Most runtimes have their default commands for installing dependencies. You can refer to the default command with {use: 'default'}:

leanengine.yaml
install:
- { use: "default" }
- npm run install-additional

When installing dependencies, only the dependency lists (like package.json) will be loaded into the build directory. To load additional files, use require:

leanengine.yaml
install:
- require:
- frontend/package.json
- frontend/package-lock.json
- cd frontend && npm ci

Overriding Command for Building With build

leanengine.yaml
build: npm run build

When building your project, all the files in your project will be loaded into the build directory.

You can specify multiple pieces of commands with an array. You can use shell syntax here as well:

leanengine.yaml
build:
- echo 'building'
- NODE_ENV=production $(npm bin)/webpack

Certain runtimes have their default build commands. You can refer to these commands with {use: 'default'}.

Build Logs

By default, the logs generated during the build process won’t be printed to the console. If the build process fails, the logs from the last completed step will be printed to the console.

To print the complete build log for debugging, check Print build logs if you are deploying from the dashboard or add --options 'printBuildLogs=true' if you are deploying with the CLI.

Cloud Environment

Custom Domains

Projects deployed to Cloud Engine can only be accessed with domains configured. You can bind domains by going to Dashboard > LeanEngine > Your group > Settings > Domains.

If you bind a domain that starts with stg- (e.g., stg-api.example.com), it will be assigned to the staging environment automatically.

Load Balancer and CDN

All HTTP and HTTPS requests sent to Cloud Engine will go through a load balancer that deals with chores including HTTPS encryption, HTTPS redirection, and response compression. You won’t have to implement features for handling these tasks yourself for the programs hosted on Cloud Engine. Meanwhile, the load balancer brings the following restrictions that your program cannot bypass:

  • Paths starting with /.well-known/acme-challenge/ are used by Cloud Engine to automatically renew certificates. Requests sent to these paths won’t be forwarded to your program.
  • The size of a request header (URL and headers) should be within 64K and each line of the request header should be within 8K.
  • The size of a request (for uploading files) should be within 100M.
  • The timeout for connecting or waiting for a response is 60 seconds.

HTTPS Redirect

When you bind a custom Cloud Engine domain, you can enable Force HTTPS to have the load balancer redirect HTTP requests to HTTPS while keeping the paths.

caution

Force HTTPS won’t work properly if CDN is enabled. You’ll still need to implement redirect in your project’s code.

CDN Caching

If you resolve your custom domain to the CDN (including the shared domain provided by Cloud Engine), the CDN will cache the responses for the requests it has received. There are some default rules for caching followed by the CDN.

The CDN will cache the response if:

  • The response header contains Last-Modified (this indicates that the resource requested is static; for HTML files, they will be cached for at most 60 seconds).

The CDN will not cache the response if:

  • There is an error with the response (not 2xx).
  • The request is not idempotent (like a POST request).
  • The response header doesn’t contain Last-Modified (this often indicates that the resource requested is dynamic).

The age of the cache for a given file will depend on the file type and the value of the Last-Modified header. The less frequently the file gets modified, the longer the file gets cached. You can override the default behavior by configuring Cache-Control and the CDN will try its best to follow your configurations. For example:

  • You can use Cache-Control: no-cache to prevent the response from being cached.
  • You can use Cache-Control: max-age=3600 to specify the age of the cache (here we set it to be 1 hour).
info

To prevent your application from being affected by the caching mechanism, consider enabling dedicated IP. You can learn more about the differences between CDN and dedicated IP on Binding Your Domains § Cloud Engine Domains.

Timezone

The server side uses Beijing Time (UTC+8).