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:
- Install the “raw-loader” loader
- 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