Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Webpack run both .LESS and .SCSS compilation. Extract text plugin not working on one bundle file

I need to run both LESS and SCSS compilation in the same project output to separate CSS files.

The project was LESS based but now adding SCSS during a transition phase.

I don't want to update webpack for the time being. Webpack runs fine but and generates common.bundle.js file but the CSS is not being extracted from this one bundle.

The other chunks and new SCSS it extracts OK but not the core bundle file (common.bundle.js).

I have tried to change the sequence in webpack.config.js but this is not helping. I see this 'Multiple Instances' as well but can't work it out.

webpack.config.js

const path = require('path');
const webpack = require('webpack');
const CommonsChunkPlugin = require("webpack/lib/optimize/CommonsChunkPlugin");
var ExtractTextPlugin = require("extract-text-webpack-plugin");


module.exports = {
    devtool: "source-map",
    entry: {
        "login.bundle": "./dash/app/login.js",
        "summary.bundle": "./dash/app/summary.js",
        "metrics.bundle": "./dash/app/metrics.js",
        "market_share.bundle": "./dash/app/market_share.js",
        "broker.bundle": "./dash/app/broker.js",
        "event_studies_custom.bundle": "./dash/app/event_studies_custom.js",
        "case_studies.bundle": "./dash/app/case_studies.js",
        "home.bundle": "./dash/app/home.js"
    },
    output: {
        path: __dirname + '/dash/static/js',
        filename: "[name].js"
    },
    module: {
        loaders: [{
            test: require.resolve("jquery"),
            loader: "expose-loader?$!expose-loader?jQuery"
        }, {
            test: /\.css$/,
            loader: ExtractTextPlugin.extract({fallback: "style-loader", use: "css-loader"})
        }, {
            test: /\.less$/,
            loader: ExtractTextPlugin.extract({fallback: "style-loader", use: "css-loader!less-loader"})
        }, {
            test:/\.scss$/,
            use: ExtractTextPlugin.extract({
                fallback: 'style-loader',
                use: ['css-loader?url=false', 'sass-loader']
            })
        }, {
            test: /\.(woff|eot|ttf|svg)(\?\S*)?$/,
            loader: "url-loader?limit=100000"
        }, {
            test: /\.(jpe?g|png|gif|svg)$/i,
            loader: 'url-loader?limit=100000!img-loader'
        }, {
            test: /\.js$/,
            exclude: /node_modules/,
            loader: "babel-loader"
        }]
    },
    plugins: [
        new CommonsChunkPlugin({
            name: ['common'],
            filename: 'common.bundle.js'
        }),
        new ExtractTextPlugin("[name].css")]
};

package.json

{
  "name": "project",
  "version": "1.0.0",
  "description": "project descritption",
  "main": "bundle.js",
  "scripts": {
    "build": "webpack -p",
    "develop": "webpack",
    "watch": "webpack --watch"
  },
  "repository": {
    "type": "git",
    "url": "project.git"
  },
  "author": "me",
  "license": "All Rights Reserved",
  "private": true,
  "devDependencies": {
    "babel-core": "^6.22.1",
    "babel-loader": "^6.2.10",
    "babel-preset-env": "^1.1.8",
    "backbone": "^1.3.3",
    "block-ui": "^2.70.1",
    "css-loader": "^0.28.11",
    "expose-loader": "^0.7.1",
    "extract-text-webpack-plugin": "^2.1.2",
    "file-loader": "^0.9.0",
    "grid-list": "^0.4.1",
    "handlebars": "^4.0.5",
    "highcharts": "5.0.11",
    "img-loader": "^1.3.1",
    "imports-loader": "^0.8.0",
    "jquery": "^3.1.1",
    "jquery-colorbox": "^1.6.4",
    "jquery-ui": "^1.12.1",
    "jquery.mousewheel": "^3.1.9",
    "less": "^2.7.1",
    "less-loader": "^2.2.3",
    "less-plugin-clean-css": "^1.5.1",
    "moment": "^2.17.0",
    "node-sass": "^4.8.3",
    "raven-js": "^3.14.0",
    "sass-loader": "^7.0.1",
    "select2": "^4.0.6-rc.1",
    "style-loader": "^0.20.3",
    "underscore": "^1.8.3",
    "url-loader": "^0.5.7",
    "vis": "4.21.0",
    "webpack": "^2.7.0"
  }
}
like image 387
Kerry7777 Avatar asked Jan 29 '23 06:01

Kerry7777


1 Answers

Yes, your direction is right. You can use extract-text-webpack-plugin for this one. Just define an extractor for each file in resulting bundle and use it in module.rules for a desired rule.

Below is an example of usage of 3 of these extractors for css/scss/less files. One per each file.

(Was created and tested on webpack 4.x)

const ExtractTextPlugin = require('extract-text-webpack-plugin');

// Create extract plugin for each file you want to create in resulting bundle
const extractCSS = new ExtractTextPlugin('output-folder/or/whatever/from-css.css');
const extractLESS = new ExtractTextPlugin('output-folder/or/whatever/from-less.css');
const extractSCSS = new ExtractTextPlugin('output-folder/or/whatever/from-scss.css');

module: {
  rules: [
      // ...
      {
        test: /\.less$/,
        use: extractLESS.extract({
          fallback: 'style-loader',
          use: [
            { loader: 'css-loader', options: { importLoaders: 1 } }, // importLoaders equals to number of loaders in array after this one.
            'less-loader'
          ]
        })
      },
      {
        test: /\.scss$/,
        use: extractSCSS.extract({
          fallback: 'style-loader',
          use: [
            { loader: 'css-loader', options: { importLoaders: 1, url: false } }, // importLoaders equals to number of loaders in array after this one.
            'sass-loader'
          ]
        })
      },
      {
        test: /\.css$/,
        use: extractCSS.extract({
          fallback: 'style-loader',
          use: 'css-loader'
        })
      }
  ],
  plugins: [
    // Include each of "extractors" here. Order is not important
    extractLESS,
    extractSCSS,
    extractCSS,
    // ...
  ]
}

I didn't actually run this example, just took it from my project and updated it to fit your question. So, feel free to leave a comment with a question if something is not working as expected. I'll update my response.

like image 58
coockoo Avatar answered Jan 30 '23 19:01

coockoo