-
Notifications
You must be signed in to change notification settings - Fork 34
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
See changesets and README for full details. --- `skuba node` runs a TypeScript file; it's like a one-off `skuba start`. Unlike start, it gives you a REPL when you omit the command line entry point rather than falling back to the entry point in `package.json`. This PR also adds some secret sauce to automatically register the `src` module alias when you're running under `skuba node` or `skuba start`. This means that you only need a runtime module alias resolver like `import skuba-dive/register` at the top of production entry points; local scripts can be run with little fanfare using the skuba commands. --- Notes: - I considered calling the command `skuba exec`, but that sounds a bit awkward when it supports opening a REPL. - You may be wondering why don't we just use `tsconfig-paths`. This is tempting but I'm not convinced that we should depend on reading configuration out of `tsconfig.json` at runtime. This can be confusing given TypeScript is generally considered a compile-time concern, and our own templates only keep `lib` and `node_modules` in the runtime Docker image. - Diving into this has uncovered that the `@babel/node` REPL is pretty unusable with modern JavaScript/TypeScript. See the README for more.
- Loading branch information
Showing
14 changed files
with
290 additions
and
19 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
--- | ||
'skuba': patch | ||
--- | ||
|
||
**start:** Improve support for non-HTTP server entry points | ||
|
||
You can now run arbitrary TypeScript files without them exiting on a `You must export callback or requestListener` error. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
--- | ||
'skuba': minor | ||
--- | ||
|
||
**node:** Add command | ||
|
||
`skuba node` lets you run a TypeScript source file, or open a REPL if none is provided: | ||
|
||
- `skuba node src/some-cli-script.ts` | ||
- `skuba node` | ||
|
||
This automatically registers a `src` module alias for ease of local development. For example, you can run a prospective `src/someLocalCliScript.ts` without having to register a module alias resolver: | ||
|
||
```typescript | ||
// This `src` module alias just works under `skuba node` and `skuba start` | ||
import { rootLogger } from 'src/framework/logging'; | ||
``` | ||
|
||
```bash | ||
yarn skuba node src/someLocalCliScript | ||
``` | ||
|
||
If you use this alias in your production code, | ||
your production entry point(s) will need to import a runtime module alias resolver like [`skuba-dive/register`](https://github.com/seek-oss/skuba-dive#register). | ||
For example, your `src/app.ts` may look like: | ||
|
||
```typescript | ||
// This must be imported directly within the `src` directory | ||
import 'skuba-dive/register'; | ||
|
||
// You can use the `src` module alias after registration | ||
import { rootLogger } 'src/framework/logging'; | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
'skuba': patch | ||
--- | ||
|
||
**start:** Support `src` module alias |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
'skuba': patch | ||
--- | ||
|
||
**start:** Support source maps |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
import path from 'path'; | ||
|
||
import getPort from 'get-port'; | ||
import parse from 'yargs-parser'; | ||
|
||
import { unsafeMapYargs } from '../utils/args'; | ||
import { createExec } from '../utils/exec'; | ||
import { isBabelFromManifest } from '../utils/manifest'; | ||
|
||
const parseArgs = () => { | ||
const { | ||
_: [entryPointArg], | ||
...yargs | ||
} = parse(process.argv.slice(2)); | ||
|
||
const entryPoint = typeof entryPointArg === 'string' ? entryPointArg : null; | ||
|
||
const inspect = unsafeMapYargs({ | ||
inspect: yargs.inspect as unknown, | ||
'inspect-brk': yargs['inspect-brk'] as unknown, | ||
}); | ||
|
||
return { | ||
entryPoint, | ||
inspect, | ||
}; | ||
}; | ||
|
||
export const node = async () => { | ||
const args = parseArgs(); | ||
|
||
const [port, isBabel] = await Promise.all([getPort(), isBabelFromManifest()]); | ||
|
||
const exec = createExec({ | ||
env: isBabel ? undefined : { __SKUBA_REGISTER_MODULE_ALIASES: '1' }, | ||
}); | ||
|
||
if (isBabel) { | ||
return exec( | ||
'babel-node', | ||
...args.inspect, | ||
'--extensions', | ||
['.js', '.json', '.ts'].join(','), | ||
'--require', | ||
path.join('skuba', 'lib', 'register'), | ||
...(args.entryPoint === null | ||
? [] | ||
: [ | ||
path.join(__dirname, '..', 'wrapper.js'), | ||
args.entryPoint, | ||
String(port), | ||
]), | ||
); | ||
} | ||
|
||
return exec( | ||
'ts-node', | ||
...args.inspect, | ||
'--require', | ||
path.join('skuba', 'lib', 'register'), | ||
'--transpile-only', | ||
...(args.entryPoint === null | ||
? [] | ||
: [path.join(__dirname, '..', 'wrapper'), args.entryPoint, String(port)]), | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,14 @@ | ||
/** | ||
* Entry point for the Node.js development API. | ||
* | ||
* This is where skuba imports point to: | ||
* | ||
* ```typescript | ||
* import { Net } from 'skuba'; | ||
* | ||
* const { Net } = require('skuba'); | ||
* ``` | ||
*/ | ||
|
||
export * as Jest from './api/jest'; | ||
export * as Net from './api/net'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
/** | ||
* Local hook for module alias and source map support. | ||
* | ||
* This is only intended for use with `skuba node` and `skuba start`, | ||
* where it is loaded before the entry point provided by the user: | ||
* | ||
* ```bash | ||
* ts-node --require skuba/lib/register src/userProvidedEntryPoint | ||
* ``` | ||
* | ||
* These commands make use of development tooling like `ts-node`, | ||
* which may not exactly match the runtime characteristics of `node`. | ||
* Production code should be compiled down to JavaScript and run with Node.js. | ||
* | ||
* For equivalent module alias and source map support in production, | ||
* import the `skuba-dive/register` hook. | ||
* | ||
* {@link https://github.com/seek-oss/skuba-dive#register} | ||
*/ | ||
|
||
import 'source-map-support/register'; | ||
|
||
import path from 'path'; | ||
|
||
import { addAlias } from 'module-alias'; | ||
import readPkgUp from 'read-pkg-up'; | ||
|
||
import { log } from './utils/logging'; | ||
|
||
const registerModuleAliases = () => { | ||
if (!process.env.__SKUBA_REGISTER_MODULE_ALIASES) { | ||
return; | ||
} | ||
|
||
// This may pick the wrong `package.json` if we are in a nested directory. | ||
// Consider revisiting this when we decide how to better support monorepos. | ||
const result = readPkgUp.sync(); | ||
|
||
if (typeof result === 'undefined') { | ||
log.warn(log.bold('src'), '→', 'not found'); | ||
|
||
return; | ||
} | ||
|
||
const root = path.dirname(result.path); | ||
const src = path.join(root, 'src'); | ||
|
||
log.subtle(log.bold('src'), '→', src); | ||
|
||
addAlias('src', src); | ||
}; | ||
|
||
registerModuleAliases(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,6 +19,7 @@ export const COMMAND_LIST = [ | |
'help', | ||
'init', | ||
'lint', | ||
'node', | ||
'release', | ||
'start', | ||
'test', | ||
|
Oops, something went wrong.