Thanks to visit codestin.com
Credit goes to github.com

Skip to content

unused default export not marked as unused, so isn't tree-shaken away #20537

@trullock

Description

@trullock

Bug Description

Summary

An export is ending up in the initial chunk instead of a dynamically imported chunk, and I don't know why or how to move it.

It is not used in the initial chunk, but isn't marked as so.

Details

I'm using vue-loader to import a vue page

vue uses a default export to define the page script
my page also has named exports for other reasons which are out-of-scope here

when I import the named export only into my app, the chunk also ends up with the unused default export, however its not marked as unused, and so it doesn't get removed/tree-shaken

Vue page:

<script>
export const opts = {
	route: '/test',
	title: 'I am a test'
}

export default {
	data() { return {
		"I": "Should not be inside the initial bundle"
	} }
}
</script>
<template>
	Testing 123
</template>

The chunk for the dynamically imported view page is:

"use strict";
(self.webpackChunkwebpack_test = self.webpackChunkwebpack_test || []).push([
  [434],
  {
    262(t, e) {
      e.A = (t, e) => {
        const s = t.__vccOpts || t;
        for (const [t, c] of e) s[t] = c;
        return s;
      };
    },
    434(t, e, s) {
      (s.r(e), s.d(e, { default: () => n, opts: () => c.p }));
      var c = s(121);
      const n = (0, s(262).A)(c.A, [
        [
          "render",
          function (t, e, s, c, n, r) {
            return " Testing 123 ";
          },
        ],
      ]);
    },
  },
]);

The default export isn't in there, but I guess thats because its in the initial chunk so thats not the real issue here.

The initial chunk has:

...
    n = {
      121(e, t, r) {
        r.d(t, { A: () => n, p: () => o });
        const o = { route: "/test", title: "I am a test" },
          n = {
            data: () => ({ I: "Should not be inside the initial bundle" }),
          };
      },
    },
...

which contains the unused default export. Why?

In dev mode:

/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({
  data() {
    return {
      "I": "Should not be inside the initial bundle"
    };
  }
});

So it doesn't think its an unused export, why?

Link to Minimal Reproduction and step to reproduce

https://github.com/trullock/webpack-mcve

> npm i
> webpack

Expected Behavior

unused default export from vue page should be marked as unused, and not included in the initial chunk.
It should be inside the dynamically loaded chunk, as thats where it's used

Actual Behavior

"unused" default export ends up in initial chunk

Environment

System:
    OS: Linux 6.8 Zorin OS 17.3 17.3
    CPU: (32) x64 AMD Ryzen 9 9950X 16-Core Processor
    Memory: 41.08 GB / 60.47 GB
  Binaries:
    Node: 23.6.0 - /home/trullock/.nvm/versions/node/v23.6.0/bin/node
    npm: 11.5.2 - /home/trullock/.nvm/versions/node/v23.6.0/bin/npm
  Packages:
    babel-loader: ^10.0.0 => 10.0.0 
    html-webpack-plugin: ^5.5.0 => 5.6.6 
    vue-loader: ^17.4.2 => 17.4.2 
    webpack: ^5.104.1 => 5.105.2 
    webpack-bundle-analyzer: ^5.1.0 => 5.2.0 
    webpack-cli: ^6.0.1 => 6.0.1 
  Global Packages:
    webpack-cli: 6.0.1
    webpack: 5.103.0

Is this a regression?

None

Last Working Version

No response

Additional Context

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions