-
Notifications
You must be signed in to change notification settings - Fork 52
/
craco.config.js
202 lines (185 loc) · 7.14 KB
/
craco.config.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
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
const path = require('path')
const { addBeforeLoader, getLoaders, loaderByName } = require('@craco/craco')
const BabelRcPlugin = require('@jackwilsdon/craco-use-babelrc')
const CircularDependencyPlugin = require('circular-dependency-plugin')
const fastRefreshCracoPlugin = require('craco-fast-refresh')
const fs = require('fs-extra')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin')
const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin')
const TerserPlugin = require('terser-webpack-plugin')
const webpack = require('webpack')
const findBackwardsCompatibleEnvVar = (varName) => {
let value = null
if (!process.env[varName]) {
value = process.argv.find((arg) => arg.includes(`--env.${varName}`))
if (value) {
value = value.split(`--env.${varName}=`)[1] || null
}
}
return value
}
module.exports = {
plugins: [{ plugin: BabelRcPlugin }, { plugin: fastRefreshCracoPlugin }],
// This is disabled as it creates a race condition which prevents load
// See https://github.com/facebook/create-react-app/issues/10315
// Type checking is done via babel
typescript: { enableTypeChecking: false },
/**
* Webpack can be passed a few environment variables to override the default
* files used to run this project. The environment variables are CUSTOM_CSS,
* HTML_FILE, YAML_CONFIG, and JS_CONFIG. For example:
*
* env YAML_CONFIG=/absolute/path/to/config.yml yarn start
*/
webpack: {
// eslint-disable-next-line complexity
configure: function (webpackConfig, { env, paths }) {
// First, check for env variables passed in the "old" way, and
// convert them to "proper" env variables
const backwardsCompatibleEnv = {}
backwardsCompatibleEnv.YAML_CONFIG =
findBackwardsCompatibleEnvVar('YAML_CONFIG')
backwardsCompatibleEnv.JS_CONFIG =
findBackwardsCompatibleEnvVar('JS_CONFIG')
backwardsCompatibleEnv.HTML_FILE =
findBackwardsCompatibleEnvVar('HTML_FILE')
backwardsCompatibleEnv.CUSTOM_CSS =
findBackwardsCompatibleEnvVar('CUSTOM_CSS')
const DEV_ENV = env === 'development'
// Config items to adjust behavior to match mastarm behavior
paths.appBuild = webpackConfig.output.path = path.join(__dirname, 'dist')
paths.appSrc = path.resolve(__dirname, 'lib')
paths.appIndexJs = path.resolve(__dirname, 'lib/main.js')
// Support YAML
const yamlLoader = {
loader: ['json-loader', 'yaml-loader'],
test: /\.(yml|yaml)$/
}
addBeforeLoader(webpackConfig, loaderByName('file-loader'), yamlLoader)
// Support webfonts (for font awesome)
const webfontLoader = {
loader: ['url-loader'],
test: /\.(svg|eot|woff|woff2|ttf)$/
}
addBeforeLoader(webpackConfig, loaderByName('file-loader'), webfontLoader)
// Support typescript
const { matches } = getLoaders(
webpackConfig,
loaderByName('babel-loader')
)
matches.forEach(({ loader }) => {
loader.test = /\.(js|jsx|ts|tsx)$/
loader.exclude = /node_modules/
})
// Gather the CSS, HTML, YAML, and JS override files.
const CUSTOM_CSS =
(process.env && process.env.CUSTOM_CSS) ||
backwardsCompatibleEnv.CUSTOM_CSS ||
'../example.css'
const HTML_FILE =
(process.env && process.env.HTML_FILE) ||
backwardsCompatibleEnv.HTML_FILE ||
'lib/index.tpl.html'
const YAML_CONFIG =
(process.env && process.env.YAML_CONFIG) ||
backwardsCompatibleEnv.YAML_CONFIG ||
'../example-config.yml'
// resolve the custom js file. If it is present, copy the file to a
// temporary folder within this project so that the file will be able to
// use the node_modules from this project
let customJsFile = './config.js'
const JS_CONFIG =
(process.env && process.env.JS_CONFIG) ||
backwardsCompatibleEnv.JS_CONFIG ||
null
if (JS_CONFIG) {
const splitPath = JS_CONFIG.split(path.sep)
customJsFile = `../tmp/${splitPath[splitPath.length - 1]}`
// copy location is relative to root, while js file for app is relative to lib
fs.copySync(JS_CONFIG, `./tmp/${splitPath[splitPath.length - 1]}`)
}
// Support React hot-reloading
const hotLoaderEntries = []
if (DEV_ENV) {
hotLoaderEntries.push(
require.resolve('react-dev-utils/webpackHotDevClient')
)
}
webpackConfig.entry = [...hotLoaderEntries, paths.appIndexJs]
// Allow for manual configuration of optimization plugins
webpackConfig.optimization = {
minimizer: [new TerserPlugin(), new OptimizeCSSAssetsPlugin({})]
}
const MAX_IMPORT_CYCLES = 7 // based on existing cycles.
let detectedCycles = []
// Custom plugins to allow trimet-mod-otp integration
const hotLoaderPlugins = []
if (env === 'development') {
hotLoaderPlugins.push(new ReactRefreshWebpackPlugin())
}
webpackConfig.plugins = [
...hotLoaderPlugins,
new HtmlWebpackPlugin({
filename: 'index.html',
inject: 'body',
template: HTML_FILE
}),
new MiniCssExtractPlugin(),
new webpack.DefinePlugin({
CSS: JSON.stringify(CUSTOM_CSS),
JS_CONFIG: JSON.stringify(customJsFile),
// Optionally override the default config files with some other
// files.
YAML_CONFIG: JSON.stringify(YAML_CONFIG)
}),
new CircularDependencyPlugin({
allowAsyncCycles: false,
cwd: './lib',
exclude: /node_modules/,
failOnError: true,
include: /lib/,
onDetected({ paths }) {
detectedCycles.push(paths.join(' -> '))
},
onEnd({ compilation }) {
if (detectedCycles.length > MAX_IMPORT_CYCLES) {
compilation.errors.push(
new Error(
`Too many circular dependencies. Detected: ${
detectedCycles.length
}, Allowed: ${MAX_IMPORT_CYCLES} (see config):\n${detectedCycles.join(
'\n'
)}`
)
)
} else if (detectedCycles.length > 0) {
console.warn(
`${detectedCycles.length} circular dependencies were found:`
)
console.warn(detectedCycles.join('\n'))
}
},
onStart() {
detectedCycles = []
}
})
].concat(DEV_ENV ? [] : [new webpack.optimize.AggressiveMergingPlugin()])
// Enable hot-reloading
webpackConfig.devServer = {
hot: true,
static: './dist'
}
// Make source-maps useful
webpackConfig.devtool = DEV_ENV ? 'eval-cheap-module-source-map' : 'none'
// Match mastarm behavior
webpackConfig.output = {
filename: 'bundle.js',
path: path.join(__dirname, '/dist'),
publicPath: ''
}
return webpackConfig
}
}
}