forked from pradel/create-react-app-esbuild
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
131 lines (116 loc) · 4.5 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
const { loaderByName, removeLoaders, addAfterLoader } = require('@craco/craco');
const { EsbuildPlugin } = require('esbuild-loader');
const removeMinimizer = (webpackConfig, name) => {
const idx = webpackConfig.optimization.minimizer.findIndex(
(m) => m.constructor.name === name
);
webpackConfig.optimization.minimizer.splice(idx, 1);
};
const replaceMinimizer = (webpackConfig, name, minimizer) => {
const idx = webpackConfig.optimization.minimizer.findIndex(
(m) => m.constructor.name === name
);
idx > -1 && webpackConfig.optimization.minimizer.splice(idx, 1, minimizer);
};
module.exports = {
/**
* To process the js/ts files we replace the babel-loader with the esbuild-loader
*/
overrideWebpackConfig: ({
webpackConfig,
pluginOptions,
context: { paths },
}) => {
const esbuildLoaderOptions =
pluginOptions && pluginOptions.esbuildLoaderOptions;
// add includePaths custom option, for including files/components in other folders than src
// Used as in addition to paths.appSrc, optional parameter.
const optionalIncludes =
(pluginOptions && pluginOptions.includePaths) || [];
// add esbuild-loader
addAfterLoader(webpackConfig, loaderByName('babel-loader'), {
test: /\.(js|mjs|jsx|ts|tsx)$/,
include: [paths.appSrc, ...optionalIncludes],
loader: require.resolve('esbuild-loader'),
options: esbuildLoaderOptions
? esbuildLoaderOptions
: {
target: 'es2015',
},
});
// remove the babel loaders
removeLoaders(webpackConfig, loaderByName('babel-loader'));
// Replace terser with esbuild
const minimizerOptions = (pluginOptions || {}).esbuildMinimizerOptions || {
target: 'es2015',
css: true,
};
replaceMinimizer(
webpackConfig,
'TerserPlugin',
new EsbuildPlugin(minimizerOptions)
);
// remove the css OptimizeCssAssetsWebpackPlugin
if (minimizerOptions.css) {
removeMinimizer(webpackConfig, 'OptimizeCssAssetsWebpackPlugin');
}
return webpackConfig;
},
/**
* To process the js/ts files we replace the babel-loader with the esbuild jest loader
*/
overrideJestConfig: ({ jestConfig, pluginOptions }) => {
if (pluginOptions && pluginOptions.skipEsbuildJest) return jestConfig;
const defaultEsbuildJestOptions = {
loaders: {
'.js': 'jsx',
'.test.js': 'jsx',
'.ts': 'tsx',
'.test.ts': 'tsx',
},
};
const esbuildJestOptions =
(pluginOptions && pluginOptions.esbuildJestOptions) ||
defaultEsbuildJestOptions;
// Replace babel transform with esbuild
// babelTransform is first transformer key
/*
transform:
{
'^.+\\.(js|jsx|mjs|cjs|ts|tsx)$': 'node_modules\\react-scripts\\config\\jest\\babelTransform.js',
'^.+\\.css$': 'node_modules\\react-scripts\\config\\jest\\cssTransform.js',
'^(?!.*\\.(js|jsx|mjs|cjs|ts|tsx|css|json)$)': 'node_modules\\react-scripts\\config\\jest\\fileTransform.js'
}
*/
const babelKey = Object.keys(jestConfig.transform)[0];
// We replace babelTransform and add loaders to esbuild-jest
jestConfig.transform[babelKey] = [
require.resolve('esbuild-jest'),
esbuildJestOptions,
];
// Adds loader to all other transform options (2 in this case: cssTransform and fileTransform)
// Reason for this is esbuild-jest plugin. It considers only loaders or other options from the last transformer
// You can see it for yourself in: /node_modules/esbuild-jest/esbuid-jest.js:21 getOptions method
// also in process method line 32 gives empty loaders, because options is already empty object
// Issue reported here: https://github.com/aelbore/esbuild-jest/issues/18
Object.keys(jestConfig.transform).forEach((key) => {
if (babelKey === key) return; // ebuild-jest transform, already has loader
// Checks if value is array, usually it's not
// Our example is above on 70-72 lines. Usually default is: {"\\.[jt]sx?$": "babel-jest"}
// (https://jestjs.io/docs/en/configuration#transform-objectstring-pathtotransformer--pathtotransformer-object)
// But we have to cover all the cases
if (
Array.isArray(jestConfig.transform[key]) &&
jestConfig.transform[key].length === 1
) {
jestConfig.transform[key].push(esbuildJestOptions);
} else {
jestConfig.transform[key] = [
jestConfig.transform[key],
esbuildJestOptions,
];
}
});
return jestConfig;
},
};