ElMassimo / vite_ruby

โšก๏ธ Vite.js in Ruby, bringing joy to your JavaScript experience
https://vite-ruby.netlify.app/
MIT License
1.28k stars 117 forks source link

Incorrectly Skipping vite build when run assets:precompile #483

Closed luca-peruzzo closed 1 month ago

luca-peruzzo commented 1 month ago

Description ๐Ÿ“–

When running RAILS_ENV=production VITE_RUBY_SSR_BUILD_ENABLED=true bundle exec rake assets:precompile only the vite client build is executed. the ssr build skips with this message: Skipping vite build. Watched files have not changed since the last build at <timestamp>

Vite Ruby Info ``` bin/vite present?: true vite_ruby: 3.6.0 vite_rails: 3.0.17 rails: 7.1.3.4 node: v20.11.1 npm: 10.2.4 yarn: 4.3.1 pnpm: Usage Error: This project is configured to use yarn $ pnpm ... ruby: ruby 3.3.4 (2024-07-09 revision be1089c8ec) [arm64-darwin23] installed packages: app@ /Users/luca.peruzzo/RubymineProjects/react-on-rails โ”œโ”€โ”ฌ @vitejs/plugin-react@4.3.1 โ”‚ โ””โ”€โ”€ vite@5.3.4 deduped โ”œโ”€โ”ฌ vite-plugin-rails@0.5.0 โ”‚ โ”œโ”€โ”ฌ vite-plugin-environment@1.1.3 โ”‚ โ”‚ โ””โ”€โ”€ vite@5.3.4 deduped โ”‚ โ”œโ”€โ”€ vite-plugin-ruby@5.0.0 deduped โ”‚ โ””โ”€โ”€ vite@5.3.4 deduped โ”œโ”€โ”ฌ vite-plugin-ruby@5.0.0 โ”‚ โ””โ”€โ”€ vite@5.3.4 deduped โ””โ”€โ”€ vite@5.3.4 ```
Output `RAILS_ENV=production VITE_RUBY_SSR_BUILD_ENABLED=true DEBUG=vite-plugin-ruby:* bundle exec rake assets:precompile` ``` โžค YN0000: ยท Yarn 4.3.1 โžค YN0000: โ”Œ Resolution step โžค YN0000: โ”” Completed โžค YN0000: โ”Œ Post-resolution validation โžค YN0002: โ”‚ app@workspace:. doesn't provide postcss (pdac39), requested by autoprefixer and other dependencies. โžค YN0086: โ”‚ Some peer dependencies are incorrectly met by your project; run yarn explain peer-requirements for details, where is the six-letter p-prefixed code. โžค YN0086: โ”‚ Some peer dependencies are incorrectly met by dependencies; run yarn explain peer-requirements for details. โžค YN0000: โ”” Completed โžค YN0000: โ”Œ Fetch step โžค YN0000: โ”” Completed โžค YN0000: โ”Œ Link step โžค YN0000: โ”” Completed โžค YN0000: ยท Done with warnings in 0s 330ms Building with Vite โšก๏ธ vite v5.3.4 building for production... transforming... โœ“ 197 modules transformed. rendering chunks... computing gzip size... ../../public/vite/.vite/manifest-assets.json 0.00 kB โ”‚ gzip: 0.02 kB ../../public/vite/.vite/manifest.json 0.56 kB โ”‚ gzip: 0.23 kB ../../public/vite/assets/style-BWAtuwdv.css 6.42 kB โ”‚ gzip: 1.50 kB ../../public/vite/assets/index-DNSjbp0Q.js 8.93 kB โ”‚ gzip: 3.90 kB โ”‚ map: 16.19 kB ../../public/vite/assets/application-DCxYrTNW.js 268.49 kB โ”‚ gzip: 90.71 kB โ”‚ map: 858.84 kB โœ“ built in 1.30s Build with Vite complete: /Users/luca.peruzzo/RubymineProjects/react-on-rails/public/vite 2024-07-21T15:06:39.458Z vite-plugin-ruby:config { base: '/vite/', build: { emptyOutDir: false, sourcemap: true, cssCodeSplit: false, rollupOptions: { input: [Object], output: [Object] }, assetsDir: 'assets', manifest: true, outDir: '../../public/vite' }, envDir: '/Users/luca.peruzzo/RubymineProjects/react-on-rails', root: '/Users/luca.peruzzo/RubymineProjects/react-on-rails/app/frontend', server: { fs: { allow: [Array], strict: true }, host: 'localhost', https: false, port: 3036, strictPort: true, hmr: { host: 'localhost', protocol: 'ws', clientPort: 3036 } }, entrypoints: { 'entrypoints/application.scss': '/Users/luca.peruzzo/RubymineProjects/react-on-rails/app/frontend/entrypoints/application.scss', 'entrypoints/application.tsx': '/Users/luca.peruzzo/RubymineProjects/react-on-rails/app/frontend/entrypoints/application.tsx' } } 2024-07-21T15:06:40.320Z vite-plugin-ruby:assets-manifest { manifest: Map(0) {}, fileName: '.vite/manifest-assets.json' } Skipping vite build. Watched files have not changed since the last build at 2024-07-21 16:43:05 ```
luca-peruzzo commented 1 month ago

