Skip to content
This repository was archived by the owner on Jan 18, 2022. It is now read-only.
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

Description

@yfxie

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)

Activity

changed the title [-]changed imported stylesheet not trigger recompiling [/-] [+]change imported stylesheet not trigger recompiling [/+] on Jun 7, 2019
TomCaserta

TomCaserta commented on Jun 13, 2019

@TomCaserta

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

morficus commented on Sep 3, 2019

@morficus

I belie this is related to #268

wbern

wbern commented on Jun 15, 2020

@wbern

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.

added this to the Zero Issues milestone on Oct 22, 2020
vladiiliev

vladiiliev commented on Oct 2, 2021

@vladiiliev

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

wbern

wbern commented on Oct 2, 2021

@wbern

@vladiiliev did you try the above workaround?

vladiiliev

vladiiliev commented on Oct 3, 2021

@vladiiliev

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

vladiiliev commented on Oct 4, 2021

@vladiiliev

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 join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @TomCaserta@morficus@yfxie@znck@vladiiliev

        Issue actions

          change imported stylesheet not trigger recompiling · Issue #286 · vuejs/rollup-plugin-vue