2
2
* #### Import members from **@edx/frontend-platform**
3
3
*
4
4
* The configuration module provides utilities for working with an application's configuration
5
- * document (ConfigDocument). This module uses `process.env` to import configuration variables
6
- * from the command-line build process. It can be dynamically extended at run-time using a
7
- * `config` initialization handler. Please see the Initialization documentation for more
8
- * information on handlers and initialization phases.
5
+ * document (ConfigDocument). Configuration variables can be supplied to the
6
+ * application in four different ways. They are applied in the following order:
7
+ *
8
+ * - Build-time Configuration
9
+ * - Environment Variables
10
+ * - JavaScript File
11
+ * - Runtime Configuration
12
+ *
13
+ * Last one in wins. Variables with the same name defined via the later methods will override any
14
+ * defined using an earlier method. i.e., if a variable is defined in Runtime Configuration, that
15
+ * will override the same variable defined in either Build-time Configuration method (environment
16
+ * variables or JS file). Configuration defined in a JS file will override environment variables.
17
+ *
18
+ * ##### Build-time Configuration
19
+ *
20
+ * Build-time configuration methods add config variables into the app when it is built by webpack.
21
+ * This saves the app an API call and means it has all the information it needs to initialize right
22
+ * away. There are two methods of supplying build-time configuration: environment variables and a
23
+ * JavaScript file.
24
+ *
25
+ * ###### Environment Variables
26
+ *
27
+ * A set list of required config variables can be supplied as
28
+ * command-line environment variables during the build process.
29
+ *
30
+ * As a simple example, these are supplied on the command-line before invoking `npm run build`:
9
31
*
10
32
* ```
11
- * import { getConfig } from '@edx/frontend-platform';
33
+ * LMS_BASE_URL=http://localhost:18000 npm run build
34
+ * ```
12
35
*
13
- * const {
14
- * BASE_URL,
15
- * LMS_BASE_URL,
16
- * LOGIN_URL,
17
- * LOGIN_URL,
18
- * REFRESH_ACCESS_TOKEN_ENDPOINT,
19
- * ACCESS_TOKEN_COOKIE_NAME,
20
- * CSRF_TOKEN_API_PATH,
21
- * } = getConfig();
36
+ * Note that additional variables _cannot_ be supplied via this method without using the `config`
37
+ * initialization handler. The app won't pick them up and they'll appear `undefined`.
38
+ *
39
+ * This configuration method is being deprecated in favor of JavaScript File Configuration.
40
+ *
41
+ * ###### JavaScript File Configuration
42
+ *
43
+ * Configuration variables can be supplied in an optional file named env.config.js. This file must
44
+ * export either an Object containing configuration variables or a function. The function must
45
+ * return an Object containing configuration variables or, alternately, a promise which resolves to
46
+ * an Object.
47
+ *
48
+ * Using a function or async function allows the configuration to be resolved at runtime (because
49
+ * the function will be executed at runtime). This is not common, and the capability is included
50
+ * for the sake of flexibility.
51
+ *
52
+ * JavaScript File Configuration is well-suited to extensibility use cases or component overrides,
53
+ * in that the configuration file can depend on any installed JavaScript module. It is also the
54
+ * preferred way of doing build-time configuration if runtime configuration isn't used by your
55
+ * deployment of the platform.
56
+ *
57
+ * Exporting a config object:
58
+ * ```
59
+ * const config = {
60
+ * LMS_BASE_URL: 'http://localhost:18000'
61
+ * };
62
+ *
63
+ * export default config;
64
+ * ```
65
+ *
66
+ * Exporting a function that returns an object:
67
+ * ```
68
+ * function getConfig() {
69
+ * return {
70
+ * LMS_BASE_URL: 'http://localhost:18000'
71
+ * };
72
+ * }
73
+ * ```
74
+ *
75
+ * Exporting a function that returns a promise that resolves to an object:
76
+ * ```
77
+ * function getAsyncConfig() {
78
+ * return new Promise((resolve, reject) => {
79
+ * resolve({
80
+ * LMS_BASE_URL: 'http://localhost:18000'
81
+ * });
82
+ * });
83
+ * }
84
+ *
85
+ * export default getAsyncConfig;
86
+ * ```
87
+ *
88
+ * ##### Runtime Configuration
89
+ *
90
+ * Configuration variables can also be supplied using the "runtime configuration" method, taking
91
+ * advantage of the Micro-frontend Config API in edx-platform. More information on this API can be
92
+ * found in the ADR which introduced it:
93
+ *
94
+ * https://github.com/openedx/edx-platform/blob/master/lms/djangoapps/mfe_config_api/docs/decisions/0001-mfe-config-api.rst
95
+ *
96
+ * The runtime configuration method can be enabled by supplying a MFE_CONFIG_API_URL via one of the other
97
+ * two configuration methods above.
98
+ *
99
+ * Runtime configuration is particularly useful if you need to supply different configurations to
100
+ * a single deployment of a micro-frontend, for instance. It is also a perfectly valid alternative
101
+ * to build-time configuration, though it introduces an additional API call to edx-platform on MFE
102
+ * initialization.
103
+ *
104
+ * ##### Initialization Config Handler
105
+ *
106
+ * The configuration document can be extended by
107
+ * applications at run-time using a `config` initialization handler. Please see the Initialization
108
+ * documentation for more information on handlers and initialization phases.
109
+ *
110
+ * ```
111
+ * initialize({
112
+ * handlers: {
113
+ * config: () => {
114
+ * mergeConfig({
115
+ * CUSTOM_VARIABLE: 'custom value',
116
+ * LMS_BASE_URL: 'http://localhost:18001' // You can override variables, but this is uncommon.
117
+ * }, 'App config override handler');
118
+ * },
119
+ * },
120
+ * });
22
121
* ```
23
122
*
24
123
* @module Config
@@ -76,8 +175,17 @@ let config = {
76
175
77
176
/**
78
177
* Getter for the application configuration document. This is synchronous and merely returns a
79
- * reference to an existing object, and is thus safe to call as often as desired. The document
80
- * should have the following keys at a minimum:
178
+ * reference to an existing object, and is thus safe to call as often as desired.
179
+ *
180
+ * Example:
181
+ *
182
+ * ```
183
+ * import { getConfig } from '@edx/frontend-platform';
184
+ *
185
+ * const {
186
+ * LMS_BASE_URL,
187
+ * } = getConfig();
188
+ * ```
81
189
*
82
190
* @returns {ConfigDocument }
83
191
*/
@@ -91,6 +199,16 @@ export function getConfig() {
91
199
* The supplied config document will be tested with `ensureDefinedConfig` to ensure it does not
92
200
* have any `undefined` keys.
93
201
*
202
+ * Example:
203
+ *
204
+ * ```
205
+ * import { setConfig } from '@edx/frontend-platform';
206
+ *
207
+ * setConfig({
208
+ * LMS_BASE_URL, // This is overriding the ENTIRE document - this is not merged in!
209
+ * });
210
+ * ```
211
+ *
94
212
* @param {ConfigDocument } newConfig
95
213
*/
96
214
export function setConfig ( newConfig ) {
@@ -157,7 +275,10 @@ export function ensureConfig(keys, requester = 'unspecified application code') {
157
275
/**
158
276
* An object describing the current application configuration.
159
277
*
160
- * The implementation loads this document via `process.env` variables.
278
+ * In its most basic form, the initialization process loads this document via `process.env`
279
+ * variables. There are other ways to add configuration variables to the ConfigDocument as
280
+ * documented above (JavaScript File Configuration, Runtime Configuration, and the Initialization
281
+ * Config Handler)
161
282
*
162
283
* ```
163
284
* {
0 commit comments