From 074d0f36da88d740167b1a033d63396e6f04af0b Mon Sep 17 00:00:00 2001 From: Brody McKee Date: Sun, 31 Mar 2019 22:31:43 +0300 Subject: [PATCH] Use babel-loader from react-scripts --- .../server/__snapshots__/cra-config.test.js.snap | 12 ++++++++++++ app/react/src/server/cra-config.js | 5 ++++- app/react/src/server/cra-config.test.js | 14 +++++++++++--- app/react/src/server/framework-preset-cra.js | 16 +++++++++++++++- lib/cli/generators/REACT_SCRIPTS/index.js | 6 +++++- lib/core/src/server/build-static.js | 1 + lib/core/src/server/manager/manager-config.js | 3 ++- .../src/server/utils/load-custom-babel-config.js | 14 +++++++++----- 8 files changed, 59 insertions(+), 12 deletions(-) diff --git a/app/react/src/server/__snapshots__/cra-config.test.js.snap b/app/react/src/server/__snapshots__/cra-config.test.js.snap index 982b51be685e..13c99b384187 100644 --- a/app/react/src/server/__snapshots__/cra-config.test.js.snap +++ b/app/react/src/server/__snapshots__/cra-config.test.js.snap @@ -47,6 +47,12 @@ Object { ".jsx", ], }, + "resolveLoader": Object { + "modules": Array [ + "node_modules", + "/app/react/src/server/__mocks__/react-scripts-2-0-0/node_modules", + ], + }, } `; @@ -110,5 +116,11 @@ Object { ".tsx", ], }, + "resolveLoader": Object { + "modules": Array [ + "node_modules", + "/app/react/src/server/__mocks__/react-scripts-2-1-0/node_modules", + ], + }, } `; diff --git a/app/react/src/server/cra-config.js b/app/react/src/server/cra-config.js index 28f6bf845011..403458403e5b 100644 --- a/app/react/src/server/cra-config.js +++ b/app/react/src/server/cra-config.js @@ -60,7 +60,7 @@ export function isReactScriptsInstalled(requiredVersion = '2.0.0') { try { // eslint-disable-next-line import/no-dynamic-require,global-require const reactScriptsJson = require(path.join(getReactScriptsPath(), 'package.json')); - return !semver.lt(reactScriptsJson.version, requiredVersion); + return !semver.gtr(requiredVersion, reactScriptsJson.version); } catch (e) { return false; } @@ -176,5 +176,8 @@ export function applyCRAWebpackConfig(baseConfig, configDir) { ...baseConfig.resolve, extensions: [...baseConfig.resolve.extensions, ...tsExtensions], }, + resolveLoader: { + modules: ['node_modules', path.join(getReactScriptsPath(), 'node_modules')], + }, }; } diff --git a/app/react/src/server/cra-config.test.js b/app/react/src/server/cra-config.test.js index 21b8a1d18322..659b632ac1d6 100644 --- a/app/react/src/server/cra-config.test.js +++ b/app/react/src/server/cra-config.test.js @@ -13,6 +13,8 @@ jest.mock('mini-css-extract-plugin', () => {}); const SCRIPT_PATH = '.bin/react-scripts'; +const stripCwd = loaderPath => loaderPath.replace(process.cwd(), ''); + describe('cra-config', () => { beforeEach(() => { fs.realpathSync.mockReset(); @@ -64,7 +66,7 @@ esac if [ -x "$basedir/node" ]; then "$basedir/node" "$basedir/../custom-react-scripts/bin/react-scripts.js" "$@" ret=$? -else +else node "$basedir/../custom-react-scripts/bin/react-scripts.js" "$@" ret=$? fi @@ -103,7 +105,10 @@ exit $ret` }); it('should apply styling webpack rules', () => { - expect(applyCRAWebpackConfig(mockConfig, '/test-project')).toMatchSnapshot(); + const webpackConfig = applyCRAWebpackConfig(mockConfig, '/test-project'); + // We don't want full paths in snapshots. + webpackConfig.resolveLoader.modules = webpackConfig.resolveLoader.modules.map(stripCwd); + expect(webpackConfig).toMatchSnapshot(); }); }); @@ -116,7 +121,10 @@ exit $ret` }); it('should apply Babel, styling rules and merge plugins', () => { - expect(applyCRAWebpackConfig(mockConfig, '/test-project')).toMatchSnapshot(); + const webpackConfig = applyCRAWebpackConfig(mockConfig, '/test-project'); + // We don't want full paths in snapshots. + webpackConfig.resolveLoader.modules = webpackConfig.resolveLoader.modules.map(stripCwd); + expect(webpackConfig).toMatchSnapshot(); }); }); }); diff --git a/app/react/src/server/framework-preset-cra.js b/app/react/src/server/framework-preset-cra.js index ce37e055ddab..c49955813f41 100644 --- a/app/react/src/server/framework-preset-cra.js +++ b/app/react/src/server/framework-preset-cra.js @@ -1,5 +1,6 @@ +import path from 'path'; import { logger } from '@storybook/node-logger'; -import { applyCRAWebpackConfig, isReactScriptsInstalled } from './cra-config'; +import { applyCRAWebpackConfig, getReactScriptsPath, isReactScriptsInstalled } from './cra-config'; export function webpackFinal(config, { configDir }) { if (!isReactScriptsInstalled()) { @@ -12,6 +13,19 @@ export function webpackFinal(config, { configDir }) { return applyCRAWebpackConfig(config, configDir); } +export function managerWebpack(config) { + if (!isReactScriptsInstalled()) { + return config; + } + + return { + ...config, + resolveLoader: { + modules: ['node_modules', path.join(getReactScriptsPath(), 'node_modules')], + }, + }; +} + export function babelDefault(config) { if (!isReactScriptsInstalled()) { return config; diff --git a/lib/cli/generators/REACT_SCRIPTS/index.js b/lib/cli/generators/REACT_SCRIPTS/index.js index db513c59b148..e96134f01d16 100644 --- a/lib/cli/generators/REACT_SCRIPTS/index.js +++ b/lib/cli/generators/REACT_SCRIPTS/index.js @@ -1,6 +1,7 @@ import mergeDirs from 'merge-dirs'; import path from 'path'; import fs from 'fs'; +import semver from 'semver'; import { getVersions, getPackageJson, writePackageJson, installBabel } from '../../lib/helpers'; export default async npmOptions => { @@ -24,7 +25,10 @@ export default async npmOptions => { packageJson.devDependencies['@storybook/addon-links'] = linksVersion; packageJson.devDependencies['@storybook/addons'] = addonsVersion; - await installBabel(npmOptions, packageJson); + // When working with `create-react-app@>=2.0.0`, we know `babel-loader` is installed. + if (semver.gtr('2.0.0', packageJson.dependencies['react-scripts'])) { + await installBabel(npmOptions, packageJson); + } packageJson.scripts.storybook = 'start-storybook -p 9009'; packageJson.scripts['build-storybook'] = 'build-storybook'; diff --git a/lib/core/src/server/build-static.js b/lib/core/src/server/build-static.js index 71983003e901..f7eb42542153 100644 --- a/lib/core/src/server/build-static.js +++ b/lib/core/src/server/build-static.js @@ -122,6 +122,7 @@ async function buildManager(configType, outputDir, configDir, options) { outputDir, configDir, corePresets: [require.resolve('./manager/manager-preset.js')], + frameworkPresets: options.frameworkPresets, }); if (options.debugWebpack) { diff --git a/lib/core/src/server/manager/manager-config.js b/lib/core/src/server/manager/manager-config.js index b53924f73784..3e0b47dc11f8 100644 --- a/lib/core/src/server/manager/manager-config.js +++ b/lib/core/src/server/manager/manager-config.js @@ -9,11 +9,12 @@ async function getManagerWebpackConfig(options, presets) { } export default async options => { - const { corePresets = [], overridePresets = [], ...restOptions } = options; + const { corePresets = [], frameworkPresets = [], overridePresets = [], ...restOptions } = options; const presetsConfig = [ ...corePresets, require.resolve('../common/babel-cache-preset.js'), + ...frameworkPresets, ...loadCustomPresets(options), ...overridePresets, ]; diff --git a/lib/core/src/server/utils/load-custom-babel-config.js b/lib/core/src/server/utils/load-custom-babel-config.js index 6ba6a94ce333..2999b0104859 100644 --- a/lib/core/src/server/utils/load-custom-babel-config.js +++ b/lib/core/src/server/utils/load-custom-babel-config.js @@ -47,11 +47,15 @@ function loadFromPath(babelConfigPath) { } function isBabelLoader8() { - // eslint-disable-next-line import/no-dynamic-require,global-require - const babelLoaderPkg = require(resolveSync('babel-loader/package.json', { - basedir: process.cwd(), - })); - return satisfies(babelLoaderPkg.version, '>=8.0.0-0'); + try { + // eslint-disable-next-line import/no-dynamic-require,global-require + const babelLoaderPkg = require(resolveSync('babel-loader/package.json', { + basedir: process.cwd(), + })); + return satisfies(babelLoaderPkg.version, '>=8.0.0-0'); + } catch (e) { + return false; + } } export default async function(configDir, getDefaultConfig) {