Skip to content

Commit

Permalink
refactor(swc): change useSwcLoader option to codeLoader
Browse files Browse the repository at this point in the history
  • Loading branch information
Heymdall committed Oct 15, 2024
1 parent f1439ee commit cdef412
Show file tree
Hide file tree
Showing 15 changed files with 368 additions and 289 deletions.
13 changes: 11 additions & 2 deletions .changeset/three-camels-repeat.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,17 @@
'arui-scripts': minor
---

Добавлены флаги `useSwcLoader` для использования swc-loader и `jestUseSwc` для использования @swc/jest.
Добавляем возможность использовать swc для загрузки кода в webpack и jest.

- Добавлена настройка `codeLoader` для выбора используемого загрузчика кода.
Настройка заменяет собой уже существовавшую `useTscLoader` и добавляет возможность использовать в качестве
загрузчика swc.
Использование swc значительно ускоряет сборку (до 2 раз), без особых негативных последствий.

Для большинства проектов миграция на swc будет абсолютно незаметна
- Добавлена настройка `jestCodeTransformer` для выбора обработчика кода для jest.
Заменяет собой `jestUseTsJest` и добавляет возможность использовать `@swc/jest`. swc в jest немного меняет поведение при использовании
spyOn для esm модулей.

- Флаг `useTscLoader` помечен как deprecated и будет удален в следующем мажорном релизе. Используйте `codeLoader: 'tsc'`.
- Флаг `jestUseTsJest` помечен как deprecated и будет удален в следующем мажорном релизе. Используйте `jestCodeTransformer: 'tsc'`.
- Флаг `webpack4Compatibility` помечен как deprecated и будет удален в следующем мажорном релизе.
43 changes: 27 additions & 16 deletions packages/arui-scripts/docs/settings.md
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,8 @@ const settings = {
- `/^thrift-services\/proptypes/`

#### useTscLoader
**Deprecated** Используйте настройку [codeLoader](#codeloader)

Использовать ts-loader вместо babel-loader для обработки ts файлов. **Не рекомендуется к использованию**.

babel-loader является предпочтительным инструментом сборки, его стоят заменять только если в вашем проекте используется неподдерживаемый им синтаксис:
Expand All @@ -208,35 +210,44 @@ babel-loader является предпочтительным инструме

Рекомендуется обновить код проекта до поддерживаемого синтаксиса и использовать babel-loader.

#### codeLoader
Позволяет выбрать какой инструмент использовать для обработки js и ts кода приложения. По умолчанию `babel`.

Возможные значения:
- `babel` - для всего кода будет использоваться `babel-loader`;
- `tsc` - для ts кода будет использоваться `ts-loader`, для всего остального - `babel-loader`;
- `swc` - для всего кода будет использоваться `swc-loader`.

`swc` является предпочтительным режимом, дефолты не меняются для сохранения обратной совместимости.
Использование swc позволяет значительно ускорить сборку (до 2 раз на больших проектах), но не будет создавать полностью идентичный с babel код.
Итоговый бандл может получиться немного больше, чем при использовании babel, но разница полностью компенсируется при использовании сжатия.

#### webpack4Compatibility
**Deprecated** Эта настройка будет удалена в будущих версиях скриптов

Включить ли режим совместимости с webpack 4. По умолчанию `false`. Подробнее можно почитать в этом [issue](https://github.com/webpack/webpack/issues/14580).

#### installServerSourceMaps
Добавлять ли в серверную сборку пакет source-map-support. По умолчанию `false`.

#### jestUseTsJest
**Deprecated** Используйте настройку [jestCodeTransformer](#jestcodetransformer)

Позволяет использовать `ts-jest` вместо `babel-jest` для обработки `ts` файлов при запуске тестов. По умолчанию `false`.

#### jestCodeTransformer
Позволяет выбрать какой инструмент использовать для обработки js и ts кода приложения при запуске тестов. По умолчанию `babel`.

Возможные значения:
- `babel` - для всего кода будет использоваться `babel-jest`;
- `tsc` - для ts кода будет использоваться `ts-jest`, для всего остального - `babel-jest`;
- `swc` - для всего кода будет использоваться `@swc/jest`.
Swc более строго следует спецификациям и [не дает возможности](https://github.com/swc-project/swc/issues/5059) делать `spyOn` для экспортов из esm модулей.

#### collectCoverage
Добавлять ли инструменты для сборки coverage при сборке. По умолчанию определяется по env переменным - будет выставлено в `true` если `NODE_ENV = 'cypress'` или `USE_ISTANBUL = 'enabled'`.
Сбор coverage не будет работать при использовании `useTscLoader=true`.

#### useSwcLoader
Использовать ли swc для обработки js и ts файлов. По умолчанию `false`.

Использование swc позволяет значительно ускорить сборку (до 2 раз на больших проектах), но не будет создавать полностью идентичный с babel код.
Итоговый может получиться немного больше, чем при использовании babel, но разница полностью компенсируется при использовании сжатия.

При включении, swc будет использоваться вместо babel-loader при сборке, а так же для транспиляции файлов в jest.
Настройки `useTscLoader` и `jestUseTsJest` имеют приоритет над этой настройкой.

#### jestUseSwc
Позволяет использовать `@swc/jest` вместо `babel-jest` для обработки `ts`/`js` файлов при запуске тестов. По умолчанию `false`.

Аналогично использованию swc в сборке - значительно ускоряет запуск тестов.

swc более строго следует спецификациям и [не дает возможности](https://github.com/swc-project/swc/issues/5059) делать `spyOn` для экспортов из esm модулей.

### Обработка изображений
#### dataUrlMaxSize
Ресурсы, не превышающие данный размер (в байтах), будут включены в исходники `inline`, иначе вынесены в отдельный файл. По умолчанию `1536`.
Expand Down
2 changes: 1 addition & 1 deletion packages/arui-scripts/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
"@babel/runtime": "^7.23.8",
"@csstools/postcss-global-data": "^2.0.1",
"@pmmmwh/react-refresh-webpack-plugin": "0.5.11",
"@swc/core": "~1.6.13",
"@swc/core": "^1.7.35",
"@swc/jest": "^0.2.36",
"assets-webpack-plugin": "7.1.1",
"autoprefixer": "^10.3.16",
Expand Down
1 change: 0 additions & 1 deletion packages/arui-scripts/src/commands/build/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ console.log(chalk.magenta('Building client...'));

build(config)
.then(({ stats, warnings }) => {
console.timeEnd('build client');
if (warnings.length) {
console.log(chalk.yellow('Client compiled with warnings.\n'));
console.log(warnings.join('\n\n'));
Expand Down
3 changes: 1 addition & 2 deletions packages/arui-scripts/src/commands/build/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,9 @@ import build from './build-wrapper';
import config from '../../configs/webpack.server.prod';

console.log(chalk.magenta('Building server...'));
console.time('build server');

build(config as any)
.then(({ warnings }) => {
console.timeEnd('build server');
if (warnings.length) {
console.log(chalk.yellow('Server compiled with warnings.\n'));
console.log(warnings.join('\n\n'));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@ import { AppConfigs, AppContext } from './types';
/**
* Обновление ключей конфига, зависящих от других. Это нужно делать в самый последний момент
*/
export function calculateDependentConfig(config: AppConfigs) {
export function calculateDependentConfig(config: AppConfigs): AppConfigs {
return {
...config,
codeLoader: config.useTscLoader ? 'tsc' : config.codeLoader,
jestCodeTransformer: config.jestUseTsJest ? 'tsc' : config.jestCodeTransformer,
clientPolyfillsEntry: getPolyfills(config),
};
}
Expand Down
4 changes: 2 additions & 2 deletions packages/arui-scripts/src/configs/app-configs/get-defaults.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,12 @@ export function getDefaultAppConfig(): AppConfigs {
// build tuning
keepPropTypes: false,
useTscLoader: false,
useSwcLoader: false,
codeLoader: 'babel',
webpack4Compatibility: false,
installServerSourceMaps: false,
disableDevWebpackTypecheck: true,
jestUseTsJest: false,
jestUseSwc: false,
jestCodeTransformer: 'babel',
collectCoverage: process.env.NODE_ENV === 'cypress' || process.env.USE_ISTANBUL === 'enabled',

// image processing
Expand Down
10 changes: 8 additions & 2 deletions packages/arui-scripts/src/configs/app-configs/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,18 @@ export type AppConfigs = {
* @deprecated использование ts-loader крайне не рекомендуется - он медленнее и не имеет преимуществ перед babel
*/
useTscLoader: boolean;
useSwcLoader: boolean;
codeLoader: 'babel' | 'tsc' | 'swc';
/**
* @deprecated эта настройка будет удалена в будущих версиях скриптов
*/
webpack4Compatibility: boolean;
installServerSourceMaps: boolean;
disableDevWebpackTypecheck: boolean;
/**
* @deprecated используйте настройку jestCodeTransformer
*/
jestUseTsJest: boolean;
jestUseSwc: boolean;
jestCodeTransformer: 'babel' | 'tsc' | 'swc';
collectCoverage: boolean;

// image processing
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,10 @@ export function warnAboutDeprecations(config: AppContextWithConfigs) {
);
}

if (config.useSwcLoader && config.useTscLoader) {
console.warn('Одновременное использование опций `useSwcLoader` и `useTscLoader` не поддерживается, выберите что-то одно');
}

if (config.jestUseSwc && config.jestUseTsJest) {
console.warn('Одновременное использование опций `jestUseSwc` и `jestUseTsJest` не поддерживается, выберите что-то одно');
if (config.webpack4Compatibility) {
console.warn(
'Опция `webpack4Compatibility` будет удалена в будущих версиях arui-scripts.',
'Обратитесь к issue в webpack https://github.com/webpack/webpack/issues/14580 для получения дополнительной информации',
);
}
}
60 changes: 35 additions & 25 deletions packages/arui-scripts/src/configs/jest/settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,27 +10,6 @@ const { swcJestConfig } = require('../swc');

const configs = require('../app-configs').default;

let tsConfigPaths = {};

if (configs.tsconfig) {
const tsConfigText = fs.readFileSync(configs.tsconfig, 'utf8');
const tsConfig = parseConfigFileTextToJson(configs.tsconfig, tsConfigText);

tsConfigPaths = tsConfig.config.compilerOptions?.paths || {};
}

let tsxTransformer = require.resolve('./babel-transform');
const jsTransformer = configs.jestUseSwc
? [require.resolve('@swc/jest'), swcJestConfig]
: require.resolve('./babel-transform');

if (configs.jestUseSwc) {
tsxTransformer = [require.resolve('@swc/jest'), swcJestConfig];
}
if (configs.jestUseTsJest) {
tsxTransformer = require.resolve('ts-jest');
}

module.exports = {
testRegex: 'src/.*(((/__test__/|/__tests__/).*)|(test|spec|tests)).(jsx?|tsx?)$',
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'],
Expand All @@ -39,15 +18,15 @@ module.exports = {
url: 'http://localhost',
},
transform: {
'^.+\\.jsx?$': jsTransformer,
'^.+\\.mjs$': jsTransformer,
'^.+\\.tsx?$': tsxTransformer,
'^.+\\.jsx?$': getJsTransformer(),
'^.+\\.mjs$': getJsTransformer(),
'^.+\\.tsx?$': getTsTransformer(),
'^(?!.*\\.(js|jsx|ts|tsx|css|json)$)': require.resolve('./file-transform'),
},
moduleNameMapper: {
// replace all css files with simple empty exports
'\\.css$': require.resolve('./css-mock'),
...pathsToModuleNameMapper(tsConfigPaths, { prefix: '<rootDir>/' }),
...pathsToModuleNameMapper(getPathMapping(), { prefix: '<rootDir>/' }),
},
snapshotSerializers: [require.resolve('jest-snapshot-serializer-class-name-to-string')],
globals: {
Expand All @@ -56,3 +35,34 @@ module.exports = {
},
},
};

function getPathMapping() {
if (!configs.tsconfig) {
return {};
}

const tsConfigText = fs.readFileSync(configs.tsconfig, 'utf8');
const tsConfig = parseConfigFileTextToJson(configs.tsconfig, tsConfigText);

return tsConfig.config.compilerOptions?.paths || {};
}

function getTsTransformer() {
if (configs.jestCodeTransformer === 'tsc') {
return require.resolve('ts-jest');
}

if (configs.jestCodeTransformer === 'swc') {
return [require.resolve('@swc/jest'), swcJestConfig];
}

return require.resolve('./babel-transform')
}

function getJsTransformer() {
if (configs.jestCodeTransformer === 'swc') {
return [require.resolve('@swc/jest'), swcJestConfig];
}

return require.resolve('./babel-transform');
}
Loading

0 comments on commit cdef412

Please sign in to comment.