Repository: nuxt/nuxt
File: packages/nuxt/src/components/plugins/islands-transform.ts (TypeScript)

Code before:
}

type ChunkPluginOptions = {
  getComponents: () => Component[]
  buildAssetsDir: string
}

export const ComponentsChunkPlugin = (options: ChunkPluginOptions) => {
  const ids = new Map<string, string>()
  const isDev = useNuxt().options.dev

  const normalizedBuildAssetsDir = options.buildAssetsDir.startsWith('/') ? options.buildAssetsDir.slice(1) : options.buildAssetsDir + '/'
  const finalBuildAssetsDir = normalizedBuildAssetsDir.endsWith('/') ? normalizedBuildAssetsDir : normalizedBuildAssetsDir + '/'
  return {
    client: createUnplugin(() => {
      return {
        name: 'nuxt:components-chunk:client',
        vite: {
          buildStart () {
            const components = options.getComponents().filter(c => c.mode === 'client' || c.mode === 'all')
            for (const component of components) {
              if (component.filePath) {
                if (isDev) {
                  ids.set(component.pascalName, `@fs/${component.filePath}`)
                } else {
                  const componentsContent = readFileSync(component.filePath, 'utf-8')
                  const id = this.emitFile({
                    type: 'chunk',
                    fileName: join(finalBuildAssetsDir, `${kebabCase(component.pascalName)}.${hash(componentsContent)}.mjs`),
                    id: component.filePath,
                    preserveSignature: 'strict',

                  })

                  ids.set(component.pascalName, this.getFileName(id))
                }
              }
            }
          },
          generateBundle (_, bundle) {
            const idSet = new Set(ids.values())
            for (const chunk of Object.values(bundle)) {
              if (chunk.type === 'chunk') {
                if (idSet.has(chunk.fileName)) {
                  chunk.isEntry = false
                }
              }
            }
          },
        },
      }

Review comment (suggestion):
```suggestion
                  const componentsContent = readFileSync((await this.resolve(component.filePath))!.id, 'utf-8')
```

Code after:
  dev: boolean
  getComponents: () => Component[]
}

const COMPONENT_CHUNK_ID = `#build/component-chunk`
const COMPONENT_CHUNK_RESOLVED_ID = '\0nuxt-component-chunk'

export const ComponentsChunkPlugin = (options: ChunkPluginOptions): Plugin[] => {
  const chunkIds = new Map<string, string>()
  const paths = new Map<string, string>()
  return [
    {
      name: 'nuxt:components-chunk:client',
      apply: config => !options.dev && !config.ssr,
      buildStart () {
        for (const c of options.getComponents()) {
          if (!c.filePath || c.mode === 'server') {
            continue
          }
          chunkIds.set(c.pascalName, this.emitFile({
            type: 'chunk',
            name: `${c.pascalName}-chunk.mjs`,
            id: c.filePath,
            preserveSignature: 'strict',
          }))
        }
      },
      generateBundle (_, bundle) {
        const ids = new Set<string>()
        for (const [name, id] of chunkIds.entries()) {
          const filename = this.getFileName(id)
          ids.add(filename)
          paths.set(name, filename)
        }
        for (const chunk of Object.values(bundle)) {
          if (chunk.type === 'chunk') {
            if (ids.has(chunk.fileName)) {
              chunk.isEntry = false
            }
          }
        }
      },
    },
    {
      name: 'nuxt:components-chunk:server',
      resolveId: {
        order: 'pre',
        handler (id) {
          if (id === COMPONENT_CHUNK_ID) {
            return COMPONENT_CHUNK_RESOLVED_ID
          }