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

Support passing babel plugin configuration in JSON #88

Merged
merged 17 commits into from
Oct 15, 2021
Merged
4 changes: 2 additions & 2 deletions src/preprocessor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@ export function preprocessor(code: string, options: PrettierOptions) {
} = options;

const plugins = getParserPlugins(prettierParser);
const experimentalParserPlugins = getExperimentalParserPlugins(experimentalBabelParserPluginsList);
const parsedExperimentalBabelParserPluginsList = getExperimentalParserPlugins(experimentalBabelParserPluginsList);

const importNodes: ImportDeclaration[] = [];

const parserOptions: ParserOptions = {
sourceType: 'module',
plugins: [...plugins, ...experimentalParserPlugins],
plugins: [...plugins, ...parsedExperimentalBabelParserPluginsList],
};

const ast = babelParser(code, parserOptions);
Expand Down
5 changes: 5 additions & 0 deletions src/utils/__tests__/get-experimental-parser-plugins.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,8 @@ test('it should return decorators with parsed options', () => {
expect(getExperimentalParserPlugins(['flow', '["decorators", { "decoratorsBeforeExport": true }]']))
.toEqual(['flow', ['decorators', { decoratorsBeforeExport: true }]]);
});

test('it should throw an Error for invalid JSON', () => {
expect(() => getExperimentalParserPlugins(['flow', '["decorators", { decoratorsBeforeExport: true }]']))
.toThrowError("Invalid JSON in experimentalBabelParserPluginsList: ");
});
23 changes: 19 additions & 4 deletions src/utils/get-experimental-parser-plugins.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ParserPlugin } from '@babel/parser';
import { ParserPlugin, ParserPluginWithOptions } from '@babel/parser';

/**
* Returns a list of babel parser plugin names
Expand All @@ -8,7 +8,22 @@ import { ParserPlugin } from '@babel/parser';
export const getExperimentalParserPlugins = (experimentalBabelParserPluginsList: string[]): ParserPlugin[] => {
// Some experimental plugins have configurations so they are passed as JSON
// in the form of ["plugin-name", { configuration: true }]
return experimentalBabelParserPluginsList.map(
pluginName => pluginName.startsWith("[") ? JSON.parse(pluginName) : pluginName
);
return experimentalBabelParserPluginsList.map(pluginNameOrJson => {
// ParserPlugin can be either a string or and array of [name: string, options: object]
// in prettier options the array will be sent in a JSON string
const isParserPluginWithOptions = pluginNameOrJson.startsWith("[");

Choose a reason for hiding this comment

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

The change I suggested was to remove this line - Instead of heuristically check if it's a JSON (like you do here), always try to parse as JSON.
Or another option that is less heuristical - you can detect plugin names using a regex (maybe `/^@?[a-zA-Z_0-9-]+(/[a-zA-Z_0-9-]+)?$/), and if it doesn't match, assume it's a JSON and then try to parse it.

Choose a reason for hiding this comment

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

BTW, what about some short documentation? The JSON string solution isn't something that users would be able to guess, to you should update the README file

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Since the options only support either strings or arrays of [string, object] I think this detection is correct and not just a heuristic.

Good catch on the documentation - done.


let plugin;
if (isParserPluginWithOptions) {
try {
plugin = JSON.parse(pluginNameOrJson);
} catch (e) {
throw Error("Invalid JSON in experimentalBabelParserPluginsList: " + pluginNameOrJson);
}
} else {
plugin = pluginNameOrJson;
}

return plugin;
});
};