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

npm run generate should not always generate a new entry file. #25133

Closed
4 tasks done
kaokei opened this issue Jan 10, 2024 · 14 comments
Closed
4 tasks done

npm run generate should not always generate a new entry file. #25133

kaokei opened this issue Jan 10, 2024 · 14 comments

Comments

@kaokei
Copy link

kaokei commented Jan 10, 2024

Describe the feature

I have already written a demo that allows for a quick examination of the issue.

The current issue is as follows:
When I run the npm run generate command, it generates not only about.js and index.js but also an additional entry.js. Initially, I thought that entry.js was the vendor file, and I expected that when I didn't modify the dependencies in node_modules, this entry.js file would remain unchanged. However, in reality, every time I modify the content of any file in pages/index.vue or pages/about.vue, npm run generate creates a new entry.js. Since other JS files depend on entry.js, this ultimately leads to the regeneration of all JS files.

The desired outcome is:
The entry.js file should remain stable and not change constantly. The ultimate goal is that modifying a page in the pages directory should not impact the build output of other pages.


我已经写好一个demo,可以快速查看现象。

目前的现象是:
当我运行npm run generate命令时,除了生成了about.jsindex.js以外,还生成了一个entry.js
我本以为这个entry.js就是vendor文件,我理解当我没有修改node_modules依赖时,这个entry.js文件应该是不会有变化的。
但实际上,我修改pages/index.vue或者pages/about.vue中任意一个文件的内容时,npm run generate都会重新生成一个新的entry.js,又因为其他js文件都是依赖于entry.js文件,最终导致所有js文件都重新生成了。

期待的效果是:
entry.js文件应该是稳定的,不应该总是变化。
最终目标是当我修改pages目录中某一个页面时,不应该影响到其他页面的构建产出。

Additional information

  • Would you be willing to help implement this feature?
  • Could this feature be implemented as a module?

Final checks

Copy link

stackblitz bot commented Jan 10, 2024

Fix this issue in StackBlitz Codeflow Start a new pull request in StackBlitz Codeflow.

@Parakoos
Copy link

You don't even need to change anything. Just run 'npm run generate' two times in a row. To really illustrate the problem, I copied the resulting .output/public folders for two consecutive runs and then compared them using WinMerge.

image

As you can see, even though nothing has changed content-wise, every single .js file under build has changed. Why? Take a look at the difference between the two page1.<hash>.js files:

image

OK, we see here that every page (and every component as it turns out) has changed because they all rely on the file name of the entry.<hash>.js file. So, why did it change? Because the buildId changed, and it is hard-coded into entry.js

image

I found this issue when I realized that with every new release, I had to download every Vuetify component, again. Loads of data! I first thought it was a problem with Vuetify, but I tracked it down to this buildId and entry.js. I can't guarantee that I haven't missed something basic here, but I wanted to give a full report of what I found on this topic.

@toto6038
Copy link
Contributor

Just want to suggest that there's a typo in the issue's title, it should be npm run generate.

@kaokei kaokei changed the title npm run generage should not always generate a new entry file. npm run generate should not always generate a new entry file. Jan 12, 2024
@kaokei
Copy link
Author

kaokei commented Jan 19, 2024

@manniL

It seems that the priority of this issue is not very high. If possible, I can try to fix this problem. My solution is to migrate the buildId from appConfig to nuxtConfig.

  1. The nuxt config represents the configuration during the build, and buildId fits the semantics perfectly.
  2. The nuxt config will be directly inlined into HTML. This means that each time the project is built, a new HTML file will be generated without creating a new entry.js file. This aligns perfectly with the requirements.

看起来这个问题的优先级不是很高,如果可以的话,我可以尝试修复这个问题。
我的解决方案是把buildId从appConfig中迁移到nuxtConfig中。

  1. nuxt config代表构建时的配置,而buildId正好符合语义。
  2. nuxt config会直接内联到html中,这样每次构建项目只会生成新的html文件,而不会新生成entry.js文件,这正好符合需求。

