How to compile SCSS to CSS and load the CSS code as string into a variable? **Solved**



  • Hi,

    I am building a SPA with Quasar in which I need to be able to:

    • Load the contents of a CSS file into a JS variable (or Vue data property) at runtime
    • This CSS file should be produced at build time from a SCSS file

    I don’t want to load a pre-made CSS file, I want to be able to author the CSS code via SASS.
    I also don’t want to compile the CSS from SCSS at runtime, e.g. on every app load.

    In other words I have the following workflow in mind:

    • Author the CSS in a pre-defined SCSS file that is part of my project structure
    • At build time (or at run-dev time) I want that this SCSS is compiled into a CSS file
    • Then at runtime, in one of my Vue components, I want to load the previously produced CSS code as string into a variable

    The reasoning for that is that this CSS code will then be fed into and iframe (via postMessage-ing) and the iframe will use CSSStyleSheet’s insertRule() to apply the styles to the page.

    How should I configure my project and packages (I am using Vue, actually Quasar) so that this can happen. One thing that I found already is that I might need to use the raw-loader but how do I prepare the CSS file when building the project so that the raw-loader can get it at runtime?



  • I have found the following solution:

    1. Install the “raw-loader” loader
    2. Import the SCSS using the following statement:

    import style from '!raw-loader!sass-loader!./my-styles.scss'

    Note: the “!” at the beginning is to override the default loaders configuration. In my case Quasar chains the “style-loader” for SCSS files by default (to output a tag in the head) so I have to disable it in this case.

    And now I have the compiled CSS code in the  style  variable.

    Update: After adding the above import statement, my ESLint complained that I shouldn’t use the import syntax to configure webpack loaders (more details why: https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-webpack-loader-syntax.md). So I removed the import statement and added this code to my quasar.conf.js:

    build: {
      // ...
      extendWebpack (cfg) {
        // ...
        const ruleIndex = cfg.module.rules.findIndex(rule => rule.test.toString() === '/\\.scss$/')
        cfg.module.rules[ruleIndex].oneOf.unshift({
          test: /my-styles\.scss$/,
          use: [
            'raw-loader',
            {
              loader: 'postcss-loader',
              options: {
                plugins: [
                  require('autoprefixer')
                ]
              }
            },
            'sass-loader'
          ]
        })
        // ...
      }
      // ...
    }
    

    Note that in this case I have also added the postcss-loader with the autoprefixer plugin as I wanted my CSS to be enriched with vendor prefixes.



  • @ddenev cool find. (moving to tips)

    p.s. can mark it as solved?



  • @metalsadman - sure, go ahead 🙂



  • An update to the solution has been added above


Log in to reply