Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add JS config handling to webpack and jest configs #515

Closed
26 changes: 25 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,6 @@ if you need to do this and are running into problems.

## Local module configuration for Webpack


The development webpack configuration allows engineers to create a
\"module.config.js\" file containing local module overrides. This means
that if you\'re developing a new feature in a shared library
Expand Down Expand Up @@ -218,6 +217,31 @@ locally. To serve a production build locally:
attempt to run the build on the same port specified in the
`env.config.js` file.

## Creating a Production Build with env.config.js

To use a private `env.config.js` file during the production build, the Webpack Production config will look for an env
variable `process.env.JS_CONFIG_FILEPATH`, which should represent a file path to the desired `env.config.js`.

The only requirement is that the filepath end with `env.config.*`, with either `.js` or `.jsx` as the extension.

// examples of acceptable filepaths

JS_CONFIG_FILEPATH="{HOME}/frontends/frontend-app-learner-dashboard/prod.env.config.js"

JS_CONFIG_FILEPATH="{HOME}/frontends/frontend-app-profile/stage.env.config.jsx"

## Requiring Jest to reference env.config.js
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this mean that an env.config.js will now be required for tests to run successfully?

Maybe it already is and I just missed it.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, env.config.js isn't required to run tests, but if there are any env variables or configuration in the env.config.js file that should be used for tests, this is what will be needed in the setupTest.js file.


Jest doesn't rely on Webpack to merge the JS-based config into the Config Document,
so to ensure Jest is aware of the environment variables in env.config, add the following to the MFE's `setupTest.js`

import envConfig from '../env.config';
import mergeConfig from '@edx/frontend-platform';

...

mergeConfig(envConfig);

## Development

This project leverages the command line interface for webpack, jest,
Expand Down
11 changes: 8 additions & 3 deletions config/jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,16 @@ const fs = require('fs');

const presets = require('../lib/presets');

// This assigns the envConfigPath filepath based on whether env.config exists, otherwise it uses the fallback filepath.
// If both env.config.js and env.config.jsx files exist, then the former will be used to populate the Config Document.
let envConfigPath = path.resolve(__dirname, './jest/fallback.env.config.js');
const appEnvConfigPath = path.resolve(process.cwd(), './env.config.js');
const appEnvConfigPathJs = path.resolve(process.cwd(), './env.config.js');
const appEnvConfigPathJsx = path.resolve(process.cwd(), './env.config.jsx');
Comment on lines +9 to +10
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[curious] Is there a chance someone may want to use .ts or .tsx with the env.config file?

Copy link
Contributor

@bradenmacdonald bradenmacdonald Mar 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would! ;)
Or at the least, let me put // @ts-check at the top of env.config.jsx to turn on VS Code's TypeScript checking, and let me write the configuration with auto-completion and type checking in the IDE.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we use https://www.npmjs.com/package/glob to find the file with regex instead? It is easier to improve in the future.


if (fs.existsSync(appEnvConfigPath)) {
envConfigPath = appEnvConfigPath;
if (fs.existsSync(appEnvConfigPathJs)) {
envConfigPath = appEnvConfigPathJs;
} else if (fs.existsSync(appEnvConfigPathJsx)) {
envConfigPath = appEnvConfigPathJsx;
Comment on lines +12 to +15
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a specific reason this logic prioritizes .js over .jsx? I don't have strong feelings either way, but the decision around the prioritization should be documented.

}

module.exports = {
Expand Down
18 changes: 18 additions & 0 deletions config/webpack.prod.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const NewRelicSourceMapPlugin = require('@edx/new-relic-source-map-webpack-plugi
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const path = require('path');
const fs = require('fs');
const PostCssAutoprefixerPlugin = require('autoprefixer');
const PostCssRTLCSS = require('postcss-rtlcss');
const PostCssCustomMediaCSS = require('postcss-custom-media');
Expand All @@ -23,6 +24,23 @@ const HtmlWebpackNewRelicPlugin = require('../lib/plugins/html-webpack-new-relic
const commonConfig = require('./webpack.common.config');
const presets = require('../lib/presets');

/**
* This condition confirms whether the configuration for the MFE has switched to a JS-based configuration
* as previously implemented in frontend-build and frontend-platform. If the environment variable JS_CONFIG_FILEPATH
* exists, then an env.config.js(x) file will be copied from the location referenced by the environment variable to the
* root directory. Its env variables can be accessed with getConfig().
*
* https://github.com/openedx/frontend-build/blob/master/docs/0002-js-environment-config.md
* https://github.com/openedx/frontend-platform/blob/master/docs/decisions/0007-javascript-file-configuration.rst
*/

const envConfigPath = process.env.JS_CONFIG_FILEPATH;

if (envConfigPath) {
const envConfigFilename = envConfigPath.slice(envConfigPath.indexOf('env.config'));
fs.copyFileSync(envConfigPath, envConfigFilename);
}

// Add process env vars. Currently used only for setting the PUBLIC_PATH.
dotenv.config({
path: path.resolve(process.cwd(), '.env'),
Expand Down
Loading