Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Extract vuetify styles to css file

I'm doing a proof of concept to include vuetify in an existing web app that is already partially using vue.

I'm have a concern with CSP, by default all vuetify styles are pushed in inline <style> tags. I don't want to allow style-src 'unsafe-inline' in my CSP.

So far there is 95 inline style tags inserted by vuetify in the <head>section. I did tried the option to put an nonce like described here, but the nonce is only added on the last tag, so still 94 to go. Moreover, I don't have a solid solution to generate nonces, so I'd prefer not relying on this.

Generating a hash for each tag is of course not realist.

I also saw this answer, but I don't think it apply to my context, I'm not server-side renderring.

I am using webpack 4.41.2, vue 2.6.10, vuetify 2.2.8.

Here are some extracts of config files. webpack.js

const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const VueLoaderPlugin = require('vue-loader/lib/plugin');
const VuetifyLoaderPlugin = require('vuetify-loader/lib/plugin');

[...]

et entryPoints = Object.assign([...], { vendor: ['vue', 'vue-router', 'axios', 'vue-i18n', 'lodash', 'interactjs'] });

var config = {
   entry: entryPoints,
   output: {
      path: __dirname,
      filename: 'module/[name].js'
   },
   [...]

   plugins: [
      new MiniCssExtractPlugin({ filename: 'module/[name].css', chunkFilename: 'module/[name].css' }),
      new VueLoaderPlugin(),
      new VuetifyLoaderPlugin()
   ],

   optimization: {
      splitChunks: {
         cacheGroups: {
            commons: {
               test: /[\\/]node_modules[\\/]/,
               name: 'vendor',
               chunks: 'all'
            }
         }
      },
      runtimeChunk: { name: 'manifest' }
   }
};

Initialisation file

import Vue from 'vue';

import Vuetify from 'vuetify/lib';
import 'vuetify/dist/vuetify.min.css';

[...]

Vue.use(Vuetify);
const vuetifyOptions = new Vuetify();

// Création de l'instance Vue.js, qui sera dessiner dans l'element définit par l'attribut el
window.Vue = new Vue({
   el: '#app',
   render: h => h(App),
   vuetify: vuetifyOptions
});

like image 433
Johnny5 Avatar asked Feb 07 '20 14:02

Johnny5


1 Answers

I finally found the solution, I was already importing MiniCssExtractPlugin, but used it with less module, but I had to add it to sass module also, used by vuetify.

         {
            test: /\.s(c|a)ss$/,
            use: [
               'vue-style-loader',
               MiniCssExtractPlugin.loader, // <-- that line
               'css-loader',
               {
                  loader: 'sass-loader',
                  // Requires sass-loader@^8.0.0
                  options: {
                     implementation: require('sass'),
                     sassOptions: {
                        fiber: require('fibers'),
                        indentedSyntax: true // optional
                     }
                  }
               }
            ]
         }
like image 130
Johnny5 Avatar answered Sep 23 '22 12:09

Johnny5