Skip to content

Commit

Permalink
feat(arui-scripts): добавление findPlugin хелпера
Browse files Browse the repository at this point in the history
  • Loading branch information
Alexander Komarov authored and Alexander Komarov committed Oct 6, 2023
1 parent 552fd8f commit 1c55d95
Show file tree
Hide file tree
Showing 8 changed files with 257 additions and 2 deletions.
2 changes: 2 additions & 0 deletions packages/arui-scripts/.eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,7 @@ module.exports = {
rules: {
'import/no-default-export': 'warn',
'import/no-named-as-default': 'warn',
// чтобы могли использовать for и генераторы
'no-restricted-syntax': 'off',
},
};
120 changes: 120 additions & 0 deletions packages/arui-scripts/src/configs/util/__tests__/find-plugin.tests.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
import { createSingleClientWebpackConfig } from '../../webpack.client';
import { createServerConfig } from '../../webpack.server';
import { findPlugin } from '../find-plugin';

const getPlugins = (
plugins: any,
name: string,
property: (...props: any[]) => Record<string, unknown>,
) =>
plugins.map((plugin: unknown) => {
if (plugin?.constructor.name === name) {
const typedPlugin = plugin as any;

return {
...typedPlugin,
...property(typedPlugin),
};
}

return plugin;
});

describe('override plugins with findPlugin', () => {
describe("client's findPlugin", () => {
it('should return original client dev config with modified MiniCssExtractPlugin: options.ignoreOrder = false', () => {
const devConfig = createSingleClientWebpackConfig('dev', './index.ts');

const [MiniCssExtractPlugin] = findPlugin<'client'>()(
devConfig,
'MiniCssExtractPlugin',
);

MiniCssExtractPlugin.options.ignoreOrder = false;

expect(devConfig).toMatchObject<typeof devConfig>({
...devConfig,
plugins: getPlugins(devConfig.plugins, 'MiniCssExtractPlugin', (pluginOptions) => ({
...pluginOptions,
options: {
...pluginOptions.options,
ignoreOrder: false,
},
})),
});
});

it('should return original client prod config with modified WebpackManifestPlugin: options.fileName = super-app-manifest.json', () => {
const prodConfig = createSingleClientWebpackConfig('prod', './index.ts');

const [WebpackManifestPlugin] = findPlugin<'client'>()(
prodConfig,
'WebpackManifestPlugin',
);

WebpackManifestPlugin.options = {
...WebpackManifestPlugin.options,
fileName: 'super-app-manifest.json',
};

expect(prodConfig).toMatchObject<typeof prodConfig>({
...prodConfig,
plugins: getPlugins(
prodConfig.plugins,
'WebpackManifestPlugin',
(pluginOptions) => ({
...pluginOptions,
options: {
...pluginOptions.options,
fileName: 'super-app-manifest.json',
},
}),
),
});
});
});

describe("server's findPlugin", () => {
it('should return original server dev config with modified BannerPlugin: options.banner = "sell garage"', () => {
const devConfig = createServerConfig('dev');

const [BannerPlugin] = findPlugin<'server'>()(devConfig, 'BannerPlugin');

BannerPlugin.options.banner = 'sell garage';

expect(devConfig).toMatchObject<typeof devConfig>({
...devConfig,
plugins: getPlugins(devConfig.plugins, 'BannerPlugin', (pluginOptions) => ({
...pluginOptions,
options: {
...pluginOptions.options,
banner: 'sell garage',
},
})),
});
});

it('should return original server dev config with modified WatchMissingNodeModulesPlugin: nodeModulesPath = ./123', () => {
const devConfig = createServerConfig('dev');

const [WatchMissingNodeModulesPlugin] = findPlugin<'server'>()(
devConfig,
'WatchMissingNodeModulesPlugin',
);

WatchMissingNodeModulesPlugin.nodeModulesPath = './123';

expect(devConfig).toMatchObject<typeof devConfig>({
...devConfig,
plugins: getPlugins(
devConfig.plugins,
'WatchMissingNodeModulesPlugin',
(pluginOptions) => ({
...pluginOptions,
nodeModulesPath: './123',
}),
),
});
});
});
});
9 changes: 9 additions & 0 deletions packages/arui-scripts/src/configs/util/apply-overrides.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { AppContextWithConfigs } from '../app-configs/types';
import { createSingleClientWebpackConfig } from '../webpack.client';

