Skip to content

Commit

Permalink
refactor(server): compile on first run if browserify files missing.
Browse files Browse the repository at this point in the history
  • Loading branch information
johnjbarton committed Feb 24, 2018
1 parent bd013d2 commit f5521df
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 14 deletions.
72 changes: 58 additions & 14 deletions lib/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,32 @@ var BrowserCollection = require('./browser_collection')
var EmitterWrapper = require('./emitter_wrapper')
var processWrapper = new EmitterWrapper(process)

const karmaJsPath = path.join(__dirname, '/../static/karma.js')
const contextJsPath = path.join(__dirname, '/../static/context.js')

// Dynamic dependence on brwoserify
var browserify = null;

/**
* Bundles a static resource using Browserify.
* @param {string} inPath the path to the file to browserify
* @param {string} outPath the path to output the bundle to
* @returns {Promise}
*/
function bundleResource (inPath, outPath) {
return new Promise((resolve, reject) => {
browserify = browserify || require('browserify')
var bundler = browserify(inPath)
bundler.bundle().pipe(fs.createWriteStream(outPath))
.once('finish', () => {
resolve()
})
.once('error', (e) => {
reject(e)
})
})
}

function createSocketIoServer (webServer, executor, config) {
var server = new SocketIO(webServer, {
// avoid destroying http upgrades from socket.io to get proxied websockets working
Expand Down Expand Up @@ -171,23 +197,41 @@ Server.prototype._start = function (config, launcher, preprocess, fileList,
self._injector.invoke(watcher.watch)
}

webServer.listen(config.port, config.listenAddress, function () {
self.log.info('Karma v%s server started at %s//%s:%s%s', constant.VERSION,
config.protocol, config.listenAddress, config.port, config.urlRoot)
var startWebServer = function () {
webServer.listen(config.port, config.listenAddress, function () {
self.log.info('Karma v%s server started at %s//%s:%s%s', constant.VERSION,
config.protocol, config.listenAddress, config.port, config.urlRoot)

self.emit('listening', config.port)
if (config.browsers && config.browsers.length) {
self._injector.invoke(launcher.launch, launcher).forEach(function (browserLauncher) {
singleRunDoneBrowsers[browserLauncher.id] = false
})
}
var noLoadErrors = self.loadErrors.length
if (noLoadErrors > 0) {
self.log.error('Found %d load error%s', noLoadErrors, noLoadErrors === 1 ? '' : 's')
self.emit('listening', config.port)
if (config.browsers && config.browsers.length) {
self._injector.invoke(launcher.launch, launcher).forEach(function (browserLauncher) {
singleRunDoneBrowsers[browserLauncher.id] = false
})
}
var noLoadErrors = self.loadErrors.length
if (noLoadErrors > 0) {
self.log.error('Found %d load error%s', noLoadErrors, noLoadErrors === 1 ? '' : 's')
process.exitCode = 1
process.kill(process.pid, 'SIGINT')
}
})
}

// Check if the static files haven't been compiled
if (!(fs.existsSync(karmaJsPath) && fs.existsSync(contextJsPath))) {
self.log.info('Front-end scripts not present. Compiling...')
var mainPromise = bundleResource(path.join(__dirname, '/../client/main.js'), karmaJsPath)
var contextPromise = bundleResource(path.join(__dirname, '/../context/main.js'), contextJsPath)
Promise.all([mainPromise, contextPromise]).then(() => {
startWebServer()
}).catch((error) => {
self.log.error('Front-end script compile failed with error: ' + error)
process.exitCode = 1
process.kill(process.pid, 'SIGINT')
}
})
})
} else {
startWebServer()
}
}

fileList.refresh().then(afterPreprocess, afterPreprocess)
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,7 @@
"devDependencies": {
"LiveScript": "^1.3.0",
"babel-core": "^6.26.0",
"browserify": "^14.5.0",
"chai": "^4.1.2",
"chai-as-promised": "^7.1.1",
"chai-subset": "^1.2.2",
Expand Down
13 changes: 13 additions & 0 deletions test/unit/server.spec.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
var Server = require('../../lib/server')
var BrowserCollection = require('../../lib/browser_collection')
var fs = require('fs')
var path = require('path')

describe('server', () => {
var mockConfig
Expand Down Expand Up @@ -103,6 +105,17 @@ describe('server', () => {
// server._start()
// ============================================================================
describe('_start', () => {
it('should compile static resources on first run', function (done) {
this.timeout(5000)
server._start(mockConfig, mockLauncher, null, mockFileList, browserCollection, mockExecutor, doneSpy)
fileListOnResolve()

setTimeout(() => {
expect(fs.existsSync(path.join(__dirname, '/../../static/karma.js')) && fs.existsSync(path.join(__dirname, '/../../static/context.js'))).to.be.true
done()
}, 4000)
})

it('should start the web server after all files have been preprocessed successfully', () => {
server._start(mockConfig, mockLauncher, null, mockFileList, browserCollection, mockExecutor, doneSpy)

Expand Down

2 comments on commit f5521df

@devoto13
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@johnjbarton Do you remember why this was introduced?
AFAICT Karma package always comes with these files pre-compiled, so it is unclear why such feature is needed.

@johnjbarton
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This supports users who install directly from github and karma developers like me who get confused when these files are missing. Probably could be done with eg install script.

Please sign in to comment.