J.BizMai
J.BizMai

Reputation: 2787

Compile several (sass|css) files into multiple css output with Webpack 4

I have a WP Theme project. I´m using Webpack 4 to compile sass files and merge them with css.

project structure

dev
|_ my-theme
   |_css
   | |_common
   | | |_main.sass
   | | |_normalize.css
   | |_home
   |   |_home.sass
   |_style.sass

I would like to do compile like this:

  1. dist/my-theme/style.css = style.sass include normalize.css and main.sass in the right order

  2. dist/my-theme/css/home/home.css = home.sass

For the moment I managed to do a unique output with the first point. I saw there is a solution with extract-text-webpack-plugin but it´s deprecated with Webpack 4 so I´m using mini-css-extract-plugin but I have got no idea how doing this.

my current webpack.config.js

const PLUGIN_DIR_NAME = "mytheme";
const GENERAL_CONFIG_INI = "../config/config.ini";
const THEME_CONFIG_INI = "./config/config.ini";

const path = require('path');
const Promise = require('bluebird');
const fs = Promise.promisifyAll( require('fs') );
const ini = require('ini');
// include the css extraction and minification plugins
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CopyPlugin = require('copy-webpack-plugin');
const {CleanWebpackPlugin} = require('clean-webpack-plugin');

module.exports = env => {
    const global_config = ini.parse( fs.readFileSync( GENERAL_CONFIG_INI, 'utf-8' ) );
    const theme_config = ini.parse( fs.readFileSync( THEME_CONFIG_INI, 'utf-8' ) );

    var a_author_uri = global_config.author_uri.split(":");
    var author_protocol = a_author_uri[0];
    var author_uri_without_protocol = a_author_uri[1].replace( "//", "" );
    var a_author_uri_domain = author_uri_without_protocol.split(".");
    var author_uri_domain_name, author_uri_extension;
    if( a_author_uri_domain.length === 3 ){
        author_uri_domain_name = a_author_uri_domain[1];
        author_uri_extension = a_author_uri_domain[2];
    }else if( a_author_uri_domain.length === 2 ){
        author_uri_domain_name = a_author_uri_domain[0];
        author_uri_extension = a_author_uri_domain[1];
    }
    var a_prev_theme_version = theme_config.theme_infos.version.split(".");
    var prev_major_theme_version = parseInt( a_prev_theme_version[0] );
    var prev_minor_theme_version = parseInt( a_prev_theme_version[1] );
    var prev_patch_theme_version = parseInt( a_prev_theme_version[2] );
    var prev_build_theme_version = parseInt( a_prev_theme_version[3] );
    var next_build_theme_version, next_patch_theme_version, next_minor_theme_version, next_major_theme_version;
    if( env.version === "build" ){
        next_build_theme_version = prev_build_theme_version + 1;
        next_patch_theme_version = prev_patch_theme_version;
        next_minor_theme_version = prev_minor_theme_version;
        next_major_theme_version = prev_major_theme_version;
    }else if( env.version === "patch" ){
        next_build_theme_version = 0;
        next_patch_theme_version = prev_patch_theme_version + 1;
        next_minor_theme_version = prev_minor_theme_version;
        next_major_theme_version = prev_major_theme_version;
    }else if( env.version === "minor" ){
        next_build_theme_version = 0;
        next_patch_theme_version = 0;
        next_minor_theme_version = prev_minor_theme_version + 1;
        next_major_theme_version = prev_major_theme_version;
    }else if( env.version === "major" ){
        next_build_theme_version = 0;
        next_patch_theme_version = 0;
        next_minor_theme_version = 0;
        next_major_theme_version = prev_major_theme_version + 1;
    }
    theme_config.theme_infos.version = next_major_theme_version + "." + next_minor_theme_version + "." + next_patch_theme_version + "." + next_build_theme_version;
    fs.writeFileSync( THEME_CONFIG_INI, ini.stringify( theme_config, {} ) );

    return{
        plugins: [
            new CleanWebpackPlugin(),
            // extract css into dedicated file
            new MiniCssExtractPlugin({
                filename: './' + PLUGIN_DIR_NAME + '/style.css'
            }),
            //Only copy php files
            new CopyPlugin([
                {
                    from: 'dev',
                    ignore: ['*.sass', 'next/css/common/**/*.css'],
                },
            ])
        ],
        entry: [ './dev/' + PLUGIN_DIR_NAME + '/style.sass', './dev/' + PLUGIN_DIR_NAME + '/css/common/normalize.css', './dev/' + PLUGIN_DIR_NAME + '/css/common/main.sass' ],
        output: {
            path: path.resolve(__dirname, 'dist/'),
        },
        module: {
            rules: [
                // compile all .scss files to plain old css
                {
                    test: [/css\/common\/.*\.(css|sass)$/],
                    use: [{loader: MiniCssExtractPlugin.loader},
                        {loader: 'css-loader'},
                        {
                            loader: 'sass-loader',
                            options: {
                                prependData: '$theme-name: ' + theme_config.theme_infos.name +
                                    ';$author:' + global_config.author +
                                    ';$author-uri-protocol:' + author_protocol +
                                    ';$author-uri-domain:' + author_uri_domain_name +
                                    ';$author-uri-extension:' + author_uri_extension +
                                    ';$description:' + theme_config.theme_infos.description.replace(/:/g, "%3A").replace(/;/g, "%3B") + ';' +
                                    ';$version-major:' + next_major_theme_version + ';' +
                                    ';$version-minor:' + next_minor_theme_version + ';' +
                                    ';$version-patch:' + next_patch_theme_version + ';' +
                                    ';$version-build:' + next_build_theme_version + ';',
                            }
                        }
                    ]
                }
            ]
        }
    }
};

Upvotes: 1

Views: 2656

Answers (1)

J.BizMai
J.BizMai

Reputation: 2787

I found a solution using MiniCssExtractPlugin. The solution was here.

Basicaly you can change the json array as entry value with an object.

before

entry: [ './dev/' + PLUGIN_DIR_NAME + '/style.sass', './dev/' + PLUGIN_DIR_NAME + '/css/common/normalize.css', './dev/' + PLUGIN_DIR_NAME + '/css/common/main.sass' ],

after

entry:{
    style: [ './dev/' + PLUGIN_DIR_NAME + '/style.sass', './dev/' + PLUGIN_DIR_NAME + '/css/common/normalize.css', './dev/' + PLUGIN_DIR_NAME + '/css/common/main.sass' ],
    home: [ './dev/' + PLUGIN_DIR_NAME + '/css/home/home.sass' ]
},

If you want that one of css files is inside a subdirectory like css/home.css :

entry:{
    style: [ './dev/' + PLUGIN_DIR_NAME + '/style.sass', './dev/' + PLUGIN_DIR_NAME + '/css/common/normalize.css', './dev/' + PLUGIN_DIR_NAME + '/css/common/main.sass' ],
    'css/home': [ './dev/' + PLUGIN_DIR_NAME + '/css/home/home.sass' ]
},

Upvotes: 3

Related Questions