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

Commit 0194f0f

Browse files
authored
feat: set webpack mode to development if missing (#87)
1 parent 07b7d12 commit 0194f0f

File tree

8 files changed

+121
-75
lines changed

8 files changed

+121
-75
lines changed

README.md

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ Object of webpack options. Just `require` in the options from your `webpack.conf
7575

7676
```javascript
7777
{
78+
mode: 'development',
7879
module: {
7980
rules: [
8081
{
@@ -92,7 +93,9 @@ Object of webpack options. Just `require` in the options from your `webpack.conf
9293
}
9394
```
9495

95-
Source maps are always enabled unless explicitly disabled by specifying `devtool: false`.
96+
Source maps are **always enabled** unless explicitly disabled by specifying `devtool: false`.
97+
98+
Webpack [mode](https://webpack.js.org/configuration/mode/) is set to `development` if not present. You can set `mode` to "development", "production" or "none".
9699

97100
### use babelrc
98101

@@ -172,6 +175,18 @@ DEBUG=cypress:webpack:stats
172175

173176
Use the [version of Node that matches Cypress](https://github.com/cypress-io/cypress/blob/develop/.node-version).
174177

178+
Build the typescript files:
179+
180+
```shell
181+
yarn build
182+
```
183+
184+
Watch the typescript files and rebuild on file change:
185+
186+
```shell
187+
yarn build --watch
188+
```
189+
175190
Run all tests once:
176191

177192
```shell

cypress/plugins/index.js

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,11 @@
1212
// This function is called when a project is opened or re-opened (e.g. due to
1313
// the project's config changing)
1414

15-
const webpack = require('../../')
16-
17-
// const webpackOptions = require('@packages/runner/webpack.config.ts').default
15+
const webpackPreprocessor = require('../../')
1816

1917
/**
2018
* @type {Cypress.PluginConfig}
2119
*/
2220
module.exports = (on) => {
23-
// on('file:preprocessor', webpack({ webpackOptions }))
24-
on('file:preprocessor', webpack({ }))
21+
on('file:preprocessor', webpackPreprocessor())
2522
}

index.ts

Lines changed: 29 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
1-
import * as webpack from 'webpack'
21
import * as Promise from 'bluebird'
32
import * as events from 'events'
4-
3+
import * as _ from 'lodash'
4+
import * as webpack from 'webpack'
55
import { createDeferred } from './deferred'
66

77
const path = require('path')
88
const debug = require('debug')('cypress:webpack')
99
const debugStats = require('debug')('cypress:webpack:stats')
1010

11-
const stubbableRequire = require('./stubbable-require')
12-
1311
type FilePath = string
1412

1513
// bundle promises from input spec filename to output bundled file paths
@@ -21,16 +19,17 @@ const getDefaultWebpackOptions = (): webpack.Configuration => {
2119
debug('load default options')
2220

2321
return {
22+
mode: 'development',
2423
module: {
2524
rules: [
2625
{
2726
test: /\.jsx?$/,
2827
exclude: [/node_modules/],
2928
use: [
3029
{
31-
loader: stubbableRequire.resolve('babel-loader'),
30+
loader: 'babel-loader',
3231
options: {
33-
presets: [stubbableRequire.resolve('@babel/preset-env')],
32+
presets: ['@babel/preset-env'],
3433
},
3534
},
3635
],
@@ -123,34 +122,45 @@ const preprocessor: WebpackPreprocessor = (options: PreprocessorOptions = {}): F
123122
return bundles[filePath]
124123
}
125124

126-
// user can override the default options
127-
let webpackOptions: webpack.Configuration = options.webpackOptions || getDefaultWebpackOptions()
128-
const watchOptions = options.watchOptions || {}
125+
const defaultWebpackOptions = getDefaultWebpackOptions()
129126

130-
debug('webpackOptions: %o', webpackOptions)
131-
debug('watchOptions: %o', watchOptions)
132-
133-
const entry = [filePath].concat(options.additionalEntries || [])
134127
// we're provided a default output path that lives alongside Cypress's
135128
// app data files so we don't have to worry about where to put the bundled
136129
// file on disk
137130
const outputPath = path.extname(file.outputPath) === '.js'
138131
? file.outputPath
139132
: `${file.outputPath}.js`
140133

141-
// we need to set entry and output
142-
webpackOptions = Object.assign(webpackOptions, {
134+
const entry = [filePath].concat(options.additionalEntries || [])
135+
136+
const watchOptions = options.watchOptions || {}
137+
138+
// user can override the default options
139+
const webpackOptions: webpack.Configuration = _
140+
.chain(options.webpackOptions)
141+
.defaultTo(defaultWebpackOptions)
142+
.defaults({
143+
mode: defaultWebpackOptions.mode,
144+
})
145+
.assign({
146+
// we need to set entry and output
143147
entry,
144148
output: {
145149
path: path.dirname(outputPath),
146150
filename: path.basename(outputPath),
147151
},
148152
})
153+
.tap((opts) => {
154+
if (opts.devtool !== false) {
155+
debug('setting devtool to inline-source-map')
149156

150-
if (webpackOptions.devtool !== false) {
151-
webpackOptions.devtool = 'inline-source-map'
152-
}
157+
opts.devtool = 'inline-source-map'
158+
}
159+
})
160+
.value() as any
153161

162+
debug('webpackOptions: %o', webpackOptions)
163+
debug('watchOptions: %o', watchOptions)
154164
debug(`input: ${filePath}`)
155165
debug(`output: ${outputPath}`)
156166

@@ -277,8 +287,7 @@ const preprocessor: WebpackPreprocessor = (options: PreprocessorOptions = {}): F
277287
}
278288
}
279289

280-
// provide a clone of the default options, lazy-loading them
281-
// so they aren't required unless the user utilizes them
290+
// provide a clone of the default options
282291
Object.defineProperty(preprocessor, 'defaultOptions', {
283292
get () {
284293
debug('get default options')

package.json

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,12 @@
1414
"secure": "nsp check",
1515
"semantic-release": "semantic-release",
1616
"size": "npm pack --dry",
17-
"pretest": "npm run lint && npm run build",
18-
"test": "npm run test-unit && npm run test-e2e",
17+
"pretest": "yarn lint && yarn build",
18+
"test": "yarn test-unit && yarn test-e2e",
1919
"test-debug": "node --inspect --debug-brk ./node_modules/.bin/_mocha",
2020
"test-e2e": "mocha test/e2e/*.spec.js",
2121
"test-unit": "mocha test/unit/*.spec.js",
22-
"test-watch": "chokidar '*.js' 'test/unit/*.js' -c 'npm run test-unit'",
22+
"test-watch": "yarn test-unit & chokidar '*.js' 'test/unit/*.js' -c 'yarn test-unit'",
2323
"types": "tsc --noEmit"
2424
},
2525
"husky": {
@@ -29,7 +29,8 @@
2929
},
3030
"dependencies": {
3131
"bluebird": "3.7.1",
32-
"debug": "4.1.1"
32+
"debug": "4.1.1",
33+
"lodash": "4.17.15"
3334
},
3435
"devDependencies": {
3536
"@babel/core": "^7.0.1",

stubbable-require.ts

Lines changed: 0 additions & 5 deletions
This file was deleted.

test/e2e/compilation.spec.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,12 @@ describe('webpack preprocessor - e2e', () => {
4343
})
4444

4545
it('correctly preprocesses the file', () => {
46-
return preprocessor()(file).then(() => {
46+
const options = preprocessor.defaultOptions
47+
48+
// our snapshot is minified
49+
options.webpackOptions.mode = 'production'
50+
51+
return preprocessor(options)(file).then(() => {
4752
snapshot(fs.readFileSync(outputPath).toString())
4853
})
4954
})

test/e2e/e2e.spec.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ const glob = require('fast-glob')
44

55
describe('can test', async () => {
66
// runs every test in cypress/tests/e2e as its own test
7-
// the comment above the test will determince the assertion on the results
7+
// the comment above the test will determine the assertion on the results
88
glob.sync(path.join(__dirname, '../../cypress/tests/e2e/**/*'))
99
.map((v) => {
1010
const filename = path.relative(process.cwd(), v)

test/unit/index.spec.js

Lines changed: 62 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ mockery.enable({
1717
mockery.registerMock('webpack', webpack)
1818

1919
const preprocessor = require('../../dist/index')
20-
const stubbableRequire = require('../../dist/stubbable-require')
2120

2221
describe('webpack preprocessor', function () {
2322
beforeEach(function () {
@@ -107,27 +106,33 @@ describe('webpack preprocessor', function () {
107106

108107
it('specifies the entry file', function () {
109108
return this.run().then(() => {
110-
expect(webpack.lastCall.args[0].entry).to.eql([this.file.filePath])
109+
expect(webpack).to.be.calledWithMatch({
110+
entry: [this.file.filePath],
111+
})
111112
})
112113
})
113114

114115
it('includes additional entry files', function () {
115116
return this.run({
116117
additionalEntries: ['entry-1.js', 'entry-2.js'],
117118
}).then(() => {
118-
expect(webpack.lastCall.args[0].entry).to.eql([
119-
this.file.filePath,
120-
'entry-1.js',
121-
'entry-2.js',
122-
])
119+
expect(webpack).to.be.calledWithMatch({
120+
entry: [
121+
this.file.filePath,
122+
'entry-1.js',
123+
'entry-2.js',
124+
],
125+
})
123126
})
124127
})
125128

126129
it('specifies output path and filename', function () {
127130
return this.run().then(() => {
128-
expect(webpack.lastCall.args[0].output).to.eql({
129-
path: 'output',
130-
filename: 'output.js',
131+
expect(webpack).to.be.calledWithMatch({
132+
output: {
133+
path: 'output',
134+
filename: 'output.js',
135+
},
131136
})
132137
})
133138
})
@@ -143,17 +148,53 @@ describe('webpack preprocessor', function () {
143148
})
144149
})
145150

146-
it('enables inline source maps', function () {
147-
return this.run().then(() => {
148-
expect(webpack.lastCall.args[0].devtool).to.equal('inline-source-map')
151+
describe('devtool', function () {
152+
it('enables inline source maps', function () {
153+
return this.run().then(() => {
154+
expect(webpack).to.be.calledWithMatch({
155+
devtool: 'inline-source-map',
156+
})
157+
})
158+
})
159+
160+
it('does not enable inline source maps when devtool is false', function () {
161+
const options = { webpackOptions: { devtool: false } }
162+
163+
return this.run(options).then(() => {
164+
expect(webpack).to.be.calledWithMatch({
165+
devtool: false,
166+
})
167+
})
168+
})
169+
170+
it('always sets devtool even when mode is "production"', function () {
171+
const options = { webpackOptions: { mode: 'production' } }
172+
173+
return this.run(options).then(() => {
174+
expect(webpack).to.be.calledWithMatch({
175+
devtool: 'inline-source-map',
176+
})
177+
})
149178
})
150179
})
151180

152-
it('does not enable inline source maps when devtool is false', function () {
153-
const options = { webpackOptions: { devtool: false } }
181+
describe('mode', function () {
182+
it('sets mode to development by default', function () {
183+
return this.run().then(() => {
184+
expect(webpack).to.be.calledWithMatch({
185+
mode: 'development',
186+
})
187+
})
188+
})
154189

155-
return this.run(options).then(() => {
156-
expect(webpack.lastCall.args[0].devtool).to.be.false
190+
it('follows user mode if present', function () {
191+
const options = { webpackOptions: { mode: 'production' } }
192+
193+
return this.run(options).then(() => {
194+
expect(webpack).to.be.calledWithMatch({
195+
mode: 'production',
196+
})
197+
})
157198
})
158199
})
159200

@@ -178,7 +219,7 @@ describe('webpack preprocessor', function () {
178219
const options = { watchOptions: { poll: true } }
179220

180221
return this.run(options).then(() => {
181-
expect(this.compilerApi.watch.lastCall.args[0]).to.eql({
222+
expect(this.compilerApi.watch).to.be.calledWith({
182223
poll: true,
183224
})
184225
})
@@ -252,26 +293,9 @@ describe('webpack preprocessor', function () {
252293
const options = { webpackOptions: { module: { rules: [] } } }
253294

254295
return this.run(options).then(() => {
255-
expect(webpack.lastCall.args[0].module).to.equal(options.webpackOptions.module)
256-
})
257-
})
258-
259-
it('requires babel dependencies when default options are used', function () {
260-
sinon.spy(stubbableRequire, 'resolve')
261-
262-
return this.run().then(() => {
263-
expect(stubbableRequire.resolve).to.be.calledWith('babel-loader')
264-
expect(stubbableRequire.resolve).to.be.calledWith('@babel/preset-env')
265-
})
266-
})
267-
268-
it('does not requires babel dependencies when user options are non-default', function () {
269-
sinon.spy(stubbableRequire, 'resolve')
270-
const options = { webpackOptions: { module: { rules: [] } } }
271-
272-
return this.run(options).then(() => {
273-
expect(stubbableRequire.resolve).not.to.be.calledWith('babel-loader')
274-
expect(stubbableRequire.resolve).not.to.be.calledWith('@babel/preset-env')
296+
expect(webpack).to.be.calledWithMatch({
297+
module: options.webpackOptions.module,
298+
})
275299
})
276300
})
277301
})

0 commit comments

Comments
 (0)