Code Monkey home page Code Monkey logo

deadfile's Introduction

deadfile

deadfile

Simple util to find deadcode and unused files in any JavaScript project (ES5, ES6, React, Vue, ...).

  • Easy to use
  • Out of box support for ES5, ES6, React, Vue, ESM, CommonJs.
  • Error tolerant: deadfile uses loose parsing of your code, so if there are errors in your code, it still works. Even if you use some random babel config, it will parse your code and find imports.
  • Syntax support: it supports import/require and even dynamic import.
  • Shows you a warning for the node_modules you import, but do not appear in your package.json

deadfile result deadfile result

Supported Node Versions

This project uses optional chaining, so you need to use Node v14.0 + to be able to use it.

Installation

Install deadfile cli with the following command:

npm

$ npm install -g deadfile

yarn

$ yarn global add deadfile

npx

$ npx deadfile <file>

Usage and Examples

simple:

deadfile ./src/index.js

multiple entry:

deadfile ./src/index.js ./src/entry2.js

with custom directory:

deadfile ./src/index.js --dir /path/to/other/folder

with exclude:

deadfile ./src/index.js --exclude tests  utils/webpack

without the report server or in CI scripts:

deadfile ./src/index.js --ci

What it does

Supported Syntaxes

All major ES Module imports are supported (including dynamic import): Import Syntax

Also the following export (aggregation) syntaxes are also supported: Export Aggregation Syntax

Development Environment

You can use deadfile for any JavaScript project, and go crazy with you code, use the latest features and it still works. Here are some examples:

JSX

React Example

Vue

Vue Example

Reassigned requires

deadfile look for import declarations and calls of the require function. As a result, if you assign require to another var and use it to load a dependency, it will not handle it.

Options

  • entry: all arguments directly after deadfile are considered as entries (yes, deadfile supports multiple entries)
deadfile ./src/index.js ./src/entry2.js
  • --dir: set search in another folder:
deadfile <file> --dir /path/to/other/folder
  • --exclude: list of paths to ignore:

Paths or files to exclude from search. It supports any valid RegExp expression to exclude:

deadfile <file> --exclude ^(\w)png$
deadfile <file> --exclude webpack utils docs

---output: used to write report results in .json file

You can specify the file to write, a json file including file lists:

deadfile <file> --output report.json

Todo

  • handle reassigned require
  • look for dead declarations too
  • Add support AMD
  • be able to include/exclude paths/extentions based on relPath/regex
  • allow file extensions for parsing, should default to (.js/.jsx/.ts/.tsx/.vue)
  • Add SASS import

deadfile's People

Contributors

dependabot[bot] avatar gamtiq avatar kevinbarabash avatar leorossi avatar luke-lacroix-healthy avatar m-izadmehr avatar rszalski avatar semantic-release-bot avatar yan-xiaoming avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

deadfile's Issues

Hangs on a big project

(develop *+$% u=)$ deadfile ./src/root.jsx 

   ╭──────────────────────────────────────────────────────────────╮
   │                                                              │
   │                          Dead File!                          │
   │                                                              │
   │   Simply find the unused files in your javascript project.   │
   │                    Press --help for help.                    │
   │                                                              │
   ╰──────────────────────────────────────────────────────────────╯

✔ 3152 total assets found in base directory.
⠙ 16 imported assets found. /path/to/the/project/src/state/routes.jsx Killed

Tried two times. Every time I had to kill the process after 4-6 minutes.
Weirdly, I couldn't also terminate the process using Ctrl+c so I killed it from the outside.

Both times the process was consuming 175-200% of CPU according to htop.

System: Linux Ubuntu 18.04

Doesn't resolve directory aliases

Hey there,

in our project we use module-resolver with directory aliases, the config looks like this:

[
    "module-resolver",
    {
      "root": [
        "."
      ],
      "alias": {
        "~": "./src",
        "lib": "./src/lib",
        "components": "./src/components",
        "state": "./src/state",
        "config": "./src/config",
        "RootParams": "./src/lib/Shared/ScreenManager/RootParams"
      }
    }
  ]

