Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

No tree shaking after dead code removal in dynamic import #16271

Closed
icy0307 opened this issue Sep 19, 2022 · 2 comments
Closed

No tree shaking after dead code removal in dynamic import #16271

icy0307 opened this issue Sep 19, 2022 · 2 comments

Comments

@icy0307
Copy link

icy0307 commented Sep 19, 2022

Bug report

With mode: production on, and "sideEffects:false", exported function that are unused after dead code removal remain in the bundle, if the module is imported dynamically.
https://stackblitz.com/edit/github-2yf5yf?file=dist/main.js

What is the current behavior?
unused function not get removed if the file is imported dynamically

If the current behavior is a bug, please provide the steps to reproduce.

  1. entry: index.ts
import { treeShakingTestSync } from './treeshaking-test';
const foo = treeShakingTestSync();
console.log(foo);
  1. treeshaking-test.ts
import { b } from "./await-import-modules";
export const treeShakingTestAsync = async () => {
    console.log('treeShakingTestAsync');
    const { b } = await import('./await-import-modules');
    return b;
};


export const treeShakingTestSync = () => {
    console.log('treeShakingTestSync');
    return b;
};
  1. await-import-modules.ts.ts
export function a() { console.log('FuncA') };
export function b() { console.log('FuncB') };
  1. webpack.config.js
const path = require('path');

module.exports = {
  entry: './src/index.ts',
  mode: 'production',
  module: {
    rules: [
      {
        test: /\.tsx?$/,
        use: 'ts-loader',
        exclude: /node_modules/,
      },
    ],
  },
  resolve: {
    extensions: ['.tsx', '.ts', '.js'],
  },
  output: {
    filename: 'main.js',
    path: path.resolve(__dirname, 'dist'),
  },
};
  1. package.json
{
  "name": "getting-started-using-a-configuration",
  "version": "1.0.0",
  "private": true,
  "scripts": {
    "build": "webpack",
    "start": "serve dist"
  },
  "sideEffects": false,
  "keywords": [],
  "author": "",
  "license": "MIT",
  "devDependencies": {
    "serve": "^12.0.0",
    "ts-loader": "^9.3.1",
    "typescript": "^4.8.3",
    "webpack": "^5.38.1",
    "webpack-cli": "^4.7.2"
  }
}

What is the expected behavior?
"treeShakingTestAsync" cannot be found in the output file, as expected.
But 'FuncA' can be found, not get tree-shaken or deadcode removed.
'FuncA' should be tree-shaken

Other relevant information:
webpack version: 5.74.0
Node.js version: v14.15.0
Operating System: macOS 12.0.1
Additional tools:

@icy0307
Copy link
Author

icy0307 commented Sep 20, 2022

I found some relates issue #13028, and understand this could not be done right now.
This issue can be closed in favor of #13028 #14800

But still got some related questions @vankop @alexander-akait :

  1. As mentioned in Unused code is not removed from dynamic imports #13028, magic comment is hard to maintain, especially in large project. If dynamic import is the reason, can we add some intermediate files to avoid this problem?
    I fiddle around a little bit , by adding an intermediate.ts to statically import from module that dynamic import originally.
    intermediate.ts. its basically the same as magic comment, expect it can be refactor (still a undesired workaround, until Support destructuring #14800 get resolved).
export { b } from "./await-import-modules";

treeshaking-test.ts

import { b } from "./intermediate";
export const treeShakingTestAsync = async () => {
    console.log('treeShakingTestAsync');
    const { b } = await import('./intermediate');
    return b;
};

in this way, unused function 'FuncA' cant't be found in the output file, as expected.
is it recommended way to solve this problem?
2. Could you elaborate on the details why #14800 is hard to implement?
3. If production mode is on , and minify set false, why unused export file is still in the output? shouldn't it be tree shaken first instead of code removal?

@alexander-akait
Copy link
Member

@icy0307 This is not hard, the main problem is babel and another transpilers and renaming variables, yes it's fixable, but need more work, if you want to help us feel free to continue dicussion here #14800 and ask questions

There is a PR with attempts to resolve, so you can build own solution

let's close this, because the root of the problem is #14800

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants