Skip to content
This repository was archived by the owner on Feb 10, 2025. It is now read-only.

cloudflare adapter breaks rollupOptions output filenames #334

Closed
1 task
mschoeffmann opened this issue Jul 20, 2024 · 20 comments
Closed
1 task

cloudflare adapter breaks rollupOptions output filenames #334

mschoeffmann opened this issue Jul 20, 2024 · 20 comments
Assignees
Labels
needs triage Issue needs to be triaged

Comments

@mschoeffmann
Copy link

mschoeffmann commented Jul 20, 2024

Astro Info

Astro                    v4.12.2
Node                     v20.14.0
System                   macOS (arm64)
Package Manager          pnpm
Output                   hybrid
Adapter                  @astrojs/cloudflare
Integrations             @astrojs/mdx
                         @astrojs/sitemap

If this issue only occurs in one browser, which browser is a problem?

No response

Describe the Bug

Using rollupOptions like entryFileNames, chunkFileNames and assetFileNames for reasons (withastro/astro#7469, withastro/astro#8549, withastro/astro#5787, ...) moves the files from ./dist folder to ./dist/_render.js which results in 404 after deploying.

      rollupOptions: {
        output: {
          entryFileNames: '_static/entry.[hash].js',
          chunkFileNames: '_static/chunk.[hash].js',
          assetFileNames: '_static/asset.[hash][extname]',
        },
      },

check out the min. reproduction stackblitz and run the command npm run build first with the above config, and second with the above lines commented out. there it only affects the .css file but on larger projects it affects all bundled chunks and assets.

not working: css is _worker.js subfolder:
Screenshot 2024-07-20 at 02 35 00

working without output filename config: css is in _astro subfolder:
Screenshot 2024-07-20 at 02 35 45

What's the expected result?

bundled files in ./_static as configured. works without adapter and 'static' output mode.

Link to Minimal Reproducible Example

https://stackblitz.com/edit/github-tzkvup?file=src%2Flayouts%2FLayout.astro%2Castro.config.mjs&on=stackblitz

Participation

  • I am willing to submit a pull request for this issue.

Changes: edited screenshot annotations and fixed issue links

@github-actions github-actions bot added the needs triage Issue needs to be triaged label Jul 20, 2024
@bluwy bluwy transferred this issue from withastro/astro Jul 22, 2024
@alexanderniebuhr alexanderniebuhr added pkg: cloudflare - P4: important Violate documented behavior or significantly improves performance (priority) and removed needs triage Issue needs to be triaged labels Jul 22, 2024
@alexanderniebuhr alexanderniebuhr self-assigned this Jul 22, 2024
@alexanderniebuhr alexanderniebuhr added needs response and removed - P4: important Violate documented behavior or significantly improves performance (priority) labels Jul 22, 2024
@alexanderniebuhr
Copy link
Member

@mschoeffmann Thank you for the report. Is this 'dist/_static/chunk.[hash].js' you expected output path?

If so I'm afraid that it won't be supported, since all SSR related files must be under the path 'dist/_worker.js'/

@mschoeffmann
Copy link
Author

@alexanderniebuhr the expected path would be './dist/_static/chunk.[hash].js'.
In the example above, the CSS file is not available for clients because it is in the _worker.js/ subdirectory.
Even without a subdirectory, just changing the filename to chunk.[hash].js like this moves the files to the _worker subdirectory.

@alexanderniebuhr
Copy link
Member

alexanderniebuhr commented Jul 22, 2024

Okay understood. I don't think it would be working with chunks. Only static assets like css, etc.

Also I don't think this is Cloudflare specific, but rather a generic issue, when the option build.client & build.server is used.

I also think their is a different configuration for that, let me see if I can find it.

@mschoeffmann
Copy link
Author

I think the adapter already knows which files belong to the client and which belong to the client. Because without using the output options, all the files are in the right place.

Okay understood. I don't think it would be working with chunks. Only static assets like css, etc.

But right now, also assets are not working. The css file for example lands in _worker.js subdirectory.

@alexanderniebuhr
Copy link
Member

I'll try to see if the same behavior happens with the Node adapter, to see if this is a core issue.

@mschoeffmann
Copy link
Author

Update:
I just tried with the latest @astrojs/vercel, @astrojs/netlify and @astrojs/node ... and the results were equal.

I also tried this with a ready-to-migrate web project and noticed especially .css files and .jpg files were inside the wrong folder.

@mschoeffmann
Copy link
Author

I'll try to see if the same behavior happens with the Node adapter, to see if this is a core issue.

Hahaha - coincidence - just done... #334 (comment)

@matthewp
Copy link
Contributor

It's pretty unlikely that this is going to work. Netlify and Vercel need files to be in special folders for their deployment. It's not really configurable.

@alexanderniebuhr
Copy link
Member

The node adapter has the same issue when using build.server & build.client: https://stackblitz.com/edit/github-tzkvup-oqmfkz?file=astro.config.mjs

@alexanderniebuhr alexanderniebuhr added needs triage Issue needs to be triaged and removed pkg: cloudflare labels Jul 22, 2024
@alexanderniebuhr
Copy link
Member

@mschoeffmann Any reason why you can't use https://docs.astro.build/en/reference/configuration-reference/#buildassets to change the name of _astro, for the static assets?

@matthewp
Copy link
Contributor

Overriding vite in your config applies to the server-side and client-side code. I think you only want client-side. So using the build.assets config option like @alexanderniebuhr suggested, or using the astro:build:setup hook to set options only for client-side builds is the way to go: https://docs.astro.build/en/reference/integrations-reference/#astrobuildsetup

@mschoeffmann
Copy link
Author

@matthewp Yes, true.
But I'm not trying to change the whole platform-specific paths.

My goal is to:

  1. remove confusing filenames like 404.[hash].css or about-us.[hash].css for globals styles (see links below or initial issue)
  2. put all static assets inside https://example.com/_static/ instead of https://example.com/_astro/

Links about the filenames:

Thanks for the quick response @matthewp and @alexanderniebuhr.
I'll try the mentioned workarounds and follow up in a few minutes ...

@matthewp
Copy link
Contributor

It's not really a workaround, those are the methods of adjusting output filenames for client-side code. vite is global configuration. Let us know if it works out!

@alexanderniebuhr
Copy link
Member

alexanderniebuhr commented Jul 22, 2024

Yeah I guess for "2." build.assets: "_static" is the correct way :)

