├── dist ├── check-expression.test.d.ts ├── index.d.ts ├── checker.d.ts ├── index.js.map ├── index.js ├── checker.js.map ├── checker.js ├── check-expression.test.js.map └── check-expression.test.js ├── .gitignore ├── .commitlintrc.yml ├── .prettierrc ├── .eslintrc ├── jest.config.ts ├── tsconfig.json ├── .github └── workflows │ ├── lint_test.yml │ └── release.yml ├── CHANGELOG.md ├── .releaserc.json ├── src ├── index.ts ├── checker.ts └── check-expression.test.ts ├── LICENSE ├── README.md ├── package.json └── CONTRIBUTING.md /dist/check-expression.test.d.ts: -------------------------------------------------------------------------------- 1 | export {}; 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | /dist 3 | /node_modules 4 | /coverage -------------------------------------------------------------------------------- /dist/index.d.ts: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | export {}; 3 | -------------------------------------------------------------------------------- /.commitlintrc.yml: -------------------------------------------------------------------------------- 1 | extends: 2 | - '@commitlint/config-conventional' -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "semi": true, 3 | "trailingComma": "all", 4 | "singleQuote": true, 5 | "printWidth": 120, 6 | "tabWidth": 2 7 | } 8 | -------------------------------------------------------------------------------- /dist/checker.d.ts: -------------------------------------------------------------------------------- 1 | export declare function getCheckExpression(file: any): string; 2 | export default function (src: any, maxOpenFiles: any, ignore: any): void; 3 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | 2 | { 3 | "parser": "@typescript-eslint/parser", 4 | "extends": ["plugin:@typescript-eslint/recommended"], 5 | "parserOptions": { "ecmaVersion": 2018, "sourceType": "module" }, 6 | "rules": {} 7 | } -------------------------------------------------------------------------------- /jest.config.ts: -------------------------------------------------------------------------------- 1 | import type { Config } from '@jest/types'; 2 | 3 | const config: Config.InitialOptions = { 4 | roots: ['src'], 5 | transform: { '\\.ts$': 'ts-jest' }, 6 | collectCoverage: true, 7 | collectCoverageFrom: ['src/**/*.{ts,js}'], 8 | }; 9 | 10 | export default config; 11 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2018", 4 | "module": "commonjs", 5 | "outDir": "dist", 6 | "sourceMap": true, 7 | "declaration": true, 8 | "esModuleInterop": true 9 | }, 10 | "include": ["src/**/*.ts"], 11 | "exclude": ["node_modules"] 12 | } -------------------------------------------------------------------------------- /.github/workflows/lint_test.yml: -------------------------------------------------------------------------------- 1 | name: Lint & Test 2 | on: 3 | pull_request: 4 | branches: 5 | - main 6 | jobs: 7 | lint_test: 8 | name: Lint & Test 9 | runs-on: ubuntu-latest 10 | steps: 11 | - name: Checkout 12 | uses: actions/checkout@v1 13 | - name: Setup Node.js 14 | uses: actions/setup-node@v1 15 | with: 16 | node-version: 12 17 | - name: Install dependencies 18 | run: npm install 19 | - name: Run Linter 20 | run: npm run lint 21 | - name: Run Tests 22 | run: npm run test 23 | -------------------------------------------------------------------------------- /dist/index.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;AACA,yCAAoC;AACpC,gDAAwB;AAExB,wDAAgC;AAEhC,mBAAO;KACJ,SAAS,CAAC,OAAO,CAAC;KAClB,WAAW,CAAC,wCAAwC,EAAE;IACrD,GAAG,EAAE,yEAAyE;CAC/E,CAAC;KACD,MAAM,CAAC,0BAA0B,EAAE,0BAA0B,CAAC;KAC9D,MAAM,CACL,qBAAqB,EACrB,kDAAkD,EAClD,0CAA0C,CAC3C;KACA,MAAM,CAAC,UAAU,GAAG,EAAE,OAAO;IAC5B,MAAM,YAAY,GAAG,GAAG,CAAC,CAAC,CAAC,cAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;IACzE,iBAAO,CAAC,YAAY,EAAE,OAAO,CAAC,SAAS,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;AAC3D,CAAC,CAAC;KACD,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC"} -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## [1.1.2](https://github.com/BerniWittmann/vue-unused-components-checker/compare/v1.1.1...v1.1.2) (2021-05-08) 2 | 3 | 4 | ### Bug Fixes 5 | 6 | * fix import of rx-text-search to prevent error during execution ([7fb3722](https://github.com/BerniWittmann/vue-unused-components-checker/commit/7fb3722b18ef84d2f510d4101638fc08a20e1677)) 7 | 8 | ## [1.1.1](https://github.com/BerniWittmann/vue-unused-components-checker/compare/v1.1.0...v1.1.1) (2021-05-08) 9 | 10 | 11 | ### Bug Fixes 12 | 13 | * improve regexp for import detection ([973115a](https://github.com/BerniWittmann/vue-unused-components-checker/commit/973115a30c71a1d0e7b254fc247afaececed52d1)) 14 | -------------------------------------------------------------------------------- /.releaserc.json: -------------------------------------------------------------------------------- 1 | { 2 | "repositoryUrl": "git@github.com:BerniWittmann/vue-unused-components-checker.git", 3 | "branches": "main", 4 | "plugins": [ 5 | "@semantic-release/commit-analyzer", 6 | "@semantic-release/release-notes-generator", 7 | [ 8 | "@semantic-release/changelog", 9 | { 10 | "changelogFile": "CHANGELOG.md" 11 | } 12 | ], 13 | "@semantic-release/npm", 14 | [ 15 | "@semantic-release/git", 16 | { 17 | "assets": ["CHANGELOG.md", "package.json", "dist/"], 18 | "message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}" 19 | } 20 | ], 21 | "@semantic-release/github" 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | import { program } from 'commander'; 3 | import path from 'path'; 4 | 5 | import checker from './checker'; 6 | 7 | program 8 | .arguments('[src]') 9 | .description('Lists unused vue components in project', { 10 | src: 'Root folder to inspect, if not provided, will default to current folder', 11 | }) 12 | .option('-o, --openfiles ', 'Number of Max Open files') 13 | .option( 14 | '-i, --ignore ', 15 | 'glob pattern or Array of glob patterns to ignore', 16 | '**/{node_modules,.nuxt,dist,coverage}/**', 17 | ) 18 | .action(function (src, options) { 19 | const completePath = src ? path.join(process.cwd(), src) : process.cwd(); 20 | checker(completePath, options.openfiles, options.ignore); 21 | }) 22 | .parse(process.argv); 23 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | on: 3 | push: 4 | branches: 5 | - main 6 | jobs: 7 | release: 8 | name: Release 9 | runs-on: ubuntu-18.04 10 | steps: 11 | - name: Checkout 12 | uses: actions/checkout@v1 13 | - name: Setup Node.js 14 | uses: actions/setup-node@v1 15 | with: 16 | node-version: 12 17 | - name: Install dependencies 18 | run: npm install 19 | - name: Run Linter 20 | run: npm run lint 21 | - name: Run Tests 22 | run: npm run test 23 | - name: Build Module 24 | run: npm run build 25 | - name: Release 26 | env: 27 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 28 | NPM_TOKEN: ${{ secrets.NPM_TOKEN }} 29 | run: npx semantic-release 30 | -------------------------------------------------------------------------------- /dist/index.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | "use strict"; 3 | var __importDefault = (this && this.__importDefault) || function (mod) { 4 | return (mod && mod.__esModule) ? mod : { "default": mod }; 5 | }; 6 | Object.defineProperty(exports, "__esModule", { value: true }); 7 | const commander_1 = require("commander"); 8 | const path_1 = __importDefault(require("path")); 9 | const checker_1 = __importDefault(require("./checker")); 10 | commander_1.program 11 | .arguments('[src]') 12 | .description('Lists unused vue components in project', { 13 | src: 'Root folder to inspect, if not provided, will default to current folder', 14 | }) 15 | .option('-o, --openfiles ', 'Number of Max Open files') 16 | .option('-i, --ignore ', 'glob pattern or Array of glob patterns to ignore', '**/{node_modules,.nuxt,dist,coverage}/**') 17 | .action(function (src, options) { 18 | const completePath = src ? path_1.default.join(process.cwd(), src) : process.cwd(); 19 | checker_1.default(completePath, options.openfiles, options.ignore); 20 | }) 21 | .parse(process.argv); 22 | //# sourceMappingURL=index.js.map -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | Copyright (c) 2018, Bernhard Wittmann 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all 12 | copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 18 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 19 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 20 | OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /dist/checker.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"checker.js","sourceRoot":"","sources":["../src/checker.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAAA,8CAAsB;AACtB,2DAA6C;AAC7C,kDAA0B;AAC1B,gDAAwB;AACxB,gDAAwB;AAExB,SAAgB,kBAAkB,CAAC,IAAI;IACrC,OAAO,sCAAsC,cAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,cAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,qCAAqC,CAAC;AAC5H,CAAC;AAFD,gDAEC;AAED,mBAAyB,GAAG,EAAE,YAAY,EAAE,MAAM;IAChD,MAAM,OAAO,GAAG,aAAG,CAAC,gCAAgC,CAAC,CAAC,KAAK,EAAE,CAAC;IAE9D,cAAI,CACF,UAAU,EACV;QACE,GAAG,EAAE,GAAG;QACR,MAAM,EAAE,MAAM;KACf,EACD,UAAU,GAAG,EAAE,KAAK;QAClB,IAAI,GAAG,EAAE;YACP,MAAM,GAAG,CAAC;SACX;QACD,MAAM,OAAO,GAAG,EAAE,CAAC;QACnB,eAAK,CAAC,WAAW,CACf,KAAK,EACL,YAAY,IAAI,EAAE,EAClB,UAAU,IAAI,EAAE,KAAK,EAAE,EAAE;YACvB,OAAO,CAAC,IAAI,GAAG,kCAAkC,GAAG,IAAI,CAAC;YACzD,UAAU;iBACP,aAAa,CAAC,IAAI,MAAM,CAAC,kBAAkB,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,sBAAsB,EAAE,UAAU,CAAC,EAAE;gBAC9F,GAAG,EAAE,GAAG;gBACR,MAAM,EAAE,MAAM;aACf,CAAC;iBACD,IAAI,CAAC,UAAU,MAAM;gBACpB,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE;oBACvB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;iBACpB;gBACD,EAAE,EAAE,CAAC;YACP,CAAC,CAAC;iBACD,KAAK,CAAC,EAAE,CAAC,CAAC;QACf,CAAC,EACD,UAAU,GAAG;YACX,IAAI,GAAG,EAAE;gBACP,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;gBACtB,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;gBACnB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;aACjB;YAED,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE;gBACxB,OAAO,CAAC,OAAO,CAAC,6BAA6B,CAAC,CAAC;gBAC/C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;aACjB;iBAAM;gBACL,OAAO,CAAC,OAAO,CAAC,UAAU,MAAM;oBAC9B,OAAO,CAAC,cAAc,CAAC;wBACrB,IAAI,EAAE,MAAM;wBACZ,MAAM,EAAE,GAAG;wBACX,KAAK,EAAE,KAAK;qBACb,CAAC,CAAC;oBACH,OAAO,CAAC,KAAK,CAAC,gCAAgC,CAAC,CAAC;gBAClD,CAAC,CAAC,CAAC;gBACH,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,mBAAmB,GAAG,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,CAAC;gBACjG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;aACjB;QACH,CAAC,CACF,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC;AA1DD,4BA0DC"} -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Vue Unused Components Checker 2 | 3 | Check your Vue project for unused Components. 4 | 5 | This tool gathers all file names of `.vue` Components and check whether they are imported and used somewhere. 6 | 7 |

