Skip to content

Commit

Permalink
replace browserify with rollup and babel (#4293)
Browse files Browse the repository at this point in the history
* Make browser specific TTY interop explicit instead of a magic bundling configuration
* Remove unnessessary browserify ignore of cli related files and chokidar
* Extract lookupFiles from utils to avoid node dependencies in browser bundle
* Replace browserify with rollup for main library bundling
* Polyfill global to check if IE11 will start working
* Don't include esm-utils in browser build. Modern syntax breaks IE
* Remove duplicate browserify configuration in karma config file
* Add custom karma rollup plugin and use it to bundle browser tests
* add process.listeners impl
* Extract browser-only helper functions from shared utils file to their own files
* Add browserslist, babel, babel-preset-env and prepare for modern js
* Add mocha.js.map to npm distributed files
* Use util function to check if we're running in a browser
* Improve documentation of self-built karma-rollup-plugin
* Renamed lib/cli/lookupFiles.js to lib/cli/lookup-files.js
* Clean up rollup config
* Kebab case file names
* Remove last traces of unused browserify
* fix bundle path under win32
* do not run bundle visualizer in CI
* Remove use of mocha.opts in browser testing
* Improved naming of rollup plugin to pick values from package.json

Co-authored-by: Christopher Hiller <boneskull@boneskull.com>
Signed-off-by: Christopher Hiller <boneskull@boneskull.com>
  • Loading branch information
Munter and boneskull committed Jul 2, 2020
1 parent 7d3151d commit 40f951b
Show file tree
Hide file tree
Showing 24 changed files with 4,641 additions and 636 deletions.
12 changes: 12 additions & 0 deletions .browserslistrc
@@ -0,0 +1,12 @@
node >= 10
last 2 Chrome versions
last 2 Edge versions
last 2 Firefox versions
last 2 Safari versions
last 2 Opera versions
unreleased Chrome versions
unreleased Edge versions
unreleased Firefox versions
unreleased Safari versions
unreleased Opera versions
IE 11
7 changes: 4 additions & 3 deletions .eslintrc.yml
Expand Up @@ -5,8 +5,9 @@ extends:
env:
node: true
browser: true
es6: true
parserOptions:
ecmaVersion: 5
ecmaVersion: 2018
ecmaFeatures:
jsx: false
sourceType: script
Expand Down Expand Up @@ -37,8 +38,6 @@ overrides:
- 'test/integration/helpers.js'
- 'test/integration/options/watch.spec.js'
- 'test/node-unit/**/*.js'
parserOptions:
ecmaVersion: 2018
env:
browser: false
rules:
Expand All @@ -48,6 +47,8 @@ overrides:
property: 'assign'
- files:
- esm-utils.js
- rollup.config.js
- scripts/pick-from-package-json.js
parserOptions:
ecmaVersion: 2018
sourceType: module
Expand Down
4 changes: 4 additions & 0 deletions .gitignore
Expand Up @@ -3,9 +3,13 @@ docs/_site
docs/_dist
docs/images/supporters
mocha.js
mocha.js.map
.karma/
!lib/mocha.js

# Bundle debugging
stats.html

#########################################
# NON-MOCHA STUFF GOES BELOW THIS THING #
#########################################
Expand Down
13 changes: 11 additions & 2 deletions browser-entry.js
Expand Up @@ -9,6 +9,8 @@

process.stdout = require('browser-stdout')({label: false});

var parseQuery = require('./lib/browser/parse-query');
var highlightTags = require('./lib/browser/highlight-tags');
var Mocha = require('./lib/mocha');

/**
Expand Down Expand Up @@ -77,6 +79,13 @@ process.on = function(e, fn) {
}
};

process.listeners = function(e) {
if (e === 'uncaughtException') {
return uncaughtExceptionHandlers;
}
return [];
};

// The BDD UI is registered by default, but no UI will be functional in the
// browser without an explicit call to the overridden `mocha.ui` (see below).
// Ensure that this default UI does not expose its methods to the global scope.
Expand Down Expand Up @@ -163,7 +172,7 @@ mocha.run = function(fn) {
var options = mocha.options;
mocha.globals('location');

var query = Mocha.utils.parseQuery(global.location.search || '');
var query = parseQuery(global.location.search || '');
if (query.grep) {
mocha.grep(query.grep);
}
Expand All @@ -182,7 +191,7 @@ mocha.run = function(fn) {
document.getElementById('mocha') &&
options.noHighlighting !== true
) {
Mocha.utils.highlightTags('code');
highlightTags('code');
}
if (fn) {
fn(err);
Expand Down
47 changes: 14 additions & 33 deletions karma.conf.js
Expand Up @@ -3,6 +3,7 @@
const fs = require('fs');
const path = require('path');
const os = require('os');
const rollupPlugin = require('./scripts/karma-rollup-plugin');
const baseBundleDirpath = path.join(__dirname, '.karma');

const hostname = os.hostname();
Expand All @@ -18,51 +19,31 @@ const browserPlatformPairs = {
module.exports = config => {
let bundleDirpath;
const cfg = {
frameworks: ['browserify', 'mocha'],
frameworks: ['rollup', 'mocha'],
files: [
// we use the BDD interface for all of the tests that
// aren't interface-specific.
'test/unit/*.spec.js'
],
preprocessors: {
'test/**/*.js': ['browserify']
},
browserify: {
debug: true,
configure: function configure(b) {
b.ignore('chokidar')
.ignore('fs')
.ignore('glob')
.ignore('path')
.ignore('supports-color')
.ignore('./lib/esm-utils.js')
.ignore('./lib/cli/*.js')
.ignore('./lib/nodejs/serializer.js')
.ignore('./lib/nodejs/worker.js')
.ignore('./lib/nodejs/buffered-worker-pool.js')
.ignore('./lib/nodejs/parallel-buffered-runner.js')
.ignore('./lib/nodejs/reporters/parallel-buffered.js')
.on('bundled', (err, content) => {
if (err) {
throw err;
}
if (bundleDirpath) {
// write bundle to directory for debugging
fs.writeFileSync(
path.join(bundleDirpath, `mocha.${Date.now()}.js`),
content
);
}
});
}
plugins: [
'karma-mocha',
'karma-mocha-reporter',
'karma-sauce-launcher',
'karma-chrome-launcher',
rollupPlugin
],
rollup: {
configFile: 'rollup.config.js',
include: ['test/**'],
bundlePath: bundleDirpath
},
reporters: ['mocha'],
colors: true,
browsers: ['ChromeHeadless'],
logLevel: config.LOG_INFO,
client: {
mocha: {
opts: require.resolve('./test/browser-specific/mocha.opts')
reporter: 'html'
}
},
mochaReporter: {
Expand Down
39 changes: 39 additions & 0 deletions lib/browser/highlight-tags.js
@@ -0,0 +1,39 @@
'use strict';

/**
* Highlight the given string of `js`.
*
* @private
* @param {string} js
* @return {string}
*/
function highlight(js) {
return js
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/\/\/(.*)/gm, '<span class="comment">//$1</span>')
.replace(/('.*?')/gm, '<span class="string">$1</span>')
.replace(/(\d+\.\d+)/gm, '<span class="number">$1</span>')
.replace(/(\d+)/gm, '<span class="number">$1</span>')
.replace(
/\bnew[ \t]+(\w+)/gm,
'<span class="keyword">new</span> <span class="init">$1</span>'
)
.replace(
/\b(function|new|throw|return|var|if|else)\b/gm,
'<span class="keyword">$1</span>'
);
}

/**
* Highlight the contents of tag `name`.
*
* @private
* @param {string} name
*/
module.exports = function highlightTags(name) {
var code = document.getElementById('mocha').getElementsByTagName(name);
for (var i = 0, len = code.length; i < len; ++i) {
code[i].innerHTML = highlight(code[i].innerHTML);
}
};
24 changes: 24 additions & 0 deletions lib/browser/parse-query.js
@@ -0,0 +1,24 @@
'use strict';

/**
* Parse the given `qs`.
*
* @private
* @param {string} qs
* @return {Object<string, string>}
*/
module.exports = function parseQuery(qs) {
return qs
.replace('?', '')
.split('&')
.reduce(function(obj, pair) {
var i = pair.indexOf('=');
var key = pair.slice(0, i);
var val = pair.slice(++i);

// Due to how the URLSearchParams API treats spaces
obj[key] = decodeURIComponent(val.replace(/\+/g, '%20'));

return obj;
}, {});
};
13 changes: 0 additions & 13 deletions lib/browser/tty.js

This file was deleted.

4 changes: 2 additions & 2 deletions lib/cli/collect-files.js
Expand Up @@ -4,8 +4,8 @@ const path = require('path');
const ansi = require('ansi-colors');
const debug = require('debug')('mocha:cli:run:helpers');
const minimatch = require('minimatch');
const utils = require('../utils');
const {NO_FILES_MATCH_PATTERN} = require('../errors').constants;
const lookupFiles = require('./lookup-files');

/**
* Exports a function that collects test files from CLI parameters.
Expand All @@ -27,7 +27,7 @@ module.exports = ({ignore, extension, file, recursive, sort, spec} = {}) => {
spec.forEach(arg => {
let newFiles;
try {
newFiles = utils.lookupFiles(arg, extension, recursive);
newFiles = lookupFiles(arg, extension, recursive);
} catch (err) {
if (err.code === NO_FILES_MATCH_PATTERN) {
unmatched.push({message: err.message, pattern: err.pattern});
Expand Down

0 comments on commit 40f951b

Please sign in to comment.