-
-
Notifications
You must be signed in to change notification settings - Fork 148
Tree shaking broken in rollup-plugin-vue@next #401
Comments
Hi, i was trying to build a vue-component library using vue 3 and was able to get treeshaking. I have working project at Github. Hope this helps |
Might give it a try...but the repo I posted is pretty vanilla usage. I would assume that something that "just works" with Vue 2 should be able to upgrade to vue3 without jumping through so many hoops and undocumented configuration... |
@shubhadip I took a look at the code in that sample repo. I personally couldn't get it to build, but that is beside the point I wish to make - namely, there is a LOT more in there than the bare minimum. The sample repo I provided is based on the minimum required to get a vue component/library on npm, and asking users of my utility to change so much of how they write components is not feasible. For example, instead of a directory of .vue files, you have several directories, one for each .vue file, and each one of those is imported into its own dedicated index.ts file for registration/export. This is a lot more code to maintain. There are some things you have done which are nice/interesting, but your repo introduces a lot more boilerplate than I think is required. As I indicated, the sample I posted works fine with Vue2, and the differences with Vue3 are so minimal and isolated as to highlight that rollup-plugin-vue is where things start to change in a non-tree-shakeable way. |
Updated to latest 6.0.0 release, and still not fixed. I tinkered with the output a little, and by manually adding the Here's a before and after: // === BEFORE ADJUSTMENTS
var script = /*#__PURE__*/defineComponent({
// component props, setup, etc.
});
const _withId = /*#__PURE__*/withScopeId("data-v-8c4b8c4a");
pushScopeId("data-v-8c4b8c4a");
const _hoisted_1 = { /* createBlock props used below */ };
popScopeId();
const render = /*#__PURE__*/_withId((_ctx, _cache, $props, $setup, $data, $options) => {
return openBlock(), createBlock("div", _hoisted_1, /* more generated render function */);
});
var css_248z = "CSS to inject";
styleInject(css_248z);
script.render = render;
script.__scopeId = "data-v-8c4b8c4a"; // === AFTER ADJUSTMENTS
const _withId = /*#__PURE__*/withScopeId("data-v-8c4b8c4a");
/*#__PURE__*/pushScopeId("data-v-8c4b8c4a");
const _hoisted_1 = { /* createBlock props used below */ };
/*#__PURE__*/popScopeId();
var script = /*#__PURE__*/defineComponent({
// component props, setup, etc.
render: /*#__PURE__*/_withId(function render(_ctx, _cache, $props, $setup, $data, $options) {
return openBlock(), createBlock("div", _hoisted_1, /* more generated render function */);
}),
__scopeId: "data-v-8c4b8c4a"
});
var css_248z = "CSS to inject";
/*#__PURE__*/styleInject(css_248z); Also, worth noting that egoist/rollup-plugin-postcss#293 might be related. As illustrated here, adding the |
This unfortunately entirely breaks tree-shaking of the library, but pending resolution of vuejs/rollup-plugin-vue#401 that's not something we can fix on our end. This takes the approach that working-but-too-big is at least better than not-working-at-all.
Hi, Thanks providing such sample project, but your sample project, every component was bundle to a single file, it's a way to make tree shaking work by file, but tree shaking doesn't work in a specific file, for examle, hello.tsx was bundle to hello.xxx.js in dist/esm, in this file, you export the component, and a function named foo. If a application import foo from lib ONLY, everything in hello.xx.js was bundled, tree shaking broken again. in mgdodge's sample, every component was bundle in a single output, everything was bundle to your application if tree shaking broken. so the difference between you two is the lines of unused code be bundle to your app. your sample produce unused code in specific file, and mgdodge's sample produce all of the lib. |
Any updates on this? I'm still experiencing this issue using 6.0.0. |
For the record, I was able to do tree shaking using the option |
Even though setting Also I've tried a lot of different things and was not able to make scoped css to work, with or without So, not tree shaking neither scoped css are working... Am I doing something wrong? This is my import path from 'path';
import esbuild from 'rollup-plugin-esbuild'
import vue from "rollup-plugin-vue";
import postcss from 'rollup-plugin-postcss';
export default {
input: "src/index.ts",
output: [
{
format: "esm",
dir: "dist",
sourcemap: true,
}
],
plugins: [
vue({
target: "browser",
preprocessStyles: true,
defaultLang: {
style: 'scss',
},
css: false,
}),
postcss({}),
esbuild({
sourceMap: true,
minify: false,
target: 'esnext'
}),
],
external: ['vue', 'vue-class-component'],
} My tsconfig.json: {
"compilerOptions": {
"target": "esnext",
"module": "esnext",
"strict": true,
"jsx": "preserve",
"importHelpers": true,
"moduleResolution": "node",
"experimentalDecorators": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"sourceMap": true,
"baseUrl": ".",
"types": [
"webpack-env",
"jest"
],
"paths": {
"@/*": [
"src/*"
]
},
"lib": [
"esnext",
"dom",
"dom.iterable",
"scripthost"
]
},
"files": [
"./src/shims-vue.d.ts"
],
"include": [
"src/**/*.ts",
"src/**/*.tsx",
"src/**/*.vue",
"tests/**/*.ts",
"tests/**/*.tsx"
],
"exclude": [
"node_modules",
"dist"
]
} |
Will need to reexamine once vuejs/core#2860 lands |
Looked at vuejs/core#2860 and things still look broken - see this comment and the new sample repo mentioned there for details. |
The output produced by vite + @vitejs/plugin-vue is really close to perfect, but still has one bug in it. The output from rollup-plugin-vue is a bit further off, but not by much! Also, it doesn't suffer from the same bug that vite still does. Please take a look at how the For example, here is a before/after of just this logic: // Before change
var script$2 = /*#__PURE__*/defineComponent({
name: 'Cat',
// vue component name
props: {
name: {
type: String,
default: 'Spot'
},
says: {
type: String,
default: 'meow'
}
}
});
function render$2(_ctx, _cache, $props, $setup, $data, $options) {
return openBlock(), createElementBlock("div", {
class: normalizeClass(_ctx.$style.cat)
}, [createElementVNode("p", null, "The cat is named " + toDisplayString(_ctx.name) + ". It says " + toDisplayString(_ctx.says) + ".", 1)], 2);
}
var style0 = {
"cat": "_cat_1c1rs_2"
};
const cssModules = script$2.__cssModules = {};
cssModules["$style"] = style0;
script$2.render = render$2;
// ... later
export { script$2 as Cat }; // After change
var _export_sfc = (sfc, props) => {
for (const [key, val] of props) {
sfc[key] = val;
}
return sfc;
};
var script$2 = /*#__PURE__*/defineComponent({
name: 'Cat',
// vue component name
props: {
name: {
type: String,
default: 'Spot'
},
says: {
type: String,
default: 'meow'
}
}
});
function render$2(_ctx, _cache, $props, $setup, $data, $options) {
return openBlock(), createElementBlock("div", {
class: normalizeClass(_ctx.$style.cat)
}, [createElementVNode("p", null, "The cat is named " + toDisplayString(_ctx.name) + ". It says " + toDisplayString(_ctx.says) + ".", 1)], 2);
}
var style0 = {
"cat": "_cat_1c1rs_2"
};
/* Attach css and render function to component in a tree-shaking friendly way */
const cssModules = {};
cssModules["$style"] = style0;
var cat = /* @__PURE__ */ _export_sfc(script$2, [["render", render$2], ["__cssModules", cssModules]]);
// ...later
export { cat as Cat }; Of course, the |
Version
6.0.0-beta.10
Reproduction link
https://github.com/mgdodge/rollup-plugin-vue-treeshake-bug-vue3
Steps to reproduce
Vue 3 tree-shaking bug
This repo has two branches - one written in Vue 2, one in Vue 3. The components and logic involved are identical (a simple diff of the branches will illustrate this). The only differences are in the dependencies introduced by Vue itself, using
defineComponent
in Vue 3 instead ofVue.extend
for Vue 2, and the inclusion of postCSS for processing the css (required for vue3).Reproducing the bug
Setup
Vue 2
branchnpm install
followed bynpm run build
andnpm pack
to create.tgz
that can be used in external projects. Rename that file todemolib-vue2.tgz
Vue 3
branch and repeat last step, renaming file todemolib-vue3.tgz
.tgz
files from the prior stepsUsage
Load 2 of the 3 components provided by the library. Components are
Cat
,Dog
, andFish
.Verify tree-shaking
Execute
npm run build
in each cli project. The resulting "optimized" javascript files will include achunk-vendors
file which should include a tree-shaken version of demolib. Search this file for the following strings:If tree-shaking worked, you should not see
The fish is named
anywhere in the output. In the Vue 2 version, tree-shaking works properly. In the Vue 3 version, the unused code is still included.What is expected?
Code output should be tree-shakeable
What is actually happening?
Code is not tree-shakeable
As an alternative to creating an entirely new cli project to test, I have used the npm package "agadoo" as a quick test in the past. On the vue 2 version of this repo, it fails with only one small warning (which has a pending PR to fix here). On the vue 3 version, the failure description is much larger, indicating a lot more issues. Using the cli is more accurate, of course, but is much more involved.
This bug was discovered while preparing the vue 3 compatible version of vue-sfc-rollup. As the reporter of another tree-shaking bug in rollup-plugin-vue (resolved) it is something I checked on.
The text was updated successfully, but these errors were encountered: