count-component-webpack-plugin
Advanced tools
| root=true | ||
| [*] | ||
| end_of_line = lf | ||
| insert_final_newline = true | ||
| [*.{cjs,js,ts,tsx,vue}] | ||
| charset = utf-8 | ||
| indent_style = tab |
| env: | ||
| node: true | ||
| es2021: true | ||
| extends: | ||
| - standard-with-typescript | ||
| - plugin:prettier/recommended | ||
| overrides: [] | ||
| ignorePatterns: | ||
| - '**/dist/**/*.js' | ||
| - '/*.d.ts' | ||
| parser: '@typescript-eslint/parser' | ||
| parserOptions: | ||
| ecmaVersion: latest | ||
| sourceType: module | ||
| project: ./tsconfig.json | ||
| plugins: | ||
| - prettier | ||
| rules: | ||
| '@typescript-eslint/triple-slash-reference': off | ||
| '@typescript-eslint/no-misused-promises': | ||
| - error | ||
| - checksVoidReturn: false | ||
| prettier/prettier: error |
| semi: false | ||
| singleQuote: true | ||
| trailingComma: 'none' | ||
| useTabs: true |
| { | ||
| "editor.codeActionsOnSave": { | ||
| "source.fixAll": true | ||
| }, | ||
| "editor.detectIndentation": false, | ||
| "editor.tokenColorCustomizations": { | ||
| "textMateRules": [ | ||
| { | ||
| "scope": "meta.function-call", | ||
| "settings": { | ||
| "fontStyle": "bold" | ||
| } | ||
| } | ||
| ] | ||
| }, | ||
| "eslint.validate": [ | ||
| "javascript", | ||
| "vue", | ||
| "typescript", | ||
| "typescriptreact", | ||
| ] | ||
| } |
| import type { Compiler } from 'webpack'; | ||
| interface CountType { | ||
| [key: string]: number; | ||
| } | ||
| interface Options { | ||
| path: string | string[] | Record<string, string[]>; | ||
| isExportExcel?: boolean; | ||
| outputDir?: string; | ||
| percentageByMime: string[]; | ||
| } | ||
| export declare class CountComponentsWebpackPlugin { | ||
| options: Options; | ||
| projectFiles: string[]; | ||
| trait: Record<string, { | ||
| components: CountType; | ||
| percentage: Record<string, string>; | ||
| total: number; | ||
| }>; | ||
| constructor(options: Options); | ||
| maintainKind(branch: string, identifierName: string): void; | ||
| toExcel(): void; | ||
| toLog(): void; | ||
| apply(compiler: Compiler): void; | ||
| } | ||
| export {}; |
+191
| 'use strict'; | ||
| var xlsx = require('xlsx'); | ||
| var lodash = require('lodash'); | ||
| /****************************************************************************** | ||
| Copyright (c) Microsoft Corporation. | ||
| Permission to use, copy, modify, and/or distribute this software for any | ||
| purpose with or without fee is hereby granted. | ||
| THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH | ||
| REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY | ||
| AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, | ||
| INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM | ||
| LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR | ||
| OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR | ||
| PERFORMANCE OF THIS SOFTWARE. | ||
| ***************************************************************************** */ | ||
| var __assign = function() { | ||
| __assign = Object.assign || function __assign(t) { | ||
| for (var s, i = 1, n = arguments.length; i < n; i++) { | ||
| s = arguments[i]; | ||
| for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; | ||
| } | ||
| return t; | ||
| }; | ||
| return __assign.apply(this, arguments); | ||
| }; | ||
| var exportToExcel = function (self) { | ||
| var trait = self.trait; | ||
| var bookNew = xlsx.utils.book_new, bookAppendSheet = xlsx.utils.book_append_sheet, jsonToSheet = xlsx.utils.json_to_sheet; | ||
| var workbook = bookNew(); | ||
| Object.keys(trait).forEach(function (key) { | ||
| var flatObj = __assign(__assign({}, trait[key].components), trait[key].percentage); | ||
| var orderedObj = {}; | ||
| Object.keys(trait).forEach(function (innerKey) { | ||
| // js对象键值对是有序的,拍一下方便看 | ||
| orderedObj = Object.keys(flatObj[innerKey]) | ||
| .sort() | ||
| .reduce(function (acc, cur) { | ||
| acc[cur] = flatObj[cur]; | ||
| return acc; | ||
| }, {}); | ||
| }); | ||
| bookAppendSheet(workbook, | ||
| // 这json_to_sheet的入参得是个数组 | ||
| jsonToSheet([ | ||
| __assign({ total: trait[key].total }, orderedObj) | ||
| ]), key); | ||
| }); | ||
| var outputDir = self.options.outputDir; | ||
| xlsx.writeFile(workbook, outputDir === undefined ? './dist/count.xlsx' : "./".concat(outputDir, "/count.xlsx")); | ||
| }; | ||
| var calculateTraitUsage = function (self) { | ||
| if (self.options.percentageByMime === undefined) | ||
| return; | ||
| var trait = self.trait; | ||
| var dedupedProjectFileArr = lodash.uniq(self.projectFiles); | ||
| self.options.percentageByMime.forEach(function (mime) { | ||
| // 算出来项目内对应格式的文件数量 | ||
| var fileCount = dedupedProjectFileArr.filter(function (fileStr) { | ||
| return fileStr.endsWith(mime); | ||
| }).length; | ||
| Object.keys(trait).forEach(function (path) { | ||
| var tp = trait[path]; | ||
| // 每个组件在项目中import次数除以fileCount,得到百分比 | ||
| Object.keys(tp.components).forEach(function (component) { | ||
| var decimal = tp.components[component] / fileCount; | ||
| tp.percentage[component] = "".concat((decimal * 100).toFixed(3), "%"); | ||
| }); | ||
| lodash.mapKeys(tp.percentage, function (_, key) { return "".concat(key, "Per"); }); | ||
| }); | ||
| }); | ||
| }; | ||
| var hookDone = function (self, compiler) { | ||
| return compiler.hooks.done.tap('count-components-webpack-plugin-done', function () { | ||
| // 维护一下百分比 | ||
| calculateTraitUsage(self); | ||
| self.options.isExportExcel !== undefined && self.options.isExportExcel | ||
| ? self.toExcel() | ||
| : self.toLog(); | ||
| }); | ||
| }; | ||
| var hookNormalModuleFactory = function (self, compiler) { | ||
| return compiler.hooks.normalModuleFactory.tap('count-components-webpack-plugin', function (factory) { | ||
| var pathHolderFromObj; | ||
| var path = self.options.path; | ||
| factory.hooks.parser | ||
| .for('javascript/auto') | ||
| .tap('count-components-webpack-plugin', function (parser) { | ||
| parser.hooks.importSpecifier.tap('count-components-webpack-plugin', function (_statement, source, _exportName, identifierName) { | ||
| if (typeof path === 'string') { | ||
| if (!source.includes(path)) | ||
| return; | ||
| self.maintainKind(path, identifierName); | ||
| } | ||
| else if (Array.isArray(path)) { | ||
| path.forEach(function (str) { | ||
| if (!source.includes(str)) | ||
| return; | ||
| self.maintainKind(str, identifierName); | ||
| }); | ||
| } | ||
| else if (lodash.isPlainObject(path)) { | ||
| if (pathHolderFromObj === undefined) | ||
| pathHolderFromObj = Object.keys(path); | ||
| pathHolderFromObj.forEach(function (key) { | ||
| path[key].forEach(function (str) { | ||
| if (!source.includes(str)) | ||
| return; | ||
| self.maintainKind(key, identifierName); | ||
| }); | ||
| }); | ||
| } | ||
| else { | ||
| throw new Error('未适配的path类型❗️'); | ||
| } | ||
| }); | ||
| }); | ||
| }); | ||
| }; | ||
| var hookResolveFactory = function (self, compiler) { | ||
| return compiler.resolverFactory.hooks.resolver | ||
| .for('normal') | ||
| .tap('name', function (resolver) { | ||
| // you can tap into resolver.hooks now | ||
| resolver.hooks.result.tap('count-components-webpack-plugin', function (result) { | ||
| // context是存在的,webpack没给标ts类型,神奇 | ||
| // descriptionFileRoot context.issuer path | ||
| var issuer = result.context.issuer; | ||
| if (Boolean(issuer) && !issuer.includes('/node_modules/')) | ||
| self.projectFiles.push(issuer); | ||
| return result; | ||
| }); | ||
| }); | ||
| }; | ||
| var logResult = function (self) { | ||
| console.log('数出来了,算出来了:', JSON.stringify(self.trait, null, 4)); | ||
| }; | ||
| var maintainKind = function (self, branch, identifierName) { | ||
| var realBranch = self.trait[branch]; | ||
| if (realBranch === undefined) { | ||
| realBranch = { | ||
| total: 0, | ||
| components: {}, | ||
| percentage: {} | ||
| }; | ||
| } | ||
| realBranch.total = realBranch.total + 1; | ||
| var key = identifierName; | ||
| realBranch.components[key] !== undefined | ||
| ? (realBranch.components[key] += 1) | ||
| : (realBranch.components[key] = 1); | ||
| // 上面为了干净赋了变量,中途可能改变,这里赋回去 | ||
| self.trait[branch] = realBranch; | ||
| }; | ||
| var CountComponentsWebpackPlugin = /** @class */ (function () { | ||
| function CountComponentsWebpackPlugin(options) { | ||
| this.options = options; | ||
| this.trait = {}; | ||
| this.projectFiles = []; | ||
| } | ||
| CountComponentsWebpackPlugin.prototype.maintainKind = function (branch, identifierName) { | ||
| maintainKind(this, branch, identifierName); | ||
| }; | ||
| // 生成excel文件 | ||
| CountComponentsWebpackPlugin.prototype.toExcel = function () { | ||
| exportToExcel(this); | ||
| }; | ||
| CountComponentsWebpackPlugin.prototype.toLog = function () { | ||
| logResult(this); | ||
| }; | ||
| CountComponentsWebpackPlugin.prototype.apply = function (compiler) { | ||
| hookNormalModuleFactory(this, compiler); | ||
| hookResolveFactory(this, compiler); | ||
| hookDone(this, compiler); | ||
| }; | ||
| return CountComponentsWebpackPlugin; | ||
| }()); | ||
| exports.CountComponentsWebpackPlugin = CountComponentsWebpackPlugin; |
| import type { CountComponentsWebpackPlugin } from '../main'; | ||
| export declare const calculateTraitUsage: (self: CountComponentsWebpackPlugin) => void; |
| import type { CountComponentsWebpackPlugin } from '../main'; | ||
| export declare const exportToExcel: (self: CountComponentsWebpackPlugin) => void; |
| import type { Compiler } from 'webpack'; | ||
| import type { CountComponentsWebpackPlugin } from '../main'; | ||
| export declare const hookDone: (self: CountComponentsWebpackPlugin, compiler: Compiler) => void; |
| import type { Compiler } from 'webpack'; | ||
| import type { CountComponentsWebpackPlugin } from '../main'; | ||
| export declare const hookNormalModuleFactory: (self: CountComponentsWebpackPlugin, compiler: Compiler) => void; |
| import type { Compiler } from 'webpack'; | ||
| import type { CountComponentsWebpackPlugin } from '../main'; | ||
| export declare const hookResolveFactory: (self: CountComponentsWebpackPlugin, compiler: Compiler) => void; |
| import type { Compiler } from 'webpack'; | ||
| import type { CountComponentsWebpackPlugin } from '../main'; | ||
| export declare const hookBuildModule: (self: CountComponentsWebpackPlugin, compiler: Compiler) => void; |
| export * from './export-to-excel'; | ||
| export * from './hook-done'; | ||
| export * from './hook-normal-module-factory'; | ||
| export * from './hook-resolver-factory'; | ||
| export * from './log-result'; | ||
| export * from './maintain-kind'; |
| import type { CountComponentsWebpackPlugin } from '../main'; | ||
| export declare const logResult: (self: CountComponentsWebpackPlugin) => void; |
| import type { CountComponentsWebpackPlugin } from '../main'; | ||
| export declare const maintainKind: (self: CountComponentsWebpackPlugin, branch: string, identifierName: string) => void; |
+23
| # Introduce | ||
| ## Install | ||
| ```shell | ||
| npm install count-components-webpack-plugin | ||
| ``` | ||
| ## Use | ||
| ```js | ||
| import { CountComponentsWebpackPlugin } from 'count-components-webpack-plugin' | ||
| // in webpack plugin array | ||
| new CountComponentsWebpackPlugin({ | ||
| path: { | ||
| uiLib: ['vant'], | ||
| projectComponents: ['@/components'] | ||
| }, | ||
| percentageByMime: ['vue'], | ||
| isExportExcel: true | ||
| }) | ||
| ``` |
| import { mapKeys, uniq } from 'lodash' | ||
| import type { CountComponentsWebpackPlugin } from '../main' | ||
| export const calculateTraitUsage = ( | ||
| self: CountComponentsWebpackPlugin | ||
| ): void => { | ||
| if (self.options.percentageByMime === undefined) return | ||
| const trait = self.trait | ||
| const dedupedProjectFileArr = uniq(self.projectFiles) | ||
| self.options.percentageByMime.forEach((mime) => { | ||
| // 算出来项目内对应格式的文件数量 | ||
| const fileCount = dedupedProjectFileArr.filter((fileStr) => | ||
| fileStr.endsWith(mime) | ||
| ).length | ||
| Object.keys(trait).forEach((path) => { | ||
| const tp = trait[path] | ||
| // 每个组件在项目中import次数除以fileCount,得到百分比 | ||
| Object.keys(tp.components).forEach((component) => { | ||
| const decimal = tp.components[component] / fileCount | ||
| tp.percentage[component] = `${(decimal * 100).toFixed(3)}%` | ||
| }) | ||
| tp.percentage = mapKeys(tp.percentage, (_, key) => `${key}Per`) | ||
| }) | ||
| }) | ||
| } |
| import { utils, writeFile } from 'xlsx' | ||
| import type { CountComponentsWebpackPlugin } from '../main' | ||
| export const exportToExcel = (self: CountComponentsWebpackPlugin): void => { | ||
| const trait = self.trait | ||
| const { | ||
| book_new: bookNew, | ||
| book_append_sheet: bookAppendSheet, | ||
| json_to_sheet: jsonToSheet | ||
| } = utils | ||
| const workbook = bookNew() | ||
| Object.keys(trait).forEach((key) => { | ||
| const flatObj = { ...trait[key].components, ...trait[key].percentage } | ||
| let orderedObj: typeof flatObj = {} | ||
| Object.keys(flatObj).forEach((innerKey) => { | ||
| // js对象键值对是有序的,排一下方便看 | ||
| orderedObj = Object.keys(flatObj) | ||
| .sort() | ||
| .reduce<typeof flatObj>((acc, cur) => { | ||
| acc[cur] = flatObj[cur] | ||
| return acc | ||
| }, {}) | ||
| }) | ||
| bookAppendSheet( | ||
| workbook, | ||
| // 这json_to_sheet的入参得是个数组 | ||
| jsonToSheet([ | ||
| { | ||
| total: trait[key].total, | ||
| ...orderedObj | ||
| } | ||
| ]), | ||
| key | ||
| ) | ||
| }) | ||
| const outputDir = self.options.outputDir | ||
| writeFile( | ||
| workbook, | ||
| outputDir === undefined ? './dist/count.xlsx' : `./${outputDir}/count.xlsx` | ||
| ) | ||
| } |
| import { calculateTraitUsage } from './calculate-trait-usage' | ||
| import type { Compiler } from 'webpack' | ||
| import type { CountComponentsWebpackPlugin } from '../main' | ||
| export const hookDone = ( | ||
| self: CountComponentsWebpackPlugin, | ||
| compiler: Compiler | ||
| ): void => { | ||
| return compiler.hooks.done.tap( | ||
| 'count-components-webpack-plugin-done', | ||
| (): void => { | ||
| // 维护一下百分比 | ||
| calculateTraitUsage(self) | ||
| self.options.isExportExcel !== undefined && self.options.isExportExcel | ||
| ? self.toExcel() | ||
| : self.toLog() | ||
| } | ||
| ) | ||
| } |
| import { isPlainObject } from 'lodash' | ||
| import type { Compiler } from 'webpack' | ||
| import type { CountComponentsWebpackPlugin } from '../main' | ||
| export const hookNormalModuleFactory = ( | ||
| self: CountComponentsWebpackPlugin, | ||
| compiler: Compiler | ||
| ): void => { | ||
| return compiler.hooks.normalModuleFactory.tap( | ||
| 'count-components-webpack-plugin', | ||
| (factory): void => { | ||
| let pathHolderFromObj: string[] | ||
| const path = self.options.path | ||
| factory.hooks.parser | ||
| .for('javascript/auto') | ||
| .tap('count-components-webpack-plugin', (parser) => { | ||
| parser.hooks.importSpecifier.tap( | ||
| 'count-components-webpack-plugin', | ||
| ( | ||
| _statement: string, | ||
| source: string, | ||
| _exportName: string, | ||
| identifierName: string | ||
| ) => { | ||
| if (typeof path === 'string') { | ||
| if (!source.includes(path)) return | ||
| self.maintainKind(path, identifierName) | ||
| } else if (Array.isArray(path)) { | ||
| path.forEach((str) => { | ||
| if (!source.includes(str)) return | ||
| self.maintainKind(str, identifierName) | ||
| }) | ||
| } else if (isPlainObject(path)) { | ||
| if (pathHolderFromObj === undefined) | ||
| pathHolderFromObj = Object.keys(path) | ||
| pathHolderFromObj.forEach((key) => { | ||
| path[key].forEach((str) => { | ||
| if (!source.includes(str)) return | ||
| self.maintainKind(key, identifierName) | ||
| }) | ||
| }) | ||
| } else { | ||
| throw new Error('未适配的path类型❗️') | ||
| } | ||
| } | ||
| ) | ||
| }) | ||
| } | ||
| ) | ||
| } |
| import type { Compiler } from 'webpack' | ||
| import type { CountComponentsWebpackPlugin } from '../main' | ||
| export const hookResolveFactory = ( | ||
| self: CountComponentsWebpackPlugin, | ||
| compiler: Compiler | ||
| ): void => { | ||
| return compiler.resolverFactory.hooks.resolver | ||
| .for('normal') | ||
| .tap('name', (resolver) => { | ||
| // you can tap into resolver.hooks now | ||
| resolver.hooks.result.tap('count-components-webpack-plugin', (result) => { | ||
| // context是存在的,webpack没给标ts类型,神奇 | ||
| // descriptionFileRoot context.issuer path | ||
| const issuer: string = (result as any).context.issuer | ||
| if (Boolean(issuer) && !issuer.includes('/node_modules/')) | ||
| self.projectFiles.push(issuer) | ||
| return result | ||
| }) | ||
| }) | ||
| } |
| export * from './export-to-excel' | ||
| export * from './hook-done' | ||
| export * from './hook-normal-module-factory' | ||
| export * from './hook-resolver-factory' | ||
| export * from './log-result' | ||
| export * from './maintain-kind' |
| import type { CountComponentsWebpackPlugin } from '../main' | ||
| export const logResult = (self: CountComponentsWebpackPlugin): void => { | ||
| console.log('数出来了,算出来了:', JSON.stringify(self.trait, null, 4)) | ||
| } |
| import type { CountComponentsWebpackPlugin } from '../main' | ||
| export const maintainKind = ( | ||
| self: CountComponentsWebpackPlugin, | ||
| branch: string, | ||
| identifierName: string | ||
| ): void => { | ||
| let realBranch = self.trait[branch] | ||
| if (realBranch === undefined) { | ||
| realBranch = { | ||
| total: 0, | ||
| components: {}, | ||
| percentage: {} | ||
| } | ||
| } | ||
| realBranch.total = realBranch.total + 1 | ||
| const key = identifierName | ||
| realBranch.components[key] !== undefined | ||
| ? (realBranch.components[key] += 1) | ||
| : (realBranch.components[key] = 1) | ||
| // 上面为了干净赋了变量,中途可能改变,这里赋回去 | ||
| self.trait[branch] = realBranch | ||
| } |
+39
-20
| { | ||
| "name": "count-component-webpack-plugin", | ||
| "version": "1.0.0", | ||
| "description": "", | ||
| "main": "src/index.ts", | ||
| "scripts": { | ||
| "build": "rollup --config" | ||
| }, | ||
| "keywords": [], | ||
| "author": "", | ||
| "license": "ISC", | ||
| "devDependencies": { | ||
| "@types/node": "^18.11.0", | ||
| "chalk": "^5.1.2", | ||
| "rollup-plugin-typescript2": "^0.34.1", | ||
| "tslib": "^2.4.0", | ||
| "typescript": "^4.8.4" | ||
| }, | ||
| "dependencies": { | ||
| "webpack": "^5.74.0" | ||
| } | ||
| "name": "count-component-webpack-plugin", | ||
| "version": "1.2.18", | ||
| "description": "count-components", | ||
| "main": "dist/main.js", | ||
| "scripts": { | ||
| "build": "rollup --config --bundleConfigAsCjs", | ||
| "lint": "eslint --fix --ext .ts" | ||
| }, | ||
| "keywords": [ | ||
| "webpack-plugin", | ||
| "typescript", | ||
| "rollup-bundle" | ||
| ], | ||
| "author": "", | ||
| "license": "ISC", | ||
| "devDependencies": { | ||
| "@rollup/plugin-node-resolve": "^15.0.0", | ||
| "@types/lodash": "^4.14.186", | ||
| "@types/node": "^18.11.0", | ||
| "@typescript-eslint/eslint-plugin": "^5.40.0", | ||
| "eslint": "^8.0.1", | ||
| "eslint-config-prettier": "^8.5.0", | ||
| "eslint-config-standard-with-typescript": "^23.0.0", | ||
| "eslint-plugin-import": "^2.25.2", | ||
| "eslint-plugin-n": "^15.0.0", | ||
| "eslint-plugin-prettier": "^4.2.1", | ||
| "eslint-plugin-promise": "^6.0.0", | ||
| "prettier": "^2.7.1", | ||
| "rollup": "^3.2.2", | ||
| "rollup-plugin-typescript2": "^0.34.1", | ||
| "tslib": "^2.4.0", | ||
| "typescript": "^4.8.4" | ||
| }, | ||
| "dependencies": { | ||
| "chalk": "^4.1.2", | ||
| "lodash": "^4.17.21", | ||
| "webpack": "^5.74.0", | ||
| "xlsx": "^0.18.5" | ||
| } | ||
| } |
+9
-8
@@ -1,10 +0,11 @@ | ||
| import typescript from "rollup-plugin-typescript2"; | ||
| import typescript from 'rollup-plugin-typescript2' | ||
| export default { | ||
| input: "./src/main.ts", | ||
| output: { | ||
| dir: "output", | ||
| format: "cjs", | ||
| }, | ||
| plugins: [typescript(/*{ plugin options }*/)], | ||
| }; | ||
| external: ['chalk', 'lodash', 'xlsx'], | ||
| input: './src/main.ts', | ||
| output: { | ||
| dir: 'dist', | ||
| format: 'cjs' | ||
| }, | ||
| plugins: [typescript()] | ||
| } |
+47
-90
@@ -1,102 +0,59 @@ | ||
| import {} from "fs"; | ||
| import chalk from "chalk"; | ||
| import { | ||
| exportToExcel, | ||
| hookDone, | ||
| hookNormalModuleFactory, | ||
| hookResolveFactory, | ||
| logResult, | ||
| maintainKind | ||
| } from './util' | ||
| import type { Compiler } from "webpack"; | ||
| import type { Compiler } from 'webpack' | ||
| interface CountType { | ||
| [key: string]: number; | ||
| [key: string]: number | ||
| } | ||
| interface Options { | ||
| path: string | string[] | Record<string, string[]> // 文件的路径 | ||
| isExportExcel?: boolean | ||
| outputDir?: string | ||
| percentageByMime: string[] | ||
| } | ||
| export class CountComponentsWebpackPlugin { | ||
| opts: { | ||
| pathname: string; // 文件的路径 | ||
| startCount: boolean; // 是否开启统计 | ||
| isExportExcel: boolean; | ||
| }; | ||
| total: { len: number; components: CountType }; | ||
| options: Options | ||
| projectFiles: string[] | ||
| // 根据path数处的组件名称和数量 | ||
| trait: Record< | ||
| string, | ||
| { | ||
| components: CountType | ||
| percentage: Record<string, string> | ||
| total: number | ||
| } | ||
| > | ||
| constructor(opts = {}) { | ||
| this.opts = { | ||
| startCount: true, // 是否开启统计 | ||
| isExportExcel: false, // 是否生成excel | ||
| pathname: "", // 文件路径 | ||
| ...opts, | ||
| }; | ||
| this.total = { | ||
| len: 0, | ||
| components: {}, | ||
| }; | ||
| } | ||
| constructor(options: Options) { | ||
| this.options = options | ||
| this.trait = {} | ||
| this.projectFiles = [] | ||
| } | ||
| sort(obj: CountType) { | ||
| this.total.components = Object.fromEntries( | ||
| Object.entries(obj).sort(([, a], [, b]) => b - a) | ||
| ); | ||
| } | ||
| maintainKind(branch: string, identifierName: string): void { | ||
| maintainKind(this, branch, identifierName) | ||
| } | ||
| // 生成excel 文件 | ||
| toExcel() { | ||
| console.log("输出为表格待完善"); | ||
| } | ||
| // 生成excel文件 | ||
| toExcel(): void { | ||
| exportToExcel(this) | ||
| } | ||
| toLog() { | ||
| this.sort(this.total.components); | ||
| Object.keys(this.total.components).forEach((key) => { | ||
| const value = this.total.components[key]; | ||
| const per = Number((value / this.total.len).toPrecision(3)) * 100; | ||
| console.log( | ||
| `\n${chalk.blue(key)} 组件引用次数 ${chalk.green( | ||
| value | ||
| )} 引用率 ${chalk.redBright(per)}%` | ||
| ); | ||
| }); | ||
| console.log( | ||
| `\n组件${chalk.blue("总共")}引用次数 ${chalk.green(this.total.len)}` | ||
| ); | ||
| } | ||
| toLog(): void { | ||
| logResult(this) | ||
| } | ||
| apply(compiler: Compiler) { | ||
| const parser = (factory: any) => { | ||
| if (!this.opts.startCount) { | ||
| return; | ||
| } | ||
| factory.hooks.parser | ||
| .for("javascript/auto") | ||
| .tap("count-webpack-plugin", (parser: any) => { | ||
| parser.hooks.importSpecifier.tap( | ||
| "count-webpack-plugin", | ||
| ( | ||
| _statement: string, | ||
| source: string, | ||
| _exportName: string, | ||
| identifierName: string | ||
| ) => { | ||
| if (source.includes(this.opts.pathname)) { | ||
| this.total.len = this.total.len + 1; | ||
| const key = identifierName; | ||
| this.total.components[key] = this.total.components[key] | ||
| ? this.total.components[key] + 1 | ||
| : 1; | ||
| } | ||
| } | ||
| ); | ||
| }); | ||
| }; | ||
| const done = () => { | ||
| if (!this.opts.startCount) { | ||
| return; | ||
| } | ||
| this.sort(this.total.components); | ||
| this.opts.isExportExcel ? this.toExcel() : this.toLog(); | ||
| }; | ||
| compiler.hooks.normalModuleFactory.tap( | ||
| "count-components-webpack-plugin", | ||
| parser | ||
| ); | ||
| compiler.hooks.done.tap("count-components-webpack-plugin-done", done); | ||
| } | ||
| apply(compiler: Compiler): void { | ||
| hookNormalModuleFactory(this, compiler) | ||
| hookResolveFactory(this, compiler) | ||
| hookDone(this, compiler) | ||
| } | ||
| } |
+8
-3
| { | ||
| "compilerOptions": { | ||
| "target": "es2016", | ||
| "target": "ES5", | ||
| "module": "ESNext", | ||
@@ -15,3 +15,3 @@ "esModuleInterop": true, | ||
| "declarationDir": "dist/types", | ||
| "outDir": "dist/lib", | ||
| "outDir": "dist", | ||
| "typeRoots": [ | ||
@@ -22,4 +22,9 @@ "node_modules/@types" | ||
| "include": [ | ||
| "src" | ||
| "src", | ||
| "rollup.config.js" | ||
| ], | ||
| "exclude": [ | ||
| "dist", | ||
| "node_modules" | ||
| ] | ||
| } |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
No README
QualityPackage does not have a README. This may indicate a failed publish or a low quality package.
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
20562
446.28%28
600%522
327.87%1
-50%24
Infinity%1
-50%4
300%16
220%1
Infinity%+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
- Removed