Skip to content

Commit 50ee86b

Browse files
committed
Add TypeScript support.
If `typescript` is installed, add the tsify plugin. If a syntax error occurs in a `.ts` file, recommend installing `typescript`. TODO: Catch and format errors from the typescript compiler.
1 parent f6b981c commit 50ee86b

File tree

8 files changed

+116
-30
lines changed

8 files changed

+116
-30
lines changed

lib/cmd-build.js

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,13 @@ function build (entry, opts) {
1818
var basedir = utils.dirname(entry)
1919
var outdir = path.join(basedir, 'dist')
2020

21-
mkdirp(outdir, function (err) {
21+
utils.hasDependency(basedir, 'electron', function (err, hasElectron) {
22+
if (err) return console.error(err)
23+
opts.electron = hasElectron
24+
mkdirp(outdir, onoutdir)
25+
})
26+
27+
function onoutdir (err) {
2228
if (err) return console.error(err)
2329

2430
var bankaiOpts = {
@@ -232,7 +238,7 @@ function build (entry, opts) {
232238
}
233239
], done)
234240
}
235-
})
241+
}
236242
}
237243

238244
function clr (text, color) {

lib/cmd-start.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
var getPort = require('get-port')
2+
var path = require('path')
23

3-
var isElectronProject = require('./is-electron-project')
4+
var hasDependency = require('./utils').hasDependency
45
var http = require('./http-server')
56
var bankai = require('../http')
67

78
module.exports = start
89

910
function start (entry, opts) {
10-
isElectronProject(process.cwd(), function (err, bool) {
11+
hasDependency(path.dirname(entry), 'electron', function (err, isElectron) {
1112
if (err) throw err
12-
opts.electron = bool
13+
opts.electron = isElectron
1314

1415
var handler = bankai(entry, opts)
1516
var state = handler.state // TODO: move all UI code into this file

lib/graph-script.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ var tinyify = require('tinyify')
1616
var glslify = require('glslify')
1717
var brfs = require('brfs')
1818

19+
var hasDependency = require('./utils').hasDependency
1920
var ttyError = require('./tty-error')
2021
var exorcise = require('./exorcise')
2122

@@ -39,8 +40,20 @@ module.exports = node
3940
function node (state, createEdge) {
4041
assert.equal(typeof state.metadata.entry, 'string', 'state.metadata.entries should be type string')
4142

43+
var self = this
4244
this.emit('progress', 'scripts', 0)
4345

46+
hasDependency(state.metadata.entry, 'typescript', function (err, hasTypescript) {
47+
if (err) {
48+
self.emit('error', err)
49+
} else {
50+
state.metadata.typescript = hasTypescript
51+
}
52+
startNode.call(self, state, createEdge)
53+
})
54+
}
55+
56+
function startNode (state, createEdge) {
4457
var self = this
4558
var entry = state.metadata.entry
4659
var fullPaths = Boolean(state.metadata.fullPaths)
@@ -56,6 +69,10 @@ function node (state, createEdge) {
5669
})
5770
}
5871

72+
if (state.metadata.typescript) {
73+
b.plugin('tsify')
74+
}
75+
5976
b.ignore('sheetify/insert')
6077
b.transform(sheetify)
6178
b.transform(glslify)
@@ -106,6 +123,8 @@ function node (state, createEdge) {
106123
b.bundle(function (err, bundle) {
107124
if (err) {
108125
delete err.stream
126+
// HACK to tell ttyError whether we have TypeScript
127+
err.hasTypeScript = state.metadata.typescript
109128
err = ttyError('scripts', 'browserify.bundle', err)
110129
return self.emit('error', 'scripts', 'browserify.bundle', err)
111130
}

lib/is-electron-project.js

Lines changed: 0 additions & 24 deletions
This file was deleted.

lib/tty-error.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ var path = require('path')
44
var fs = require('fs')
55

66
var cwd = process.cwd()
7+
var typescriptRx = /\.tsx?$/
78

89
module.exports = ttyError
910

@@ -15,6 +16,7 @@ function ttyError (src, sub, err) {
1516
var loc = err.loc
1617
var line = loc.line
1718
var col = loc.column + 1
19+
var hasTypeScript = err.hasTypeScript
1820

1921
var lineNum = String(line) + ' '
2022
var padLen = lineNum.length
@@ -38,6 +40,11 @@ function ttyError (src, sub, err) {
3840
str += clr(lineNum + '|', 'blue') + ` ${clr(code, 'white')}\n`
3941
str += clr(empty, 'blue') + clr(syntaxError, 'red') + '\n\n'
4042
str += clr(`Hmmm. We're having trouble parsing a file.`, 'white')
43+
if (typescriptRx.test(longFilename) && !hasTypeScript) {
44+
str += '\n\n'
45+
str += clr(`To enable TypeScript in your project, install the TypeScript compiler: `, 'white') + '\n'
46+
str += ' ' + clr('npm install --save-dev typescript', 'grey')
47+
}
4148

4249
err.pretty = str
4350
return err

lib/utils.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ var recursiveWatch = require('recursive-watch')
22
var findup = require('findup')
33
var Debug = require('debug')
44
var path = require('path')
5+
var explain = require('explain-error')
6+
var fs = require('fs')
57

68
// Figure out what directory the file is in.
79
// Does nothing if a directory is passed.
@@ -93,3 +95,21 @@ try {
9395
}
9496
}
9597
exports.brotli = brotliCompress
98+
99+
exports.hasDependency = function hasDependency (dirname, dep, cb) {
100+
findup(dirname, 'package.json', function (err, dir) {
101+
if (err) return cb(null, false)
102+
fs.readFile(path.join(dir, 'package.json'), function (err, json) {
103+
if (err) return cb(explain(err, 'bankai.hasDependency: error reading package.json'))
104+
105+
try {
106+
var pkg = JSON.parse(json)
107+
var hasTypeScriptDep = Boolean((pkg.dependencies && pkg.dependencies[dep]) ||
108+
(pkg.devDependencies && pkg.devDependencies[dep]))
109+
cb(null, hasTypeScriptDep)
110+
} catch (err) {
111+
if (err) return cb(explain(err, 'bankai.hasDependency: error parsing package.json'))
112+
}
113+
})
114+
})
115+
}

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@
7272
"tfilter": "^1.0.1",
7373
"through2": "^2.0.3",
7474
"tinyify": "^2.4.0",
75+
"tsify": "^3.0.4",
7576
"v8-compile-cache": "^1.1.0",
7677
"wasm-brotli": "^1.0.2",
7778
"watchify": "^3.9.0",
@@ -87,6 +88,7 @@
8788
"rimraf": "^2.6.1",
8889
"standard": "^10.0.2",
8990
"tachyons": "^4.7.4",
90-
"tape": "^4.7.0"
91+
"tape": "^4.7.0",
92+
"typescript": "^2.6.2"
9193
}
9294
}

test/script.js

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
var async = require('async-collection')
12
var dedent = require('dedent')
23
var rimraf = require('rimraf')
34
var mkdirp = require('mkdirp')
@@ -73,6 +74,60 @@ tape('output multiple bundles if `split-require` is used', function (assert) {
7374
})
7475
})
7576

77+
tape('adds tsify if typescript is installed', function (assert) {
78+
assert.plan(3)
79+
80+
var barePackage = JSON.stringify({
81+
dependencies: {}
82+
}, null, 2)
83+
var tsPackage = JSON.stringify({
84+
dependencies: {},
85+
devDependencies: { typescript: '^2.6.2' }
86+
}, null, 2)
87+
88+
var file = `
89+
class Counter {
90+
private count: number;
91+
public next (): number {
92+
return this.count++;
93+
}
94+
}
95+
export = Counter
96+
`
97+
98+
var tmpDirname = path.join(__dirname, '../tmp', 'js-pipeline-' + (Math.random() * 1e4).toFixed())
99+
mkdirp.sync(tmpDirname)
100+
fs.writeFileSync(path.join(tmpDirname, 'app.ts'), file)
101+
102+
async.series([
103+
withoutTypescript,
104+
withTypescript
105+
], assert.end)
106+
107+
function withoutTypescript (cb) {
108+
fs.writeFileSync(path.join(tmpDirname, 'package.json'), barePackage)
109+
var compiler = bankai(path.join(tmpDirname, 'app.ts'), { watch: false })
110+
compiler.on('error', function (step, type, err) {
111+
assert.equal(err.filename, path.join(tmpDirname, 'app.ts'))
112+
cb()
113+
})
114+
compiler.scripts('bundle.js', function () {
115+
assert.fail('should have failed')
116+
})
117+
}
118+
function withTypescript (cb) {
119+
fs.writeFileSync(path.join(tmpDirname, 'package.json'), tsPackage)
120+
121+
var compiler = bankai(path.join(tmpDirname, 'app.ts'), { watch: false })
122+
compiler.on('error', assert.error)
123+
compiler.scripts('bundle.js', function (err, res) {
124+
assert.error(err, 'error compiling typescript')
125+
assert.ok(res)
126+
cb()
127+
})
128+
}
129+
})
130+
76131
tape('use custom babel config for local files, but not for dependencies', function (assert) {
77132
assert.plan(2)
78133

0 commit comments

Comments
 (0)