diff --git a/README.md b/README.md index 3996175e..a3ffed94 100644 --- a/README.md +++ b/README.md @@ -111,6 +111,10 @@ module.exports = Object.assign(jestConfig, { > configuring things to make it less magical and more straightforward. Extending > can take place on your terms. I think this is actually a great way to do this. +### Flow support + +If the `flow-bin` is a dependency on the project the `@babel/preset-flow` will automatically get loaded you only need to install it manually by running `npm install --save-dev @babel/preset-flow` + ## Inspiration This is inspired by `react-scripts`. diff --git a/src/__tests__/utils.js b/src/__tests__/utils.js index 4aaca33d..724bee53 100644 --- a/src/__tests__/utils.js +++ b/src/__tests__/utils.js @@ -11,6 +11,16 @@ beforeEach(() => { readPkgUpSyncMock = require('read-pkg-up').sync }) +test(`optionalRequire returns undefined for not existing module`, () => { + expect( + require('../utils').optionalRequire('this-module-is-missing'), + ).toBeUndefined() +}) + +test(`optionalRequire returns undefined for known module`, () => { + expect(require('../utils').optionalRequire('prettier')).not.toBeUndefined() +}) + test('pkg is the package.json', () => { const myPkg = {name: 'blah'} mockPkg({pkg: myPkg}) diff --git a/src/config/babelrc.js b/src/config/babelrc.js index 30fb764d..0e1459a1 100644 --- a/src/config/babelrc.js +++ b/src/config/babelrc.js @@ -1,7 +1,13 @@ const browserslist = require('browserslist') const semver = require('semver') -const {ifAnyDep, parseEnv, appDirectory, pkg} = require('../utils') +const { + ifAnyDep, + parseEnv, + appDirectory, + pkg, + optionalRequire, +} = require('../utils') const {BABEL_ENV, NODE_ENV, BUILD_FORMAT} = process.env const isTest = (BABEL_ENV || NODE_ENV) === 'test' @@ -13,8 +19,11 @@ const isWebpack = parseEnv('BUILD_WEBPACK', false) const treeshake = parseEnv('BUILD_TREESHAKE', isRollup || isWebpack) const alias = parseEnv('BUILD_ALIAS', isPreact ? {react: 'preact'} : null) -const hasBabelRuntimeDep = Boolean(pkg.dependencies && pkg.dependencies['@babel/runtime']) -const RUNTIME_HELPERS_WARN = 'You should add @babel/runtime as dependency to your package. It will allow reusing so-called babel helpers from npm rather than bundling their copies into your files.' +const hasBabelRuntimeDep = Boolean( + pkg.dependencies && pkg.dependencies['@babel/runtime'], +) +const RUNTIME_HELPERS_WARN = + 'You should add @babel/runtime as dependency to your package. It will allow reusing so-called babel helpers from npm rather than bundling their copies into your files.' if (!treeshake && !hasBabelRuntimeDep) { throw new Error(RUNTIME_HELPERS_WARN) @@ -35,8 +44,8 @@ const browsersConfig = browserslist.loadConfig({path: appDirectory}) || [ const envTargets = isTest ? {node: 'current'} : isWebpack || isRollup - ? {browsers: browsersConfig} - : {node: getNodeVersion(pkg)} + ? {browsers: browsersConfig} + : {node: getNodeVersion(pkg)} const envOptions = {modules: false, loose: true, targets: envTargets} module.exports = () => ({ @@ -49,9 +58,13 @@ module.exports = () => ({ {pragma: isPreact ? 'React.h' : undefined}, ], ), + ifAnyDep(['flow-bin'], [optionalRequire('@babel/preset-flow')]), ].filter(Boolean), plugins: [ - [require.resolve('@babel/plugin-transform-runtime'), { useESModules: treeshake && !isCJS }], + [ + require.resolve('@babel/plugin-transform-runtime'), + {useESModules: treeshake && !isCJS}, + ], require.resolve('babel-plugin-macros'), alias ? [ diff --git a/src/utils.js b/src/utils.js index 74539493..18367eba 100644 --- a/src/utils.js +++ b/src/utils.js @@ -70,6 +70,14 @@ const ifDevDep = ifPkgSubProp('devDependencies') const ifAnyDep = (deps, t, f) => (hasAnyDep(arrify(deps)) ? t : f) const ifScript = ifPkgSubProp('scripts') +function optionalRequire(name) { + try { + return require.resolve(name) + } catch (e) { + return undefined + } +} + function parseEnv(name, def) { if (envIsSet(name)) { try { @@ -189,4 +197,5 @@ module.exports = { resolveKcdScripts, uniq, writeExtraEntry, + optionalRequire, }