vitejs / vite-plugin-vue

Vite Vue Plugins
MIT License
468 stars 146 forks source link

when i build the vue3 project, i got a output file name like [component].vue_vue_type_script_setup_true_lang.[hash].js #19

Open JiatLn opened 2 years ago

JiatLn commented 2 years ago

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

image

Reproduction

https://github.com/JiatLn/vite-build-demo.git

System Info

System:
    OS: Windows 10 10.0.19042
    CPU: (4) x64 Intel(R) Core(TM) i3-6100 CPU @ 3.70GHz
    Memory: 1.36 GB / 7.88 GB
  Binaries:
    Node: 14.19.0 - E:\software\nodejs\node.EXE
    Yarn: 1.22.18 - E:\software\nodejs\yarn.CMD
    npm: 6.14.16 - E:\software\nodejs\npm.CMD
  Browsers:
    Edge: Spartan (44.19041.1266.0), Chromium (103.0.1264.62)
    Internet Explorer: 11.0.19041.1202

Used Package Manager

yarn

Logs

No response

Validations

sapphi-red commented 2 years ago

What is the problem here?

ydcjeff commented 2 years ago

I think the problem is the weird output (comp.vue_vue_type_script_setup_true_lang.[hash].js) instead of [name].[hash].js.

sapphi-red commented 2 years ago

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.

hrishikesh-k commented 2 years ago

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:

image

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:

image

while all the other chunks are from my pages directory:

image

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.

JiatLn commented 2 years ago

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:

image

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:

image

while all the other chunks are from my pages directory:

image

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.

I have a guess that it will happen when the component had use to many times.

hrishikesh-k commented 2 years ago

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.

BigFrontEnd-China commented 2 years ago

I have the same problem! image image

// 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()],
});
robokozo commented 1 year ago

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

jonaskuske commented 1 year ago

@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.

robokozo commented 1 year ago

@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.

lingdu1234 commented 1 year ago

2022-10-18 184452 i have the same problem ,not all the file,and not found any reason

hrishikesh-k commented 1 year ago

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.

emhamzahazeen commented 1 year ago

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.

woyehenni commented 1 year ago

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].

wrufeger commented 1 year ago

for me the files with that cryptic name showed up after using import statements in async loaded components

dflock commented 1 year ago

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 

So, @sapphi-red & @bluwy - this isn't just a curiosity - this breaks the site when deployed!

dflock commented 1 year ago

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.

dflock commented 1 year ago

Great, now there are two of them.

dflock commented 1 year ago

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",
}
chris-upmind commented 1 year ago

I also have this same issue :(. Seems to be for shared components being imported into more than one asynchronously loaded/defined components.

GideonRoose commented 1 year ago

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>
sapphi-red commented 1 year ago

@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

jfrs commented 1 year ago

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.

dflock commented 1 year ago

@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.

sapphi-red commented 1 year ago

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.

dflock commented 1 year ago

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!

jiikoosol commented 1 year ago

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.

thexeos commented 1 year ago

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.

Vector-Green commented 1 year ago

Is there a way without rollup options? it breaks, for example vite-plugin-compressin

exidot commented 1 year ago

Now there is still this problem, I wrote a project to reproduce it. https://github.com/exidot/vitepluginvue-iss19-reproduce

1

2

3

exidot commented 12 months ago

Now there is still this problem, I wrote a project to reproduce it. https://github.com/exidot/vitepluginvue-iss19-reproduce

1

2

3

Sorry, my conclusion was wrong, and I did not find a pattern in which it occurred !

litvinenkow commented 8 months ago

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

Shuyinsama commented 8 months ago

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?

sinchijackal commented 8 months ago

Now there is still this problem, I wrote a project to reproduce it. https://github.com/exidot/vitepluginvue-iss19-reproduce 1 2 3

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"
babsey commented 5 months ago

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`;
}
jfrs commented 1 month ago

Is this definitely a vite-plugin-vue issue or could it a Vite problem?