Skip to content
This repository was archived by the owner on Oct 1, 2020. It is now read-only.

Commit 34d492b

Browse files
Release the next version (#54)
Release the next version
2 parents c240d71 + f9ad5e7 commit 34d492b

File tree

5 files changed

+123
-59
lines changed

5 files changed

+123
-59
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,8 @@ Object of webpack options. Just `require` in the options from your `webpack.conf
8585
}
8686
```
8787

88+
Source maps are always enabled unless explicitly disabled by specifying `devtool: false`.
89+
8890
### watchOptions
8991

9092
Object of options for watching. See [webpack's docs](https://webpack.github.io/docs/node.js-api.html#compiler).

index.js

Lines changed: 53 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,35 @@
1-
const cloneDeep = require('lodash.clonedeep')
21
const path = require('path')
32
const webpack = require('webpack')
4-
const log = require('debug')('cypress:webpack')
3+
const debug = require('debug')('cypress:webpack')
54

65
const createDeferred = require('./deferred')
6+
const stubbableRequire = require('./stubbable-require')
77

88
const bundles = {}
99

10-
// by default, we transform JavaScript supported by @babel/preset-env
11-
const defaultBabelLoaderRules = () => {
12-
return [
13-
{
14-
test: /\.js?$/,
15-
exclude: [/node_modules/],
16-
use: [
17-
{
18-
loader: require.resolve('babel-loader'),
19-
options: {
20-
presets: [require.resolve('@babel/preset-env')],
21-
},
22-
},
23-
],
24-
},
25-
]
26-
}
27-
2810
// we don't automatically load the rules, so that the babel dependencies are
2911
// not required if a user passes in their own configuration
30-
const defaultOptions = {
31-
webpackOptions: {
12+
const getDefaultWebpackOptions = () => {
13+
debug('load default options')
14+
15+
return {
3216
module: {
33-
rules: [],
17+
rules: [
18+
{
19+
test: /\.jsx?$/,
20+
exclude: [/node_modules/],
21+
use: [
22+
{
23+
loader: stubbableRequire.resolve('babel-loader'),
24+
options: {
25+
presets: [stubbableRequire.resolve('@babel/preset-env')],
26+
},
27+
},
28+
],
29+
},
30+
],
3431
},
35-
},
36-
watchOptions: {},
32+
}
3733
}
3834

3935
// export a function that returns another function, making it easy for users
@@ -42,7 +38,7 @@ const defaultOptions = {
4238
// on('file:preprocessor', webpack(options))
4339
//
4440
const preprocessor = (options = {}) => {
45-
log('user options:', options)
41+
debug('user options:', options)
4642

4743
// we return function that accepts the arguments provided by
4844
// the event 'file:preprocessor'
@@ -57,24 +53,24 @@ const preprocessor = (options = {}) => {
5753
// the supported file and spec file to be requested again
5854
return (file) => {
5955
const filePath = file.filePath
60-
log('get', filePath)
56+
57+
debug('get', filePath)
6158

6259
// since this function can get called multiple times with the same
6360
// filePath, we return the cached bundle promise if we already have one
6461
// since we don't want or need to re-initiate webpack for it
6562
if (bundles[filePath]) {
66-
log(`already have bundle for ${filePath}`)
63+
debug(`already have bundle for ${filePath}`)
64+
6765
return bundles[filePath]
6866
}
6967

7068
// user can override the default options
71-
let webpackOptions = Object.assign({}, defaultOptions.webpackOptions, options.webpackOptions)
72-
// here is where we load the default rules if the user has not passed
73-
// in their own configuration
74-
if (webpackOptions.module.rules === defaultOptions.webpackOptions) {
75-
webpackOptions.module.rules = defaultBabelLoaderRules()
76-
}
77-
let watchOptions = Object.assign({}, defaultOptions.watchOptions, options.watchOptions)
69+
let webpackOptions = options.webpackOptions || getDefaultWebpackOptions()
70+
const watchOptions = options.watchOptions || {}
71+
72+
debug('webpackOptions: %o', webpackOptions)
73+
debug('watchOptions: %o', watchOptions)
7874

7975
// we're provided a default output path that lives alongside Cypress's
8076
// app data files so we don't have to worry about where to put the bundled
@@ -90,8 +86,12 @@ const preprocessor = (options = {}) => {
9086
},
9187
})
9288

93-
log(`input: ${filePath}`)
94-
log(`output: ${outputPath}`)
89+
if (webpackOptions.devtool !== false) {
90+
webpackOptions.devtool = 'inline-source-map'
91+
}
92+
93+
debug(`input: ${filePath}`)
94+
debug(`output: ${outputPath}`)
9595

9696
const compiler = webpack(webpackOptions)
9797

@@ -108,7 +108,7 @@ const preprocessor = (options = {}) => {
108108
err.filePath = filePath
109109
// backup the original stack before it's potentially modified by bluebird
110110
err.originalStack = err.stack
111-
log(`errored bundling ${outputPath}`, err)
111+
debug(`errored bundling ${outputPath}`, err)
112112
latestBundle.reject(err)
113113
}
114114

@@ -129,11 +129,11 @@ const preprocessor = (options = {}) => {
129129

130130
// these stats are really only useful for debugging
131131
if (jsonStats.warnings.length > 0) {
132-
log(`warnings for ${outputPath}`)
133-
log(jsonStats.warnings)
132+
debug(`warnings for ${outputPath}`)
133+
debug(jsonStats.warnings)
134134
}
135135

136-
log('finished bundling', outputPath)
136+
debug('finished bundling', outputPath)
137137
// resolve with the outputPath so Cypress knows where to serve
138138
// the file from
139139
latestBundle.resolve(outputPath)
@@ -143,12 +143,12 @@ const preprocessor = (options = {}) => {
143143
const plugin = { name: 'CypressWebpackPreprocessor' }
144144

145145
const onCompile = () => {
146-
log('compile', filePath)
146+
debug('compile', filePath)
147147
// we overwrite the latest bundle, so that a new call to this function
148148
// returns a promise that resolves when the bundling is finished
149149
latestBundle = createDeferred()
150150
bundles[filePath] = latestBundle.promise.tap(() => {
151-
log('- compile finished for', filePath)
151+
debug('- compile finished for', filePath)
152152
// when the bundling is finished, emit 'rerun' to let Cypress
153153
// know to rerun the spec
154154
file.emit('rerun')
@@ -158,7 +158,7 @@ const preprocessor = (options = {}) => {
158158
// when we should watch, we hook into the 'compile' hook so we know when
159159
// to rerun the tests
160160
if (file.shouldWatch) {
161-
log('watching')
161+
debug('watching')
162162

163163
if (compiler.hooks) {
164164
compiler.hooks.compile.tap(plugin, onCompile)
@@ -172,7 +172,7 @@ const preprocessor = (options = {}) => {
172172
// when the spec or project is closed, we need to clean up the cached
173173
// bundle promise and stop the watcher via `bundler.close()`
174174
file.on('close', () => {
175-
log('close', filePath)
175+
debug('close', filePath)
176176
delete bundles[filePath]
177177

178178
if (file.shouldWatch) {
@@ -186,14 +186,16 @@ const preprocessor = (options = {}) => {
186186
}
187187
}
188188

189-
// provide a clone of the default options, making sure to lazy-load
190-
// babel dependencies so that they aren't required unless the user
191-
// utilizes them
189+
// provide a clone of the default options, lazy-loading them
190+
// so they aren't required unless the user utilizes them
192191
Object.defineProperty(preprocessor, 'defaultOptions', {
193192
get () {
194-
const clonedDefaults = cloneDeep(defaultOptions)
195-
clonedDefaults.webpackOptions.module.rules = defaultBabelLoaderRules()
196-
return clonedDefaults
193+
debug('get default options')
194+
195+
return {
196+
webpackOptions: getDefaultWebpackOptions(),
197+
watchOptions: {},
198+
}
197199
},
198200
})
199201

package.json

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
"secure": "nsp check",
3030
"size": "t=\"$(npm pack .)\"; wc -c \"${t}\"; tar tvf \"${t}\"; rm \"${t}\";",
3131
"test": "mocha",
32-
"test-watch": "chokidar '*.js' 'test/*.js' -c 'npm test'",
32+
"test-watch": "chokidar '*.js' 'test/*.js' -c 'mocha'",
3333
"semantic-release": "semantic-release pre && npm publish --access public && semantic-release post"
3434
},
3535
"devDependencies": {
@@ -68,8 +68,7 @@
6868
},
6969
"dependencies": {
7070
"bluebird": "3.5.0",
71-
"debug": "3.1.0",
72-
"lodash.clonedeep": "4.5.0"
71+
"debug": "3.1.0"
7372
},
7473
"release": {
7574
"verifyConditions": "condition-circle",

stubbable-require.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
module.exports = {
2+
resolve (dependency) {
3+
return require.resolve(dependency)
4+
},
5+
}

test/index_spec.js

Lines changed: 61 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ mockery.enable({
1515
mockery.registerMock('webpack', webpack)
1616

1717
const preprocessor = require('../index')
18+
const stubbableRequire = require('../stubbable-require')
1819

1920
describe('webpack preprocessor', function () {
2021
beforeEach(function () {
@@ -43,15 +44,14 @@ describe('webpack preprocessor', function () {
4344
on: sandbox.stub(),
4445
emit: sandbox.spy(),
4546
}
46-
this.options = {}
4747
this.util = {
4848
getOutputPath: sandbox.stub().returns(this.outputPath),
4949
fileUpdated: sandbox.spy(),
5050
onClose: sandbox.stub(),
5151
}
5252

53-
this.run = () => {
54-
return preprocessor(this.options)(this.file)
53+
this.run = (options, file = this.file) => {
54+
return preprocessor(options)(file)
5555
}
5656
})
5757

@@ -111,6 +111,20 @@ describe('webpack preprocessor', function () {
111111
})
112112
})
113113

114+
it('enables inline source maps', function () {
115+
return this.run().then(() => {
116+
expect(webpack.lastCall.args[0].devtool).to.equal('inline-source-map')
117+
})
118+
})
119+
120+
it('does not enable inline source maps when devtool is false', function () {
121+
const options = { webpackOptions: { devtool: false } }
122+
123+
return this.run(options).then(() => {
124+
expect(webpack.lastCall.args[0].devtool).to.be.false
125+
})
126+
})
127+
114128
it('runs when shouldWatch is false', function () {
115129
return this.run().then(() => {
116130
expect(this.compilerApi.run).to.be.called
@@ -128,8 +142,9 @@ describe('webpack preprocessor', function () {
128142
it('includes watchOptions if provided', function () {
129143
this.file.shouldWatch = true
130144
this.compilerApi.watch.yields(null, this.statsApi)
131-
this.options.watchOptions = { poll: true }
132-
return this.run().then(() => {
145+
const options = { watchOptions: { poll: true } }
146+
147+
return this.run(options).then(() => {
133148
expect(this.compilerApi.watch.lastCall.args[0]).to.eql({
134149
poll: true,
135150
})
@@ -174,6 +189,47 @@ describe('webpack preprocessor', function () {
174189
expect(this.watchApi.close).not.to.be.called
175190
})
176191
})
192+
193+
it('uses default webpack options when no user options', function () {
194+
return this.run().then(() => {
195+
expect(webpack.lastCall.args[0].module.rules[0].use).to.have.length(1)
196+
expect(webpack.lastCall.args[0].module.rules[0].use[0].loader).to.be.a('string')
197+
})
198+
})
199+
200+
it('uses default options when no user webpack options', function () {
201+
return this.run({}).then(() => {
202+
expect(webpack.lastCall.args[0].module.rules[0].use).to.have.length(1)
203+
expect(webpack.lastCall.args[0].module.rules[0].use[0].loader).to.be.a('string')
204+
})
205+
})
206+
207+
it('does not use default options when user options are non-default', function () {
208+
const options = { webpackOptions: { module: { rules: [] } } }
209+
210+
return this.run(options).then(() => {
211+
expect(webpack.lastCall.args[0].module).to.equal(options.webpackOptions.module)
212+
})
213+
})
214+
215+
it('requires babel dependencies when default options are used', function () {
216+
sandbox.spy(stubbableRequire, 'resolve')
217+
218+
return this.run().then(() => {
219+
expect(stubbableRequire.resolve).to.be.calledWith('babel-loader')
220+
expect(stubbableRequire.resolve).to.be.calledWith('@babel/preset-env')
221+
})
222+
})
223+
224+
it('does not requires babel dependencies when user options are non-default', function () {
225+
sandbox.spy(stubbableRequire, 'resolve')
226+
const options = { webpackOptions: { module: { rules: [] } } }
227+
228+
return this.run(options).then(() => {
229+
expect(stubbableRequire.resolve).not.to.be.calledWith('babel-loader')
230+
expect(stubbableRequire.resolve).not.to.be.calledWith('@babel/preset-env')
231+
})
232+
})
177233
})
178234

179235
describe('when it errors', function () {

0 commit comments

Comments
 (0)