Skip to content
This repository was archived by the owner on Jan 18, 2022. It is now read-only.

change imported stylesheet not trigger recompiling #286

Open
yfxie opened this issue Jun 7, 2019 · 7 comments
Open

change imported stylesheet not trigger recompiling #286

yfxie opened this issue Jun 7, 2019 · 7 comments

Comments

@yfxie
Copy link

yfxie commented Jun 7, 2019

Version

5.0.0

Steps to reproduce

  1. create a component with <style lang="scss">
  2. import another stylesheet via @import './another-stylesheet';
  3. run rollup with minimal config and watch mode
  4. change the styles in another-stylesheet

What is expected?

recompile the style

What is actually happening?

do nothing


change the styles in style block can trigger recompiling but didn't work for its dependencies(stylesheet imported in style block)

@yfxie yfxie changed the title changed imported stylesheet not trigger recompiling change imported stylesheet not trigger recompiling Jun 7, 2019
@TomCaserta
Copy link

TomCaserta commented Jun 13, 2019

Also doesn't work for external style files using <style src='X' />. Seems to be because this plugin doesn't call this.addWatchFile to notify rollup that theres a dependency on another file.

Get's a bit tricky as this plugin utilises vue compiler utils which actually performs the style compilation (instead of deferring to rollup) and therefore it has no idea what style files import other style files so it can't tell rollup what files to watch.

@morficus
Copy link

morficus commented Sep 3, 2019

I belie this is related to #268

@wbern
Copy link

wbern commented Jun 15, 2020

Because of my inexperience with rollup, my workarounds in previous posts were not perfect, so I deleted those posts to not bloat this issue. I did arrive at a pretty good solution in in the end however, at cost of variable performance.

This work-around is a rollup plugin which seems to patch up most issues, but I've imposed my own limitations on it to not drain performance too much, which I'll explain further down.

rollup-plugin-vue-scss-watcher-glob.js

import globby from 'globby'
import fs from 'fs'
import path from 'path'

export default (globPatterns, globbyOptions) =>
  process.env.ROLLUP_WATCH
    ? {
        async buildStart() {
          let filePaths = await globby(globPatterns, globbyOptions)

          filePaths.forEach((filePath) => {
            this.addWatchFile(filePath)
          })
        },
        async transform(code, file) {
          if (file.includes(".vue")) {
            let potentialStylefileName = path.join(
              path.dirname(file),
              path.basename(file, ".vue") + ".scss"
            )
            const exists = await new Promise((resolve) => {
              fs.access(potentialStylefileName, (err) => resolve(!err))
            })
            if (exists) {
              this.addWatchFile(potentialStylefileName)
            }
          }
        }
      }
    : {}

rollup.config.js

import vueScssWatcher from './rollup-plugin-vue-scss-watcher-glob'
import { RushConfiguration } from '@microsoft/rush-lib/lib/api/RushConfiguration'

const { projects } = RushConfiguration.loadFromDefaultLocation()

const config= {
  ...
  plugins: [
    /* to fix rebuilds not happening issues with scss files referenced from vue files */
    vueScssWatcher(
      projects.map((project) => project.projectFolder + '/src/**/*.scss')
    ),

This rollup plugin will watch Vue-referenced .scss files for changes (the transform method), if the .scss file has the same name as the .Vue file. You can fix that to be more broad, but be wary of performance issues. The drawback of only using the transform method is that it won't watch scss files that you modify that your "main" scss file depends on.

That's why I added "onBuildStart" hook, which will watch all scss files inside all "src" directories in my org's monorepo. You can modify that however you want, it's just the globby pattern exposed to the rollup.config.js. Initially I had some logic to prevent watching files that I had already done this.addWatchFile() on, but rollup seems to prune those watched files by itself, so I removed all that caching logic.

Combining these two seems to trigger changes in all relevant scss files, as well as Vue files.

@znck znck added this to the Zero Issues milestone Oct 22, 2020
@vladiiliev
Copy link

Hey, is there any progress on this? Because we face the same issue :(

@wbern
Copy link

wbern commented Oct 2, 2021

@vladiiliev did you try the above workaround?

@vladiiliev
Copy link

vladiiliev commented Oct 3, 2021

Yes, and unfortunately it doesn't work completely (for us). The *.scss files are added to the queue with the watched files, but the code changes are not reflected in the output bundle.
But our case is a little different. We have scss partials that are imported into the scss of the component. For example:

// ExampleComponent.scss
@import '../../assets/scss/variables.scss';

.example-component-container {
    padding: 40px;
    background-color: brown;
    color: $var-2;
}
// assets/scss/variables.scss
$var-1: red;
$var-2: brown;

The changes in the file variables.scss are watched, but as I already mentioned there is no change in the output bundle.

@vladiiliev
Copy link

I created a plugin to cover the functionality we need. Successfully watches scss partials added with @import.

https://www.npmjs.com/package/rollup-plugin-watcher

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

No branches or pull requests

6 participants