Skip to content

Commit

Permalink
refactor(config): load the config as a JS module instead of parsing i…
Browse files Browse the repository at this point in the history
…t as JSON
  • Loading branch information
emmenko committed May 9, 2022
1 parent dc5b02e commit 8fff87e
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 49 deletions.
6 changes: 6 additions & 0 deletions .changeset/calm-apricots-carry.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@commercetools-frontend/application-config': patch
---

Internally load the Custom Application config as a JS module instead of parsing it as JSON.
This is to unlock some future work.
29 changes: 29 additions & 0 deletions packages/application-config/loaders/load-js-module.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/**
* This script file is used to load and parse a JS module in a child process,
* to isolate the Babel configuration from the main program and avoid causing
* unnecessary issues.
*
* NOTE: keep this file as a `.js` file, as we want to be able to run this
* in any Node environment.
*/

const get = require('lodash/get');

function requireModule(filePath) {
// Load JS modules using Babel, as we need to load
// the config synchronously with `require`, no `await import`.
require('@babel/register')({
babelrc: false,
extensions: ['.js', '.cjs', '.mjs', '.ts'],
presets: [
require.resolve('@commercetools-frontend/babel-preset-mc-app/production'),
],
});

// Require the module. It's expected that the module exports the application config
const moduleExport = require(filePath);
// In case we are loading an ES module, we need to pick the `default` export.
return get(moduleExport, 'default', moduleExport);
}

module.exports = requireModule;
2 changes: 1 addition & 1 deletion packages/application-config/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
"files": [
"dist",
"ssr",
"scripts",
"loaders",
"schema.json",
"package.json",
"LICENSE",
Expand Down
34 changes: 0 additions & 34 deletions packages/application-config/scripts/load-js-module.js

This file was deleted.

22 changes: 8 additions & 14 deletions packages/application-config/src/load-config.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
import type { JSONSchemaForCustomApplicationConfigurationFiles } from './schema';
import type { LoaderSync } from 'cosmiconfig';

import fs from 'fs';
import path from 'path';
import { execFileSync } from 'child_process';
import { cosmiconfigSync, defaultLoaders } from 'cosmiconfig';
import { cosmiconfigSync, defaultLoaders, type LoaderSync } from 'cosmiconfig';
import type { JSONSchemaForCustomApplicationConfigurationFiles } from './schema';
import { MissingOrInvalidConfigError } from './errors';

// Helper function to find the package root path from the current location,
Expand All @@ -23,18 +20,15 @@ const loadJsModule: LoaderSync = (filePath) => {
// Start from the parent folder
path.join(__dirname, '..')
);
// Load the JS module using a child process. This is primarly to avoid
// Load the JS module using a separate module loader. This is primarly to avoid
// unwanted behaviors using `@babel/register` in the main process.
// The loader script does the actual `require` of the given `filePath`
// and uses `@babel/register` to correctly parse and execute the file.
// The "required module output" is then written into `stdout` and parsed
// as JSON.
const output = execFileSync(
'node',
[path.join(packageRootPath, 'scripts/load-js-module.js'), filePath],
{ encoding: 'utf8' }
);
return JSON.parse(output);
const requireModule = require(path.join(
packageRootPath,
'loaders/load-js-module'
));
return requireModule(filePath);
};

const moduleName = 'custom-application-config';
Expand Down

0 comments on commit 8fff87e

Please sign in to comment.