preset.ts 2.6 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
import {PluginItem} from '@babel/core'
const env = process.env.NODE_ENV
const isProduction = env === 'production'
const isDevelopment = env === 'development'
const isTest = env === 'test'

type StyledJsxPlugin = [string, any] | string
type StyledJsxBabelOptions = {
  plugins?: StyledJsxPlugin[]
} | undefined

// Resolve styled-jsx plugins
function styledJsxOptions (options: StyledJsxBabelOptions) {
  if (!options) {
    return {}
  }

  if (!Array.isArray(options.plugins)) {
    return options
  }

  options.plugins = options.plugins.map((plugin: StyledJsxPlugin): StyledJsxPlugin => {
    if (Array.isArray(plugin)) {
      const [name, options] = plugin
      return [
        require.resolve(name),
        options
      ]
    }

    return require.resolve(plugin)
  })

  return options
}

type NextBabelPresetOptions = {
  'preset-env'?: any,
  'preset-react'?: any,
  'class-properties'?: any,
  'transform-runtime'?: any,
  'styled-jsx'?: StyledJsxBabelOptions
}

type BabelPreset = {
  presets?: PluginItem[] | null,
  plugins?: PluginItem[] | null
}

module.exports = (context: any, options: NextBabelPresetOptions = {}): BabelPreset => {
51 52 53 54 55 56
  const presetEnvConfig = {
    // In the test environment `modules` is often needed to be set to true, babel figures that out by itself using the `'auto'` option
    // In production/development this option is set to `false` so that webpack can handle import/export with tree-shaking
    modules: isDevelopment || isProduction ? false : 'auto',
    ...options['preset-env']
  }
57 58
  return {
    presets: [
59
      [require('@babel/preset-env').default, presetEnvConfig],
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
      [require('@babel/preset-react'), {
        // This adds @babel/plugin-transform-react-jsx-source and
        // @babel/plugin-transform-react-jsx-self automatically in development
        development: isDevelopment || isTest,
        ...options['preset-react']
      }]
    ],
    plugins: [
      require('babel-plugin-react-require'),
      require('@babel/plugin-syntax-dynamic-import'),
      require('./plugins/react-loadable-plugin'),
      [require('@babel/plugin-proposal-class-properties'), options['class-properties'] || {}],
      require('@babel/plugin-proposal-object-rest-spread'),
      [require('@babel/plugin-transform-runtime'), {
        corejs: 2,
        helpers: true,
        regenerator: true,
77
        useESModules: !isTest && presetEnvConfig.modules !== 'commonjs',
78 79 80
        ...options['transform-runtime']
      }],
      [require('styled-jsx/babel'), styledJsxOptions(options['styled-jsx'])],
81
      isProduction && require('babel-plugin-transform-react-remove-prop-types')
82 83 84
    ].filter(Boolean)
  }
}