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

#7563 Support TSX in config folder #7566

Merged
merged 1 commit into from
Jul 28, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions app/react/src/server/__mocks__/mockRules.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
export default [
{ parser: { requireEnsure: false } },
{
test: /\.(js|mjs|jsx)$/,
test: /\.(js|mjs|jsx|ts|tsx)$/,
enforce: 'pre',
use: [
{
Expand All @@ -10,7 +10,6 @@ export default [
eslintPath: '/mock_folder/node_modules/eslint/lib/api.js',
baseConfig: {
extends: ['/mock_folder/node_modules/eslint-config-react-app/index.js'],
settings: { react: { version: '999.999.999' } },
},
ignore: false,
useEslintrc: false,
Expand Down Expand Up @@ -44,7 +43,7 @@ export default [
{
loaderMap: {
svg: {
ReactComponent: '@svgr/webpack?-prettier,-svgo![path]',
ReactComponent: '@svgr/webpack?-svgo,+titleProp,+ref![path]',
},
},
},
Expand Down
12 changes: 5 additions & 7 deletions app/react/src/server/cra-config.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,18 +83,16 @@ exit $ret`

describe('when used with TypeScript', () => {
it('should return the correct config', () => {
// Normalise the return, as we know our new rules object will be an array, whereas a string is expected.
const rules = getTypeScriptRules(mockRules, './.storybook');
const rulesObject = { ...rules[0], include: rules[0].include[0] };
expect(rulesObject).toMatchObject(mockRules[2].oneOf[1]);
expect(rules.length).toBe(2);
});

// Allows using TypeScript in the `.storybook` (or config) folder.
it('should add the Storybook config directory to `include`', () => {
it('should add the Storybook config directory to `include` for all TS related rules', () => {
const rules = getTypeScriptRules(mockRules, './.storybook');
expect(rules[0].include.findIndex((string: string) => string.includes('.storybook'))).toEqual(
1
);
expect(
rules.every(rule => rule.include.find(filePath => filePath.includes('.storybook')))
).toBe(true);
});

it('should get the baseUrl from a tsconfig.json', () => {
Expand Down
64 changes: 37 additions & 27 deletions app/react/src/server/cra-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,43 +71,53 @@ export function isReactScriptsInstalled(requiredVersion = '2.0.0') {
}

export const getRules = (extensions: string[]) => (rules: RuleSetRule[]) =>
rules.reduce((craRules: any, rule: any) => {
// If at least one extension satisfies the rule test, the rule is one
// we want to extract
if (rule.test && extensions.some(normalizeCondition(rule.test))) {
// If the base test is for extensions, return early
return craRules.concat(rule);
}
rules.reduce(
(craRules, rule) => {
// If at least one extension satisfies the rule test, the rule is one
// we want to extract
if (rule.test && extensions.some(normalizeCondition(rule.test))) {
// If the base test is for extensions, return early
return craRules.concat(rule);
}

// Get any rules contained in rule.oneOf
if (!rule.test && rule.oneOf) {
craRules.push(...getRules(extensions)(rule.oneOf));
}
// Get any rules contained in rule.oneOf
if (!rule.test && rule.oneOf) {
craRules.push(...getRules(extensions)(rule.oneOf));
}

// Get any rules contained in rule.rules
if (!rule.test && rule.rules) {
craRules.push(...getRules(extensions)(rule.rules));
}
// Get any rules contained in rule.rules
if (!rule.test && rule.rules) {
craRules.push(...getRules(extensions)(rule.rules));
}

return craRules;
}, []);
return craRules;
},
[] as RuleSetRule[]
);

const getStyleRules = getRules(cssExtensions.concat(cssModuleExtensions));

export const getTypeScriptRules = (webpackConfigRules: RuleSetRule[], configDir: string) => {
const rules = getRules(typeScriptExtensions)(webpackConfigRules);
// We know CRA only has one rule targeting TS for now, which is the first rule.
const babelRule = rules[0];
// Resolves an issue where this config is parsed twice (#4903).
if (typeof babelRule.include !== 'string') return rules;

// Adds support for using TypeScript in the `.storybook` (or config) folder.
return [
{
...babelRule,
include: [babelRule.include, path.resolve(configDir)],
return rules.reduce(
(accRules, rule) => {
// Resolves an issue where this config is parsed twice (#4903).
if (typeof rule.include !== 'string') {
return [...accRules, rule];
}

return [
...accRules,
{
...rule,
include: [rule.include, path.resolve(configDir)],
},
];
},
...rules.slice(1),
];
[] as RuleSetRule[]
);
};

export const getModulePath = () => {
Expand Down