@xuyifeiOnly
Copy link

这个就算是在nuxt.config.js中配置也不行,entry 还是会生成新的hash,导致组件也会改变,这个有啥解决方式吗?
image

@kaokei
Copy link
Author

kaokei commented Jan 31, 2024

@xuyifeiOnly 你是怎么配置的?我的理解是目前nuxt还不支持这个功能呢。我的解决方案说是要把buildId从appConfig中迁移到nuxtConfig中,实际意思是指要提交pr去修改nuxt的构建逻辑。我估计改动还不小。

@xuyifeiOnly
Copy link

@kaokei
image
wo我尝试着重写了output,但是因为entry.js每次都发生改变,所以导致每次还是都会产生新的文件

@kaokei
Copy link
Author

kaokei commented Feb 1, 2024

@xuyifeiOnly 当然了,entry.js的内容中包含了buildId,这个buildId是一个随机生成的字符串。所以每次构建都会产生一个新的buildId,这样就导致entry.js的文件内容发生了变化,既然内容都变化了,entry.js的hash肯定会变化。
所以这个问题不是能通过配置能解决的,需要修改nuxt本身的构建逻辑。

@xuyifeiOnly
Copy link

@kaokei 这个看起来只能等官方解决了

@ranedk
Copy link

ranedk commented Feb 9, 2024

There is a bug/issue in bundling done by Rollup, (hence Vite and hence Nuxt) because of which even if the buildId is not random, it still generates different hashes.

You can try this with the following:

export default defineNuxtConfig({
  appConfig: {
    nuxt: {
      buildId: '1',
    },
  },
....

With this, if you run nuxt generate multiple times, it wont change the hash .
You can just grep for buildId after and before to see that the random.UUID buildId is gone now.

However, for my and everyone's bad luck, it still doesn't work and with a small change, all hashes change again.

Why? Because of the Vite bug/issue discussed here:

vitejs/vite#6773

This has to be a P1. Why will anyone choose Nuxt/Vite/Rollup if Caching performance is so badly hit. In my case I am working on a PWA. So all customers have to download the entire build again for a small typo change.

@ranedk
Copy link

ranedk commented Feb 10, 2024

This works perfectly for me.

export default defineNuxtConfig({
  appConfig: {
    nuxt: {
      buildId: '1',
    },
  },
  vite: {
    build: {
      rollupOptions: {
        output: {
          entryFileNames: '_nuxt/[name].js',
        },
      },
    },
  },
...

Hash is changed only for the file where changes are made (and if that is included in other files)

@jsvini
Copy link

jsvini commented Apr 5, 2024

This works perfectly for me.

export default defineNuxtConfig({
  appConfig: {
    nuxt: {
      buildId: '1',
    },
  },
  vite: {
    build: {
      rollupOptions: {
        output: {
          entryFileNames: '_nuxt/[name].js',
        },
      },
    },
  },
...

Hash is changed only for the file where changes are made (and if that is included in other files)

this saved me, just upgraded from nuxt 3.6 to 3.11 and multiple instances of the same app stopped working because the file hash for the CDN version of entry.js won't match the version in the app instances, even though they are built from the exact same source code.

@gherkster
Copy link

This works perfectly for me.

export default defineNuxtConfig({
  appConfig: {
    nuxt: {
      buildId: '1',
    },
  },
  vite: {
    build: {
      rollupOptions: {
        output: {
          entryFileNames: '_nuxt/[name].js',
        },
      },
    },
  },
...

Hash is changed only for the file where changes are made (and if that is included in other files)

For me at least this seems to cause stale cache issues. That entry file includes __vite__mapDeps which references all the generated chunks, and in my case the client had cached that entry.js so it was referencing all the old chunks with their old hashes, not the updated ones

@danielroe danielroe self-assigned this May 22, 2024
@danielroe
Copy link
Member

This should be resolved in the nightly release, or in the next release.

Let me know if not and I'll reopen.

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

No branches or pull requests

9 participants