Skip to content

Commit

Permalink
Add support for [email protected]
Browse files Browse the repository at this point in the history
  • Loading branch information
mrmckeb committed Apr 18, 2019
1 parent 165a5f6 commit c122019
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 10 deletions.
1 change: 1 addition & 0 deletions app/react/src/server/__mocks__/mockConfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export default {
alias: {
baseAlias: 'base-alias',
},
modules: [],
},
module: {
noParse: /jquery/,
Expand Down
2 changes: 2 additions & 0 deletions app/react/src/server/__snapshots__/cra-config.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ Object {
".js",
".jsx",
],
"modules": Array [],
},
"resolveLoader": Object {
"modules": Array [
Expand Down Expand Up @@ -115,6 +116,7 @@ Object {
".ts",
".tsx",
],
"modules": Array [],
},
"resolveLoader": Object {
"modules": Array [
Expand Down
27 changes: 26 additions & 1 deletion app/react/src/server/cra-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ import MiniCssExtractPlugin from 'mini-css-extract-plugin';
import { normalizeCondition } from 'webpack/lib/RuleSet';
import { logger } from '@storybook/node-logger';

const JSCONFIG = 'jsconfig.json';
const TSCONFIG = 'tsconfig.json';

const appDirectory = fs.realpathSync(process.cwd());
const cssExtensions = ['.css', '.scss', '.sass'];
const cssModuleExtensions = ['.module.css', '.module.scss', '.module.sass'];
const typeScriptExtensions = ['.ts', '.tsx'];
Expand All @@ -14,7 +18,6 @@ let reactScriptsPath;
export function getReactScriptsPath({ noCache } = {}) {
if (reactScriptsPath && !noCache) return reactScriptsPath;

const appDirectory = fs.realpathSync(process.cwd());
let reactScriptsScriptPath = fs.realpathSync(
path.join(appDirectory, '/node_modules/.bin/react-scripts')
);
Expand Down Expand Up @@ -106,6 +109,23 @@ export const getTypeScriptRules = (webpackConfigRules, configDir) => {
];
};

export const getModulePath = () => {
// As with CRA, we only support `jsconfig.json` if `tsconfig.json` doesn't exist.
let configName;
if (fs.existsSync(path.join(appDirectory, TSCONFIG))) {
configName = TSCONFIG;
} else if (fs.existsSync(path.join(appDirectory, JSCONFIG))) {
configName = JSCONFIG;
}

if (configName) {
// eslint-disable-next-line import/no-dynamic-require,global-require
const config = require(path.join(appDirectory, configName));
return config.compilerOptions && config.compilerOptions.baseUrl;
}
return false;
};

function mergePlugins(basePlugins, additionalPlugins) {
return [...basePlugins, ...additionalPlugins].reduce((plugins, plugin) => {
if (
Expand Down Expand Up @@ -146,6 +166,10 @@ export function applyCRAWebpackConfig(baseConfig, configDir) {
const tsExtensions = hasTsSupport ? typeScriptExtensions : [];
const extensions = [...cssExtensions, ...tsExtensions];

// Support for this was added in `[email protected]`.
// https://github.com/facebook/create-react-app/pull/6656
const modulePath = isReactScriptsInstalled('3.0.0') && getModulePath();

// Remove any rules from baseConfig that test true for any one of the extensions
const filteredBaseRules = baseConfig.module.rules.filter(
rule => !rule.test || !extensions.some(normalizeCondition(rule.test))
Expand Down Expand Up @@ -175,6 +199,7 @@ export function applyCRAWebpackConfig(baseConfig, configDir) {
resolve: {
...baseConfig.resolve,
extensions: [...baseConfig.resolve.extensions, ...tsExtensions],
modules: baseConfig.resolve.modules.concat(modulePath || []),
},
resolveLoader: {
modules: ['node_modules', path.join(getReactScriptsPath(), 'node_modules')],
Expand Down
31 changes: 23 additions & 8 deletions app/react/src/server/cra-config.test.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
import fs from 'fs';
import path from 'path';
import { getReactScriptsPath, getTypeScriptRules, applyCRAWebpackConfig } from './cra-config';
import {
applyCRAWebpackConfig,
getModulePath,
getReactScriptsPath,
getTypeScriptRules,
} from './cra-config';
import mockRules from './__mocks__/mockRules';
import mockConfig from './__mocks__/mockConfig';

jest.mock('fs', () => ({
realpathSync: jest.fn(),
realpathSync: jest.fn(() => '/test-project'),
readFileSync: jest.fn(),
existsSync: () => true,
existsSync: jest.fn(() => true),
}));
jest.mock('mini-css-extract-plugin', () => {});

Expand All @@ -16,11 +21,6 @@ const SCRIPT_PATH = '.bin/react-scripts';
const stripCwd = loaderPath => loaderPath.replace(process.cwd(), '');

describe('cra-config', () => {
beforeEach(() => {
fs.realpathSync.mockReset();
fs.realpathSync.mockImplementationOnce(() => '/test-project');
});

describe('when used with the default react-scripts package', () => {
beforeEach(() => {
fs.realpathSync.mockImplementationOnce(filePath =>
Expand Down Expand Up @@ -94,6 +94,21 @@ exit $ret`
const rules = getTypeScriptRules(mockRules, './.storybook');
expect(rules[0].include.findIndex(string => string.includes('.storybook'))).toEqual(1);
});

it('should get the baseUrl from a tsconfig.json', () => {
jest.spyOn(path, 'join').mockImplementation(() => 'project/tsconfig.json');
jest.mock(
'project/tsconfig.json',
() => ({
compilerOptions: {
baseUrl: 'src',
},
}),
{ virtual: true }
);
expect(getModulePath()).toEqual('src');
path.join.mockRestore();
});
});

describe('when used with react-scripts < 2.1.0', () => {
Expand Down
2 changes: 1 addition & 1 deletion examples/cra-ts-kitchen-sink/.env
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
SKIP_PREFLIGHT_CHECK=true
NODE_PATH=src
NODE_PATH=src

0 comments on commit c122019

Please sign in to comment.