@@ -45,14 +45,17 @@ export default function webpackConfigFactory(buildOptions) {
4545 const ifProdClient = ifElse ( isProd && isClient ) ;
4646
4747 console . log (
48- `==> Creating ${ isProd ? 'an optimised' : 'a development' } bundle configuration for the "${ target } "` ,
48+ `==> Creating ${ isProd
49+ ? 'an optimised'
50+ : 'a development' } bundle configuration for the "${ target } "`,
4951 ) ;
5052
51- const bundleConfig = isServer || isClient
52- ? // This is either our "server" or "client" bundle.
53- config ( [ 'bundles' , target ] )
54- : // Otherwise it must be an additional node bundle.
55- config ( [ 'additionalNodeBundles' , target ] ) ;
53+ const bundleConfig =
54+ isServer || isClient
55+ ? // This is either our "server" or "client" bundle.
56+ config ( [ 'bundles' , target ] )
57+ : // Otherwise it must be an additional node bundle.
58+ config ( [ 'additionalNodeBundles' , target ] ) ;
5659
5760 if ( ! bundleConfig ) {
5861 throw new Error ( 'No bundle configuration exists for target:' , target ) ;
@@ -75,7 +78,9 @@ export default function webpackConfigFactory(buildOptions) {
7578 // Required to support hot reloading of our client.
7679 ifDevClient (
7780 ( ) =>
78- `webpack-hot-middleware/client?reload=true&path=http://${ config ( 'host' ) } :${ config ( 'clientDevServerPort' ) } /__webpack_hmr` ,
81+ `webpack-hot-middleware/client?reload=true&path=http://${ config ( 'host' ) } :${ config (
82+ 'clientDevServerPort' ,
83+ ) } /__webpack_hmr`,
7984 ) ,
8085 // The source entry file for the bundle.
8186 path . resolve ( appRootDir . get ( ) , bundleConfig . srcEntryFile ) ,
@@ -109,7 +114,9 @@ export default function webpackConfigFactory(buildOptions) {
109114 publicPath : ifDev (
110115 // As we run a seperate development server for our client and server
111116 // bundles we need to use an absolute http path for the public path.
112- `http://${ config ( 'host' ) } :${ config ( 'clientDevServerPort' ) } ${ config ( 'bundles.client.webPath' ) } ` ,
117+ `http://${ config ( 'host' ) } :${ config ( 'clientDevServerPort' ) } ${ config (
118+ 'bundles.client.webPath' ,
119+ ) } `,
113120 // Otherwise we expect our bundled client to be served from this path.
114121 bundleConfig . webPath ,
115122 ) ,
@@ -212,6 +219,11 @@ export default function webpackConfigFactory(buildOptions) {
212219 } ) ,
213220 ) ,
214221
222+ // Implement webpack 3 scope hoisting that will remove function wrappers
223+ // around your modules you may see some small size improvements. However,
224+ // the significant improvement will be how fast the JavaScript loads in the browser.
225+ ifProdClient ( new webpack . optimize . ModuleConcatenationPlugin ( ) ) ,
226+
215227 // We use this so that our generated [chunkhash]'s are only different if
216228 // the content for our respective chunks have changed. This optimises
217229 // our long term browser caching strategy for our client bundle, avoiding
@@ -420,95 +432,109 @@ export default function webpackConfigFactory(buildOptions) {
420432 // -----------------------------------------------------------------------
421433 ] ) ,
422434 module : {
423- rules : removeNil ( [
424- // JAVASCRIPT
435+ // Use strict export presence so that a missing export becomes a compile error.
436+ strictExportPresence : true ,
437+ rules : [
425438 {
426- test : / \. j s x ? $ / ,
427- // We will defer all our js processing to the happypack plugin
428- // named "happypack-javascript".
429- // See the respective plugin within the plugins section for full
430- // details on what loader is being implemented.
431- loader : 'happypack/loader?id=happypack-javascript' ,
432- include : removeNil ( [
433- ...bundleConfig . srcPaths . map ( srcPath => path . resolve ( appRootDir . get ( ) , srcPath ) ) ,
434- ifProdClient ( path . resolve ( appRootDir . get ( ) , 'src/html' ) ) ,
435- ] ) ,
436- } ,
437-
438- // CSS
439- // This is bound to our server/client bundles as we only expect to be
440- // serving the client bundle as a Single Page Application through the
441- // server.
442- ifElse ( isClient || isServer ) (
443- mergeDeep (
439+ // "oneOf" will traverse all imports with following loaders until one will
440+ // match the requirements. When no loader matches it will fallback to the
441+ // "file" loader at the end of the loader list.
442+ oneOf : removeNil ( [
443+ // JAVASCRIPT
444444 {
445- test : / \. c s s $ / ,
445+ test : / \. j s x ? $ / ,
446+ // We will defer all our js processing to the happypack plugin
447+ // named "happypack-javascript".
448+ // See the respective plugin within the plugins section for full
449+ // details on what loader is being implemented.
450+ loader : 'happypack/loader?id=happypack-javascript' ,
451+ include : removeNil ( [
452+ ...bundleConfig . srcPaths . map ( srcPath => path . resolve ( appRootDir . get ( ) , srcPath ) ) ,
453+ ifProdClient ( path . resolve ( appRootDir . get ( ) , 'src/html' ) ) ,
454+ ] ) ,
446455 } ,
447- // For development clients we will defer all our css processing to the
448- // happypack plugin named "happypack-devclient-css".
449- // See the respective plugin within the plugins section for full
450- // details on what loader is being implemented.
451- ifDevClient ( {
452- loaders : [ 'happypack/loader?id=happypack-devclient-css' ] ,
456+
457+ // CSS
458+ // This is bound to our server/client bundles as we only expect to be
459+ // serving the client bundle as a Single Page Application through the
460+ // server.
461+ ifElse ( isClient || isServer ) (
462+ mergeDeep (
463+ {
464+ test : / \. c s s $ / ,
465+ } ,
466+ // For development clients we will defer all our css processing to the
467+ // happypack plugin named "happypack-devclient-css".
468+ // See the respective plugin within the plugins section for full
469+ // details on what loader is being implemented.
470+ ifDevClient ( {
471+ loaders : [ 'happypack/loader?id=happypack-devclient-css' ] ,
472+ } ) ,
473+ // For a production client build we use the ExtractTextPlugin which
474+ // will extract our CSS into CSS files. We don't use happypack here
475+ // as there are some edge cases where it fails when used within
476+ // an ExtractTextPlugin instance.
477+ // Note: The ExtractTextPlugin needs to be registered within the
478+ // plugins section too.
479+ ifProdClient ( ( ) => ( {
480+ loader : ExtractTextPlugin . extract ( {
481+ fallback : 'style-loader' ,
482+ use : [ 'css-loader' ] ,
483+ } ) ,
484+ } ) ) ,
485+ // When targetting the server we use the "/locals" version of the
486+ // css loader, as we don't need any css files for the server.
487+ ifNode ( {
488+ loaders : [ 'css-loader/locals' ] ,
489+ } ) ,
490+ ) ,
491+ ) ,
492+
493+ // MODERNIZR
494+ // This allows you to do feature detection.
495+ // @see https://modernizr.com/docs
496+ // @see https://github.com/peerigon/modernizr-loader
497+ ifClient ( {
498+ test : / \. m o d e r n i z r r c .j s $ / ,
499+ loader : 'modernizr-loader' ,
453500 } ) ,
454- // For a production client build we use the ExtractTextPlugin which
455- // will extract our CSS into CSS files. We don't use happypack here
456- // as there are some edge cases where it fails when used within
457- // an ExtractTextPlugin instance.
458- // Note: The ExtractTextPlugin needs to be registered within the
459- // plugins section too.
460- ifProdClient ( ( ) => ( {
461- loader : ExtractTextPlugin . extract ( {
462- fallback : 'style-loader' ,
463- use : [ 'css-loader' ] ,
464- } ) ,
465- } ) ) ,
466- // When targetting the server we use the "/locals" version of the
467- // css loader, as we don't need any css files for the server.
468- ifNode ( {
469- loaders : [ 'css-loader/locals' ] ,
501+ ifClient ( {
502+ test : / \. m o d e r n i z r r c ( \. j s o n ) ? $ / ,
503+ loader : 'modernizr-loader!json-loader' ,
470504 } ) ,
471- ) ,
472- ) ,
473505
474- // ASSETS (Images/Fonts/etc)
475- // This is bound to our server/client bundles as we only expect to be
476- // serving the client bundle as a Single Page Application through the
477- // server.
478- ifElse ( isClient || isServer ) ( ( ) => ( {
479- test : new RegExp ( `\\.(${ config ( 'bundleAssetTypes' ) . join ( '|' ) } )$` , 'i' ) ,
480- loader : 'file-loader' ,
481- query : {
482- // What is the web path that the client bundle will be served from?
483- // The same value has to be used for both the client and the
484- // server bundles in order to ensure that SSR paths match the
485- // paths used on the client.
486- publicPath : isDev
487- ? // When running in dev mode the client bundle runs on a
488- // seperate port so we need to put an absolute path here.
489- `http://${ config ( 'host' ) } :${ config ( 'clientDevServerPort' ) } ${ config ( 'bundles.client.webPath' ) } `
490- : // Otherwise we just use the configured web path for the client.
491- config ( 'bundles.client.webPath' ) ,
492- // We only emit files when building a web bundle, for the server
493- // bundle we only care about the file loader being able to create
494- // the correct asset URLs.
495- emitFile : isClient ,
496- } ,
497- } ) ) ,
498-
499- // MODERNIZR
500- // This allows you to do feature detection.
501- // @see https://modernizr.com/docs
502- // @see https://github.com/peerigon/modernizr-loader
503- ifClient ( {
504- test : / \. m o d e r n i z r r c .j s $ / ,
505- loader : 'modernizr-loader' ,
506- } ) ,
507- ifClient ( {
508- test : / \. m o d e r n i z r r c ( \. j s o n ) ? $ / ,
509- loader : 'modernizr-loader!json-loader' ,
510- } ) ,
511- ] ) ,
506+ // ASSETS (Images/Fonts/etc)
507+ // This is bound to our server/client bundles as we only expect to be
508+ // serving the client bundle as a Single Page Application through the
509+ // server.
510+ ifElse ( isClient || isServer ) ( ( ) => ( {
511+ loader : 'file-loader' ,
512+ exclude : [ / \. j s $ / , / \. h t m l $ / , / \. j s o n $ / ] ,
513+ query : {
514+ // What is the web path that the client bundle will be served from?
515+ // The same value has to be used for both the client and the
516+ // server bundles in order to ensure that SSR paths match the
517+ // paths used on the client.
518+ publicPath : isDev
519+ ? // When running in dev mode the client bundle runs on a
520+ // seperate port so we need to put an absolute path here.
521+ `http://${ config ( 'host' ) } :${ config ( 'clientDevServerPort' ) } ${ config (
522+ 'bundles.client.webPath' ,
523+ ) } `
524+ : // Otherwise we just use the configured web path for the client.
525+ config ( 'bundles.client.webPath' ) ,
526+ // We only emit files when building a web bundle, for the server
527+ // bundle we only care about the file loader being able to create
528+ // the correct asset URLs.
529+ emitFile : isClient ,
530+ } ,
531+ } ) ) ,
532+
533+ // Do not add any loader after file loader (fallback loader)
534+ // Make sure to add the new loader(s) before the "file" loader.
535+ ] ) ,
536+ } ,
537+ ] ,
512538 } ,
513539 } ;
514540
0 commit comments