@@ -13,20 +13,22 @@ const WebpackConfig = require('./lib/WebpackConfig');
1313const configGenerator = require ( './lib/config-generator' ) ;
1414const validator = require ( './lib/config/validator' ) ;
1515const PrettyError = require ( 'pretty-error' ) ;
16- const runtimeConfig = require ( './lib/context' ) . runtimeConfig ;
1716const logger = require ( './lib/logger' ) ;
17+ const parseRuntime = require ( './lib/config/parse-runtime' ) ;
1818
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 ;
2321
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+ }
2729}
2830
29- module . exports = {
31+ const publicApi = {
3032 /**
3133 * The directory where your files should be output.
3234 *
@@ -431,17 +433,9 @@ module.exports = {
431433 * @returns {* }
432434 */
433435 getWebpackConfig ( ) {
434- try {
435- validator ( webpackConfig ) ;
436+ validator ( webpackConfig ) ;
436437
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 ) ;
445439 } ,
446440
447441 /**
@@ -454,5 +448,99 @@ module.exports = {
454448 */
455449 reset ( ) {
456450 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+ } ,
458510} ;
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