/
index.js
145 lines (117 loc) · 5.32 KB
/
index.js
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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
/* eslint-disable filenames/match-exported */
import { get as getAppRoot } from "app-root-dir"
import { resolve as resolvePath } from "path"
import browserslist from "browserslist"
import envPreset from "babel-preset-env"
import reactPreset from "babel-preset-react"
import flowPreset from "babel-preset-flow"
import dynamicImportPlugin from "babel-plugin-syntax-dynamic-import"
import moduleResolverPlugin from "babel-plugin-module-resolver"
import fastAsyncPlugin from "babel-plugin-fast-async"
import classPropertiesPlugin from "babel-plugin-transform-class-properties"
import objectRestSpreadPlugin from "babel-plugin-transform-object-rest-spread"
import lodashPlugin from "babel-plugin-lodash"
import transformRuntimePlugin from "babel-plugin-transform-runtime"
import reactIntlPlugin from "babel-plugin-react-intl"
import removePropTypesPlugin from "babel-plugin-transform-react-remove-prop-types"
import reactInlineElementsPlugin from "babel-plugin-transform-react-inline-elements"
import reactConstantElements from "babel-plugin-transform-react-constant-elements"
export default function buildPreset(context, opts = {})
{
const presets = []
const plugins = []
const looseMode = true
const specMode = false
const defaults = {
modules: "commonjs",
target: "nodejs"
}
const options = { ...defaults, ...opts }
// There is also a BROWSERSLIST_ENV
const envValue = process.env.BABEL_ENV || process.env.NODE_ENV || "development"
const isProduction = envValue === "production"
let envTargets = {}
if (options.target === "nodejs") {
// Last stable NodeJS (LTS)
envTargets.node = "6.0"
} else if (options.target === "script" || options.target === "test") {
// Scripts which are directly used like tests can be transpiled for the current NodeJS version
envTargets.node = "current"
} else if (options.target === "browser") {
// Until this issue is fixed we can't use auto config detection for browserslist in babel-preset-env
// https://github.com/babel/babel-preset-env/issues/149
// What we do here is actually pretty clever/ytupid as we just pass over the already normalized
// browser list to browserslist again.
const autoBrowsers = browserslist(null, { env: isProduction ? "production" : "development" })
// For the abstract browsers config we let browserslist find the config file
envTargets.browsers = autoBrowsers
} else if (typeof options.target === "object") {
envTargets = options.target
}
presets.push([ envPreset, {
// Setting this to false will not transform modules.
modules: options.modules,
// Prefer built-ins which also prefers global polyfills which is the right thing to do
// for most scenarios like SPAs and NodeJS environments.
useBuiltIns: true,
loose: looseMode,
spec: specMode,
// Debug output of features, plugins and presets which are enabled.
// debug: true,
// We prefer the transpilation of the "fast-async" plugin over the
// slower and more complex Babel internal implementation.
exclude: [ "transform-regenerator", "transform-async-to-generator" ],
// Differ between development and production for our scope.
// NodeJS is generally fine in development to match the runtime version which is currently installed.
targets: envTargets
}])
presets.push(reactPreset)
presets.push(flowPreset)
// Support for new @import() syntax
plugins.push(dynamicImportPlugin)
// Optimization for cheery-picking from lodash, asyncjs, ramba and recompose.
// Auto cherry-picking es2015 imports from path imports.
plugins.push([ lodashPlugin, { id: [ "lodash", "async", "rambda", "recompose" ] }])
// Supports loading files in source folder without relative folders
plugins.push([ moduleResolverPlugin, {
root: [ resolvePath(getAppRoot(), "src") ]
}])
// Alternative to Babel Regenerator
// Implements the ES7 keywords async and await using syntax transformation at compile-time, rather than generators.
plugins.push([ fastAsyncPlugin, {
useRuntimeModule: true
}])
// Support for ES7 Class Properties (currently stage-2)
plugins.push(classPropertiesPlugin)
// Support for Object Rest Spread `...` operator in objects.
plugins.push([ objectRestSpreadPlugin, { useBuiltIns: true }])
// Use helpers, but not polyfills, in a way that omits duplication.
// For polyfills better use polyfill.io or another more sophisticated solution.
plugins.push([ transformRuntimePlugin, {
regenerator: false,
polyfill: false,
useBuiltIns: true,
useESModules: true
}])
if (isProduction) {
// Cleanup descriptions for translations from compilation output
plugins.push(reactIntlPlugin)
// Remove prop types from our code
plugins.push([ removePropTypesPlugin, { removeImport: true }])
// Replaces the React.createElement function with one that is
// more optimized for production.
// NOTE: Symbol needs to be polyfilled.
plugins.push(reactInlineElementsPlugin)
// Hoists element creation to the top level for subtrees that
// are fully static, which reduces call to React.createElement
// and the resulting allocations. More importantly, it tells
// React that the subtree hasn’t changed so React can completely
// skip it when reconciling.
plugins.push(reactConstantElements)
}
// Assemble final config
return {
presets,
plugins
}
}