Advanced TypeScript Tooling at Scale @felixfbecker StackOverflow - - PowerPoint PPT Presentation

advanced typescript tooling at scale
SMART_READER_LITE
LIVE PREVIEW

Advanced TypeScript Tooling at Scale @felixfbecker StackOverflow - - PowerPoint PPT Presentation

Advanced TypeScript Tooling at Scale @felixfbecker StackOverflow developer survey 2018 % of npm users using a transpiler, npm developer survey 2018 What makes TypeScript great? What makes TypeScript great? What makes TypeScript great?


slide-1
SLIDE 1

Advanced TypeScript Tooling at Scale

@felixfbecker

slide-2
SLIDE 2

StackOverflow developer survey 2018

slide-3
SLIDE 3

% of npm users using a transpiler, npm developer survey 2018

slide-4
SLIDE 4

What makes TypeScript great? What makes TypeScript great? What makes TypeScript great?

slide-5
SLIDE 5

Tooling

slide-6
SLIDE 6

TypeScript architecture

slide-7
SLIDE 7

TSServer protocol

Editor tsserver

{ "command": "definition", "seq": 1, "type": "request", "arguments": { "file": "/foo.ts", "line": 17, "offset": 10 } } { "seq": 1, "type": "response", "command": "definition", "request_seq": 6, "success": true, "body": [ { "file": "/bar.ts", "start": { "line": 17, "offset": 10 }, "end": { "line": 17, "offset": 16 } } ] }

STDIN STDOUT

slide-8
SLIDE 8
slide-9
SLIDE 9

We can do that!

WebSocket

wss://typescript.sourcegraph.com

slide-10
SLIDE 10

WebSocket

slide-11
SLIDE 11

LSP vs TSServer protocol

  • Almost the same!
  • Except LSP

○ Is language-agnostic ○ Uses the JSON-RPC standard ○ Has simpler request cancellation ○ Uses URIs instead of file paths

{ "command": "definition", "seq": 1, "type": "request", "arguments": { "file": "/foo.ts", "line": 17, "offset": 10 } } { "jsonrpc": "2.0", "id": 1, "method": "textDocument/definition", "params": { "textDocument": { "uri": "file:///foo.ts" }, "position": { "line": 17, "character": 10 } } }

slide-12
SLIDE 12

WebSocket

{ "jsonrpc": "2.0", "id": 1, "method": "initialize", "params": { "rootUri": "https://sourcegraph.com/github.com/nestjs/nest/-/raw/" } }

slide-13
SLIDE 13

HTTP root URLs

GET https://sourcegraph.com/github.com/nestjs/nest/-/raw/packages/core/index.ts HEAD https://sourcegraph.com/github.com/nestjs/nest/-/raw/packages/core/notexist.ts GET https://sourcegraph.com/github.com/nestjs/nest/-/raw/ Accept: application/x-tar

slide-14
SLIDE 14

WebSocket HTTP

{ "jsonrpc": "2.0", "id": 1, "method": "initialize", "params": { "rootUri": "https://sourcegraph.com/github.com/nestjs/nest/-/raw/" } }

slide-15
SLIDE 15
slide-16
SLIDE 16
slide-17
SLIDE 17
slide-18
SLIDE 18

Dependencies

slide-19
SLIDE 19

Type declaration files

export function insertionSort(array: number[]): number[] { let current: number; let j: number; for (let i = 1; i < array.length; i += 1) { current = array[i]; j = i - 1; while (j >= 0 && array[j] - current > 0) { array[j + 1] = array[j]; j -= 1; } array[j + 1] = current; } return array; } export function insertionSort(array: number[]): number[];

insertionSort.ts insertionSort.d.ts

slide-20
SLIDE 20

HTTP npm install

slide-21
SLIDE 21

Dependencies

slide-22
SLIDE 22

Cross-repository code intelligence

{ "command": "definition", "seq": 1, "type": "request", "arguments": { "file": "/foo.ts", "line": 17, "offset": 10 } } { "seq": 1, "type": "response", "command": "definition", "request_seq": 6, "success": true, "body": [ { "file": "/node_modules/bar/index.d.ts", "start": { "line": 17, "offset": 10 }, "end": { "line": 17, "offset": 16 } } ] }

tsserver

slide-23
SLIDE 23

Where is the source of the package?

/node_modules/foo/package.json { "name": "foo", "repository": { "type": "git", "url": "https://github.com/foo/foo", "directory": "packages/foo" }, "gitHead": "2d80b06460d26dbbb88ce271c60cfef94ddb5824" }

slide-24
SLIDE 24

Declaration Maps

foo.d.ts foo.ts foo.d.ts.map

slide-25
SLIDE 25

foo.js foo.ts foo.js.map { "file": "foo.js", "sources": ["../src/foo.ts"], "mappings": "AAAA,OAAO,6BAA6B,CAAA;AAMpC,OAAO,IAAI,CAAA" }

slide-26
SLIDE 26

Declaration Maps

foo.d.ts foo.ts foo.d.ts.map

export function insertionSort(array: number[]): number[] { let current: number; let j: number; for (let i = 1; i < array.length; i += 1) { current = array[i]; j = i - 1; while (j >= 0 && array[j] - current > 0) { array[j + 1] = array[j]; j -= 1; export function insertionSort(array: number[]): number[];

slide-27
SLIDE 27
slide-28
SLIDE 28

What about the inverse?

slide-29
SLIDE 29

Cross-repository find-references

?

slide-30
SLIDE 30
slide-31
SLIDE 31

{ "name": "foo", "repository": { "type": "git", "url": "https://github.com/foo/foo" } }

slide-32
SLIDE 32

"rootUri": "https://sourcegraph.com/github.com/some/dependent/-/raw/" { "jsonrpc": "2.0", "id": 1, "method": "textDocument/references", "params": { "textDocument": { "uri": "https://sourcegraph.com/github.com/foo/foo/-/raw/src/index.ts" }, "position": { "line": 17, "character": 10 } } }

D

slide-33
SLIDE 33

GET https://sourcegraph.com/github.com/foo/foo/-/raw/package.json ⬤ 200 OK { "name": "foo" } find **/node_modules/foo/**/*.d.ts.map { "file": “index.d.ts", "sources": ["../src/index.ts"], "mappings": "AAAA,OAAO,6BAA6B,CAAA;AAMpC,OAAO,IAAI,CAAA" }

  • 1. Find out package name
  • 2. Find declaration map that points to source file we try to find references for

GET https://sourcegraph.com/github.com/foo/foo/-/raw/src/package.json ⬤ 404 Not Found

slide-34
SLIDE 34

dist/index.d.ts src/index.ts dist/index.d.ts.map

export function insertionSort(array: number[]): number[] { let current: number; let j: number; for (let i = 1; i < array.length; i += 1) { current = array[i]; j = i - 1; while (j >= 0 && array[j] - current > 0) { array[j + 1] = array[j]; j -= 1; export function insertionSort(array: number[]): number[];

  • 3. Use declaration map to map position in source file to position in declaration file
slide-35
SLIDE 35
slide-36
SLIDE 36

Last words

  • Everything shown is live in production!

○ https://sourcegraph.com ○ On GitHub: Sourcegraph browser extension

  • Everything shown is open source!

https://github.com/sourcegraph/sourcegraph-typescript

slide-37
SLIDE 37

Thanks for listening

AMA