Skip to content
This repository has been archived by the owner on Jun 5, 2021. It is now read-only.

Commit

Permalink
Add an example of Dockerized NodeJS build in TypeScript
Browse files Browse the repository at this point in the history
This should help address #13.
  • Loading branch information
fwouts committed Aug 21, 2018
1 parent e260b79 commit 657f383
Show file tree
Hide file tree
Showing 15 changed files with 536 additions and 0 deletions.
6 changes: 6 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,9 @@ jobs:
cd tests/examples/react-app
yarn install
bazel build ...
- run:
name: Build Dockerized TypeScript Node example
command: |
cd examples/node-typescript-app
bazel build //...
bazel run //services/my-service:image
6 changes: 6 additions & 0 deletions WORKSPACE
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,9 @@ git_repository(
load("@build_bazel_rules_nodejs//:defs.bzl", "node_repositories")

node_repositories(package_json = [])

# See https://github.com/bazelbuild/bazel/issues/2460#issuecomment-362284757
local_repository(
name = "ignore_examples",
path = "./examples",
)
1 change: 1 addition & 0 deletions examples/WORKSPACE
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# See https://github.com/bazelbuild/bazel/issues/2460#issuecomment-362284757
11 changes: 11 additions & 0 deletions examples/node-typescript-app/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package(default_visibility = ["//visibility:public"])

exports_files(["tsconfig.json"])

load("@bazel_javascript//:defs.bzl", "npm_packages")

npm_packages(
name = "packages",
package_json = ":package.json",
yarn_lock = ":yarn.lock",
)
12 changes: 12 additions & 0 deletions examples/node-typescript-app/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Dockerized Node server in TypeScript

This directory contains a Docker image with a Node server built from TypeScript with Bazel.

A few things worth noting:
- `tsconfig.json` must have `allowSyntheticDefaultImports` set to `false`
- We generate source maps and run `node -r source-map-support/register` so error stack traces
match the TypeScript source.
- We don't use any TypeScript aliases, because they will remain as such and confuse Node. This
could be fixed by re-introducing preprocessing which was removed in [d81c2e3](https://github.com/zenclabs/bazel-javascript/commit/d81c2e3f130fe09348952963d58fe560a416e5da).
- We use a symlinked directory to ensure `node_modules` is available to Node.
- `WORKSPACE` needs to be edited to include the remote, not local version of `bazel_javascript`.
49 changes: 49 additions & 0 deletions examples/node-typescript-app/WORKSPACE
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Note: We use a local version of bazel-javascript rules here.
#
# You should remove this and use the remote version below instead.
local_repository(
name = "bazel_javascript",
path = "../..",
)

# git_repository(
# name = "bazel_javascript",
# remote = "https://github.com/zenclabs/bazel-javascript.git",
# tag = <use the latest tag>,
# )

git_repository(
name = "build_bazel_rules_nodejs",
remote = "https://github.com/bazelbuild/rules_nodejs.git",
tag = "0.10.0",
)

load("@build_bazel_rules_nodejs//:defs.bzl", "node_repositories")

node_repositories(
package_json = [],
)

load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")

http_archive(
name = "io_bazel_rules_docker",
sha256 = "5d64414477ffe87b16e248986c0731aee821ea3d626121cfeeec4ef7096812ca",
strip_prefix = "rules_docker-0.5.0",
urls = ["https://github.com/bazelbuild/rules_docker/archive/v0.5.0.tar.gz"],
)

load(
"@io_bazel_rules_docker//container:container.bzl",
"container_pull",
container_repositories = "repositories",
)

container_repositories()

container_pull(
name = "node_alpine_image",
registry = "index.docker.io",
repository = "library/node",
tag = "8.11.3-alpine",
)
9 changes: 9 additions & 0 deletions examples/node-typescript-app/libs/shared-package/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package(default_visibility = ["//visibility:public"])

load("@bazel_javascript//:defs.bzl", "ts_library")

ts_library(
name = "shared-package",
srcs = glob(["**/*.ts"]),
tsconfig = "//:tsconfig.json",
)
3 changes: 3 additions & 0 deletions examples/node-typescript-app/libs/shared-package/greeter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export function greet(name: string): string {
return `Hello, ${name}`;
}
10 changes: 10 additions & 0 deletions examples/node-typescript-app/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"name": "node-typescript-app",
"version": "1.0.0",
"dependencies": {
"@types/koa": "^2.0.46",
"@types/node": "^10.7.1",
"koa": "^2.5.2",
"source-map-support": "^0.5.9"
}
}
11 changes: 11 additions & 0 deletions examples/node-typescript-app/services/base-image/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package(default_visibility = ["//visibility:public"])

load("@io_bazel_rules_docker//container:container.bzl", "container_image", "container_push")

## The Backend Base Image
container_image(
name = "service",
base = "@node_alpine_image//image:image",
stamp = True,
workdir = "/app",
)
37 changes: 37 additions & 0 deletions examples/node-typescript-app/services/my-service/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package(default_visibility = ["//visibility:public"])

load("@io_bazel_rules_docker//container:container.bzl", "container_image", "container_push")

container_image(
name = "image",
base = "//services/base-image:service",
data_path = ".",
directory = "/app",
files = [
"//:packages",
"//services/my-service/server:server_compiled",
],
symlinks = {
"/app/node_modules": "/app/packages_installed_dir/node_modules",
},
cmd = [
"node",
"-r",
"source-map-support/register",
"server/server_compiled/services/my-service/server/server.js",
],
ports = [
"3000",
],
stamp = True,
)

container_push(
name = "publish",
format = "Docker",
image = ":image",
registry = "my.repo.com",
repository = "my-service",
stamp = True,
tag = "{BUILD_USER}",
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package(default_visibility = ["//visibility:public"])

load("@bazel_javascript//:defs.bzl", "ts_library")

ts_library(
name = "server",
srcs = glob(["**/*.ts"]),
tsconfig = "//:tsconfig.json",
deps = [
"//:packages",
"//libs/shared-package",
],
)
15 changes: 15 additions & 0 deletions examples/node-typescript-app/services/my-service/server/server.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import * as Koa from "koa";
import { greet } from "../../../libs/shared-package/greeter";

const app = new Koa();

app.use(async ctx => {
ctx.body = greet("World");
// Just for fun, add a small chance of crashing. This allows us to check whether stack
// traces are readable.
if (Math.random() < 0.1) {
throw new Error("Random crash.");
}
});

app.listen(3000, () => console.log("Server is ready."));
18 changes: 18 additions & 0 deletions examples/node-typescript-app/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"compilerOptions": {
"target": "es2015",
"module": "commonjs",
"moduleResolution": "node",
"declaration": true,
"sourceMap": true,
"strict": true,
"noImplicitAny": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"strictPropertyInitialization": true,
"noImplicitThis": true,
"alwaysStrict": true,
"jsx": "react",
"allowSyntheticDefaultImports": false
}
}
Loading

0 comments on commit 657f383

Please sign in to comment.