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
@@ -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
192191Object . 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
0 commit comments