it happens also when running bin/vite build --ssr manually after the production build: Skipping vite build. Watched files have not changed since the last build at 2024-07-21 16:43:05`

ElMassimo commented 1 month ago

Hi Luca!

The SSR build uses a different file to track whether the last build is stale or not.

Running a non-SSR build should not affect that check.

To confirm whether this is a bug or not, I'd appreciate if you could provide a repo with a minimal reproduction, demonstrating the problem.

luca-peruzzo commented 1 month ago

I will as soon as possible!

luca-peruzzo commented 1 month ago

@ElMassimo I have noticed that it only occurs when at least one build has been performed. Step to reproduce:

also deleting public/vite-dev causes the issue:

I think it is a systematic problem, so you can try with your demo repo. If you can't reproduce it i will give you access to my test repo

luca-peruzzo commented 1 month ago

@ElMassimo I checked your code and I see that the cache is stored in tmp/cache/vite. Therefore, when a user deletes the output folder, the system cannot know if it should invalidate the cache. I'll try to add this functionality if you agree

ElMassimo commented 1 month ago

The described replication steps fall within what I consider to be incorrect configuration.

Ensuring a proper strategy for managing buildCacheDir in a way that's consistent with how the publicOutputDir is managed, is up to the user.


This library provides a vite:clobber task to use when intending to remove all previous builds, which will also clear buildCacheDir.

luca-peruzzo commented 1 month ago

"This library provides a vite:clobber task to use when intending to remove all previous builds, which will also clear buildCacheDir."

yes but you can easily track if the build output exists. something like:

   def build_output_exists?(ssr:)
    if ssr
      Dir.exist? config.ssr_output_dir
    else
      Dir.exist? config.build_output_dir
    end
  end

and

 def build(*args)
    last_build = last_build_metadata(ssr: args.include?('--ssr'))

    if args.delete('--force') || last_build.stale? || config.manifest_paths.empty? || !build_output_exists?(ssr: args.include?('--ssr'))
      stdout, stderr, status = build_with_vite(*args)
      log_build_result(stdout, stderr, status)
      record_build_metadata(last_build, errors: stderr, success: status.success?)
      status.success?
    elsif last_build.success
      logger.debug "Skipping vite build. Watched files have not changed since the last build at #{ last_build.timestamp }"
      true
    else
      logger.error "Skipping vite build. Watched files have not changed since the build failed at #{ last_build.timestamp } โŒ"
      false
    end
  end

I've done this modification locally and it works. if you agree I can reopen the pull request