import { findLoader } from './find-loader';
import { findPlugin } from './find-plugin';

type Overrides = {
webpack: WebpackConfiguration | WebpackConfiguration[];
Expand Down Expand Up @@ -43,6 +44,12 @@ type BoundCreateSingleClientWebpackConfig = OmitFirstArg<typeof createSingleClie
type ClientWebpackAdditionalArgs = {
createSingleClientWebpackConfig: BoundCreateSingleClientWebpackConfig;
findLoader: typeof findLoader;
findPlugin: ReturnType<typeof findPlugin<'client'>>
};

type ServerWebpackAdditionalArgs = {
findLoader: typeof findLoader;
findPlugin: ReturnType<typeof findPlugin<'server'>>;
};

/**
Expand All @@ -53,6 +60,8 @@ type OverridesAdditionalArgs = {
webpackClient: ClientWebpackAdditionalArgs;
webpackDev: ClientWebpackAdditionalArgs;
webpackClientDev: ClientWebpackAdditionalArgs;
webpackServer: ServerWebpackAdditionalArgs;
webpackServerDev: ServerWebpackAdditionalArgs;
};

type OverrideFunction<
Expand Down
118 changes: 118 additions & 0 deletions packages/arui-scripts/src/configs/util/find-plugin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
import { Cluster } from 'cluster';

import { ReactRefreshPluginOptions } from '@pmmmwh/react-refresh-webpack-plugin/types/lib/types';
import AssetsPlugin from 'assets-webpack-plugin';
import CaseSensitivePathsPlugin from 'case-sensitive-paths-webpack-plugin';
import CompressionPlugin from 'compression-webpack-plugin';
import { ForkTsCheckerWebpackPluginOptions } from 'fork-ts-checker-webpack-plugin/lib/ForkTsCheckerWebpackPluginOptions';
import MiniCssExtractPlugin from 'mini-css-extract-plugin';
import { RunScriptWebpackPlugin } from 'run-script-webpack-plugin';
import webpack from 'webpack';
import { WebpackDeduplicationPlugin } from 'webpack-deduplication-plugin';
import { WebpackManifestPlugin } from 'webpack-manifest-plugin';

/*
вариации плагинов клиента
Сюда не попали:
1. ModuleFederationPlugin
*/
type PluginsListClient = {
AssetsWebpackPlugin: {
options: AssetsPlugin.Options;
};
DefinePlugin: {
definitions: Record<string, string>;
};
MiniCssExtractPlugin: {
options: MiniCssExtractPlugin.PluginOptions;
runtimeOptions: MiniCssExtractPlugin.RuntimeOptions;
};
ForkTsCheckerWebpackPlugin: {
options: ForkTsCheckerWebpackPluginOptions;
};
IgnorePlugin: {
options:
| {
contextRegExp?: RegExp;
resourceRegExp: RegExp;
}
| {
checkResource: (resource: string, context: string) => boolean;
};
checkIgnore: (resolveData: webpack.ResolveData) => undefined | false;
};
WebpackDeduplicationPlugin: WebpackDeduplicationPlugin;
ReactRefreshPlugin: {
options: ReactRefreshPluginOptions;
};
CaseSensitivePathsPlugin: {
options: CaseSensitivePathsPlugin.Options;
logger: {
[K in keyof Console]: Console[K];
};
};
WebpackManifestPlugin: {
options: ConstructorParameters<typeof WebpackManifestPlugin>[number];
};
CompressionPlugin: {
options: ConstructorParameters<typeof CompressionPlugin>[number];
};
NormalModuleReplacementPlugin: webpack.NormalModuleReplacementPlugin;
};

/*
вариации плагинов сервера
сюда не попали:
1. HotModuleReplacementPlugin
2. NoEmitOnErrorsPlugin
*/
type PluginsListServer = {
BannerPlugin: {
options: webpack.BannerPlugin['options'];
};
RunScriptWebpackPlugin: {
options: ConstructorParameters<typeof RunScriptWebpackPlugin>[number];
};
ReloadServerPlugin: {
done: (...props: unknown[]) => unknown | null;
workers: Array<Cluster['Worker']>;
};
CaseSensitivePathsPlugin: {
options: CaseSensitivePathsPlugin.Options;
logger: {
[K in keyof Console]: Console[K];
};
};
WatchMissingNodeModulesPlugin: {
nodeModulesPath: string;
};
};

type SelectedPluginsList<Type extends 'client' | 'server'> = Type extends 'client'
? PluginsListClient
: PluginsListServer;

/**
*
* @param config конфигурация webpack
* @param pluginName имя плагина
* @returns плагин или плагины, которые подошли под условие из testRule
*/
export function findPlugin<Type extends 'client' | 'server'>() {
return <PluginName extends keyof SelectedPluginsList<Type>>(
config: webpack.Configuration,
pluginName: PluginName,
) => {
if (!config.plugins || !pluginName) return [];

const result: Array<SelectedPluginsList<Type>[PluginName]> = [];

for (const plugin of config.plugins) {
if (plugin?.constructor.name === pluginName) {
result.push(plugin as any);
}
}

return result;
};
}
2 changes: 2 additions & 0 deletions packages/arui-scripts/src/configs/webpack.client.dev.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import applyOverrides from './util/apply-overrides';
import { findLoader } from './util/find-loader';
import { findPlugin } from './util/find-plugin';
import { createClientWebpackConfig, createSingleClientWebpackConfig } from './webpack.client';

const config = applyOverrides(
Expand All @@ -8,6 +9,7 @@ const config = applyOverrides(
{
createSingleClientWebpackConfig: createSingleClientWebpackConfig.bind(null, 'dev'),
findLoader,
findPlugin: findPlugin<'client'>(),
},
);

Expand Down
2 changes: 2 additions & 0 deletions packages/arui-scripts/src/configs/webpack.client.prod.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import applyOverrides from './util/apply-overrides';
import { findLoader } from './util/find-loader';
import { findPlugin } from './util/find-plugin';
import { createClientWebpackConfig, createSingleClientWebpackConfig } from './webpack.client';

const config = applyOverrides(
Expand All @@ -8,6 +9,7 @@ const config = applyOverrides(
{
createSingleClientWebpackConfig: createSingleClientWebpackConfig.bind(null, 'prod'),
findLoader,
findPlugin: findPlugin<'client'>(),
},
);

Expand Down
3 changes: 2 additions & 1 deletion packages/arui-scripts/src/configs/webpack.server.dev.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import applyOverrides from './util/apply-overrides';
import { findLoader } from './util/find-loader';
import { findPlugin } from './util/find-plugin';
import { createServerConfig } from './webpack.server';

const config = applyOverrides(
['webpack', 'webpackServer', 'webpackDev', 'webpackServerDev'],
createServerConfig('dev'),
{ findLoader },
{ findLoader, findPlugin: findPlugin<'server'>() },
);

export default config;
3 changes: 2 additions & 1 deletion packages/arui-scripts/src/configs/webpack.server.prod.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import applyOverrides from './util/apply-overrides';
import { findLoader } from './util/find-loader';
import { findPlugin } from './util/find-plugin';
import { createServerConfig } from './webpack.server';

const config = applyOverrides(
['webpack', 'webpackServer', 'webpackProd', 'webpackServerProd'],
createServerConfig('prod'),
{ findLoader },
{ findLoader, findPlugin: findPlugin<'server'>() },
);

export default config;

0 comments on commit 1c55d95

Please sign in to comment.