Skip to content

Commit c5ccbf9

Browse files
committed
support webpack 5 asset modules
1 parent e5644f1 commit c5ccbf9

File tree

7 files changed

+227
-48
lines changed

7 files changed

+227
-48
lines changed

package-lock.json

Lines changed: 8 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@craco/craco",
33
"description": "Create React App Configuration Override, an easy and comprehensible configuration layer for create-react-app.",
4-
"version": "7.0.0-alpha.5",
4+
"version": "7.0.0-alpha.6",
55
"scripts": {
66
"prepublishOnly": "tsc"
77
},
@@ -52,10 +52,10 @@
5252
"@types/eslint": "^8.4.3",
5353
"@types/lodash": "^4.14.182",
5454
"@types/semver": "^7.3.10",
55-
"@types/webpack": "^5.28.0",
5655
"eslint-webpack-plugin": "^3.2.0",
5756
"react-scripts": "5.*",
58-
"typescript": "^4.7.4"
57+
"typescript": "^4.7.4",
58+
"webpack": "^5.73.0"
5959
},
6060
"dependencies": {
6161
"autoprefixer": "^10.4.7",

src/index.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
1+
import {
2+
addAfterAssetModule,
3+
addAfterAssetModules,
4+
addBeforeAssetModule,
5+
addBeforeAssetModules,
6+
assetModuleByName,
7+
getAssetModule,
8+
getAssetModules,
9+
removeAssetModules,
10+
} from './lib/asset-modules';
111
import { createDevServerConfigProviderProxy } from './lib/features/dev-server/api';
212
import { createJestConfig } from './lib/features/jest/api';
313
import {
@@ -32,6 +42,14 @@ export {
3242
addAfterLoader,
3343
addAfterLoaders,
3444
loaderByName,
45+
getAssetModule,
46+
getAssetModules,
47+
removeAssetModules,
48+
addBeforeAssetModule,
49+
addBeforeAssetModules,
50+
addAfterAssetModule,
51+
addAfterAssetModules,
52+
assetModuleByName,
3553
getPlugin,
3654
pluginByName,
3755
addPlugins,

src/lib/asset-modules.ts

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
import type { RuleSetRule, Configuration as WebpackConfig } from 'webpack';
2+
import type {
3+
AssetModule,
4+
AssetModuleMatcher,
5+
AssetModuleType,
6+
} from '../types/asset-modules';
7+
8+
export function assetModuleByName(assetModuleName: AssetModuleType) {
9+
return (rule: RuleSetRule) => rule.type === assetModuleName;
10+
}
11+
12+
const toMatchingAssetModule = (
13+
rule: RuleSetRule,
14+
index: number
15+
): AssetModule => ({
16+
rule,
17+
index,
18+
});
19+
20+
export function getAssetModule(
21+
webpackConfig: WebpackConfig,
22+
matcher: AssetModuleMatcher
23+
) {
24+
let matchingAssetModule: AssetModule | undefined;
25+
(webpackConfig.module?.rules as RuleSetRule[])?.some((rule, index) => {
26+
if (matcher(rule)) {
27+
matchingAssetModule = toMatchingAssetModule(rule, index);
28+
}
29+
return matchingAssetModule !== undefined;
30+
});
31+
return {
32+
isFound: matchingAssetModule !== undefined,
33+
match: matchingAssetModule,
34+
};
35+
}
36+
37+
export function getAssetModules(
38+
webpackConfig: WebpackConfig,
39+
matcher: AssetModuleMatcher
40+
) {
41+
const matchingAssetModules: AssetModule[] = [];
42+
(webpackConfig.module?.rules as RuleSetRule[])?.forEach((rule, index) => {
43+
if (matcher(rule)) {
44+
matchingAssetModules.push(toMatchingAssetModule(rule, index));
45+
}
46+
});
47+
48+
return {
49+
hasFoundAny: matchingAssetModules.length !== 0,
50+
matches: matchingAssetModules,
51+
};
52+
}
53+
54+
export function removeAssetModules(
55+
webpackConfig: WebpackConfig,
56+
matcher: AssetModuleMatcher
57+
) {
58+
const toRemove: number[] = [];
59+
(webpackConfig.module?.rules as RuleSetRule[])?.forEach((rule, index) => {
60+
if (matcher(rule)) {
61+
toRemove.push(index);
62+
}
63+
});
64+
65+
toRemove.forEach((index) => {
66+
webpackConfig.module?.rules?.splice(index, 1);
67+
});
68+
69+
return {
70+
rules: webpackConfig.module?.rules,
71+
removedCount: toRemove.length,
72+
};
73+
}
74+
75+
function addAssetModule(
76+
webpackConfig: WebpackConfig,
77+
matcher: AssetModuleMatcher,
78+
newAssetModule: RuleSetRule,
79+
positionAdapter: (index: number) => number
80+
) {
81+
const { match } = getAssetModule(webpackConfig, matcher);
82+
83+
if (match !== undefined) {
84+
webpackConfig.module?.rules?.splice(
85+
positionAdapter(match.index),
86+
0,
87+
newAssetModule
88+
);
89+
90+
return { isAdded: true };
91+
}
92+
93+
return { isAdded: false };
94+
}
95+
96+
export const addBeforeAssetModule = (
97+
webpackConfig: WebpackConfig,
98+
matcher: AssetModuleMatcher,
99+
newAssetModule: RuleSetRule
100+
) => addAssetModule(webpackConfig, matcher, newAssetModule, (x) => x);
101+
102+
export const addAfterAssetModule = (
103+
webpackConfig: WebpackConfig,
104+
matcher: AssetModuleMatcher,
105+
newAssetModule: RuleSetRule
106+
) => addAssetModule(webpackConfig, matcher, newAssetModule, (x) => x + 1);
107+
108+
function addAssetModules(
109+
webpackConfig: WebpackConfig,
110+
matcher: AssetModuleMatcher,
111+
newLoader: RuleSetRule,
112+
positionAdapter: (index: number) => number
113+
) {
114+
const { matches } = getAssetModules(webpackConfig, matcher);
115+
116+
if (matches.length !== 0) {
117+
matches.forEach((match) => {
118+
webpackConfig.module?.rules?.splice(
119+
positionAdapter(match.index),
120+
0,
121+
newLoader
122+
);
123+
});
124+
125+
return { isAdded: true, addedCount: matches.length };
126+
}
127+
128+
return { isAdded: false, addedCount: 0 };
129+
}
130+
131+
export const addBeforeAssetModules = (
132+
webpackConfig: WebpackConfig,
133+
matcher: AssetModuleMatcher,
134+
newAssetModule: RuleSetRule
135+
) => addAssetModules(webpackConfig, matcher, newAssetModule, (x) => x);
136+
137+
export const addAfterAssetModules = (
138+
webpackConfig: WebpackConfig,
139+
matcher: AssetModuleMatcher,
140+
newAssetModule: RuleSetRule
141+
) => addAssetModules(webpackConfig, matcher, newAssetModule, (x) => x + 1);

0 commit comments

Comments
 (0)