@mschoeffmann
Copy link
Author

@matthewp yep - sorry :-)

I wrote a quick integration to test this:

export const genericClientFilenames = () => {
  let integration = {
    name: 'generic-client-filenames',
    hooks: {
      'astro:build:setup': ({ vite, target }) => {
        if (target === 'client') {
          console.log(vite.build.rollupOptions.output)
          vite.build.rollupOptions.output.entryFileNames =
            '_static-CLIENT/entry.[hash].js'
          vite.build.rollupOptions.output.chunkFileNames =
            '_static-CLIENT/chunk.[hash].js'
          vite.build.rollupOptions.output.assetFileNames =
            '_static-CLIENT/asset.[hash][extname]'
          console.log(vite.build.rollupOptions.output)
        }
        if (target === 'server') {
          console.log(vite.build.rollupOptions.output)
          //// COMMENTED OUT BECAUSE ENTRY AND CHUNK FOR SERVER BUILD ARE GENERATED ON THE FLY BY FUNCTIONS --->
          // vite.build.rollupOptions.output.entryFileNames =
          //   '_static/entry.[hash].js'
          // vite.build.rollupOptions.output.chunkFileNames =
          //   '_static/chunk.[hash].js'
          //// COMMENTED OUT BECAUSE ENTRY AND CHUNK FOR SERVER BUILD ARE GENERATED ON THE FLY BY FUNCTIONS ---<
          vite.build.rollupOptions.output.assetFileNames =
            '_static-SERVER/asset.[hash][extname]'
          console.log(vite.build.rollupOptions.output)
        }
      },
    },
  }
  return integration
}

