Skip to content

Commit

Permalink
Add TypeScript support.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
goto-bus-stop committed Jan 31, 2018
1 parent f6b981c commit 2f08575
Show file tree
Hide file tree
Showing 8 changed files with 115 additions and 30 deletions.
10 changes: 8 additions & 2 deletions lib/cmd-build.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,13 @@ function build (entry, opts) {
var basedir = utils.dirname(entry)
var outdir = path.join(basedir, 'dist')

mkdirp(outdir, function (err) {
utils.hasDependency(basedir, 'electron', function (err, hasElectron) {
if (err) return console.error(err)
opts.electron = hasElectron
mkdirp(outdir, onoutdir)
})

function onoutdir (err) {
if (err) return console.error(err)

var bankaiOpts = {
Expand Down Expand Up @@ -232,7 +238,7 @@ function build (entry, opts) {
}
], done)
}
})
}
}

function clr (text, color) {
Expand Down
7 changes: 4 additions & 3 deletions lib/cmd-start.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
var getPort = require('get-port')
var path = require('path')

var isElectronProject = require('./is-electron-project')
var hasDependency = require('./utils').hasDependency
var http = require('./http-server')
var bankai = require('../http')

module.exports = start

function start (entry, opts) {
isElectronProject(process.cwd(), function (err, bool) {
hasDependency(path.dirname(entry), 'electron', function (err, isElectron) {
if (err) throw err
opts.electron = bool
opts.electron = isElectron

var handler = bankai(entry, opts)
var state = handler.state // TODO: move all UI code into this file
Expand Down
18 changes: 18 additions & 0 deletions lib/graph-script.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ var tinyify = require('tinyify')
var glslify = require('glslify')
var brfs = require('brfs')

var hasDependency = require('./utils').hasDependency
var ttyError = require('./tty-error')
var exorcise = require('./exorcise')

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

var self = this
this.emit('progress', 'scripts', 0)

hasDependency(state.metadata.entry, 'typescript', function (err, hasTypescript) {
if (err) {
self.emit('error', err)
} else {
state.metadata.typescript = hasTypescript
}
startNode.call(self, state, createEdge)
})
}

function startNode (state, createEdge) {
var self = this
var entry = state.metadata.entry
var fullPaths = Boolean(state.metadata.fullPaths)
Expand All @@ -56,6 +69,10 @@ function node (state, createEdge) {
})
}

if (state.metadata.typescript) {
b.plugin('tsify')
}

b.ignore('sheetify/insert')
b.transform(sheetify)
b.transform(glslify)
Expand Down Expand Up @@ -106,6 +123,7 @@ function node (state, createEdge) {
b.bundle(function (err, bundle) {
if (err) {
delete err.stream
err.hasTypeScript = state.metadata.typescript
err = ttyError('scripts', 'browserify.bundle', err)
return self.emit('error', 'scripts', 'browserify.bundle', err)
}
Expand Down
24 changes: 0 additions & 24 deletions lib/is-electron-project.js

This file was deleted.

7 changes: 7 additions & 0 deletions lib/tty-error.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ var path = require('path')
var fs = require('fs')

var cwd = process.cwd()
var typescriptRx = /\.tsx?$/

module.exports = ttyError

Expand All @@ -15,6 +16,7 @@ function ttyError (src, sub, err) {
var loc = err.loc
var line = loc.line
var col = loc.column + 1
var hasTypeScript = err.hasTypeScript

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

err.pretty = str
return err
Expand Down
20 changes: 20 additions & 0 deletions lib/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ var recursiveWatch = require('recursive-watch')
var findup = require('findup')
var Debug = require('debug')
var path = require('path')
var explain = require('explain-error')
var fs = require('fs')

// Figure out what directory the file is in.
// Does nothing if a directory is passed.
Expand Down Expand Up @@ -93,3 +95,21 @@ try {
}
}
exports.brotli = brotliCompress

exports.hasDependency = function hasDependency (dirname, dep, cb) {
findup(dirname, 'package.json', function (err, dir) {
if (err) return cb(null, false)
fs.readFile(path.join(dir, 'package.json'), function (err, json) {
if (err) return cb(explain(err, 'bankai.hasDependency: error reading package.json'))

try {
var pkg = JSON.parse(json)
var hasTypeScriptDep = Boolean((pkg.dependencies && pkg.dependencies[dep]) ||
(pkg.devDependencies && pkg.devDependencies[dep]))
cb(null, hasTypeScriptDep)
} catch (err) {
if (err) return cb(explain(err, 'bankai.hasDependency: error parsing package.json'))
}
})
})
}
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
"tfilter": "^1.0.1",
"through2": "^2.0.3",
"tinyify": "^2.4.0",
"tsify": "^3.0.4",
"v8-compile-cache": "^1.1.0",
"wasm-brotli": "^1.0.2",
"watchify": "^3.9.0",
Expand All @@ -87,6 +88,7 @@
"rimraf": "^2.6.1",
"standard": "^10.0.2",
"tachyons": "^4.7.4",
"tape": "^4.7.0"
"tape": "^4.7.0",
"typescript": "^2.6.2"
}
}
55 changes: 55 additions & 0 deletions test/script.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
var async = require('async-collection')
var dedent = require('dedent')
var rimraf = require('rimraf')
var mkdirp = require('mkdirp')
Expand Down Expand Up @@ -73,6 +74,60 @@ tape('output multiple bundles if `split-require` is used', function (assert) {
})
})

tape('adds tsify if typescript is installed', function (assert) {
assert.plan(3)

var barePackage = JSON.stringify({
dependencies: {}
}, null, 2)
var tsPackage = JSON.stringify({
dependencies: {},
devDependencies: { typescript: '^2.6.2' }
}, null, 2)

var file = `
class Counter {
private count: number;
public next (): number {
return this.count++;
}
}
export = Counter
`

var tmpDirname = path.join(__dirname, '../tmp', 'js-pipeline-' + (Math.random() * 1e4).toFixed())
mkdirp.sync(tmpDirname)
fs.writeFileSync(path.join(tmpDirname, 'app.ts'), file)

async.series([
withoutTypescript,
withTypescript
], assert.end)

function withoutTypescript (cb) {
fs.writeFileSync(path.join(tmpDirname, 'package.json'), barePackage)
var compiler = bankai(path.join(tmpDirname, 'app.ts'), { watch: false })
compiler.on('error', function (step, type, err) {
assert.equal(err.filename, path.join(tmpDirname, 'app.ts'))
cb()
})
compiler.scripts('bundle.js', function () {
assert.fail('should have failed')
})
}
function withTypescript (cb) {
fs.writeFileSync(path.join(tmpDirname, 'package.json'), tsPackage)

var compiler = bankai(path.join(tmpDirname, 'app.ts'), { watch: false })
compiler.on('error', assert.error)
compiler.scripts('bundle.js', function (err, res) {
assert.error(err, 'error compiling typescript')
assert.ok(res)
cb()
})
}
})

tape('use custom babel config for local files, but not for dependencies', function (assert) {
assert.plan(2)

Expand Down

0 comments on commit 2f08575

Please sign in to comment.