1- const cloneDeep = require ( 'lodash.clonedeep' )
21const path = require ( 'path' )
32const webpack = require ( 'webpack' )
4- const log = require ( 'debug' ) ( 'cypress:webpack' )
3+ const debug = require ( 'debug' ) ( 'cypress:webpack' )
54
65const createDeferred = require ( './deferred' )
6+ const stubbableRequire = require ( './stubbable-require' )
77
88const bundles = { }
99
10- // by default, we transform JavaScript supported by @babel/preset-env
11- const defaultBabelLoaderRules = ( ) => {
12- return [
13- {
14- test : / \. j s ? $ / ,
15- exclude : [ / n o d e _ m o d u l e s / ] ,
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 : / \. j s x ? $ / ,
20+ exclude : [ / n o d e _ m o d u l e s / ] ,
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//
4440const 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
@@ -94,8 +90,8 @@ const preprocessor = (options = {}) => {
9490 webpackOptions . devtool = 'inline-source-map'
9591 }
9692
97- log ( `input: ${ filePath } ` )
98- log ( `output: ${ outputPath } ` )
93+ debug ( `input: ${ filePath } ` )
94+ debug ( `output: ${ outputPath } ` )
9995
10096 const compiler = webpack ( webpackOptions )
10197
@@ -112,7 +108,7 @@ const preprocessor = (options = {}) => {
112108 err . filePath = filePath
113109 // backup the original stack before it's potentially modified by bluebird
114110 err . originalStack = err . stack
115- log ( `errored bundling ${ outputPath } ` , err )
111+ debug ( `errored bundling ${ outputPath } ` , err )
116112 latestBundle . reject ( err )
117113 }
118114
@@ -133,11 +129,11 @@ const preprocessor = (options = {}) => {
133129
134130 // these stats are really only useful for debugging
135131 if ( jsonStats . warnings . length > 0 ) {
136- log ( `warnings for ${ outputPath } ` )
137- log ( jsonStats . warnings )
132+ debug ( `warnings for ${ outputPath } ` )
133+ debug ( jsonStats . warnings )
138134 }
139135
140- log ( 'finished bundling' , outputPath )
136+ debug ( 'finished bundling' , outputPath )
141137 // resolve with the outputPath so Cypress knows where to serve
142138 // the file from
143139 latestBundle . resolve ( outputPath )
@@ -147,12 +143,12 @@ const preprocessor = (options = {}) => {
147143 const plugin = { name : 'CypressWebpackPreprocessor' }
148144
149145 const onCompile = ( ) => {
150- log ( 'compile' , filePath )
146+ debug ( 'compile' , filePath )
151147 // we overwrite the latest bundle, so that a new call to this function
152148 // returns a promise that resolves when the bundling is finished
153149 latestBundle = createDeferred ( )
154150 bundles [ filePath ] = latestBundle . promise . tap ( ( ) => {
155- log ( '- compile finished for' , filePath )
151+ debug ( '- compile finished for' , filePath )
156152 // when the bundling is finished, emit 'rerun' to let Cypress
157153 // know to rerun the spec
158154 file . emit ( 'rerun' )
@@ -162,7 +158,7 @@ const preprocessor = (options = {}) => {
162158 // when we should watch, we hook into the 'compile' hook so we know when
163159 // to rerun the tests
164160 if ( file . shouldWatch ) {
165- log ( 'watching' )
161+ debug ( 'watching' )
166162
167163 if ( compiler . hooks ) {
168164 compiler . hooks . compile . tap ( plugin , onCompile )
@@ -176,7 +172,7 @@ const preprocessor = (options = {}) => {
176172 // when the spec or project is closed, we need to clean up the cached
177173 // bundle promise and stop the watcher via `bundler.close()`
178174 file . on ( 'close' , ( ) => {
179- log ( 'close' , filePath )
175+ debug ( 'close' , filePath )
180176 delete bundles [ filePath ]
181177
182178 if ( file . shouldWatch ) {
@@ -190,14 +186,16 @@ const preprocessor = (options = {}) => {
190186 }
191187}
192188
193- // provide a clone of the default options, making sure to lazy-load
194- // babel dependencies so that they aren't required unless the user
195- // utilizes them
189+ // provide a clone of the default options, lazy-loading them
190+ // so they aren't required unless the user utilizes them
196191Object . defineProperty ( preprocessor , 'defaultOptions' , {
197192 get ( ) {
198- const clonedDefaults = cloneDeep ( defaultOptions )
199- clonedDefaults . webpackOptions . module . rules = defaultBabelLoaderRules ( )
200- return clonedDefaults
193+ debug ( 'get default options' )
194+
195+ return {
196+ webpackOptions : getDefaultWebpackOptions ( ) ,
197+ watchOptions : { } ,
198+ }
201199 } ,
202200} )
203201
0 commit comments