Skip to content

Commit

Permalink
support webpack 5 asset modules
Browse files Browse the repository at this point in the history
  • Loading branch information
dilanx committed Jun 29, 2022
1 parent e5644f1 commit c5ccbf9
Show file tree
Hide file tree
Showing 7 changed files with 227 additions and 48 deletions.
12 changes: 8 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@craco/craco",
"description": "Create React App Configuration Override, an easy and comprehensible configuration layer for create-react-app.",
"version": "7.0.0-alpha.5",
"version": "7.0.0-alpha.6",
"scripts": {
"prepublishOnly": "tsc"
},
Expand Down Expand Up @@ -52,10 +52,10 @@
"@types/eslint": "^8.4.3",
"@types/lodash": "^4.14.182",
"@types/semver": "^7.3.10",
"@types/webpack": "^5.28.0",
"eslint-webpack-plugin": "^3.2.0",
"react-scripts": "5.*",
"typescript": "^4.7.4"
"typescript": "^4.7.4",
"webpack": "^5.73.0"
},
"dependencies": {
"autoprefixer": "^10.4.7",
Expand Down
18 changes: 18 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
import {
addAfterAssetModule,
addAfterAssetModules,
addBeforeAssetModule,
addBeforeAssetModules,
assetModuleByName,
getAssetModule,
getAssetModules,
removeAssetModules,
} from './lib/asset-modules';
import { createDevServerConfigProviderProxy } from './lib/features/dev-server/api';
import { createJestConfig } from './lib/features/jest/api';
import {
Expand Down Expand Up @@ -32,6 +42,14 @@ export {
addAfterLoader,
addAfterLoaders,
loaderByName,
getAssetModule,
getAssetModules,
removeAssetModules,
addBeforeAssetModule,
addBeforeAssetModules,
addAfterAssetModule,
addAfterAssetModules,
assetModuleByName,
getPlugin,
pluginByName,
addPlugins,
Expand Down
141 changes: 141 additions & 0 deletions src/lib/asset-modules.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
import type { RuleSetRule, Configuration as WebpackConfig } from 'webpack';
import type {
AssetModule,
AssetModuleMatcher,
AssetModuleType,
} from '../types/asset-modules';

export function assetModuleByName(assetModuleName: AssetModuleType) {
return (rule: RuleSetRule) => rule.type === assetModuleName;
}

const toMatchingAssetModule = (
rule: RuleSetRule,
index: number
): AssetModule => ({
rule,
index,
});

export function getAssetModule(
webpackConfig: WebpackConfig,
matcher: AssetModuleMatcher
) {
let matchingAssetModule: AssetModule | undefined;
(webpackConfig.module?.rules as RuleSetRule[])?.some((rule, index) => {
if (matcher(rule)) {
matchingAssetModule = toMatchingAssetModule(rule, index);
}
return matchingAssetModule !== undefined;
});
return {
isFound: matchingAssetModule !== undefined,
match: matchingAssetModule,
};
}

export function getAssetModules(
webpackConfig: WebpackConfig,
matcher: AssetModuleMatcher
) {
const matchingAssetModules: AssetModule[] = [];
(webpackConfig.module?.rules as RuleSetRule[])?.forEach((rule, index) => {
if (matcher(rule)) {
matchingAssetModules.push(toMatchingAssetModule(rule, index));
}
});

return {
hasFoundAny: matchingAssetModules.length !== 0,
matches: matchingAssetModules,
};
}

export function removeAssetModules(
webpackConfig: WebpackConfig,
matcher: AssetModuleMatcher
) {
const toRemove: number[] = [];
(webpackConfig.module?.rules as RuleSetRule[])?.forEach((rule, index) => {
if (matcher(rule)) {
toRemove.push(index);
}
});

toRemove.forEach((index) => {
webpackConfig.module?.rules?.splice(index, 1);
});

return {
rules: webpackConfig.module?.rules,
removedCount: toRemove.length,
};
}

function addAssetModule(
webpackConfig: WebpackConfig,
matcher: AssetModuleMatcher,
newAssetModule: RuleSetRule,
positionAdapter: (index: number) => number
) {
const { match } = getAssetModule(webpackConfig, matcher);

if (match !== undefined) {
webpackConfig.module?.rules?.splice(
positionAdapter(match.index),
0,
newAssetModule
);

return { isAdded: true };
}

return { isAdded: false };
}

export const addBeforeAssetModule = (
webpackConfig: WebpackConfig,
matcher: AssetModuleMatcher,
newAssetModule: RuleSetRule
) => addAssetModule(webpackConfig, matcher, newAssetModule, (x) => x);

export const addAfterAssetModule = (
webpackConfig: WebpackConfig,
matcher: AssetModuleMatcher,
newAssetModule: RuleSetRule
) => addAssetModule(webpackConfig, matcher, newAssetModule, (x) => x + 1);

function addAssetModules(
webpackConfig: WebpackConfig,
matcher: AssetModuleMatcher,
newLoader: RuleSetRule,
positionAdapter: (index: number) => number
) {
const { matches } = getAssetModules(webpackConfig, matcher);

if (matches.length !== 0) {
matches.forEach((match) => {
webpackConfig.module?.rules?.splice(
positionAdapter(match.index),
0,
newLoader
);
});

return { isAdded: true, addedCount: matches.length };
}

return { isAdded: false, addedCount: 0 };
}

export const addBeforeAssetModules = (
webpackConfig: WebpackConfig,
matcher: AssetModuleMatcher,
newAssetModule: RuleSetRule
) => addAssetModules(webpackConfig, matcher, newAssetModule, (x) => x);

export const addAfterAssetModules = (
webpackConfig: WebpackConfig,
matcher: AssetModuleMatcher,
newAssetModule: RuleSetRule
) => addAssetModules(webpackConfig, matcher, newAssetModule, (x) => x + 1);
Loading

0 comments on commit c5ccbf9

Please sign in to comment.