Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions packages/perftool/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,11 @@
"react-dom": ">=16.8.0"
},
"dependencies": {
"@babel/parser": "^7.21.4",
"@babel/preset-env": "7.21.4",
"@babel/preset-react": "7.18.6",
"@babel/preset-typescript": "7.21.4",
"@babel/traverse": "^7.21.4",
"@swc/core": "1.3.50",
"babel-loader": "9.1.2",
"chalk": "5.2.0",
Expand All @@ -59,6 +61,8 @@
},
"devDependencies": {
"@jest/globals": "29.5.0",
"@types/babel__parser": "^7.1.1",
"@types/babel__traverse": "^7.18.4",
"@types/express": "4.17.17",
"@types/jest": "29.5.0",
"@types/morgan": "1.9.4",
Expand Down
31 changes: 27 additions & 4 deletions packages/perftool/src/build/collect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import getSubjectId from '../utils/subjectId';
import checkPath from '../utils/checkPath';
import { Config } from '../config';
import { debug, info, warn } from '../utils/logger';
import { getAst } from '../utils/ast';
import traverse from '../utils/traverseExport';

export type ExportPickRule = 'named'; // | 'default' | 'all'

Expand All @@ -20,10 +22,25 @@ export type TestModule = {

const PICK_RULE_METHODS: Record<ExportPickRule, (fileContents: string) => string[]> = {
named(fileContents) {
const regex = /export\s+(?:const|var|let|function)\s+?([\w$_][\w\d$_]*)/g;
const matches = [...fileContents.matchAll(regex)];

return matches.map(([, name]) => name);
const exports: string[] = [];
const ast = getAst(fileContents);

if (!ast) {
return exports;
}

traverse(ast, {
ExportNamedDeclaration(path: any) {
if (path.node.declaration) {
exports.push(path.node.declaration.id?.name);
} else {
path.node.specifiers.array.forEach((specifier: any) => {
exports.push(specifier.exported.name);
});
}
},
});
return exports;
},
};

Expand Down Expand Up @@ -71,6 +88,12 @@ export default async function collectTestSubjects(config: Config): Promise<TestM
const paths = await fg(config.include, { ignore: config.exclude });

debug('found modules: ', paths);

if (!paths.length) {
info('Component test will not run because no exports names were found');
return [];
}

debug('parsing modules... ');

const modulesPromise = Promise.all(paths.map((path) => getTestModule(path, config.exportPickRule)));
Expand Down
11 changes: 11 additions & 0 deletions packages/perftool/src/config/babelOptions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import * as babelCore from '@babel/core';

export const babelOptions: babelCore.TransformOptions = {
sourceType: 'module',
presets: [
['@babel/preset-env', { targets: { chrome: '90', esmodules: true } }],
'@babel/preset-react',
'@babel/preset-typescript',
],
plugins: [],
};
4 changes: 4 additions & 0 deletions packages/perftool/src/config/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,9 @@ export type Config = {
runWaitTimeout: number;
dryRunTimes: number;
modifyWebpackConfig: (defaultConfig: WebpackConfig) => WebpackConfig;
modifyTranspilerConfig: (defaultConfig: WebpackConfig) => WebpackConfig;
exportPickRule: ExportPickRule;
transpiler: 'babel' | 'none';
};

export type ProjectConfig = Partial<Omit<Config, 'configPath' | 'logLevel'>>;
Expand Down Expand Up @@ -95,7 +97,9 @@ export function getConfig(cliConfig: CliConfig = {}, projectConfig: ProjectConfi
runWaitTimeout: withDefault(mixedInputConfig.runWaitTimeout, 1000 * 60 * 2),
dryRunTimes: withDefault(mixedInputConfig.taskWaitTimeout, 1),
modifyWebpackConfig: withDefault(mixedInputConfig.modifyWebpackConfig, (c) => c),
modifyTranspilerConfig: withDefault(mixedInputConfig.modifyWebpackConfig, (c) => c),
exportPickRule: withDefault(mixedInputConfig.exportPickRule, 'named'),
transpiler: withDefault(mixedInputConfig.transpiler, 'babel'),
};

debug('final config: ', result);
Expand Down
16 changes: 16 additions & 0 deletions packages/perftool/src/config/transpiler.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { RuleSetRule } from 'webpack';

import { babelOptions } from './babelOptions';

export function getTranspilerConfig(transpiler: string): RuleSetRule {
if (transpiler === 'babel') {
return {
loader: require.resolve('babel-loader'),
test: /\.(js|mjs|jsx|ts|tsx)$/,
exclude: /node_modules/,
options: babelOptions,
};
}
// TODO: swc
return {};
}
32 changes: 19 additions & 13 deletions packages/perftool/src/config/webpack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { fileURLToPath } from 'url';

import { debug } from '../utils/logger';

// import { getTranspilerConfig } from './transpiler';
import { Config } from './common';

const require = createRequire(import.meta.url);
Expand Down Expand Up @@ -35,19 +36,6 @@ const defaultConfig: WebpackConfig = {
},
module: {
rules: [
{
loader: require.resolve('babel-loader'),
test: /\.(js|mjs|jsx|ts|tsx)$/,
exclude: /node_modules/,
options: {
presets: [
['@babel/preset-env', { targets: { chrome: '90', esmodules: true } }],
'@babel/preset-react',
'@babel/preset-typescript',
],
plugins: [],
},
},
{
loader: 'url-loader',
test: /\.(jpg|jpeg|ico|webp|jp2|avif|png|gif|woff|eot|ttf|svg)$/,
Expand All @@ -70,6 +58,24 @@ export function getWebpackConfig(entry: string, output: string, config: Config):

const finalConfig = config.modifyWebpackConfig(defaultConfig);

if (config.transpiler !== 'none') {
// const transpiler = getTranspilerConfig(config); // пока что не похватывает настройки для babel
finalConfig.module?.rules?.push({
loader: require.resolve('babel-loader'),
test: /\.(js|mjs|jsx|ts|tsx)$/,
exclude: /node_modules/,
options: {
sourceType: 'module',
presets: [
['@babel/preset-env', { targets: { chrome: '90', esmodules: true } }],
'@babel/preset-react',
'@babel/preset-typescript',
],
plugins: [],
},
});
}

finalConfig.entry = entry;
finalConfig.output!.path = output;

Expand Down
6 changes: 6 additions & 0 deletions packages/perftool/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,12 @@ async function start() {
const config = getConfig(cliConfig, importedConfig?.value);

const testModules = await collectTestSubjects(config);

if (!testModules.length) {
info('Component test will not run because no exports names were found');
return;
}

const tasks = getAllTasks(config);

info(
Expand Down
18 changes: 18 additions & 0 deletions packages/perftool/src/utils/ast.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import * as babelCore from '@babel/core';
import { File } from '@babel/types';

import { info } from '../utils/logger';
import { babelOptions } from '../config/babelOptions';

export function getAst(fileContents: string): File | null {
try {
const ast = babelCore.parseSync(fileContents, {
filename: 'file.tsx',
...babelOptions,
});
return ast as File;
} catch (error) {
info('Ошибка при получении AST:', error);
return null;
}
}
4 changes: 4 additions & 0 deletions packages/perftool/src/utils/traverseExport.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import * as _traverse from '@babel/traverse';

const traverse = (_traverse.default as unknown as typeof _traverse).default;
export default traverse;
Loading