8 | 9 | 10 | 11 | 12 |

13 | 14 |

15 | 16 |

17 | 18 | ## Purpose 19 | 20 | To help eliminate dead code in your Vue project, this package scans your codebase for components that have not been imported anywhere and thus are unused, so you can spot and remove them easily. 21 | 22 | ## Installation 23 | 24 | You should have [node](https://nodejs.org/en/) and npm or [yarn](https://yarnpkg.com) installed. 25 | 26 | ```bash 27 | $ npm install vue-unused-components-checker -g 28 | ``` 29 | 30 | ## Basic Usage 31 | 32 | Check the current file tree 33 | 34 | ```bash 35 | $ check-unused-comp . 36 | ``` 37 | 38 | Check a specific folder 39 | 40 | ```bash 41 | $ check-unused-comp src/js 42 | ``` 43 | 44 | Limit the count of open files, since this can lead to errors, when directories are too large 45 | 46 | ```bash 47 | $ check-unused-comp -o 20 src/js 48 | ``` 49 | 50 | Ignore specific files using [glob](https://www.npmjs.com/package/glob#glob-primer) patterns. Default: `**/{node_modules,.nuxt,dist,coverage}/**` 51 | 52 | ```bash 53 | $ check-unused-comp -i **/node_modules/** src/js 54 | ``` 55 | 56 | ## Documentation 57 | 58 | > Refer to the basic instructions above. More thorough documentation will be added asap. 59 | 60 | ## Changelog 61 | 62 | For a list of changes, please refer to the [CHANGELOG](CHANGELOG.md). 63 | 64 | ## Contributions 65 | 66 | Contributions are more than welcome, check our [CONTRIBUTING Guide](CONTRIBUTING.md). 67 | 68 | ## License 69 | 70 | [MIT licensed](LICENSE). 71 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-unused-components-checker", 3 | "version": "1.1.2", 4 | "description": "Check your Vue project for unused Components", 5 | "main": "dist/index.js", 6 | "scripts": { 7 | "build": "tsc", 8 | "lint": "eslint src/**/*.ts", 9 | "format": "eslint src/**/*.ts --fix", 10 | "test": "jest --config jest.config.ts --passWithNoTests", 11 | "semantic-release": "semantic-release" 12 | }, 13 | "bin": { 14 | "check-unused-comp": "dist/index.js" 15 | }, 16 | "keywords": [ 17 | "check", 18 | "vue", 19 | "unused", 20 | "components" 21 | ], 22 | "author": "BerniWittmann ", 23 | "license": "MIT", 24 | "dependencies": { 25 | "async": "^2.6.0", 26 | "commander": "^7.2.0", 27 | "glob": "^7.1.6", 28 | "ora": "^2.0.0", 29 | "rx-text-search": "^1.0.0" 30 | }, 31 | "repository": { 32 | "type": "git", 33 | "url": "https://github.com/BerniWittmann/vue-unused-components-checker.git" 34 | }, 35 | "bugs": { 36 | "url": "https://github.com/BerniWittmann/vue-unused-components-checker/issues" 37 | }, 38 | "files": [ 39 | "dist", 40 | "LICENSE", 41 | "README.md" 42 | ], 43 | "publishConfig": { 44 | "access": "public" 45 | }, 46 | "husky": { 47 | "hooks": { 48 | "pre-commit": "npm run lint", 49 | "commit-msg": "commitlint -E HUSKY_GIT_PARAMS" 50 | } 51 | }, 52 | "devDependencies": { 53 | "@commitlint/cli": "^8.3.4", 54 | "@commitlint/config-conventional": "^8.3.4", 55 | "@semantic-release/changelog": "^5.0.1", 56 | "@semantic-release/commit-analyzer": "^8.0.0", 57 | "@semantic-release/git": "^9.0.0", 58 | "@semantic-release/github": "^7.2.0", 59 | "@semantic-release/npm": "^7.0.0", 60 | "@semantic-release/release-notes-generator": "^9.0.0", 61 | "@types/jest": "^25.1.0", 62 | "@types/node": "^14.14.35", 63 | "@typescript-eslint/eslint-plugin": "^2.15.0", 64 | "@typescript-eslint/parser": "^2.15.0", 65 | "eslint": "^6.8.0", 66 | "husky": "^4.0.6", 67 | "jest": "^26.6.3", 68 | "semantic-release": "^17.0.0", 69 | "ts-jest": "^25.1.0", 70 | "ts-node": "^9.1.1", 71 | "typescript": "^3.7.4" 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/checker.ts: -------------------------------------------------------------------------------- 1 | import ora from 'ora'; 2 | import * as textSearch from 'rx-text-search'; 3 | import async from 'async'; 4 | import path from 'path'; 5 | import glob from 'glob'; 6 | 7 | export function getCheckExpression(file): string { 8 | return `(import|require).*(?:[\'\"]\\b|\\/)${path.basename(file, path.extname(file))}(?:\\.(?:vue))?[\'\"][\\\);,]?[,;]?`; 9 | } 10 | 11 | export default function (src, maxOpenFiles, ignore): void { 12 | const spinner = ora('Checking for unused Components').start(); 13 | 14 | glob( 15 | '**/*.vue', 16 | { 17 | cwd: src, 18 | ignore: ignore, 19 | }, 20 | function (err, files) { 21 | if (err) { 22 | throw err; 23 | } 24 | const results = []; 25 | async.eachOfLimit( 26 | files, 27 | maxOpenFiles || 30, 28 | function (file, index, cb) { 29 | spinner.text = 'Checking for unused Components: ' + file; 30 | textSearch 31 | .findAsPromise(new RegExp(getCheckExpression(file), 'i'), ['**/*.{js,jsx,ts,tsx}', '**/*.vue'], { 32 | cwd: src, 33 | ignore: ignore, 34 | }) 35 | .then(function (result) { 36 | if (result.length === 0) { 37 | results.push(file); 38 | } 39 | cb(); 40 | }) 41 | .catch(cb); 42 | }, 43 | function (err) { 44 | if (err) { 45 | spinner.fail('Error'); 46 | console.error(err); 47 | process.exit(1); 48 | } 49 | 50 | if (results.length === 0) { 51 | spinner.succeed('No unused Components found.'); 52 | process.exit(0); 53 | } else { 54 | results.forEach(function (result) { 55 | spinner.stopAndPersist({ 56 | text: result, 57 | symbol: '-', 58 | color: 'red', 59 | }); 60 | spinner.start('Checking for unused Components'); 61 | }); 62 | spinner.fail(results.length + ' unused Component' + (results.length > 1 ? 's' : '') + ' found.'); 63 | process.exit(1); 64 | } 65 | }, 66 | ); 67 | }, 68 | ); 69 | } 70 | -------------------------------------------------------------------------------- /dist/checker.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { 3 | if (k2 === undefined) k2 = k; 4 | Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); 5 | }) : (function(o, m, k, k2) { 6 | if (k2 === undefined) k2 = k; 7 | o[k2] = m[k]; 8 | })); 9 | var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { 10 | Object.defineProperty(o, "default", { enumerable: true, value: v }); 11 | }) : function(o, v) { 12 | o["default"] = v; 13 | }); 14 | var __importStar = (this && this.__importStar) || function (mod) { 15 | if (mod && mod.__esModule) return mod; 16 | var result = {}; 17 | if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); 18 | __setModuleDefault(result, mod); 19 | return result; 20 | }; 21 | var __importDefault = (this && this.__importDefault) || function (mod) { 22 | return (mod && mod.__esModule) ? mod : { "default": mod }; 23 | }; 24 | Object.defineProperty(exports, "__esModule", { value: true }); 25 | exports.getCheckExpression = void 0; 26 | const ora_1 = __importDefault(require("ora")); 27 | const textSearch = __importStar(require("rx-text-search")); 28 | const async_1 = __importDefault(require("async")); 29 | const path_1 = __importDefault(require("path")); 30 | const glob_1 = __importDefault(require("glob")); 31 | function getCheckExpression(file) { 32 | return `(import|require).*(?:[\'\"]\\b|\\/)${path_1.default.basename(file, path_1.default.extname(file))}(?:\\.(?:vue))?[\'\"][\\\);,]?[,;]?`; 33 | } 34 | exports.getCheckExpression = getCheckExpression; 35 | function default_1(src, maxOpenFiles, ignore) { 36 | const spinner = ora_1.default('Checking for unused Components').start(); 37 | glob_1.default('**/*.vue', { 38 | cwd: src, 39 | ignore: ignore, 40 | }, function (err, files) { 41 | if (err) { 42 | throw err; 43 | } 44 | const results = []; 45 | async_1.default.eachOfLimit(files, maxOpenFiles || 30, function (file, index, cb) { 46 | spinner.text = 'Checking for unused Components: ' + file; 47 | textSearch 48 | .findAsPromise(new RegExp(getCheckExpression(file), 'i'), ['**/*.{js,jsx,ts,tsx}', '**/*.vue'], { 49 | cwd: src, 50 | ignore: ignore, 51 | }) 52 | .then(function (result) { 53 | if (result.length === 0) { 54 | results.push(file); 55 | } 56 | cb(); 57 | }) 58 | .catch(cb); 59 | }, function (err) { 60 | if (err) { 61 | spinner.fail('Error'); 62 | console.error(err); 63 | process.exit(1); 64 | } 65 | if (results.length === 0) { 66 | spinner.succeed('No unused Components found.'); 67 | process.exit(0); 68 | } 69 | else { 70 | results.forEach(function (result) { 71 | spinner.stopAndPersist({ 72 | text: result, 73 | symbol: '-', 74 | color: 'red', 75 | }); 76 | spinner.start('Checking for unused Components'); 77 | }); 78 | spinner.fail(results.length + ' unused Component' + (results.length > 1 ? 's' : '') + ' found.'); 79 | process.exit(1); 80 | } 81 | }); 82 | }); 83 | } 84 | exports.default = default_1; 85 | //# sourceMappingURL=checker.js.map -------------------------------------------------------------------------------- /dist/check-expression.test.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"check-expression.test.js","sourceRoot":"","sources":["../src/check-expression.test.ts"],"names":[],"mappings":"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"} -------------------------------------------------------------------------------- /src/check-expression.test.ts: -------------------------------------------------------------------------------- 1 | import { getCheckExpression } from './checker'; 2 | 3 | describe('Check Expression', () => { 4 | const expression = new RegExp(getCheckExpression('test.vue'), 'i'); 5 | describe('should detect normal imports', () => { 6 | it('should be able to detect with vue file suffix', () => { 7 | expect(expression.test("foo bar\n import MyComponent from 'my/file/path/test.vue' \n")).toBeTruthy(); 8 | }); 9 | it('should be able to detect without vue file suffix', () => { 10 | expect(expression.test("foo bar\n import MyComponent from 'my/file/path/test' \n")).toBeTruthy(); 11 | expect(expression.test("foo bar\n import MyComponent from '@/components/test' \n")).toBeTruthy(); 12 | expect(expression.test("foo bar\n import MyComponent from '@/test' \n")).toBeTruthy(); 13 | }); 14 | it('should be able to detect @ in filepath', () => { 15 | expect(expression.test("foo bar\n import MyComponent from '@/components/test.vue' \n")).toBeTruthy(); 16 | expect(expression.test("foo bar\n import MyComponent from '@/test.vue' \n")).toBeTruthy(); 17 | }); 18 | it('should be able to detect ~ in filepath', () => { 19 | expect(expression.test("foo bar\n import MyComponent from '~/components/test.vue' \n")).toBeTruthy(); 20 | expect(expression.test("foo bar\n import MyComponent from '~/test.vue' \n")).toBeTruthy(); 21 | }); 22 | it('should be able to detect with "', () => { 23 | expect(expression.test('foo bar\n import MyComponent from "my/file/path/test.vue" \n')).toBeTruthy(); 24 | }); 25 | it('should be able to detect with semicolon', () => { 26 | expect(expression.test("foo bar\n import MyComponent from 'my/file/path/test.vue'; \n")).toBeTruthy(); 27 | expect(expression.test('foo bar\n import MyComponent from "my/file/path/test.vue"; \n')).toBeTruthy(); 28 | expect(expression.test("foo bar\n import MyComponent from 'my/file/path/test'; \n")).toBeTruthy(); 29 | expect(expression.test('foo bar\n import MyComponent from "my/file/path/test"; \n')).toBeTruthy(); 30 | }); 31 | }); 32 | describe('should detect require calls', () => { 33 | it('should be able to detect with vue file suffix', () => { 34 | expect(expression.test("foo bar\n require('my/file/path/test.vue') \n")).toBeTruthy(); 35 | }); 36 | it('should be able to detect without vue file suffix', () => { 37 | expect(expression.test("foo bar\n require('my/file/path/test') \n")).toBeTruthy(); 38 | expect(expression.test("foo bar\n require('@/components/test') \n")).toBeTruthy(); 39 | expect(expression.test("foo bar\n require('@/test') \n")).toBeTruthy(); 40 | }); 41 | it('should be able to detect @ in filepath', () => { 42 | expect(expression.test("foo bar\n require('@/components/test.vue') \n")).toBeTruthy(); 43 | expect(expression.test("foo bar\n require('@/test.vue') \n")).toBeTruthy(); 44 | }); 45 | it('should be able to detect ~ in filepath', () => { 46 | expect(expression.test("foo bar\n require('~/components/test.vue') \n")).toBeTruthy(); 47 | expect(expression.test("foo bar\n require('~/test.vue') \n")).toBeTruthy(); 48 | }); 49 | it('should be able to detect with "', () => { 50 | expect(expression.test('foo bar\n require("my/file/path/test.vue") \n')).toBeTruthy(); 51 | }); 52 | it('should be able to detect with semicolon', () => { 53 | expect(expression.test("foo bar\n require('my/file/path/test.vue'); \n")).toBeTruthy(); 54 | expect(expression.test('foo bar\n require("my/file/path/test.vue"); \n')).toBeTruthy(); 55 | expect(expression.test("foo bar\n require('my/file/path/test'); \n")).toBeTruthy(); 56 | expect(expression.test('foo bar\n require("my/file/path/test"); \n')).toBeTruthy(); 57 | }); 58 | }); 59 | describe('should detect import calls', () => { 60 | it('should be able to detect with vue file suffix', () => { 61 | expect(expression.test("foo bar\n import('my/file/path/test.vue') \n")).toBeTruthy(); 62 | }); 63 | it('should be able to detect without vue file suffix', () => { 64 | expect(expression.test("foo bar\n import('my/file/path/test') \n")).toBeTruthy(); 65 | expect(expression.test("foo bar\n import('@/components/test') \n")).toBeTruthy(); 66 | expect(expression.test("foo bar\n import('@/test') \n")).toBeTruthy(); 67 | }); 68 | it('should be able to detect @ in filepath', () => { 69 | expect(expression.test("foo bar\n import('@/components/test.vue') \n")).toBeTruthy(); 70 | expect(expression.test("foo bar\n import('@/test.vue') \n")).toBeTruthy(); 71 | }); 72 | it('should be able to detect ~ in filepath', () => { 73 | expect(expression.test("foo bar\n import('~/components/test.vue') \n")).toBeTruthy(); 74 | expect(expression.test("foo bar\n import('~/test.vue') \n")).toBeTruthy(); 75 | }); 76 | it('should be able to detect with "', () => { 77 | expect(expression.test('foo bar\n import("my/file/path/test.vue") \n')).toBeTruthy(); 78 | }); 79 | it('should be able to detect with semicolon', () => { 80 | expect(expression.test("foo bar\n import('my/file/path/test.vue'); \n")).toBeTruthy(); 81 | expect(expression.test('foo bar\n import("my/file/path/test.vue"); \n')).toBeTruthy(); 82 | expect(expression.test("foo bar\n import('my/file/path/test'); \n")).toBeTruthy(); 83 | expect(expression.test('foo bar\n import("my/file/path/test"); \n')).toBeTruthy(); 84 | }); 85 | }); 86 | }); 87 | -------------------------------------------------------------------------------- /dist/check-expression.test.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | const checker_1 = require("./checker"); 4 | describe('Check Expression', () => { 5 | const expression = new RegExp(checker_1.getCheckExpression('test.vue'), 'i'); 6 | describe('should detect normal imports', () => { 7 | it('should be able to detect with vue file suffix', () => { 8 | expect(expression.test("foo bar\n import MyComponent from 'my/file/path/test.vue' \n")).toBeTruthy(); 9 | }); 10 | it('should be able to detect without vue file suffix', () => { 11 | expect(expression.test("foo bar\n import MyComponent from 'my/file/path/test' \n")).toBeTruthy(); 12 | expect(expression.test("foo bar\n import MyComponent from '@/components/test' \n")).toBeTruthy(); 13 | expect(expression.test("foo bar\n import MyComponent from '@/test' \n")).toBeTruthy(); 14 | }); 15 | it('should be able to detect @ in filepath', () => { 16 | expect(expression.test("foo bar\n import MyComponent from '@/components/test.vue' \n")).toBeTruthy(); 17 | expect(expression.test("foo bar\n import MyComponent from '@/test.vue' \n")).toBeTruthy(); 18 | }); 19 | it('should be able to detect ~ in filepath', () => { 20 | expect(expression.test("foo bar\n import MyComponent from '~/components/test.vue' \n")).toBeTruthy(); 21 | expect(expression.test("foo bar\n import MyComponent from '~/test.vue' \n")).toBeTruthy(); 22 | }); 23 | it('should be able to detect with "', () => { 24 | expect(expression.test('foo bar\n import MyComponent from "my/file/path/test.vue" \n')).toBeTruthy(); 25 | }); 26 | it('should be able to detect with semicolon', () => { 27 | expect(expression.test("foo bar\n import MyComponent from 'my/file/path/test.vue'; \n")).toBeTruthy(); 28 | expect(expression.test('foo bar\n import MyComponent from "my/file/path/test.vue"; \n')).toBeTruthy(); 29 | expect(expression.test("foo bar\n import MyComponent from 'my/file/path/test'; \n")).toBeTruthy(); 30 | expect(expression.test('foo bar\n import MyComponent from "my/file/path/test"; \n')).toBeTruthy(); 31 | }); 32 | }); 33 | describe('should detect require calls', () => { 34 | it('should be able to detect with vue file suffix', () => { 35 | expect(expression.test("foo bar\n require('my/file/path/test.vue') \n")).toBeTruthy(); 36 | }); 37 | it('should be able to detect without vue file suffix', () => { 38 | expect(expression.test("foo bar\n require('my/file/path/test') \n")).toBeTruthy(); 39 | expect(expression.test("foo bar\n require('@/components/test') \n")).toBeTruthy(); 40 | expect(expression.test("foo bar\n require('@/test') \n")).toBeTruthy(); 41 | }); 42 | it('should be able to detect @ in filepath', () => { 43 | expect(expression.test("foo bar\n require('@/components/test.vue') \n")).toBeTruthy(); 44 | expect(expression.test("foo bar\n require('@/test.vue') \n")).toBeTruthy(); 45 | }); 46 | it('should be able to detect ~ in filepath', () => { 47 | expect(expression.test("foo bar\n require('~/components/test.vue') \n")).toBeTruthy(); 48 | expect(expression.test("foo bar\n require('~/test.vue') \n")).toBeTruthy(); 49 | }); 50 | it('should be able to detect with "', () => { 51 | expect(expression.test('foo bar\n require("my/file/path/test.vue") \n')).toBeTruthy(); 52 | }); 53 | it('should be able to detect with semicolon', () => { 54 | expect(expression.test("foo bar\n require('my/file/path/test.vue'); \n")).toBeTruthy(); 55 | expect(expression.test('foo bar\n require("my/file/path/test.vue"); \n')).toBeTruthy(); 56 | expect(expression.test("foo bar\n require('my/file/path/test'); \n")).toBeTruthy(); 57 | expect(expression.test('foo bar\n require("my/file/path/test"); \n')).toBeTruthy(); 58 | }); 59 | }); 60 | describe('should detect import calls', () => { 61 | it('should be able to detect with vue file suffix', () => { 62 | expect(expression.test("foo bar\n import('my/file/path/test.vue') \n")).toBeTruthy(); 63 | }); 64 | it('should be able to detect without vue file suffix', () => { 65 | expect(expression.test("foo bar\n import('my/file/path/test') \n")).toBeTruthy(); 66 | expect(expression.test("foo bar\n import('@/components/test') \n")).toBeTruthy(); 67 | expect(expression.test("foo bar\n import('@/test') \n")).toBeTruthy(); 68 | }); 69 | it('should be able to detect @ in filepath', () => { 70 | expect(expression.test("foo bar\n import('@/components/test.vue') \n")).toBeTruthy(); 71 | expect(expression.test("foo bar\n import('@/test.vue') \n")).toBeTruthy(); 72 | }); 73 | it('should be able to detect ~ in filepath', () => { 74 | expect(expression.test("foo bar\n import('~/components/test.vue') \n")).toBeTruthy(); 75 | expect(expression.test("foo bar\n import('~/test.vue') \n")).toBeTruthy(); 76 | }); 77 | it('should be able to detect with "', () => { 78 | expect(expression.test('foo bar\n import("my/file/path/test.vue") \n')).toBeTruthy(); 79 | }); 80 | it('should be able to detect with semicolon', () => { 81 | expect(expression.test("foo bar\n import('my/file/path/test.vue'); \n")).toBeTruthy(); 82 | expect(expression.test('foo bar\n import("my/file/path/test.vue"); \n')).toBeTruthy(); 83 | expect(expression.test("foo bar\n import('my/file/path/test'); \n")).toBeTruthy(); 84 | expect(expression.test('foo bar\n import("my/file/path/test"); \n')).toBeTruthy(); 85 | }); 86 | }); 87 | }); 88 | //# sourceMappingURL=check-expression.test.js.map -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to Vue Unused Component Checker 2 | 3 | ✨ Thanks for contributing to **Vue Unused Component Checker** ✨ 4 | 5 | ## How to contribute? 6 | 7 | ### Improve documentation 8 | 9 | As a user, you are the perfect candidate to help us improve our documentation: typo corrections, clarifications, more examples, etc. Every improvement is welcome. 10 | 11 | ### Give feedback on issues 12 | 13 | Some [issues](https://github.com/BerniWittmann/vue-unused-components-checker/issues) are created without enough information to reproduce or resolve them. Help make them easier to resolve by adding any relevant information. 14 | 15 | ### Fix bugs and implement features 16 | 17 | Take a look at the currently open [issues](https://github.com/BerniWittmann/vue-unused-components-checker/issues) or find a bug or feature you want to see implemented and go for it. 18 | 19 | ## Working with the code 20 | 21 | ### Setup the workspace 22 | 23 | You should have [node](https://nodejs.org/en/) and npm or [yarn](https://yarnpkg.com) installed. 24 | 25 | Fork the project and clone your fork: 26 | 27 | ```bash 28 | # Clone Repository 29 | $ git clone https://github.com/BerniWittmann/vue-unused-components-checker/ 30 | # Navigate to newly cloned directory 31 | $ cd vue-unused-components-checker 32 | # Install dependencies 33 | $ npm install 34 | ``` 35 | 36 | ### Linting 37 | 38 | The project uses [ESLint](https://eslint.org/) and [Prettier](https://prettier.io/) for formatting 39 | 40 | Before pushing your code changes make sure there are no linting errors with 41 | 42 | ```bash 43 | $ npm run lint 44 | ``` 45 | 46 | ### Tests 47 | 48 | This repository uses [Jest](https://jestjs.io) for writing and running tests. 49 | 50 | Before pushing your code changes make sure there are no failing tests 51 | 52 | ```bash 53 | $ npm run test 54 | ``` 55 | 56 | ## Commit Guidelines 57 | 58 | Before each commit, this repository uses [husky](https://typicode.github.io/husky/#/) to check for linting errors and whether the commit message guidelines have been met. 59 | 60 | ### Commit message guidelines 61 | 62 | #### Atomic commits 63 | 64 | If possible, make [atomic commits](https://en.wikipedia.org/wiki/Atomic_commit), which means: 65 | 66 | - a commit should contain exactly one self-contained functional change 67 | - a functional change should be contained in exactly one commit 68 | - a commit should not create an inconsistent state (such as test errors, linting errors, partial fix, feature with documentation etc...) 69 | 70 | A complex feature can be broken down into multiple commits as long as each one maintains a consistent state and consists of a self-contained change. 71 | 72 | #### Commit message format 73 | 74 | This project uses [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/), a standard to create an explicit commit history. 75 | 76 | Each commit message consists of a **header**, a **body** and a **footer**. The header has a special format that includes a **type**, a **scope** and a **subject**: 77 | 78 | ```commit 79 | (): 80 | 81 | 82 | 83 |