@@ -13,20 +13,22 @@ const WebpackConfig = require('./lib/WebpackConfig');
13
13
const configGenerator = require ( './lib/config-generator' ) ;
14
14
const validator = require ( './lib/config/validator' ) ;
15
15
const PrettyError = require ( 'pretty-error' ) ;
16
- const runtimeConfig = require ( './lib/context' ) . runtimeConfig ;
17
16
const logger = require ( './lib/logger' ) ;
17
+ const parseRuntime = require ( './lib/config/parse-runtime' ) ;
18
18
19
- // at this time, the encore executable should have set the runtimeConfig
20
- if ( ! runtimeConfig ) {
21
- throw new Error ( 'Are you trying to require index.js directly?' ) ;
22
- }
19
+ let webpackConfig = null ;
20
+ let runtimeConfig = require ( './lib/context' ) . runtimeConfig ;
23
21
24
- let webpackConfig = new WebpackConfig ( runtimeConfig ) ;
25
- if ( runtimeConfig . verbose ) {
26
- logger . verbose ( ) ;
22
+ // If runtimeConfig is already set webpackConfig can directly
23
+ // be initialized here.
24
+ if ( runtimeConfig && ( webpackConfig === null ) ) {
25
+ webpackConfig = new WebpackConfig ( runtimeConfig ) ;
26
+ if ( runtimeConfig . verbose ) {
27
+ logger . verbose ( ) ;
28
+ }
27
29
}
28
30
29
- module . exports = {
31
+ const publicApi = {
30
32
/**
31
33
* The directory where your files should be output.
32
34
*
@@ -431,17 +433,9 @@ module.exports = {
431
433
* @returns {* }
432
434
*/
433
435
getWebpackConfig ( ) {
434
- try {
435
- validator ( webpackConfig ) ;
436
+ validator ( webpackConfig ) ;
436
437
437
- return configGenerator ( webpackConfig ) ;
438
- } catch ( error ) {
439
- // prettifies errors thrown by our library
440
- const pe = new PrettyError ( ) ;
441
-
442
- console . log ( pe . render ( error ) ) ;
443
- process . exit ( 1 ) ; // eslint-disable-line
444
- }
438
+ return configGenerator ( webpackConfig ) ;
445
439
} ,
446
440
447
441
/**
@@ -454,5 +448,99 @@ module.exports = {
454
448
*/
455
449
reset ( ) {
456
450
webpackConfig = new WebpackConfig ( runtimeConfig ) ;
457
- }
451
+ } ,
452
+
453
+ /**
454
+ * Initialize the runtime environment.
455
+ *
456
+ * It can be used to directly manipulate the Encore API without
457
+ * executing the "./node_module/.bin/encore" utility.
458
+ *
459
+ * Encore.configureRuntimeEnvironment(
460
+ * // Environment to use (dev, dev-server, production)
461
+ * 'dev-server',
462
+ *
463
+ * // Same options you would use with the
464
+ * // CLI utility with their name in
465
+ * // camelCase.
466
+ * {
467
+ * https: true,
468
+ * keepPublicPath: true
469
+ * }
470
+ * )
471
+ *
472
+ * Be aware than using this method will also reset the current
473
+ * webpack configuration.
474
+ *
475
+ * @param {string } environment
476
+ * @param {object } options
477
+ * @returns {exports }
478
+ */
479
+ configureRuntimeEnvironment ( environment , options = { } ) {
480
+ runtimeConfig = parseRuntime (
481
+ Object . assign (
482
+ { } ,
483
+ require ( 'yargs/yargs' ) ( [ environment ] ) . argv ,
484
+ options
485
+ ) ,
486
+ process . cwd ( )
487
+ ) ;
488
+
489
+ if ( runtimeConfig . verbose ) {
490
+ logger . verbose ( ) ;
491
+ }
492
+
493
+ webpackConfig = new WebpackConfig ( runtimeConfig ) ;
494
+
495
+ return this ;
496
+ } ,
497
+
498
+ /**
499
+ * Clear the runtime environment.
500
+ *
501
+ * Be aware than using this method will also reset the
502
+ * current webpack configuration.
503
+ *
504
+ * @returns {void }
505
+ */
506
+ clearRuntimeEnvironment ( ) {
507
+ runtimeConfig = null ;
508
+ webpackConfig = null ;
509
+ } ,
458
510
} ;
511
+
512
+ // Proxy the API in order to prevent calls to most of its methods
513
+ // if the webpackConfig object hasn't been initialized yet.
514
+ const publicApiProxy = new Proxy ( publicApi , {
515
+ get : ( target , prop ) => {
516
+ if ( typeof target [ prop ] === 'function' ) {
517
+ // These methods of the public API can be called even if the
518
+ // webpackConfig object hasn't been initialized yet.
519
+ const safeMethods = [
520
+ 'configureRuntimeEnvironment' ,
521
+ 'clearRuntimeEnvironment' ,
522
+ ] ;
523
+
524
+ if ( ! webpackConfig && ( safeMethods . indexOf ( prop ) === - 1 ) ) {
525
+ throw new Error ( `Encore.${ prop } () cannot be called yet because the runtime environment doesn't appear to be configured. Try calling Encore.configureRuntimeEnvironment() first.` ) ;
526
+ } else {
527
+ // Either a safe method has been called or the webpackConfig
528
+ // object is already available. In this case act as a passthrough.
529
+ return ( ...parameters ) => {
530
+ try {
531
+ const res = target [ prop ] ( ...parameters ) ;
532
+ return ( res === target ) ? publicApiProxy : res ;
533
+ } catch ( error ) {
534
+ // prettifies errors thrown by our library
535
+ const pe = new PrettyError ( ) ;
536
+
537
+ console . log ( pe . render ( error ) ) ;
538
+ process . exit ( 1 ) ; // eslint-disable-line
539
+ }
540
+ } ;
541
+ }
542
+ }
543
+ }
544
+ } ) ;
545
+
546
+ module . exports = publicApiProxy ;
0 commit comments