Skip to content

Commit

Permalink
feat(bundler): add a bundler layer
Browse files Browse the repository at this point in the history
The input config supplies 'patterns' which FileList expands into Files.
These files are preprocessed and then 'file-list-modified' is fired.
The event offers a pair of file lists, {included, served}.
The bundle layer maps this pair to a new pair where fewer files are included.
By default the bundler copies the inputs to outputs.

Fixes #3633
  • Loading branch information
johnjbarton committed Jan 27, 2021
1 parent 17c5029 commit ae4f6c6
Show file tree
Hide file tree
Showing 9 changed files with 208 additions and 112 deletions.
12 changes: 5 additions & 7 deletions lib/middleware/karma.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ function getXUACompatibleUrl (url) {
}

function createKarmaMiddleware (
currentFiles,
currentWebFiles,
serveStaticFile,
serveFile,
injector,
Expand Down Expand Up @@ -132,7 +132,6 @@ function createKarmaMiddleware (
const isRequestingDebugFile = requestUrl === '/debug.html'
const isRequestingClientContextFile = requestUrl === '/client_with_context.html'
if (isRequestingContextFile || isRequestingDebugFile || isRequestingClientContextFile) {
const files = currentFiles.files
let fileServer
let requestedFileUrl
log.debug('custom files', customContextFile, customDebugFile, customClientContextFile)
Expand All @@ -157,7 +156,7 @@ function createKarmaMiddleware (
fileServer(requestedFileUrl, requestedRangeHeader, response, function (data) {
common.setNoCacheHeaders(response)
const scriptTags = []
for (const file of files.included) {
for (const file of currentWebFiles.included) {
let filePath = file.path
const fileType = file.type || file.detectType()

Expand Down Expand Up @@ -212,7 +211,7 @@ function createKarmaMiddleware (
}
}

const mappings = data.includes('%MAPPINGS%') ? files.served.map((file) => {
const mappings = data.includes('%MAPPINGS%') ? currentWebFiles.served.map((file) => {
const filePath = filePathToUrlPath(file.path, basePath, urlRoot, proxyPath)
.replace(/\\/g, '\\\\') // Windows paths contain backslashes and generate bad IDs if not escaped
.replace(/'/g, '\\\'') // Escape single quotes - double quotes should not be allowed!
Expand All @@ -228,11 +227,10 @@ function createKarmaMiddleware (
.replace('\n%X_UA_COMPATIBLE%', getXUACompatibleMetaElement(request.url))
})
} else if (requestUrl === '/context.json') {
const files = currentFiles.files
common.setNoCacheHeaders(response)
response.writeHead(200)
response.end(JSON.stringify({
files: files.included.map((file) => filePathToUrlPath(file.path + '?' + file.sha, basePath, urlRoot, proxyPath))
files: currentWebFiles.included.map((file) => filePathToUrlPath(file.path + '?' + file.sha, basePath, urlRoot, proxyPath))
}))
} else {
next()
Expand All @@ -241,7 +239,7 @@ function createKarmaMiddleware (
}

createKarmaMiddleware.$inject = [
'currentFiles',
'currentWebFiles',
'serveStaticFile',
'serveFile',
'injector',
Expand Down
7 changes: 3 additions & 4 deletions lib/middleware/source_files.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ function composeUrl (url, basePath, urlRoot) {
}

// Source Files middleware is responsible for serving all the source files under the test.
function createSourceFilesMiddleware (currentFiles, serveFile, basePath, urlRoot) {
function createSourceFilesMiddleware (currentWebFiles, serveFile, basePath, urlRoot) {
return function (request, response, next) {
const requestedFilePath = composeUrl(request.url, basePath, urlRoot)
// When a path contains HTML-encoded characters (e.g %2F used by Jenkins for branches with /)
Expand All @@ -29,9 +29,8 @@ function createSourceFilesMiddleware (currentFiles, serveFile, basePath, urlRoot
log.debug(`Requesting ${request.url}`)
log.debug(`Fetching ${requestedFilePath}`)

const files = currentFiles.files
// TODO(vojta): change served to be a map rather then an array
const file = findByPath(files.served, requestedFilePath) || findByPath(files.served, requestedFilePathUnescaped)
const file = findByPath(currentWebFiles.served, requestedFilePath) || findByPath(currentWebFiles.served, requestedFilePathUnescaped)
const rangeHeader = request.headers.range

if (file) {
Expand Down Expand Up @@ -60,7 +59,7 @@ function createSourceFilesMiddleware (currentFiles, serveFile, basePath, urlRoot
}

createSourceFilesMiddleware.$inject = [
'currentFiles', 'serveFile', 'config.basePath', 'config.urlRoot'
'currentWebFiles', 'serveFile', 'config.basePath', 'config.urlRoot'
]

exports.create = createSourceFilesMiddleware
12 changes: 8 additions & 4 deletions lib/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@ const plugin = require('./plugin')

const createServeFile = require('./web-server').createServeFile
const createServeStaticFile = require('./web-server').createServeStaticFile
const createCurrentFiles = require('./web-server').createCurrentFiles
const createFilesPromise = require('./web-server').createFilesPromise
const createWebServer = require('./web-server').createWebServer
const createWebFiles = require('./web-files').createWebFiles
const preprocessor = require('./preprocessor')
const Launcher = require('./launcher').Launcher
const FileList = require('./file-list')
Expand Down Expand Up @@ -82,7 +83,10 @@ class Server extends KarmaEventEmitter {
webServer: ['factory', createWebServer],
serveFile: ['factory', createServeFile],
serveStaticFile: ['factory', createServeStaticFile],
currentFiles: ['factory', createCurrentFiles],
// Obsolete, do not use
filesPromise: ['factory', createFilesPromise],
// The files to be included/served to browser for test
currentWebFiles: ['factory', createWebFiles],
socketServer: ['factory', createSocketIoServer],
executor: ['factory', Executor.factory],
// TODO: Deprecated. Remove in the next major
Expand Down Expand Up @@ -343,8 +347,8 @@ class Server extends KarmaEventEmitter {
}

if (config.autoWatch) {
this.on('file_list_modified', () => {
this.log.debug('List of files has changed, trying to execute')
this.on('web_files_modified', () => {
this.log.debug('List of included/served files has changed, trying to execute')
if (config.restartOnFileChange) {
socketServer.sockets.emit('stop')
}
Expand Down
45 changes: 45 additions & 0 deletions lib/web-files.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/**
Container class for the files included in context.html and served upon
request. Two instances fit into the files pipeline:
1. The result from FileList.files, the list of preprocessed input files.
2. The result of bundling #1 stored in currentWebFiles
*/
class WebFiles {
constructor (included, served) {
this.included = [...included]
this.served = [...served]
}
}

let currentWebFiles = new WebFiles([], [])

function noOpBundler (webFiles) {
return new WebFiles(webFiles.included, webFiles.served)
}

let bundler = noOpBundler

function registerBundler (emitter) {
emitter.on('file_list_modified', (modifiedWebFiles) => {
// Any bundler is expected to return a WebFiles object.
// For sourcemap support, //# sourceUrl in the bundler result should
// point back to the input files.
currentWebFiles = Object.assign(currentWebFiles, bundler(modifiedWebFiles))
emitter.emit('web_files_modified', currentWebFiles)
})
}

function createWebFiles (configBundler, instantiatePlugin, emitter) {
if (configBundler) {
bundler = instantiatePlugin('bundler', configBundler)
}
registerBundler(emitter)
return currentWebFiles
}

createWebFiles.$inject = ['config.bundler', 'instantiatePlugin', 'emitter']

module.exports = {
createWebFiles,
WebFiles
}
9 changes: 1 addition & 8 deletions lib/web-server.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,6 @@ function createFilesPromise (emitter, fileList) {
return Promise.resolve(files).then(...args)
}
}

function createCurrentFiles (emitter, fileList) {
const currentFileList = { files: fileList.files }
emitter.on('file_list_modified', (modifiedFiles) => {
currentFileList.files = modifiedFiles
})
return currentFileList
}

function createServeStaticFile (config) {
Expand Down Expand Up @@ -121,5 +114,5 @@ module.exports = {
createWebServer,
createServeFile,
createServeStaticFile,
createCurrentFiles
createFilesPromise
}

0 comments on commit ae4f6c6

Please sign in to comment.