From 601c8f4694ce45d0ba32c556e2bf3109a5d416c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20Kr=C3=BCger?= Date: Fri, 3 Apr 2020 23:22:32 +0200 Subject: [PATCH] :tada: Initial Commit --- .gitignore | 2 ++ README.md | 8 +++++++ package.json | 19 +++++++++++++++ src/analyse.ts | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++ tsconfig.json | 10 ++++++++ yarn.lock | 30 +++++++++++++++++++++++ 6 files changed, 134 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 package.json create mode 100644 src/analyse.ts create mode 100644 tsconfig.json create mode 100644 yarn.lock diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c925c21 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/dist +/node_modules diff --git a/README.md b/README.md new file mode 100644 index 0000000..b62f6b2 --- /dev/null +++ b/README.md @@ -0,0 +1,8 @@ +# elmjs-inspect + +## TODO + +* Wrap with CLI stuff (commander?) +* Allow giving .js file by options or otherwise by file input (inquirer.js?) +* Show results by package/module/file level +* NPM Publish diff --git a/package.json b/package.json new file mode 100644 index 0000000..d2511f7 --- /dev/null +++ b/package.json @@ -0,0 +1,19 @@ +{ + "name": "sizes", + "version": "1.0.0", + "main": "src/index.ts", + "license": "MIT", + "scripts": { + "repl": "ts-node --project .", + "build": "tsc" + }, + "type": "module", + "devDependencies": { + "@types/esprima": "^4.0.2", + "@types/node": "^13.11.0", + "typescript": "^3.8.3" + }, + "dependencies": { + "esprima": "^4.0.1" + } +} \ No newline at end of file diff --git a/src/analyse.ts b/src/analyse.ts new file mode 100644 index 0000000..c167727 --- /dev/null +++ b/src/analyse.ts @@ -0,0 +1,65 @@ +import * as FS from 'fs'; +import * as Console from 'console'; +import { promisify } from 'util'; +import * as Esprima from 'esprima'; +import * as ESTree from 'estree'; + +function* yieldElmJsDefinitionInfos(script: Esprima.Program) { + for (const statement of yieldElmJsStatements(script)) { + yield* yieldFunctionDeclarationInfo(statement); + yield* yieldVariableDeclarationInfos(statement); + } +} + +function* yieldElmJsStatements(script: Esprima.Program) { + for (const e of script.body) { + if (e.type === 'ExpressionStatement' + && e.expression.type === 'CallExpression' + && e.expression.callee.type === 'FunctionExpression') { + yield* e.expression.callee.body.body; + } + }; +} + +function* yieldFunctionDeclarationInfo(statement: ESTree.Statement) { + if (statement.type === 'FunctionDeclaration') { + yield { + name: statement.id.name, + range: statement.range + }; + } +} + +function* yieldVariableDeclarationInfos(statement: ESTree.Statement) { + if (statement.type === 'VariableDeclaration') { + for (const declaration of statement.declarations) { + if (declaration.id.type === 'Identifier') { + yield { + name: declaration.id.name, + range: declaration.range + }; + } + } + } +} + +function rangeSize([start, end]) { + return end - start; +} + +function pct(value: number, of: number) { + return `${Number(value / of * 100).toFixed(3)}%` +} + +export async function analyse(elmOutputJsFilePath: string) { + const file = await promisify(FS.readFile)(elmOutputJsFilePath); + const parsed = Esprima.parseScript(file.toString(), { range: true }); + const size = parsed.range; + const infos = Array.from(yieldElmJsDefinitionInfos(parsed)); + infos.sort((a, b) => rangeSize(b.range) - rangeSize(a.range)); + infos.forEach(({ name, range }) => { + Console.log(`${pct(rangeSize(range), rangeSize(size))}: ${name}`); + }); + const rangeSum = infos.map(({ range }) => rangeSize(range)).reduce((a, b) => a + b, 0); + Console.log(`Range sum: ${rangeSum} total: ${rangeSize(size)}, analized ${pct(rangeSum, rangeSize(size))}`); +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..0ea2bc1 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + // "target": "ES2019", + "downlevelIteration": true, + "outDir": "dist" + }, + "files": [ + "src/index.ts" + ] +} \ No newline at end of file diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 0000000..1ba017b --- /dev/null +++ b/yarn.lock @@ -0,0 +1,30 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@types/esprima@^4.0.2": + version "4.0.2" + resolved "https://registry.yarnpkg.com/@types/esprima/-/esprima-4.0.2.tgz#0303602d0644086d4802635d7abc9ac0eec57207" + integrity sha512-DKqdyuy7Go7ir6iKhZ0jUvgt/h9Q5zb9xS+fLeeXD2QSHv8gC6TimgujBBGfw8dHrpx4+u2HlMv7pkYOOfuUqg== + dependencies: + "@types/estree" "*" + +"@types/estree@*": + version "0.0.44" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.44.tgz#980cc5a29a3ef3bea6ff1f7d021047d7ea575e21" + integrity sha512-iaIVzr+w2ZJ5HkidlZ3EJM8VTZb2MJLCjw3V+505yVts0gRC4UMvjw0d1HPtGqI/HQC/KdsYtayfzl+AXY2R8g== + +"@types/node@^13.11.0": + version "13.11.0" + resolved "https://registry.yarnpkg.com/@types/node/-/node-13.11.0.tgz#390ea202539c61c8fa6ba4428b57e05bc36dc47b" + integrity sha512-uM4mnmsIIPK/yeO+42F2RQhGUIs39K2RFmugcJANppXe6J1nvH87PvzPZYpza7Xhhs8Yn9yIAVdLZ84z61+0xQ== + +esprima@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== + +typescript@^3.8.3: + version "3.8.3" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.8.3.tgz#409eb8544ea0335711205869ec458ab109ee1061" + integrity sha512-MYlEfn5VrLNsgudQTVJeNaQFUAI7DkhnOjdpAp4T+ku1TfQClewlbSuTVHiA+8skNBgaf02TL/kLOvig4y3G8w==