I'm sure there are other places where it's applicable, but modern javascript and webapps have to be the quintessential use case.
To apply this to python is interesting - if you were creating a packaged version, I could see "compiling" the code to a separate package with only the required imports.
Those are both dead code elimination. Webpack even says:
> Tree shaking is a term commonly used in the JavaScript context for dead-code elimination.
It could be, but I don't see it as too practical as dependencies are very likely quite transparent and don't themselves rely on many dependencies. But for JS?
There's no reason you can't write JS the same way you would write Java or C++. (And if you were writing "serious" applications in JS that weren't web apps before NodeJS came along, you did. Of course, you still can, too.)
For example a Lisp system may consist of starting a memory image from disk, which leads to a live running memory heap. The tree shaker then may break unused links in memory - either automatic or under programmer direction. The garbage collector then frees the unused memory. Lisp then dumps a new (typically smaller) image, which has unused code and data removed.
Such features appeared no later than end 1980s.
That's exactly how all dead code elimination works. How else would you do it?
Tree shaking happens at the import level. If I say `import { abc } from 'some-lib'`, tree shaking won’t include any other objects some-lib may export.
Removing a branch that can never be true, like `if ('production' === 'production') { … } else { /* dead code */ }` is dead code elimination, but webpack wouldn’t consider that tree shaking.