Open JiatLn opened 2 years ago
What is the problem here?
I think the problem is the weird output (comp.vue_vue_type_script_setup_true_lang.[hash].js
) instead of [name].[hash].js
.
The name is generated by rollup from id(comp.vue?vue&type=script&setup=true&lang.js
).
We could treat vue files specially and replace the filename in generateBundle
hook. But I don't think this causes any problem.
It's probably not a problem, except the cause is unknown. I did not have a problem in any of my other Vite 3 + Vue 3 projects. I haven't made many, but not sure what's happening here. Here's how my chunks
folder looks:
My Vite config:
import {defineConfig} from 'vite'
import vue from '@vitejs/plugin-vue'
export default defineConfig({
build: {
rollupOptions: {
output: {
assetFileNames: 'assets/[name].[ext]',
chunkFileNames: 'chunks/[name].js',
entryFileNames: 'entries/[name].js'
}
},
sourcemap: true,
target: 'esnext'
}
})
Note that, badge
is the only file from my components
folder that's ending up like that:
while all the other chunks are from my pages
directory:
I know this is not really useful without me actually providing a reproduction (as I've said, this doesn't always happen), but providing a reproduction is most likely going to be tough. If someone has some pointers on what to check (try to add/edit) to avoid this, that would be great!
Note that, the badge
component is nothing fancy. It's a super simple component which is using defineProps
, computed
and is one of my smallest components. button
for example is a bit complex than that - with various states and props, it goes about 200 lines. So, I don't think "complexity" of the component is an issue (not sure if it ever was), but that's my only guess.
It's probably not a problem, except the cause is unknown. I did not have a problem in any of my other Vite 3 + Vue 3 projects. I haven't made many, but not sure what's happening here. Here's how my
chunks
folder looks:My Vite config:
import {defineConfig} from 'vite' import vue from '@vitejs/plugin-vue' export default defineConfig({ build: { rollupOptions: { output: { assetFileNames: 'assets/[name].[ext]', chunkFileNames: 'chunks/[name].js', entryFileNames: 'entries/[name].js' } }, sourcemap: true, target: 'esnext' } })
Note that,
badge
is the only file from mycomponents
folder that's ending up like that:while all the other chunks are from my
pages
directory:I know this is not really useful without me actually providing a reproduction (as I've said, this doesn't always happen), but providing a reproduction is most likely going to be tough. If someone has some pointers on what to check (try to add/edit) to avoid this, that would be great!
Note that, the
badge
component is nothing fancy. It's a super simple component which is usingdefineProps
,computed
and is one of my smallest components.button
for example is a bit complex than that - with various states and props, it goes about 200 lines. So, I don't think "complexity" of the component is an issue (not sure if it ever was), but that's my only guess.
I have a guess that it will happen when the component had use to many times.
Thank you for your message!
I have a guess that it will happen when the component had use to many times.
I don't think it's being used too many times, but even if that's the case, it still doesn't explain the weird name that component is getting while others are working as expected.
I have the same problem!
// package.json
{
"name": "demo-components",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vue-tsc --noEmit && vite build",
"preview": "vite preview"
},
"dependencies": {
"vue": "^3.2.37"
},
"devDependencies": {
"@vitejs/plugin-vue": "^3.1.0",
"typescript": "^4.6.4",
"vite": "^3.1.0",
"vue-tsc": "^0.40.4"
}
}
// vite.config.ts
import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
// https://vitejs.dev/config/
export default defineConfig({
build: {
lib: {
entry: "./src/components/index.ts",
formats: ["cjs"],
name: "components",
},
rollupOptions: {
external: ["vue"],
output: [
{
dir: "dist/components",
format: "cjs",
entryFileNames: "[name].js",
preserveModules: true,
preserveModulesRoot: "components",
},
],
},
},
plugins: [vue()],
});
I'm also seeing the same thing:
...
dist/assets/dates.32565151.js
dist/assets/ConfirmationButton.vue_vue_type_script_setup_true_lang.db3c1ab5.js
dist/assets/SubtleSortToggleButton.vue_vue_type_script_setup_true_lang.d7615288.js
dist/assets/index.350ee0b4.css
...
Also FWIW.. those components also seem to be MASSIVE compared to what they actually are. That SubtleSortToggleButton is 146.95 KiB. It's a <button>
with some css toggling
When I inspect the minified js it also seems to include a lot of stuff that I wasn't expecting.
@JiatLn 's affected FillBlankTextarea is also significantly larger than the others
@robokozo are you using any images, fonts, other kinds of assets? All assets are inlined into the JS/CSS files if you build in lib mode, so the generated JS/CSS files can get huge.
@jonaskuske its a normal vue app. I can show the details tomorrow but the file is a relatively simple. It's a button that uses different classes based on a Boolean. I believe it only has 1 dependency on a file with interface definitions.
i have the same problem ,not all the file,and not found any reason
Still seems to happen with Vite 4. It's always the same files that have this problem. So, there must be some kind of a consistency, not sure what though.
Have the same issue. I've noticed in my case that if the the component is traversed multiple times by the bundler then it produces one file with correct name which in turn references to the weird name file.
I have the same problem! I used the plugin 'vite-plugin-multi-pages' to support multi page application. The currently generated assets are
.
├── assets
│ ├── css
│ │ ├── [componentA].css
│ │ ├── [componentB].css
│ │ ├── main.css
│ │ ├── page1
│ │ │ └── index.css
│ │ ├── page2
│ │ │ └── index.css
│ │ └── page3
│ │ └── index.css
├── favicon.ico
├── js
│ ├── common
│ │ ├── [componentA].vue_vue_type_script_setup_true_lang.js
│ │ ├── [componentB].vue_vue_type_script_setup_true_lang.js
│ │ └── main.js
│ ├── page1.js
│ ├── page2.js
│ └── page3.js
├── page1.html
├── page2.html
└── page3.html
what i expect is
.
├── assets
│ ├── css
│ │ ├── main.css
│ │ ├── page1
│ │ │ └── index.css
│ │ ├── page2
│ │ │ └── index.css
│ │ └── page3
│ │ └── index.css
├── favicon.ico
├── js
│ ├── common
│ │ └── main.js
│ ├── page1.js
│ ├── page2.js
│ └── page3.js
├── page1.html
├── page2.html
└── page3.html
The code in [componentA].vue_vue_type_script_setup_true_lang.js is a common code and has nothing to do with [componentA].
The css in [componentA].css is a common css and has nothing to do with [componentA].
for me the files with that cryptic name showed up after using import statements in async loaded components
I have this exact same issue - and it does cause a problem when you deploy the built site. When I run vite build
I get output like this:
dist/index.html 1.00 kB
dist/assets/NewJob-d9a4925b.css 0.08 kB │ gzip: 0.10 kB
dist/assets/index-dc13f7c7.css 237.30 kB │ gzip: 33.05 kB
dist/assets/JobManager-8867603d.js 0.06 kB │ gzip: 0.08 kB
dist/assets/NewJobList-6fcb2b4f.js 0.06 kB │ gzip: 0.08 kB
dist/assets/_...all_-9d958754.js 0.16 kB │ gzip: 0.16 kB
dist/assets/index-95d5fcd6.js 0.47 kB │ gzip: 0.29 kB
dist/assets/_name_-11e79e2a.js 0.49 kB │ gzip: 0.34 kB
dist/assets/Support-48cf7069.js 0.50 kB │ gzip: 0.40 kB
dist/assets/BackButton.vue_vue_type_script_setup_true_generic_T%20extends%20any%2C%20O%20extends%20any_lang-3d94f20b.js 0.63 kB │ gzip: 0.43 kB
dist/assets/Login-7e5c89a2.js 0.63 kB │ gzip: 0.39 kB
This only affects one of my components. The component where this happens is very simple - only 11 lines long, and produces a reasonably sized asset file, who's contents look reasonable - it's just the filename is weird. This is the component:
<!-- Copyright 2023, Blah Inc. All Rights Reserved. -->
<script setup lang="ts" generic="T extends any, O extends any">
const router = useRouter()
</script>
<template>
<button type="button" class="btn btn-secondary" @click="router.back()">
<i-tabler-arrow-left inline-block mt--4px /> Back
</button>
</template>
It looks like the first line of the components script is being slugified and used as part of the filename?
What that means is that most of these files are blah-hash.js
- i.e. they have a .js
(or .css
) extension - but the super long one effectively has a file extension of .vue_vue_type_script_setup_true_generic_T%20extends%20any%2C%20O%20extends%20any_lang-3d94f20b.js
.
This causes Nginx to serve that file with text/html
Content-Type - which causes the browser to not load the module:
Failed to load module script: Expected a JavaScript module script but the server responded with a MIME type of "text/html". Strict MIME type checking is enforced for module scripts per HTML spec.
index-d3622a25.js:9
I am currently fixing this up manually after the build by doing:
$ cd .\dist\assets\
$ sd '.vue_vue_type_script_setup_true_generic_T%20extends%20any%2C%20O%20extends%20any_lang' '' $(fd --type file)
$ mv BackButton.vue_vue_type_script_setup_true_generic_T%20extends%20any%2C%20O%20extends%20any_lang-3d94f20b.js BackButton-3d94f20b.js
That works, but it's obviously not ideal.
Great, now there are two of them.
Confirmed that this happens when running vite build
on both Windows 10 and Ubuntu 20.04.5 LTS (Focal Fossa).
This PowerShell script will fixup the build output, correcting this issue after a build has been run on Windows:
Write-Output "Running Post build fixes..."
$pattern = '.vue_vue_type_script_setup_true_lang'
$path = '.\dist\assets'
# Search & replace pattern inside all .js files
Get-ChildItem -Path "$path\*.js" -Recurse | ForEach-Object {
(Get-Content $_ | ForEach-Object {$_ -replace $pattern, ''}) | Set-Content $_
}
# Remove pattern from filesnames
Get-ChildItem -Path $path -Recurse -Filter "*$pattern*" | ForEach-Object {
Rename-Item $_.FullName -NewName ($_ -replace $pattern)
}
This shell script will do the same on Linux:
echo "Running Post build fixes..."
pattern='\.vue_vue_type_script_setup_true_lang'
path='./dist/assets'
cd $path
# Remove pattern only in files which contain it
# sd --string-mode "$pattern" '' $(fd "$pattern" --type file)
files=$(grep -r --files-with-matches $pattern | sort | uniq) && echo $files | xargs sed -i 's/'"$pattern"'//g'
# Remove pattern from filesnames
find . -path "*$pattern*" -type f | perl -pe 'print $_; s/(.*)'"$pattern"'(.*)/$1$2/' | xargs -d "\n" -n2 mv
You can then add this to your build in package,json like this:
"scripts": {
"build": "vite build && powershell ./post-build.ps1",
}
Or, if you need the build to work on either Windows or Linux, you can install https://github.com/charlesguse/run-script-os, then do this:
"scripts": {
"build": "vite build && run-script-os",
"build:windows": "powershell ./post-build.ps1",
"build:nix": "./post-build.sh",
}
I also have this same issue :(. Seems to be for shared components being imported into more than one asynchronously loaded/defined components.
Same here, exactly as @dflock describes, for generic components it will break the app if you have a component with whitespace in the generic
attribute, e.g.:
<script setup lang="ts" generic="T extends any">
...
</script>
@dflock @GideonRoose I created a new issue for that problem as I think it is slightly different and should have a higher priority than this issue: #169
I'm wondering if the other template parameters could be ignored just like generic
? It doesn't seem to break anything for me but it's a little bit annoying.
@sapphi-red Your new issue #169 seems to have been fixed by https://github.com/vuejs/core/issues/8270 - but doesn't fix the whole issue. I can confirm that since I updated to @vitejs/plugin-vue >= 4.2.2, my broken filename seems to have changed from this:
BackButton.vue_vue_type_script_setup_true_generic_T%20extends%20any%2C%20O%20extends%20any_lang-3d94f20b.js
to this:
BackButton.vue_vue_type_script_setup_true_lang-2a2f9473.js
... but this will still break the site when deployed, because NGINX still thinks the file extension is .vue_vue_type_script_setup_true_lang-2a2f9473.js
, not .js
EDIT: I was wrong, see below.
I believe nginx would work with that file name. In past, Vite was using a file name like foo.12345.js
and we didn't get any reports like that.
I finally got around to testing this out properly end-to-end - and I stand corrected! The components with the long filenames are served up as expected as application/javascript
, so everything works and I can remove my workarounds!
Thanks!
I had the same problem and can confirm that it is related to component imports (what @chris-upmind mentioned above). I'm asynchronously importing several components in a file and I had one of the components also imported inside those async components. Whenever I ran build phase the component got .vue_vue_type_script_setup_true_lang.[hash].js
appended to it's filename. After I removed the double-imported component from the async import list everything was working as intended.
Since there is no actual code output or bundling issue in Vite or this plugin and the problem is purely aesthetic, you can avoid names like that by using this simple function in your Vite config (compatible with Vite 4):
rollupOptions: {
output: {
chunkFileNames: (assetInfo) => {
if (assetInfo.name?.endsWith('.vue_vue_type_style_index_0_lang')) {
return `assets/${assetInfo.name.slice(0, -32)}-[hash:8].js`
} else if (assetInfo.name?.endsWith('.vue_vue_type_script_setup_true_lang')) {
return `assets/${assetInfo.name.slice(0, -36)}-[hash:8].js`
} else {
return 'assets/[name]-[hash:8].js'
}
}
}
}
This change will only affect the file name - file contents remain the same and, as mentioned above, will include any external libraries that your component and no other component in the application relies on.
Is there a way without rollup options? it breaks, for example vite-plugin-compressin
Now there is still this problem, I wrote a project to reproduce it. https://github.com/exidot/vitepluginvue-iss19-reproduce
Now there is still this problem, I wrote a project to reproduce it. https://github.com/exidot/vitepluginvue-iss19-reproduce
Sorry, my conclusion was wrong, and I did not find a pattern in which it occurred !
i'm having this issue too, it happens when component imported twice or more in project and this genrates too big files importing full css from main component and js
Same issue here. It seems to get triggered by something. It did seem to trigger on components that are imported more then once (which is weird in itself since that is the whole idea in a component based project).
For us it also seems to try and import a lot of other components that are not even related to the component. It generates a 51kb file with a lot of imports not even used in the source file.
Could it be an issue with Vue/Async/Suspense and Vite?
Now there is still this problem, I wrote a project to reproduce it. https://github.com/exidot/vitepluginvue-iss19-reproduce
Sorry, my conclusion was wrong, and I did not find a pattern in which it occurred !
Same problem occurs with vite 5.0. and vue js 3.4. tested with these packages:
"@types/node": "^18.19.3",
"@vitejs/plugin-vue": "^4.5.2",
"typescript": "~5.3.0",
"vite": "^5.0.10",
"vue-tsc": "^1.8.25"
Is the issue still on?
My temporary solution is (similar to @thexeos):
chunkFileNames: (assetInfo: { name: string }) => {
const name =
assetInfo.name.endsWith(".vue_vue_type_style_index_0_lang") ||
assetInfo.name.endsWith(".vue_vue_type_script_setup_true_lang") ?
assetInfo.name.split(".")[0] : assetInfo.name;
return `assets/js/${name}-[hash].js`;
}
Is this definitely a vite-plugin-vue
issue or could it a Vite problem?
Describe the bug
when i npm run build, i got a output file name like [component].vue_vue_type_script_setup_true_lang.[hash].js
Reproduction
https://github.com/JiatLn/vite-build-demo.git
System Info
Used Package Manager
yarn
Logs
No response
Validations