but when running deadfile we get the following error:

err:  Error: Can't resolve './src' in '/Users/workstation/Development/example/mobile'
    at /Users/workstation/.nvm/versions/node/v12.13.1/lib/node_modules/deadfile/node_modules/enhanced-resolve/lib/Resolver.js:209:21
    at /Users/workstation/.nvm/versions/node/v12.13.1/lib/node_modules/deadfile/node_modules/enhanced-resolve/lib/Resolver.js:285:5
    at eval (eval at create (/Users/workstation/.nvm/versions/node/v12.13.1/lib/node_modules/deadfile/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:15:1)
    at /Users/workstation/.nvm/versions/node/v12.13.1/lib/node_modules/deadfile/node_modules/enhanced-resolve/lib/Resolver.js:285:5
    at eval (eval at create (/Users/workstation/.nvm/versions/node/v12.13.1/lib/node_modules/deadfile/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:27:1)
    at /Users/workstation/.nvm/versions/node/v12.13.1/lib/node_modules/deadfile/node_modules/enhanced-resolve/lib/DescriptionFilePlugin.js:67:43
    at /Users/workstation/.nvm/versions/node/v12.13.1/lib/node_modules/deadfile/node_modules/enhanced-resolve/lib/Resolver.js:285:5
    at eval (eval at create (/Users/workstation/.nvm/versions/node/v12.13.1/lib/node_modules/deadfile/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:16:1)
    at /Users/workstation/.nvm/versions/node/v12.13.1/lib/node_modules/deadfile/node_modules/enhanced-resolve/lib/Resolver.js:285:5
    at eval (eval at create (/Users/workstation/.nvm/versions/node/v12.13.1/lib/node_modules/deadfile/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:27:1) {
  details: "resolve './src' in '/Users/workstation/Development/example/mobile'\n" +
    '  using description file: /Users/workstation/Development/example/mobile/package.json (relative path: .)\n' +
    '    using description file: /Users/workstation/Development/example/mobile/package.json (relative path: ./src)\n' +
    '      no extension\n' +
    '        /Users/workstation/Development/example/mobile/src is not a file\n' +
    '      .js\n' +
    "        /Users/workstation/Development/example/mobile/src.js doesn't exist\n" +
    '      .jsx\n' +
    "        /Users/workstation/Development/example/mobile/src.jsx doesn't exist\n" +
    '      .ts\n' +
    "        /Users/workstation/Development/example/mobile/src.ts doesn't exist\n" +
    '      tsx\n' +
    "        /Users/workstation/Development/example/mobile/srctsx doesn't exist\n" +
    '      .vue\n' +
    "        /Users/workstation/Development/example/mobile/src.vue doesn't exist\n" +
    '      as directory\n' +
    '        existing directory\n' +
    '          using path: /Users/workstation/Development/example/mobile/src/index\n' +
    '            using description file: /Users/workstation/Development/example/mobile/package.json (relative path: ./src/index)\n' +
    '              no extension\n' +
    "                /Users/workstation/Development/example/mobile/src/index doesn't exist\n" +
    '              .js\n' +
    "                /Users/workstation/Development/example/mobile/src/index.js doesn't exist\n" +
    '              .jsx\n' +
    "                /Users/workstation/Development/example/mobile/src/index.jsx doesn't exist\n" +
    '              .ts\n' +
    "                /Users/workstation/Development/example/mobile/src/index.ts doesn't exist\n" +
    '              tsx\n' +
    "                /Users/workstation/Development/example/mobile/src/indextsx doesn't exist\n" +
    '              .vue\n' +
    "                /Users/workstation/Development/example/mobile/src/index.vue doesn't exist",
  missing: [
    '/Users/workstation/Development/example/mobile/src',
    '/Users/workstation/Development/example/mobile/src.js',
    '/Users/workstation/Development/example/mobile/src.jsx',
    '/Users/workstation/Development/example/mobile/src.ts',
    '/Users/workstation/Development/example/mobile/srctsx',
    '/Users/workstation/Development/example/mobile/src.vue',
    '/Users/workstation/Development/example/mobile/src/index',
    '/Users/workstation/Development/example/mobile/src/index.js',
    '/Users/workstation/Development/example/mobile/src/index.jsx',
    '/Users/workstation/Development/example/mobile/src/index.ts',
    '/Users/workstation/Development/example/mobile/src/indextsx',
    '/Users/workstation/Development/example/mobile/src/index.vue'
  ]
}

Looks like the problem is enhanced-resolver doesn't understand that /src refers to a directory (and not a file), and is trying to find a specific file in there.

Any ideas?

Thanks

Monorepo support

I think we are one step away from adding a monorepo support.

I've checked the source code and it seems to me that we only need to add support for multiple --dir options.

configure a baseUrl

I'm using create-react-app and have a file like this in the root of my project:

{
  "compilerOptions": {
    "baseUrl": "src"
  }
}

So all of my imports look like

import { abc } from 'components/XYZ'

for a file in src/components/XYZ.js

Right now when I run deadfile it shows every single file as being dead.
eg:

673 total files found!
670 dead files found!
...

Is it possible to configure it so I can tell it the baseUrl is src?

Kudos on the lib btw, it looks really nicely put together!

[Feature Request] Use a config file

Very nice project, thank you.

It would be great to be able to use a config file. For instance the list of excluded paths can be pretty long, it could be nicer to place that info in a config file rather than a script?

Module resolver support?

Hey,

First of all thanks for this awesome lib! It's really good =)

I wonder if we could add babel.js module-resolver support - in order to support absolute imports.

For example I have this setup in my project:

import FadeIn from "components/Loading/FadeIn";

Thanks to module-resolver I don't have to do ../../../components/Loading/FadeIn, since it simplifies that by allowing me to directly target components folder.

But due to module-resolver, deadfile doesn't recognise that the component is being imported:

image

Any ideas? I'm willing to contribute to this project. 😃

Use as NodeJS module

To speed up process while working on #5 I realized that this tool may be useful also to be used as node module rather than CLI only.

I spotted a couple of issues that may be worth working on

  • since UsedAssets is async, there is not way to know when Deadfile has finished his work, maybe extend EventEmitter and send events may be a solution?
  • reporting is enabled by default, this means logging in console, on a file and starting a reporting server which parses the file. This should be optional and results of Deadfile's work can be stored in a variable

I'd like to use it like

const instance = new Deadfile(opts);
instance.on('end', (results) => {
    console.log(results) // console.log(instance.results)
   // do your own stuff with results of deadfile
});

Debug mode

Should introduce a debug mode when running the scan, I got a huge project with .js & .ts files, it calculates the amount of assets & files, then just gets stuck & uncancellable.

Is it compliant with typescript files?

License

This library looks great! We have a large typescript/javascript repo and are hoping to find some dead code.
Would it be possible to add a license to this repository so that we know under what circumstances we can use and modify the code?
(MIT / ISC preferred -- but of course it's up to your preferences)

Deadfile for libraries should respect exports

Super project! Thank you.

I've got a use case where my project is a library that exports much of it's functionality for 3rd parties to use. I want to know what files are not getting exported. It seems like this could have an option to run in library mode that tells you not just what isn't imported, but also what isn't exported.

Exclude doesn't work

folder list

  • src/main/app
  • src/test

I want to include src/main/app and exclude src/test

npx deadfile src/main/app/application.tsx --exclude src/main/java src/main/resources dist storybook-static static bin src/test browser-tests build src/stories

Actual Result
files in src/test are not excluded

TypeError: Cannot read property '1' of undefined with deadfile dependency

same error keeps repeating ... I cant get any results

deadfile ./src/App.js

╭──────────────────────────────────────────────────────────────╮
│ │
│ Dead File! │
│ │
│ Simply find the unused files in your javascript project. │
│ Press --help for help. │
│ │
╰──────────────────────────────────────────────────────────────╯

✔ 614 total assets found in base directory.
⠋ Counting imported assetserr: TypeError: Cannot read property '1' of undefined
at checkBabelModuleResolver (/usr/local/lib/node_modules/deadfile/src/handlers/fileResolver.js:26:38)
at resolve (/usr/local/lib/node_modules/deadfile/src/handlers/fileResolver.js:53:15)
at UsedAssets.updateSources (/usr/local/lib/node_modules/deadfile/src/handlers/UsedAssets.js:99:38)
at UsedAssets.checkImports (/usr/local/lib/node_modules/deadfile/src/handlers/UsedAssets.js:142:21)
at c (/usr/local/lib/node_modules/deadfile/node_modules/acorn-walk/dist/walk.js:79:24)
at Object.skipThrough (/usr/local/lib/node_modules/deadfile/node_modules/acorn-walk/dist/walk.js:186:39)
at c (/usr/local/lib/node_modules/deadfile/node_modules/acorn-walk/dist/walk.js:78:24)
at Object.base.Program.base.BlockStatement (/usr/local/lib/node_modules/deadfile/node_modules/acorn-walk/dist/walk.js:198:7)
at c (/usr/local/lib/node_modules/deadfile/node_modules/acorn-walk/dist/walk.js:78:24)
at Object.full (/usr/local/lib/node_modules/deadfile/node_modules/acorn-walk/dist/walk.js:80:7)
err: TypeError: Cannot read property '1' of undefined
at checkBabelModuleResolver (/usr/local/lib/node_modules/deadfile/src/handlers/fileResolver.js:26:38)
at resolve (/usr/local/lib/node_modules/deadfile/src/handlers/fileResolver.js:53:15)
at UsedAssets.updateSources (/usr/local/lib/node_modules/deadfile/src/handlers/UsedAssets.js:99:38)
at UsedAssets.checkImports (/usr/local/lib/node_modules/deadfile/src/handlers/UsedAssets.js:142:21)
at c (/usr/local/lib/node_modules/deadfile/node_modules/acorn-walk/dist/walk.js:79:24)
at Object.skipThrough (/usr/local/lib/node_modules/deadfile/node_modules/acorn-walk/dist/walk.js:186:39)
at c (/usr/local/lib/node_modules/deadfile/node_modules/acorn-walk/dist/walk.js:78:24)
at Object.base.Program.base.BlockStatement (/usr/local/lib/node_modules/deadfile/node_modules/acorn-walk/dist/walk.js:198:7)
at c (/usr/local/lib/node_modules/deadfile/node_modules/acorn-walk/dist/walk.js:78:24)
at Object.full (/usr/local/lib/node_modules/deadfile/node_modules/acorn-walk/dist/walk.js:80:7)
err: TypeError: Cannot read property '1' of undefined
at checkBabelModuleResolver (/usr/local/lib/node_modules/deadfile/src/handlers/fileResolver.js:26:38)
at resolve (/usr/local/lib/node_modules/deadfile/src/handlers/fileResolver.js:53:15)
at UsedAssets.updateSources (/usr/local/lib/node_modules/deadfile/src/handlers/UsedAssets.js:99:38)
at UsedAssets.checkImports (/usr/local/lib/node_modules/deadfile/src/handlers/UsedAssets.js:142:21)
at c (/usr/local/lib/node_modules/deadfile/node_modules/acorn-walk/dist/walk.js:79:24)
at Object.skipThrough (/usr/local/lib/node_modules/deadfile/node_modules/acorn-walk/dist/walk.js:186:39)
at c (/usr/local/lib/node_modules/deadfile/node_modules/acorn-walk/dist/walk.js:78:24)
at Object.base.Program.base.BlockStatement (/usr/local/lib/node_modules/deadfile/node_modules/acorn-walk/dist/walk.js:198:7)
at c (/usr/local/lib/node_modules/deadfile/node_modules/acorn-walk/dist/walk.js:78:24)
at Object.full (/usr/local/lib/node_modules/deadfile/node_modules/acorn-walk/dist/walk.js:80:7)

Error: Table data must not contain control characters.

I just tried on my project and unfortunately it returned an error. Any idea what's causing the issue?

$ deadfile ./src/index.js     

   ╭──────────────────────────────────────────────────────────────╮
   │                                                              │
   │                          Dead File!                          │
   │                                                              │
   │   Simply find the unused files in your javascript project.   │
   │                    Press --help for help.                    │
   │                                                              │
   ╰──────────────────────────────────────────────────────────────╯

✔ 1221 total assets found in base directory.
✔ 76 imported assets found.
/usr/local/lib/node_modules/deadfile/node_modules/table/dist/validateTableData.js:88
        throw _iteratorError;
        ^

Error: Table data must not contain control characters.
    at validateTableData (/usr/local/lib/node_modules/deadfile/node_modules/table/dist/validateTableData.js:60:19)
    at table (/usr/local/lib/node_modules/deadfile/node_modules/table/dist/table.js:96:34)
    at logger (/usr/local/lib/node_modules/deadfile/src/cli/Logger.js:38:18)
    at DeadFile.reporting (/usr/local/lib/node_modules/deadfile/src/index.js:84:5)
    at DeadFile.checkDiff (/usr/local/lib/node_modules/deadfile/src/index.js:78:12)
    at DeadFile.setUsedAssets (/usr/local/lib/node_modules/deadfile/src/index.js:47:10)
    at /usr/local/lib/node_modules/deadfile/src/handlers/UsedAssets.js:75:12
    at FSReqCallback.readFileAfterClose [as oncomplete] (node:internal/fs/read_file_context:68:3)

The automated release is failing 🚨

🚨 The automated release from the master branch failed. 🚨

I recommend you give this issue a high priority, so other packages depending on you can benefit from your bug fixes and new features again.

You can find below the list of errors reported by semantic-release. Each one of them has to be resolved in order to automatically publish your package. I’m sure you can fix this 💪.

Errors are usually caused by a misconfiguration or an authentication problem. With each error reported below you will find explanation and guidance to help you to resolve it.

Once all the errors are resolved, semantic-release will release your package the next time you push a commit to the master branch. You can also manually restart the failed CI job that runs semantic-release.

If you are not sure how to resolve this, here are some links that can help you:

If those don’t help, or if this issue is reporting something you think isn’t right, you can always ask the humans behind semantic-release.


No npm token specified.

An npm token must be created and set in the NPM_TOKEN environment variable on your CI environment.

Please make sure to create an npm token and to set it in the NPM_TOKEN environment variable on your CI environment. The token must allow to publish to the registry https://registry.npmjs.org/.


Good luck with your project ✨

Your semantic-release bot 📦🚀

[Feature Request] Possible to check imported folder from `package.json` `name`

This tools awesome to check all my unused files, but i have some import file that used package.json

let say i have this structure folder

assets (dir)
  welcome.png
  splash_screen.png
  package.json
index.js (file)

where package.json inside assets folder has json :

{
    "name": "@images"
}

and my index.js contain some code like this :

const WelcomeImage = require('@images/welcome.png')

this way, deadfile checking welcome.png is not imported

is there some way to solve this issue @M-Izadmehr ?

.gitignore support

Hi, was linked this utility and it looks great! 🤩

One feature I'd really love is to be able to ignore files based on my .gitignore. Currently, these files pollute the output of this utility and there's no simple way to ignore them.

I tried e.g. npx deadfile ./src/App.tsx --exclude $(cat .gitignore) but that fails due to my .gitignore containing wildcards. Maybe e.g. parse-gitignore could be a simple way of acheving this?

Include support for lazy() load components

Hello,

I have a large project and for performance I'am using lazy() to load my views

const Home = lazy(() => import('@/views/home'))

however this files are not being considered when runing the tool and they appear as unused.

Is there a work around to make this work right now or is not possible?

Thanks for your attention

Option to Disable Visualisation Server/Page

I'm currently investigating running this as part of a CI process in GHA.

The visualisation is great for manual investigations, but in this case, I just need to pipe machine readable output to a script that iterates over unused files and deletes them.

I've been writing and reading the JSON output as a stop-gap for sending JSON to stdout, but it seems that the process which launches the visualisation server causes the CI to hang and never resolve.

It would be great to expose a CLI argument to switch this feature off, and also optionally, to pipe the JSON output to stdout.

Thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.