-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathcraco.config.js
151 lines (132 loc) · 6.35 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
/* eslint-disable prefer-import/prefer-import-over-require */
const path = require('path');
const fs = require('fs');
const { getLoaders, loaderByName, addBeforeLoader } = require('@craco/craco');
module.exports = {
style: {
postcss: {
mode: 'file',
},
},
plugins: [
// Setup aliases
{
plugin: {
overrideWebpackConfig: ({ webpackConfig }) => {
// Make react hooks work when libraries are linked: https://github.com/webpack/webpack/issues/8607
webpackConfig.resolve.alias.react = require.resolve('react');
// Alias nextTick to setImmediate because of timers being throttled when background is inactive
// This was making IPFS very slow
// See: https://github.com/webpack/node-libs-browser/issues/92
// See: https://github.com/ipfs/js-ipfs-bitswap/issues/196#issuecomment-502130902
webpackConfig.resolve.alias['async/nextTick'] = require.resolve('async/setImmediate');
return webpackConfig;
},
},
},
// Setup babel-loader to use babel.config.js
{
plugin: {
overrideWebpackConfig: ({ webpackConfig }) => {
// Search for all instances of babel-loader
const { matches } = getLoaders(
webpackConfig,
loaderByName('babel-loader'),
);
const rules = matches.map((match) => match.loader);
const appRule = rules.find((rule) => rule.include === path.resolve('src'));
// If we can't find the loader then throw an error
if (!appRule) {
throw new Error('Could not find babel-loader entry for src/');
}
// Enable babelrc and clear any presets
appRule.options.configFile = true;
delete appRule.options.presets;
return webpackConfig;
},
},
},
// Change css rule to apply CSS modules to all CSS files, even without the .module.css extension
{
plugin: {
overrideWebpackConfig: ({ webpackConfig, context: { env } }) => {
// Find 'oneOf' rule of the CRA config, which contains all the rules of files
const oneOfRule = webpackConfig.module.rules.find((rule) => rule.oneOf);
if (!oneOfRule) {
throw new Error(`'oneOf' rule not found under module.rules in the ${env} webpack config`);
}
// Find .module.css files rule and remove it
// We will later add it before the generic `css` one
const moduleCssRuleIndex = oneOfRule.oneOf.findIndex(
(rule) => rule.test && rule.test.toString().includes('\\.module\\.css')
);
const moduleCssRule = oneOfRule.oneOf[moduleCssRuleIndex];
if (!moduleCssRule) {
throw new Error('Could not find \'.module.css\' rule in \'oneOf\' set of rules');
}
oneOfRule.oneOf.splice(moduleCssRuleIndex, 1);
// Find generic `css` rule add the newModuleCssRule before it
// Aso remove the `exclude` of the generic `css` rule because it's no longer necessary
const cssRuleIndex = oneOfRule.oneOf.findIndex(
(rule) => rule.test && rule.test.toString().startsWith('/\\.css')
);
const cssRule = oneOfRule.oneOf[cssRuleIndex];
if (!cssRule) {
throw new Error('Could not find \'.css\' rule in \'oneOf\' set of rules');
}
delete cssRule.exclude;
const newModuleCssRule = {
test: /\.css$/,
include: [
path.resolve('src'),
fs.realpathSync('node_modules/@nomios/web-uikit'),
],
exclude: [
fs.existsSync('node_modules/@nomios/web-uikit/node_modules') && fs.realpathSync('node_modules/@nomios/web-uikit/node_modules'),
].filter(Boolean),
use: moduleCssRule.use,
};
oneOfRule.oneOf.splice(cssRuleIndex, 0, newModuleCssRule);
return webpackConfig;
},
},
},
// Setup loader for svg files
{
plugin: {
overrideWebpackConfig: ({ webpackConfig }) => {
const svgLoader = {
test: /\.svg$/,
use: [
{
loader: require.resolve('raw-loader'),
},
{
loader: require.resolve('svgo-loader'),
options: {
plugins: [
{ removeTitle: true },
{ removeDimensions: true },
{ removeViewBox: false },
{ cleanupIDs: false },
],
},
},
// Uniquify classnames and ids so that they are unique and
// don't conflict with each other
{
loader: require.resolve('svg-css-modules-loader'),
options: {
transformId: true,
localIdentName: '[name]__[local]',
},
},
],
};
addBeforeLoader(webpackConfig, loaderByName('file-loader'), svgLoader);
return webpackConfig;
},
},
},
],
};