export default genericClientFilenames

The result is:

  • _static-CLIENT folder contains the entry.* files > correct
  • _static-CLIENT folder DOES NOT contain the asset.* files > NOT CORRECT
  • _static-SERVER folder does not exist > correct
  • _worker.js/_static-SERVER i guess it is > correct
  • _worker.js/_static-SERVER DOE NOT contain the asset.* files > NOT CORRECT

So for me it looks like the asset files were generated only for server target?

the -client and -server folder suffix as well as the console statements are for better debugging.

@mschoeffmann
Copy link
Author

@mschoeffmann
Copy link
Author

I found a working solution now by overwriting the each *FileNames key of the output object with a function to replace [name] with a string like entry, chunk or asset.
Also I just change the filename so the build.assets option mentioned by @alexanderniebuhr still works.

I'm not sure if this is the best way, and it still looks strange that somehow css assets are generated in "server" target.
But well ¯_(ツ)_/¯

Maybe I'll release an integration package on npm for this one ... Reading the mentioned threads sounds like more people want to get rid of the confusing filenames.

// ./src/integrations/generic-client-filenames.ts

import type { AstroIntegration } from 'astro'
import type { PreRenderedChunk, PreRenderedAsset, OutputOptions } from 'rollup'

export const genericClientFilenames = () => {
  let integration: AstroIntegration = {
    name: 'generic-client-filenames',
    hooks: {
      'astro:build:setup': ({ vite }) => {
        const usedOutputOptions = vite.build.rollupOptions.output as OutputOptions
        const originalOutputOptions = Object.assign(
          {},
          vite.build.rollupOptions.output,
        ) as OutputOptions
        usedOutputOptions.entryFileNames = (chunkInfo: PreRenderedChunk) => {
          const originalNames =
            typeof originalOutputOptions.entryFileNames === 'function'
              ? originalOutputOptions.entryFileNames(chunkInfo)
              : originalOutputOptions.entryFileNames
          return originalNames.replace('[name]', 'entry')
        }
        usedOutputOptions.chunkFileNames = (chunkInfo: PreRenderedChunk) => {
          const originalNames =
            typeof originalOutputOptions.chunkFileNames === 'function'
              ? originalOutputOptions.chunkFileNames(chunkInfo)
              : originalOutputOptions.chunkFileNames
          return originalNames.replace('[name]', 'chunk')
        }
        usedOutputOptions.assetFileNames = (assetInfo: PreRenderedAsset) => {
          const originalNames =
            typeof originalOutputOptions.assetFileNames === 'function'
              ? originalOutputOptions.assetFileNames(assetInfo)
              : originalOutputOptions.assetFileNames
          return originalNames.replace('[name]', 'asset')
        }
      },
    },
  }
  return integration
}

export default genericClientFilenames
// ./astro.config.mjs

import genericClientFilenames from './src/integrations/generic-client-filenames'
...

export default defineConfig({
...
  integrations: [genericClientFilenames()],
  build: {
    assets: '_static',
  },
...
})

@alexanderniebuhr
Copy link
Member

Great to hear you found a way to solve your use-case, I'll close the issue for now.

@alexanderniebuhr alexanderniebuhr closed this as not planned Won't fix, can't repro, duplicate, stale Jul 24, 2024
@mschoeffmann
Copy link
Author

For reference:
I created an integration npm package for this, available from https://www.npmjs.com/package/astro-generic-build-filenames

@alexanderniebuhr
Copy link
Member

That's great. I suggest posting this to the showcase channel in Discord too :)

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
needs triage Issue needs to be triaged
Projects
None yet
Development

No branches or pull requests

3 participants