jgoz / esbuild-plugins

My esbuild plugins monorepo
MIT License
40 stars 4 forks source link

Full reloading happening on every change (including css-only changes) #131

Open vccoffey opened 2 months ago

vccoffey commented 2 months ago

My application is doing a full reload on css changes. How can I prevent that?

What version of esbuild will this work with? I'm using "esbuild-envfile-plugin": "^1.0.3", "esbuild-plugin-import-glob": "^0.1.1", "esbuild-sass-plugin": "^3.3.1", "@jgoz/esbuild-plugin-livereload": "^2.1.1",

my esbuild.config.js

/* eslint-disable no-console */

const path = require('path')
const esbuild = require('esbuild')
const esbuildEnvfilePlugin = require('esbuild-envfile-plugin')
const esbuildPluginImportGlob = require('esbuild-plugin-import-glob')
const esbuildPluginSvgr = require('@imacdonald/esbuild-plugin-svgr')
const esbuildSassPlugin = require('esbuild-sass-plugin')
const { livereloadPlugin } = require('@jgoz/esbuild-plugin-livereload')

const isWatchMode = process.argv.includes('--watch')

const onEndPlugin = {
  name: 'on-end',
  setup(build) {
    build.onEnd((result) => {
      if (result.errors.length > 0) {
        console.error('build failed with errors')
        console.log(result.errors)
      } else console.log(`build finished successfully`)
    })
  },
}

const define = {}
for (const k in process.env) {
  if (Object.prototype.hasOwnProperty.call(process.env, k))
    define[`process.env.${k}`] = JSON.stringify(process.env[k])
}

const esbuildConfig = {
  absWorkingDir: path.join(process.cwd(), 'app/javascript'),
  bundle: true,
  entryPoints: ['application.js'],
  loader: { '.png': 'dataurl' },
  metafile: true, // Enable metafile to track dependencies
  outdir: path.join(process.cwd(), 'app/assets/builds'),
  sourcemap: 'linked',
  write: true,
  plugins: [
    esbuildEnvfilePlugin,
    esbuildPluginImportGlob.default(),
    esbuildPluginSvgr(),
    esbuildSassPlugin.sassPlugin(),
    livereloadPlugin({ fullReloadOnCssUpdates: false }),
    onEndPlugin,
  ],
  define,
}

async function buildProject() {
  try {
    if (isWatchMode) {
      console.log('Starting watch mode...')
      const context = await esbuild.context(esbuildConfig)
      await context.watch()
    } else {
      await esbuild.build(esbuildConfig)
      console.log('Build complete.')
    }
  } catch (err) {
    console.error('esbuild.config.js ERROR in buildProject')
    console.error(err)
    process.exit(1)
  }
}

// Execute the build function
buildProject()
jgoz commented 2 months ago

Are the CSS files being included via imports from JS/TS files? If so, esbuild might be invalidating the JS portion of the dependency graph as well as the CSS portion, which would trigger a full page reload.

vccoffey commented 2 months ago

Yes @jgoz that is correct. The css files are imported into .JSX files. Is there a way avoid the JS becoming invalidated? Coupling .scss and .jsx files in this way is a file architecture that we are pretty attached to.