1

How can I extract the CSS from a compiled JS file into my own application.css? I want to detail this question by using an example:

Using Webpack 4, Rails webpacker and Vue.js I have built a SPA. I have added the external Vue component Vue-infinite-loading. This component offers a dist JS file I've added:

In application.js:

import InfiniteLoading from 'vue-infinite-loading'

This JS includes the CSS and adds the styles into the <head> tag. I'm looking for a way to avoid this in production env. I want to move the CSS to my own application.css file (generated by Webpack).

enter image description here

I found the following (bad) solution:

The external component uses LESS, which I don't use in my project. But if I add LESS to my project, I can use the source files of the component and use MiniCssExtractPlugin to extract the styles:

In application.js:

import InfiniteLoading from 'vue-infinite-loading/src/index'

In environment.js:

....
const isProduction = process.env.NODE_ENV === 'production'
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
environment.loaders.append('less', {
  test: /\.less$/,
  use: [
    isProduction ? MiniCssExtractPlugin.loader : 'style-loader',
    'css-loader',
    'less-loader'
  ],
})
....

But adding LESS to my project only to extract styles from an external component seems not right to me. Is there a better way?

It is possible to extract styles from a JS file?

Georg Ledermann
  • 2,712
  • 4
  • 31
  • 35
  • 1
    You can extract css with this plugin without using LESS https://github.com/webpack-contrib/mini-css-extract-plugin – Dominic Oct 22 '18 at 12:12
  • If you `import InfiniteLoading from 'vue-infinite-loading'` you shouldn't need to do anything else since the distribution package would have already compiled all it needs. However if you're including from the `src` then you're including from the source code and not from the distribution package. You shouldn't do that unless you're 100% certain that it's what you need to be doing – apokryfos Oct 22 '18 at 12:25
  • @apokryfos: If I use the compiled distribution package this adds styles to the HEAD tag in production which I don't want. Importing the source code from the component is a workaround I found (which I actually want to avoid). – Georg Ledermann Oct 22 '18 at 13:23
  • Trying to use a 3rd party package in a way the authors did not intend is just one big headache. Try finding an alternative package instead. It's probably a better solution in this case. – apokryfos Oct 22 '18 at 13:49

1 Answers1

0

You don't need to add less to extract your css.

const isProduction = process.env.NODE_ENV === 'production'
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
environment.loaders.append('css', {
  test: /\.css$/,
  use: [
    isProduction ? MiniCssExtractPlugin.loader : 'style-loader',
    'css-loader',
  ],
})
PlayMa256
  • 6,603
  • 2
  • 34
  • 54
  • Hm, this didn't work, the styles are still added to the HEAD tag in production. Maybe because it's not the CSS files in src, but the CSS from within the external component (living in node_modules/vue-infinitive-loading/dist/vue-infinite-loading.js). Is it possible to extract styles from there? – Georg Ledermann Oct 22 '18 at 13:20
  • It is always extracted from there. If it still in the head of the page, style-loader is still being applied. Make sure that isProduction is true (try to debugg, see what you are receiving) – PlayMa256 Oct 22 '18 at 13:37
  • Thanks! I found that the CSS is coming from a SingleFileComponent (.vue) inside the component, so vue-loader is involved. I will check this out... – Georg Ledermann Oct 22 '18 at 14:47