Skip to content

Commit

Permalink
add example with programmatic build (#207)
Browse files Browse the repository at this point in the history
* add example with programmatic build

* fix package name
  • Loading branch information
maxbeatty authored and rauchg committed Dec 31, 2018
1 parent 0b8395e commit c813b07
Show file tree
Hide file tree
Showing 9 changed files with 276 additions and 0 deletions.
34 changes: 34 additions & 0 deletions examples/programmatic/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Programmatic

This example shows how you can programmatically build multiple bundles. The build script (`scripts/build.js`) finds `.js` files in `src/routes/`, builds each one with `ncc`, and then writes the resulting file and its sourcemap to a new directory in `dist/`.

## How to use

Within this directory, run `yarn` to install dependencies.

To run a development server with `ncc`, run `yarn dev`. You can then test the routes:

- [http://localhost:3000/cat]()
- [http://localhost:3000/dog]()
- [http://localhost:3000/fox]()

To build all of the bundles, run `yarn build`.

```
❯ yarn build
yarn run v1.12.3
$ node ./scripts/build.js
✓ dist/dog/index.js (289.17KB)
✓ dist/dog/index.map.js (234.37KB)
✓ dist/fox/index.js (289.18KB)
✓ dist/fox/index.map.js (234.43KB)
✓ dist/cat/index.js (289.17KB)
✓ dist/cat/index.map.js (234.43KB)
✨ Done in 2.79s.
```

Each subdirectory of `dist/` could be deployed to [a serverless environment](https://zeit.co/examples/nodejs/) to run independent of each other!

## Thanks

Special thanks to [random.cat](http://random.cat/), [AdenFlorian/random.dog](https://github.com/AdenFlorian/random.dog), and [xinitrc-dev/randomfox.ca](https://github.com/xinitrc-dev/randomfox.ca) for their open APIs to make this example more fun and realistic!
19 changes: 19 additions & 0 deletions examples/programmatic/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"name": "programmatic",
"private": true,
"version": "0.0.0",
"license": "MIT",
"scripts": {
"dev": "ncc run ./src/__dev__.js --watch",
"build": "node ./scripts/build.js"
},
"dependencies": {
"node-fetch": "^2.3.0"
},
"devDependencies": {
"@zeit/ncc": "latest",
"bytes": "^3.0.0",
"glob": "^7.1.3",
"mkdirp": "^0.5.1"
}
}
58 changes: 58 additions & 0 deletions examples/programmatic/scripts/build.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
const { statSync, writeFileSync } = require("fs");
const { basename, relative, resolve } = require("path");
const { promisify } = require("util");

const bytes = require("bytes");
const glob = promisify(require("glob"));
const mkdirp = promisify(require("mkdirp"));
const ncc = require("@zeit/ncc");

// output directories
const DIST_DIR = resolve(__dirname, "../dist");
const CACHE_DIR = resolve(DIST_DIR, ".cache");

// options for ncc with mix of defaults and customization
const options = {
// provide a custom cache path
cache: CACHE_DIR,
// externals to leave as requires of the build
externals: [],
minify: true,
sourceMap: true,
watch: false // default
};

// write file to disk and print final size
function write(file, data) {
writeFileSync(file, data);

console.log(
`✓ ${relative(__dirname + "/../", file)} (${bytes(statSync(file).size)})`
);
}

// build file with its dependencies using ncc
async function build(file) {
const { code, map, assets } = await ncc(file, options);

if (Object.keys(assets).length)
console.error("New unexpected assets are being emitted for", file);

const name = basename(file, ".js");
await mkdirp(resolve(DIST_DIR, name));
write(resolve(DIST_DIR, name, "index.js"), code);
write(resolve(DIST_DIR, name, "index.map.js"), map);
}

async function main() {
// create our output and custom cache directories
await mkdirp(CACHE_DIR);

// find all routes we want to bundle
const files = await glob(resolve(__dirname, "../src/routes/*.js"));

// build all found files
return Promise.all(files.map(build));
}

main();
25 changes: 25 additions & 0 deletions examples/programmatic/src/__dev__.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Development server only intended to be used by `yarn dev`

import { Server, STATUS_CODES } from "http";
import { parse } from "url";

import cat from "./routes/cat";
import dog from "./routes/dog";
import fox from "./routes/fox";

const server = new Server(async (req, res) => {
const { pathname } = parse(req.url);

if (pathname === "/cat") return cat(req, res);
if (pathname === "/dog") return dog(req, res);
if (pathname === "/fox") return fox(req, res);

res.writeHead(404);
res.end(STATUS_CODES[404]);
});

const port = process.env.PORT || 3000;

server.listen(port, () => {
console.log(`Listening for HTTP requests on port ${port}...`);
});
4 changes: 4 additions & 0 deletions examples/programmatic/src/routes/cat.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { animalAPI } from "../utils";

export default (req, res) =>
animalAPI(res, "Cat", "https://aws.random.cat/meow", "file");
4 changes: 4 additions & 0 deletions examples/programmatic/src/routes/dog.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { animalAPI } from "../utils";

export default (req, res) =>
animalAPI(res, "Dog", "https://random.dog/woof.json", "url");
4 changes: 4 additions & 0 deletions examples/programmatic/src/routes/fox.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { animalAPI } from "../utils";

export default (req, res) =>
animalAPI(res, "Fox", "https://randomfox.ca/floof/", "image");
26 changes: 26 additions & 0 deletions examples/programmatic/src/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import fetch from "node-fetch";

export async function animalAPI(res, title, api, key) {
const resp = await fetch(api);
const json = await resp.json();

const body = `
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>${title}</title>
</head>
<body>
<img src="${json[key]}" alt="${title}" />
</body>
</html>
`;

res.writeHead(200, {
"Content-Length": Buffer.byteLength(body),
"Content-Type": "text/html; charset=utf-8"
});

res.end(body);
}
102 changes: 102 additions & 0 deletions examples/programmatic/yarn.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1


"@zeit/ncc@latest":
version "0.8.1"
resolved "https://registry.yarnpkg.com/@zeit/ncc/-/ncc-0.8.1.tgz#f24982591fe0e2a0f2c53e59e533837eddb8b891"
integrity sha512-AFgYOmh8gVRd8Bzkvygvbhdq6DayCc+O++bcGr+TFQcsHLWa6Lx9L55VVGU8sVEJibX/6BkDgcrJFZ3vYbh/ww==

balanced-match@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c=

brace-expansion@^1.1.7:
version "1.1.11"
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==
dependencies:
balanced-match "^1.0.0"
concat-map "0.0.1"

bytes@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048"
integrity sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=

concat-map@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=

fs.realpath@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8=

glob@^7.1.3:
version "7.1.3"
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1"
integrity sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==
dependencies:
fs.realpath "^1.0.0"
inflight "^1.0.4"
inherits "2"
minimatch "^3.0.4"
once "^1.3.0"
path-is-absolute "^1.0.0"

inflight@^1.0.4:
version "1.0.6"
resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=
dependencies:
once "^1.3.0"
wrappy "1"

inherits@2:
version "2.0.3"
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=

minimatch@^3.0.4:
version "3.0.4"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==
dependencies:
brace-expansion "^1.1.7"

minimist@0.0.8:
version "0.0.8"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d"
integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=

mkdirp@^0.5.1:
version "0.5.1"
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903"
integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=
dependencies:
minimist "0.0.8"

node-fetch@^2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.3.0.tgz#1a1d940bbfb916a1d3e0219f037e89e71f8c5fa5"
integrity sha512-MOd8pV3fxENbryESLgVIeaGKrdl+uaYhCSSVkjeOb/31/njTpcis5aWfdqgNlHIrKOLRbMnfPINPOML2CIFeXA==

once@^1.3.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E=
dependencies:
wrappy "1"

path-is-absolute@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18=

wrappy@1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=

0 comments on commit c813b07

Please sign in to comment.