Skip to content
This repository was archived by the owner on Jan 31, 2023. It is now read-only.

Commit 01cfcdb

Browse files
committed
add comments to document code
1 parent ddd95fa commit 01cfcdb

File tree

1 file changed

+52
-2
lines changed

1 file changed

+52
-2
lines changed

index.js

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,13 @@ const log = require('debug')('cypress:browserify')
1111

1212
const bundles = {}
1313

14+
// by default, we transform JavaScript (up to anything at stage-4), JSX,
15+
// CoffeeScript, and CJSX (CoffeeScript + JSX)
1416
const defaults = {
1517
extensions: ['.js', '.jsx', '.coffee', '.cjsx'],
1618
watchOptions: {
19+
// ignore watching the following or the user's system can get bogged down
20+
// by watchers
1721
ignoreWatch: [
1822
'**/.git/**',
1923
'**/.nyc_output/**',
@@ -33,31 +37,59 @@ const defaults = {
3337
options: {
3438
ast: false,
3539
babelrc: false,
40+
// irons out differents between ES6 modules and node exports
3641
plugins: ['babel-plugin-add-module-exports'].map(require.resolve),
42+
// babel-preset-env supports any JS that's stage-4, meaning it's
43+
// completely finalized in the ECMA standard
3744
presets: ['babel-preset-env', 'babel-preset-react'].map(require.resolve),
3845
},
3946
},
4047
],
4148
}
4249

50+
// export a function that returns another function, making it easy for users
51+
// to configure like so:
52+
//
53+
// register('on:spec:file:preprocessor', browserify(config, userOptions))
54+
//
4355
module.exports = (config, userOptions = {}) => {
4456
log('received user options', userOptions)
4557

4658
if (!config || typeof config.isTextTerminal !== 'boolean') {
4759
throw new Error(`Cypress Browserify Preprocessor must be called with the Cypress config as its first argument. You passed: ${JSON.stringify(config, null, 2)}`)
4860
}
4961

62+
// allow user to override default options
5063
const options = Object.assign({}, defaults, userOptions)
5164

65+
// we return function that accepts the arguments provided by
66+
// the event 'on:spec:file:preprocessor'
67+
//
68+
// this function will get called for the support file when a project is loaded
69+
// (if the support file is not disabled)
70+
// it will also get calledfor a spec file when that spec is requested by
71+
// the Cypress runner
72+
//
73+
// when running in the GUI, it will likely get called multiple times
74+
// with the same filePath, as the user could re-run the tests, causing
75+
// the supported file and spec file to be requested again
5276
return (filePath, util) => {
5377
log('get', filePath)
5478

79+
// since this function can get called multiple times with the same
80+
// filePath, we return the cached bundle promise if we already have one
81+
// since we don't want or need to re-initiate browserify/watchify for it
5582
if (bundles[filePath]) {
5683
log(`already have bundle for ${filePath}`)
5784
return bundles[filePath]
5885
}
5986

87+
// if we're in a text terminal, this is a one-time run, probably in CI
88+
// so we don't need to watch
6089
const shouldWatch = !config.isTextTerminal
90+
// util.getOutputPath returns a path alongside Cypress's other app data
91+
// files so we don't have to worry about where to put the bundled
92+
// file on disk
6193
const outputPath = util.getOutputPath(filePath)
6294

6395
log(`input: ${filePath}`)
@@ -75,26 +107,34 @@ module.exports = (config, userOptions = {}) => {
75107
bundler.plugin(watchify, options.watchOptions || {})
76108
}
77109

110+
// yield the bundle if onBundle is specified so the user can modify it
111+
// as need via `bundle.external()`, `bundle.plugin()`, etc
78112
const onBundle = options.onBundle
79113
if (typeof onBundle === 'function') {
80114
onBundle(bundler)
81115
}
82116

117+
// transforms are part of the options so that users can easily override
118+
// the options of the default cjsxify and babelify tranforms
83119
const transforms = options.transforms
84120
if (Object.prototype.toString.call(transforms) === '[object Array]') {
85121
transforms.forEach((transform) => {
86122
bundler.transform(transform.transform, transform.options)
87123
})
88124
}
89125

126+
// this kicks off the bundling and wraps it up in a promise. the promise
127+
// is what is ultimately returned from this function
128+
// it resolves with the outputPath so Cypress knows where to serve
129+
// the file from
90130
const bundle = () => {
91131
return new Promise((resolve, reject) => {
92132
log(`making bundle ${outputPath}`)
93133

94134
const onError = (err) => {
95135
err.filePath = filePath
96-
//// backup the original stack before its
97-
//// potentially modified from bluebird
136+
// backup the original stack before its
137+
// potentially modified from bluebird
98138
err.originalStack = err.stack
99139
log(`errored bundling ${outputPath}`, err)
100140
reject(err)
@@ -114,8 +154,12 @@ module.exports = (config, userOptions = {}) => {
114154
})
115155
}
116156

157+
// when we're notified of an update via watchify, we call `util.fileUpdated`
158+
// to let Cypress know to re-run the spec
117159
bundler.on('update', () => {
118160
log(`update ${filePath}`)
161+
// we overwrite the cached bundle promise, so on subsequent invocations
162+
// it gets the latest bundle
119163
bundles[filePath] = bundle().tap(() => {
120164
log(`- update finished for ${filePath}`)
121165
util.fileUpdated(filePath)
@@ -124,8 +168,12 @@ module.exports = (config, userOptions = {}) => {
124168

125169
const bundlePromise = fs.ensureDirAsync(path.dirname(outputPath)).then(bundle)
126170

171+
// cache the bundle promise, so it can be returned if this function
172+
// is invoked again with the same filePath
127173
bundles[filePath] = bundlePromise
128174

175+
// when the spec or project is closed, we need to clean up the cached
176+
// bundle promise and stop the watcher via `bundler.close()`
129177
util.onClose(() => {
130178
log(`close ${filePath}`)
131179
delete bundles[filePath]
@@ -134,6 +182,8 @@ module.exports = (config, userOptions = {}) => {
134182
}
135183
})
136184

185+
// return the promise, which will resolve with the outputPath or reject
186+
// with any error encountered
137187
return bundlePromise
138188
}
139189
}

0 commit comments

Comments
 (0)