Прежде чем перейти к статье, хочу вам представить, экономическую онлайн игру Brave Knights, в которой вы можете играть и зарабатывать. Регистируйтесь, играйте и зарабатывайте!
39% — это количество уникальных функций в папке node_modules
в дефолтном Angular проекте, созданном командой ng new my-app
.
Мне было интересно посмотреть, сколько похожих функций существует в node_modules. Ведь наверняка же разработчики открытых библиотек решают проблемы одинаковыми способами, так же изучают одни и те же алгоритмы, ну и, чего кривить душой, копируют одни и те же решения со StackOverflow.
Как сравнить функции в Javascript?
Если вы захотите сравнить пару функци в javascript, то сделать это проще простого, после пребразования их в строковый вид:
const a = () => 'hi';
a.toString(); // "() => 'hi'"
А если названия переменных разные?
Нужно привести их к одному виду при помощи библиотеки Uglifyjs, которая минимизирует функцию, удалит лишнее, сделает простейщие вычисления.
Как же извлечь функции из Javascript файла?
Для этого я воспользовался библиотекой Esprima. То есть парсим файл и обходим AST дерево. Думаю что можно было бы обойтись только Uglifyjs, но что-то у меня сходу не завелось, а разбираться было лень.
В общем план действий я нарисовал следующий
- Перебираем все
*.js
файлы в директории - Парсим каждый файл и извлекаем функции типов
ArrowFunctionExpression
,FunctionExpression
иFunctionDeclaration
- Ужимаем каждую из функций при помощи
UglifyJs
и записываем её в файл, имя которого — это хеш функции - В отдельный файл
info.csv
записываем строку с id записи, названием файла, из которого была извлечена функция и хешем функции - Загружаем файл
info.csv
вSQLite
и делаем по нему всякие запросы, ведь эта база — не игрушка!
Детали реализации
- Всем стрелочным функциям и фунциональным выражениям я дал название
z
; - Обычные функции я переименовал в
MORK
, но сохранил отдельно названия функций для учета, потому что функция может быть той же самой, но называться по-другому; - Возможно с этими переименованиями я потерял часть статистики, связанной с рекурсивными функциями, ну и ладно!
Пример извлечения функций из файла
Код javascript файла, и которого будем извлекать функции:
(function () {
const arbuz = (test) => {
function apple(t) {
function test () {
return 'ttt';
}
return t + 3;
}
const aa = 1;
const b1 = () => 2;
// comment
return aa + b1() + apple(test);
}
return arbuz;
})();
Обратите внимание, что некоторые выражения в извлеченных функциях вычеслены, что поможет сравнению функций. Список извлеченных функций:
"const z=function(){return n=>{return 3+(n+3)}};";
"const z=n=>{return 3+(n+3)};";
"function MORK(n){return n+3}";
"function MORK(){return"ttt"}";
"const z=()=>2;";
Полный скрипт можно найти тут
Первый объект исследования: node_modules дефолтного проекта Angular 11
Итак, создаём проект при помощи @angular/cli
: ng new my-app
, запускаем скрипт на парсинг node_modules
и оставляем его на ночь.
{
"name": "my-app",
"version": "0.0.0",
"scripts": {
"ng": "ng",
"start": "ng serve",
"build": "ng build --prod",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e"
},
"private": true,
"dependencies": {
"@angular/animations": "~11.2.10",
"@angular/common": "~11.2.10",
"@angular/compiler": "~11.2.10",
"@angular/core": "~11.2.10",
"@angular/forms": "~11.2.10",
"@angular/platform-browser": "~11.2.10",
"@angular/platform-browser-dynamic": "~11.2.10",
"@angular/router": "~11.2.10",
"rxjs": "~6.6.0",
"tslib": "^2.0.0",
"zone.js": "~0.11.3"
},
"devDependencies": {
"@angular-devkit/build-angular": "~0.1102.9",
"@angular/cli": "~11.2.9",
"@angular/compiler-cli": "~11.2.10",
"@types/jasmine": "~3.6.0",
"@types/node": "^12.11.1",
"codelyzer": "^6.0.0",
"jasmine-core": "~3.6.0",
"jasmine-spec-reporter": "~5.0.0",
"karma": "~6.1.0",
"karma-chrome-launcher": "~3.1.0",
"karma-coverage": "~2.0.3",
"karma-jasmine": "~4.0.0",
"karma-jasmine-html-reporter": "^1.5.0",
"protractor": "~7.0.0",
"ts-node": "~8.3.0",
"tslint": "~6.1.0",
"typescript": "~4.1.5"
}
}
Полный package-lock.json тут
Результаты
В папке node_modules 26982 *.js файлов:
$ find . -name '*.js' | wc -l
26982
А в них найдено 338230 функций:
sqlite> select count(*) from info;
338230
Из которых 130886 уникальных:
sqlite> Select count(*) from (SELECT hash, count(id) as c FROM info group By hash);
130886
То есть 130886/338230 * 100% =
39% функций действительно уникальны, а остальные — это дубликаты уже существующих.
Скачать csv файл для самостоятельной проверки можно тут.
Топ 20 самых популярных функций в node_modules для проекта Angular
То есть функции с самым большим количеством дубликатов.
SELECT hash, count(id) as c FROM info group By hash order by c desc LIMIT 20;
# | id | количество дубликатов |
---|---|---|
1 | 285d00ca29fcc46aa113c7aefc63827d | 2730 |
2 | cf6a0564f1128496d1e4706f302787d6 | 1871 |
3 | 12f746f2689073d5c949998e0216f68a | 1174 |
4 | 7d1e7aad635be0f7382696c4f846beae | 772 |
5 | c2da306af9b041ba213e3b189699d45c | 699 |
6 | c41eb44114860f3aa1e9fa79c779e02f | 697 |
7 | 5911b29c89fa44f28ce030aa5e433327 | 691 |
8 | 05c2b9b254be7e4b8460274c1353b5ad | 653 |
9 | fcaede1b9e574664c893e75ee7dc1d8b | 652 |
10 | e743dd760a03449be792c00e65154a48 | 635 |
11 | 777c390d3cc4663f8ebe4933e5c33e9d | 441 |
12 | 27628ad740cff22386b0ff029e844e85 | 385 |
13 | f6822db5c8812f4b09ab142afe908cda | 375 |
14 | d98a03a472615305b012eceb3e9947d5 | 330 |
15 | 4728096fca2b3575800dafbdebf4276a | 324 |
16 | 7b769d3e4ba438fc53b42ad8bece86ba | 289 |
17 | 7d6f69751712ef9fa94238b38120adc6 | 282 |
18 | b7081aad7510b0993fcb57bfb95c5c2c | 255 |
19 | d665499155e104f749bf3a67caed576a | 250 |
20 | 99fa7dfce87269a564fc848a7f7515b9 | 250 |
285d00ca29fcc46aa113c7aefc63827d, 2730 идентичных
const z=function(){};
cf6a0564f1128496d1e4706f302787d6, 1871 идентичных, названия функций одинаковые:
__export
function MORK(r){for(var o in r)exports.hasOwnProperty(o)||(exports[o]=r[o])}
12f746f2689073d5c949998e0216f68a, 1174 идентичных, названия функций:
_interopRequireDefault
и__importDefault
function MORK(e){return e&&e.__esModule?e:{default:e}}
7d1e7aad635be0f7382696c4f846beae, 772 идентичных, у всех у них было примерно 300 уникальных названий
function MORK(){}
c2da306af9b041ba213e3b189699d45c, 699 идентичных
const z=function(o,_){o.__proto__=_};
c41eb44114860f3aa1e9fa79c779e02f, 697 идентичных, имя
__
function MORK(){this.constructor=d}
5911b29c89fa44f28ce030aa5e433327, 691 идентичная
const z=function(n,o){for(var r in o)o.hasOwnProperty(r)&&(n[r]=o[r])};
05c2b9b254be7e4b8460274c1353b5ad, 653 идентичных
const z=function(t,n){return extendStatics=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var o in n)n.hasOwnProperty(o)&&(t[o]=n[o])},extendStatics(t,n)};
fcaede1b9e574664c893e75ee7dc1d8b, 652 идентичных
const z=function(t,o){function e(){this.constructor=t}extendStatics(t,o),t.prototype=null===o?Object.create(o):(e.prototype=o.prototype,new e)};
e743dd760a03449be792c00e65154a48, 635 идентичных
function(){var r=function(t,o){return(r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,o){t.__proto__=o}||function(t,o){for(var n in o)o.hasOwnProperty(n)&&(t[n]=o[n])})(t,o)};return function(t,o){function n(){this.constructor=t}r(t,o),t.prototype=null===o?Object.create(o):(n.prototype=o.prototype,new n)}};
777c390d3cc4663f8ebe4933e5c33e9d, 441 идентичная, имена функций различные, чаще всего:
Rule
,AsapScheduler
,ComplexOuterSubscriber
и другие
function MORK(){return null!==_super&&_super.apply(this,arguments)||this}
27628ad740cff22386b0ff029e844e85, 385 идентичных, имена функций чаще разные, чаще всего
identity
,forwardResolution
и тд
function MORK(n){return n}
f6822db5c8812f4b09ab142afe908cda, 375 идентичных
const z=function(n){};
d98a03a472615305b012eceb3e9947d5, 330 идентичных
const z=function(n,c){};
4728096fca2b3575800dafbdebf4276a, 324 идентичных
const z=function(n){return n};
7b769d3e4ba438fc53b42ad8bece86ba, 289 идентичных, все имена
plural
function MORK(t){var r=Math.floor(Math.abs(t)),t=t.toString().replace(/^[^.]*\.?/,"").length;return 1===r&&0===t?1:5}
7d6f69751712ef9fa94238b38120adc6, 255 идентичных
const z=function(){return this};
b7081aad7510b0993fcb57bfb95c5c2c, 250 идентичных
const z=function(){return!1};
d665499155e104f749bf3a67caed576a, 250 идентичных
const z=function(n){return null==n};
99fa7dfce87269a564fc848a7f7515b9, 255 идентичных
const z=function(a,c){this._array.forEach(a,c)};
Файлы с самым большим количеством функций
SELECT count(id) as c, path FROM info group By path order by c desc LIMIT 20;
Количество | Файл |
---|---|
13638 | typescript/lib/tsserver.js |
13617 | typescript/lib/tsserverlibrary.js |
12411 | typescript/lib/typescriptServices.js |
12411 | typescript/lib/typescript.js |
12411 | @schematics/angular/third_party/github.com/Microsoft/TypeScript/lib/typescript.js |
10346 | sass/sass.dart.js |
8703 | typescript/lib/typingsInstaller.js |
8528 | typescript/lib/tsc.js |
3933 | @angular/compiler/bundles/compiler.umd.js |
3803 | @angular/compiler/bundles/compiler.umd.min.js |
2602 | selenium-webdriver/lib/test/data/js/tinymce.min.js |
2264 | @angular/core/bundles/core.umd.js |
2028 | @angular/core/bundles/core.umd.min.js |
1457 | terser/dist/bundle.min.js |
1416 | rxjs/bundles/rxjs.umd.js |
1416 | @angular-devkit/schematics/node_modules/rxjs/bundles/rxjs.umd.js |
1416 | @angular-devkit/core/node_modules/rxjs/bundles/rxjs.umd.js |
1416 | @angular-devkit/build-webpack/node_modules/rxjs/bundles/rxjs.umd.js |
1416 | @angular-devkit/build-angular/node_modules/rxjs/bundles/rxjs.umd.js |
1416 | @angular-devkit/architect/node_modules/rxjs/bundles/rxjs.umd.js |
Вы спросите — А как насчет собранного бандла?
На самом деле, ничего интересного. Сборшики работают эффективно. Из 1282 используемых функций, 95% уникальны. Привожу пятерку функций, которые имеют дубликаты:
Количество | Функция |
---|---|
11 | const z=function(){}; |
10 | const z=()=>R; |
8 | const z=function(n){return new(n||t)}; |
6 | const z=function(n){}; |
5 | const z=()=>{}; |
А что там у нас с React'ом?
Я так же проверил и React. Сравнение я вынес в таблицу ниже:
В node_modules | Angular | React |
---|---|---|
всего файлов *.js | 26982 | 23942 |
всего функций | 338230 | 163385 |
уникальных функций | 130886 | 92766 |
% уникальных функций | 39% | 57% |
Скачать csv файл для самостоятельной проверки можно тут.
Топ 20 самых популярных функций в node_modules для проекта React
Я использовал create-react-app
. Файлы package.json
и yarn.lock
можно найти тут.
# | id | количество дубликатов |
---|---|---|
1 | 12f746f2689073d5c949998e0216f68a | 1377 |
2 | 285d00ca29fcc46aa113c7aefc63827d | 1243 |
3 | 3f993321f73e83f277c20c178e5587b9 | 989 |
4 | 54782ec6cef850906484808b86946b33 | 299 |
5 | 7d1e7aad635be0f7382696c4f846beae | 278 |
6 | d11004e998280b565ad084b0ad5ca214 | 239 |
7 | a02c66d8928b3353552e4804c6714326 | 237 |
8 | 79e9bd3cdf15cf0af97f73ccaed50fa0 | 231 |
9 | 7d6f69751712ef9fa94238b38120adc6 | 189 |
10 | b8dd34af96b042c23a4be7f82c881fe4 | 176 |
11 | 863a48e36413feba8bb299623dbc9b20 | 174 |
12 | 2482d2afd404031c67adb9cbc012768b | 174 |
13 | 4728096fca2b3575800dafbdebf4276a | 170 |
14 | bf8b05684375b26205e50fa27317057e | 157 |
15 | fd114ee6b71ee06738b5b547b00e8102 | 156 |
16 | df1c43e5a72e92d11bdefcead13a5e14 | 156 |
17 | 094afc30995ff28993ec5326e8b3c4d4 | 156 |
18 | 042490db7093660e74a762447f64f950 | 156 |
19 | 5c5979ec3533f13b22153de05ffc64d5 | 154 |
20 | 50645492c50621c0847c4ebd1fdd65cd | 154 |
12f746f2689073d5c949998e0216f68a, 1377 идентичных, названия функций обычно:
_interopRequireDefault
function MORK(e){return e&&e.__esModule?e:{default:e}}
285d00ca29fcc46aa113c7aefc63827d, 1243 идентичных
const z=function(){};
3f993321f73e83f277c20c178e5587b9, 989 идентичных
const z=function(){return data};
54782ec6cef850906484808b86946b33, 299 идентичных
const z=()=>{};
7d1e7aad635be0f7382696c4f846beae, 278 идентичных, имена функций чаще всего
emptyFunction
,Generator
function MORK(){}
d11004e998280b565ad084b0ad5ca214, 239 идентичных
const z=function(){return cache};
a02c66d8928b3353552e4804c6714326, 237 идентичных, имя функции
_getRequireWildcardCache
function MORK(){if("function"!=typeof WeakMap)return null;var e=new WeakMap;return _getRequireWildcardCache=function(){return e},e}
79e9bd3cdf15cf0af97f73ccaed50fa0, 231 идентичных, имя функции
_interopRequireWildcard
function MORK(e){if(e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var t=_getRequireWildcardCache();if(t&&t.has(e))return t.get(e);var r,n,o={},c=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(r in e)Object.prototype.hasOwnProperty.call(e,r)&&((n=c?Object.getOwnPropertyDescriptor(e,r):null)&&(n.get||n.set)?Object.defineProperty(o,r,n):o[r]=e[r]);return o.default=e,t&&t.set(e,o),o}
7d6f69751712ef9fa94238b38120adc6, 189 идентичных
const z=function(){return this};
b8dd34af96b042c23a4be7f82c881fe4, 176 идентичных
const z=function(n,o,c,i){n[i=void 0===i?c:i]=o[c]};
863a48e36413feba8bb299623dbc9b20, 174 идентичных
const z=function(e,n,t,o){void 0===o&&(o=t),Object.defineProperty(e,o,{enumerable:!0,get:function(){return n[t]}})};
2482d2afd404031c67adb9cbc012768b, 174 идентичных
const z=function(){return m[k]};
4728096fca2b3575800dafbdebf4276a, 170 идентичных
const z=function(n){return n};
bf8b05684375b26205e50fa27317057e, 157 идентичных
const z=s=>exposed.has(s);
fd114ee6b71ee06738b5b547b00e8102, 156 идентичных
const z=(r,e,p)=>{var t=makeWrapper(r);return exports.setup(t,r,e,p)};
df1c43e5a72e92d11bdefcead13a5e14, 156 идентичных
const z=t=>utils.isObject(t)&&t instanceof Impl.implementation;
094afc30995ff28993ec5326e8b3c4d4, 156 идентичных
const z=i=>utils.isObject(i)&&utils.hasOwn(i,implSymbol)&&i[implSymbol]instanceof Impl.implementation;
042490db7093660e74a762447f64f950, 156 идентичных
const z=(r,e,t)=>{t=exports.create(r,e,t);return utils.implForWrapper(t)};
5c5979ec3533f13b22153de05ffc64d5, 154 идентичных
const z=function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var r in e)"default"!==r&&Object.prototype.hasOwnProperty.call(e,r)&&__createBinding(t,e,r);return __setModuleDefault(t,e),t};
50645492c50621c0847c4ebd1fdd65cd, 154 идентичных
const z=function(e,n){Object.defineProperty(e,"default",{enumerable:!0,value:n})};
В каких файлах используется функция 8 (79e9bd3cdf15cf0af97f73ccaed50fa0)
Список длинный
/jest-worker/build/base/BaseWorkerPool.js
/@svgr/hast-util-to-babel-ast/lib/index.js
/@svgr/hast-util-to-babel-ast/lib/handlers.js
/@svgr/hast-util-to-babel-ast/lib/stringToObjectStyle.js
/@svgr/hast-util-to-babel-ast/lib/getAttributes.js
/babel-jest/node_modules/@babel/core/lib/transform-file.js
/babel-jest/node_modules/@babel/core/lib/config/files/configuration.js
/babel-jest/node_modules/@babel/core/lib/config/files/utils.js
/babel-jest/node_modules/@babel/core/lib/config/full.js
/babel-jest/node_modules/@babel/core/lib/transformation/normalize-file.js
/babel-jest/node_modules/@babel/core/lib/transformation/file/file.js
/babel-jest/node_modules/@babel/core/lib/tools/build-external-helpers.js
/babel-jest/node_modules/@babel/core/lib/index.js
/jest-pnp-resolver/node_modules/jest-resolve/build/defaultResolver.js
/jest-pnp-resolver/node_modules/jest-resolve/build/ModuleNotFoundError.js
/jest-circus/build/utils.js
/jest-haste-map/build/ModuleMap.js
/jest-haste-map/build/lib/normalizePathSep.js
/jest-haste-map/build/lib/fast_path.js
/jest-haste-map/build/lib/WatchmanWatcher.js
/jest-haste-map/build/worker.js
/jest-haste-map/build/getMockName.js
/jest-haste-map/build/HasteFS.js
/jest-haste-map/build/crawlers/watchman.js
/jest-jasmine2/build/index.js
/eslint/node_modules/@babel/code-frame/lib/index.js
/mini-css-extract-plugin/dist/index.js
/react-scripts/node_modules/@babel/core/lib/transform-file.js
/react-scripts/node_modules/@babel/core/lib/config/files/configuration.js
/react-scripts/node_modules/@babel/core/lib/config/files/utils.js
/react-scripts/node_modules/@babel/core/lib/config/full.js
/react-scripts/node_modules/@babel/core/lib/transformation/normalize-file.js
/react-scripts/node_modules/@babel/core/lib/transformation/file/file.js
/react-scripts/node_modules/@babel/core/lib/tools/build-external-helpers.js
/react-scripts/node_modules/@babel/core/lib/index.js
/react-scripts/node_modules/jest-resolve/build/defaultResolver.js
/react-scripts/node_modules/jest-resolve/build/ModuleNotFoundError.js
/eslint-plugin-flowtype/dist/utilities/index.js
/jest-util/build/index.js
/jest-util/build/createDirectory.js
/jest-util/build/installCommonGlobals.js
/babel-preset-react-app/node_modules/@babel/plugin-transform-react-jsx-development/node_modules/@babel/core/lib/transform-file.js
/babel-preset-react-app/node_modules/@babel/plugin-transform-react-jsx-development/node_modules/@babel/core/lib/config/files/configuration.js
/babel-preset-react-app/node_modules/@babel/plugin-transform-react-jsx-development/node_modules/@babel/core/lib/config/files/utils.js
/babel-preset-react-app/node_modules/@babel/plugin-transform-react-jsx-development/node_modules/@babel/core/lib/config/full.js
/babel-preset-react-app/node_modules/@babel/plugin-transform-react-jsx-development/node_modules/@babel/core/lib/transformation/normalize-file.js
/babel-preset-react-app/node_modules/@babel/plugin-transform-react-jsx-development/node_modules/@babel/core/lib/transformation/file/file.js
/babel-preset-react-app/node_modules/@babel/plugin-transform-react-jsx-development/node_modules/@babel/core/lib/tools/build-external-helpers.js
/babel-preset-react-app/node_modules/@babel/plugin-transform-react-jsx-development/node_modules/@babel/core/lib/index.js
/babel-preset-react-app/node_modules/@babel/plugin-transform-react-pure-annotations/node_modules/@babel/core/lib/transform-file.js
/babel-preset-react-app/node_modules/@babel/plugin-transform-react-pure-annotations/node_modules/@babel/core/lib/config/files/configuration.js
/babel-preset-react-app/node_modules/@babel/plugin-transform-react-pure-annotations/node_modules/@babel/core/lib/config/files/utils.js
/babel-preset-react-app/node_modules/@babel/plugin-transform-react-pure-annotations/node_modules/@babel/core/lib/config/full.js
/babel-preset-react-app/node_modules/@babel/plugin-transform-react-pure-annotations/node_modules/@babel/core/lib/transformation/normalize-file.js
/babel-preset-react-app/node_modules/@babel/plugin-transform-react-pure-annotations/node_modules/@babel/core/lib/transformation/file/file.js
/babel-preset-react-app/node_modules/@babel/plugin-transform-react-pure-annotations/node_modules/@babel/core/lib/tools/build-external-helpers.js
/babel-preset-react-app/node_modules/@babel/plugin-transform-react-pure-annotations/node_modules/@babel/core/lib/index.js
/babel-preset-react-app/node_modules/@babel/plugin-transform-react-jsx/node_modules/@babel/core/lib/transform-file.js
/babel-preset-react-app/node_modules/@babel/plugin-transform-react-jsx/node_modules/@babel/core/lib/config/files/configuration.js
/babel-preset-react-app/node_modules/@babel/plugin-transform-react-jsx/node_modules/@babel/core/lib/config/files/utils.js
/babel-preset-react-app/node_modules/@babel/plugin-transform-react-jsx/node_modules/@babel/core/lib/config/full.js
/babel-preset-react-app/node_modules/@babel/plugin-transform-react-jsx/node_modules/@babel/core/lib/transformation/normalize-file.js
/babel-preset-react-app/node_modules/@babel/plugin-transform-react-jsx/node_modules/@babel/core/lib/transformation/file/file.js
/babel-preset-react-app/node_modules/@babel/plugin-transform-react-jsx/node_modules/@babel/core/lib/tools/build-external-helpers.js
/babel-preset-react-app/node_modules/@babel/plugin-transform-react-jsx/node_modules/@babel/core/lib/index.js
/babel-preset-react-app/node_modules/@babel/preset-env/node_modules/@babel/plugin-proposal-class-properties/node_modules/@babel/core/lib/transform-file.js
/babel-preset-react-app/node_modules/@babel/preset-env/node_modules/@babel/plugin-proposal-class-properties/node_modules/@babel/core/lib/config/files/configuration.js
/babel-preset-react-app/node_modules/@babel/preset-env/node_modules/@babel/plugin-proposal-class-properties/node_modules/@babel/core/lib/config/files/utils.js
/babel-preset-react-app/node_modules/@babel/preset-env/node_modules/@babel/plugin-proposal-class-properties/node_modules/@babel/core/lib/config/full.js
/babel-preset-react-app/node_modules/@babel/preset-env/node_modules/@babel/plugin-proposal-class-properties/node_modules/@babel/core/lib/transformation/normalize-file.js
/babel-preset-react-app/node_modules/@babel/preset-env/node_modules/@babel/plugin-proposal-class-properties/node_modules/@babel/core/lib/transformation/file/file.js
/babel-preset-react-app/node_modules/@babel/preset-env/node_modules/@babel/plugin-proposal-class-properties/node_modules/@babel/core/lib/tools/build-external-helpers.js
/babel-preset-react-app/node_modules/@babel/preset-env/node_modules/@babel/plugin-proposal-class-properties/node_modules/@babel/core/lib/index.js
/babel-preset-react-app/node_modules/@babel/preset-env/node_modules/@babel/plugin-proposal-optional-chaining/node_modules/@babel/core/lib/transform-file.js
/babel-preset-react-app/node_modules/@babel/preset-env/node_modules/@babel/plugin-proposal-optional-chaining/node_modules/@babel/core/lib/config/files/configuration.js
/babel-preset-react-app/node_modules/@babel/preset-env/node_modules/@babel/plugin-proposal-optional-chaining/node_modules/@babel/core/lib/config/files/utils.js
/babel-preset-react-app/node_modules/@babel/preset-env/node_modules/@babel/plugin-proposal-optional-chaining/node_modules/@babel/core/lib/config/full.js
/babel-preset-react-app/node_modules/@babel/preset-env/node_modules/@babel/plugin-proposal-optional-chaining/node_modules/@babel/core/lib/transformation/normalize-file.js
/babel-preset-react-app/node_modules/@babel/preset-env/node_modules/@babel/plugin-proposal-optional-chaining/node_modules/@babel/core/lib/transformation/file/file.js
/babel-preset-react-app/node_modules/@babel/preset-env/node_modules/@babel/plugin-proposal-optional-chaining/node_modules/@babel/core/lib/tools/build-external-helpers.js
/babel-preset-react-app/node_modules/@babel/preset-env/node_modules/@babel/plugin-proposal-optional-chaining/node_modules/@babel/core/lib/index.js
/babel-preset-react-app/node_modules/@babel/preset-env/node_modules/@babel/plugin-proposal-nullish-coalescing-operator/node_modules/@babel/core/lib/transform-file.js
/babel-preset-react-app/node_modules/@babel/preset-env/node_modules/@babel/plugin-proposal-nullish-coalescing-operator/node_modules/@babel/core/lib/config/files/configuration.js
/babel-preset-react-app/node_modules/@babel/preset-env/node_modules/@babel/plugin-proposal-nullish-coalescing-operator/node_modules/@babel/core/lib/config/files/utils.js
/babel-preset-react-app/node_modules/@babel/preset-env/node_modules/@babel/plugin-proposal-nullish-coalescing-operator/node_modules/@babel/core/lib/config/full.js
/babel-preset-react-app/node_modules/@babel/preset-env/node_modules/@babel/plugin-proposal-nullish-coalescing-operator/node_modules/@babel/core/lib/transformation/normalize-file.js
/babel-preset-react-app/node_modules/@babel/preset-env/node_modules/@babel/plugin-proposal-nullish-coalescing-operator/node_modules/@babel/core/lib/transformation/file/file.js
/babel-preset-react-app/node_modules/@babel/preset-env/node_modules/@babel/plugin-proposal-nullish-coalescing-operator/node_modules/@babel/core/lib/tools/build-external-helpers.js
/babel-preset-react-app/node_modules/@babel/preset-env/node_modules/@babel/plugin-proposal-nullish-coalescing-operator/node_modules/@babel/core/lib/index.js
/babel-preset-react-app/node_modules/@babel/preset-env/node_modules/@babel/plugin-proposal-numeric-separator/node_modules/@babel/core/lib/transform-file.js
/babel-preset-react-app/node_modules/@babel/preset-env/node_modules/@babel/plugin-proposal-numeric-separator/node_modules/@babel/core/lib/config/files/configuration.js
/babel-preset-react-app/node_modules/@babel/preset-env/node_modules/@babel/plugin-proposal-numeric-separator/node_modules/@babel/core/lib/config/files/utils.js
/babel-preset-react-app/node_modules/@babel/preset-env/node_modules/@babel/plugin-proposal-numeric-separator/node_modules/@babel/core/lib/config/full.js
/babel-preset-react-app/node_modules/@babel/preset-env/node_modules/@babel/plugin-proposal-numeric-separator/node_modules/@babel/core/lib/transformation/normalize-file.js
/babel-preset-react-app/node_modules/@babel/preset-env/node_modules/@babel/plugin-proposal-numeric-separator/node_modules/@babel/core/lib/transformation/file/file.js
/babel-preset-react-app/node_modules/@babel/preset-env/node_modules/@babel/plugin-proposal-numeric-separator/node_modules/@babel/core/lib/tools/build-external-helpers.js
/babel-preset-react-app/node_modules/@babel/preset-env/node_modules/@babel/plugin-proposal-numeric-separator/node_modules/@babel/core/lib/index.js
/babel-preset-react-app/node_modules/@babel/preset-env/lib/targets-parser.js
/babel-preset-react-app/node_modules/@babel/preset-env/lib/index.js
/babel-preset-react-app/node_modules/@babel/preset-env/lib/utils.js
/babel-preset-react-app/node_modules/@babel/preset-react/node_modules/@babel/plugin-transform-react-display-name/node_modules/@babel/core/lib/transform-file.js
/babel-preset-react-app/node_modules/@babel/preset-react/node_modules/@babel/plugin-transform-react-display-name/node_modules/@babel/core/lib/config/files/configuration.js
/babel-preset-react-app/node_modules/@babel/preset-react/node_modules/@babel/plugin-transform-react-display-name/node_modules/@babel/core/lib/config/files/utils.js
/babel-preset-react-app/node_modules/@babel/preset-react/node_modules/@babel/plugin-transform-react-display-name/node_modules/@babel/core/lib/config/full.js
/babel-preset-react-app/node_modules/@babel/preset-react/node_modules/@babel/plugin-transform-react-display-name/node_modules/@babel/core/lib/transformation/normalize-file.js
/babel-preset-react-app/node_modules/@babel/preset-react/node_modules/@babel/plugin-transform-react-display-name/node_modules/@babel/core/lib/transformation/file/file.js
/babel-preset-react-app/node_modules/@babel/preset-react/node_modules/@babel/plugin-transform-react-display-name/node_modules/@babel/core/lib/tools/build-external-helpers.js
/babel-preset-react-app/node_modules/@babel/preset-react/node_modules/@babel/plugin-transform-react-display-name/node_modules/@babel/core/lib/index.js
/babel-preset-react-app/node_modules/@babel/core/lib/transform-file.js
/babel-preset-react-app/node_modules/@babel/core/lib/config/files/configuration.js
/babel-preset-react-app/node_modules/@babel/core/lib/config/files/utils.js
/babel-preset-react-app/node_modules/@babel/core/lib/config/full.js
/babel-preset-react-app/node_modules/@babel/core/lib/transformation/normalize-file.js
/babel-preset-react-app/node_modules/@babel/core/lib/transformation/file/file.js
/babel-preset-react-app/node_modules/@babel/core/lib/tools/build-external-helpers.js
/babel-preset-react-app/node_modules/@babel/core/lib/index.js
/@babel/code-frame/lib/index.js
/@babel/traverse/lib/path/inference/inferer-reference.js
/@babel/traverse/lib/path/inference/inferers.js
/@babel/traverse/lib/path/inference/index.js
/@babel/traverse/lib/path/comments.js
/@babel/traverse/lib/path/replacement.js
/@babel/traverse/lib/path/ancestry.js
/@babel/traverse/lib/path/conversion.js
/@babel/traverse/lib/path/index.js
/@babel/traverse/lib/path/introspection.js
/@babel/traverse/lib/path/removal.js
/@babel/traverse/lib/path/lib/hoister.js
/@babel/traverse/lib/path/lib/virtual-types.js
/@babel/traverse/lib/path/modification.js
/@babel/traverse/lib/path/family.js
/@babel/traverse/lib/path/generated/asserts.js
/@babel/traverse/lib/path/generated/validators.js
/@babel/traverse/lib/path/generated/virtual-types.js
/@babel/traverse/lib/index.js
/@babel/traverse/lib/visitors.js
/@babel/traverse/lib/context.js
/@babel/traverse/lib/scope/index.js
/@babel/traverse/lib/scope/lib/renamer.js
/@babel/traverse/lib/types.js
/@babel/helper-hoist-variables/lib/index.js
/@babel/helper-wrap-function/lib/index.js
/@babel/helper-builder-binary-assignment-operator-visitor/lib/index.js
/@babel/helper-explode-assignable-expression/lib/index.js
/@babel/helper-replace-supers/lib/index.js
/@babel/helper-module-imports/lib/import-builder.js
/@babel/helper-module-imports/lib/import-injector.js
/@babel/helper-skip-transparent-expression-wrappers/lib/index.js
/@babel/helper-compilation-targets/lib/index.js
/@babel/types/lib/definitions/jsx.js
/@babel/types/lib/definitions/misc.js
/@babel/types/lib/definitions/typescript.js
/@babel/types/lib/definitions/flow.js
/@babel/types/lib/definitions/experimental.js
/@babel/types/lib/definitions/core.js
/@babel/types/lib/index.js
/@babel/helpers/lib/index.js
/@babel/helper-remap-async-to-generator/lib/index.js
/@babel/helper-split-export-declaration/lib/index.js
/@babel/helper-simple-access/lib/index.js
/@babel/helper-module-transforms/lib/rewrite-this.js
/@babel/helper-module-transforms/lib/rewrite-live-references.js
/@babel/helper-module-transforms/lib/index.js
/@babel/preset-env/lib/targets-parser.js
/@babel/preset-env/lib/index.js
/@babel/preset-env/lib/utils.js
/@babel/highlight/lib/index.js
/@babel/generator/lib/generators/jsx.js
/@babel/generator/lib/generators/base.js
/@babel/generator/lib/generators/template-literals.js
/@babel/generator/lib/generators/typescript.js
/@babel/generator/lib/generators/classes.js
/@babel/generator/lib/generators/expressions.js
/@babel/generator/lib/generators/statements.js
/@babel/generator/lib/generators/flow.js
/@babel/generator/lib/generators/modules.js
/@babel/generator/lib/generators/types.js
/@babel/generator/lib/generators/methods.js
/@babel/generator/lib/node/parentheses.js
/@babel/generator/lib/node/index.js
/@babel/generator/lib/node/whitespace.js
/@babel/generator/lib/printer.js
/@babel/helper-get-function-arity/lib/index.js
/@babel/helper-function-name/lib/index.js
/@babel/helper-annotate-as-pure/lib/index.js
/@babel/helper-create-class-features-plugin/node_modules/@babel/core/lib/transform-file.js
/@babel/helper-create-class-features-plugin/node_modules/@babel/core/lib/config/files/configuration.js
/@babel/helper-create-class-features-plugin/node_modules/@babel/core/lib/config/files/utils.js
/@babel/helper-create-class-features-plugin/node_modules/@babel/core/lib/config/full.js
/@babel/helper-create-class-features-plugin/node_modules/@babel/core/lib/transformation/normalize-file.js
/@babel/helper-create-class-features-plugin/node_modules/@babel/core/lib/transformation/file/file.js
/@babel/helper-create-class-features-plugin/node_modules/@babel/core/lib/tools/build-external-helpers.js
/@babel/helper-create-class-features-plugin/node_modules/@babel/core/lib/index.js
/@babel/helper-create-class-features-plugin/lib/fields.js
/@babel/plugin-transform-classes/lib/transformClass.js
/@babel/template/lib/parse.js
/@babel/template/lib/formatters.js
/@babel/template/lib/populate.js
/@babel/template/lib/index.js
/@babel/core/lib/transform-file.js
/@babel/core/lib/config/files/configuration.js
/@babel/core/lib/config/files/utils.js
/@babel/core/lib/config/full.js
/@babel/core/lib/transformation/normalize-file.js
/@babel/core/lib/transformation/file/file.js
/@babel/core/lib/tools/build-external-helpers.js
/@babel/core/lib/index.js
/@babel/helper-optimise-call-expression/lib/index.js
/jest-snapshot/build/SnapshotResolver.js
/jest-snapshot/build/State.js
/jest-snapshot/build/index.js
/jest-serializer/build/index.js
/react-dev-utils/node_modules/@babel/code-frame/lib/index.js
/jest-resolve/build/defaultResolver.js
/jest-resolve/build/ModuleNotFoundError.js
/pretty-format/build/plugins/ReactElement.js
/jest-each/build/table/array.js
/@jest/transform/build/shouldInstrument.js
/@jest/transform/build/index.js
/@jest/reporters/build/NotifyReporter.js
/@jest/reporters/build/CoverageWorker.js
/@jest/reporters/build/utils.js
/@jest/reporters/build/generateEmptyCoverage.js
/@jest/core/build/collectHandles.js
/@jest/core/build/watch.js
/@testing-library/react/dist/@testing-library/react.umd.js
/@testing-library/react/dist/@testing-library/react.pure.umd.js
/@testing-library/dom/dist/@testing-library/dom.umd.js
/jest-config/build/getCacheDirectory.js
/jest-config/build/resolveConfigPath.js
/jest-config/build/constants.js
А какие выводы?
Возможно это небольшое исследование кого-нибудь натолкнет на мысли какие-нибудь мысли о рефакторинге. Или изменении подхода к программированию.
Хорошо, что люди используют для программирования некоторые общие подходы и паттерны.
Плохо что очень много копипасты.
P.S.
- Скрипты, которые я использовал, можно найти на Гитхабе.
- Я попытался перевести статью и на английский.