0

I have been trying to use webpack for my project. I have successfully got webpack to compile all of my js into one file correctly. But what i need is for it to also get the css. All of my css is in one file so i figured it would be easy but i cant figure it out. I have tried to split it up into 2 phases CSS_CONFIG and JS_CONFIG

const path = require('path');
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
const TerserPlugin = require("terser-webpack-plugin");


var JS_CONFIG = {
  entry: path.join(__dirname, 'src/js/main.js'),
  resolve: {
    alias: {
      '/components': path.resolve(__dirname, 'src/components/'),
      '/js': path.resolve(__dirname, 'src/js/'),
      '/views': path.resolve(__dirname, 'src/views/'),
    },
  },
  optimization: {
    minimizer: [
      // For webpack@5 you can use the `...` syntax to extend existing minimizers (i.e. `terser-webpack-plugin`), uncomment the next line
      new TerserPlugin(),
      //new CssMinimizerPlugin(),
    ],
  },
}

var CSS_CONFIG = {
  entry:path.join(__dirname,"src/index.html"),
  module: {
    rules: [
      {
        test: /.s?css$/,
        use: [],
      },
    ],
  },
  optimization: {
    minimize:true,
    minimizer: [
      // For webpack@5 you can use the `...` syntax to extend existing minimizers (i.e. `terser-webpack-plugin`), uncomment the next line
      // `...`,
      
      //new CssMinimizerPlugin(),
    ],
  },
  plugins: [],
}


module.exports = [JS_CONFIG, CSS_CONFIG];

This seems like it should be pretty straightforward with webpack but I must not be grasping somthing. Can anyone help me out?

2 Answers 2

1

I believe that your CSS_CONFIG should look more like this:

const path = require("path"); 
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const RemoveEmptyScriptsPlugin = require('webpack-remove-empty-scripts'); 
const isDevelopment = process.env.NODE_ENV === 'development'

var config = {
  module: {},
}; 

var cssConfig = Object.assign({}, config, {
  devtool: 'source-map',
  entry:  {
    main: path.resolve(__dirname, 'public/css/main.scss'),
    fonts: path.resolve(__dirname, 'public/css/fonts.scss'),
    app: path.resolve(__dirname, 'public/css/app.scss'),
  },
  output: {
    path: path.resolve(__dirname, 'public/css')
  },
  performance: {
    hints: false
  },
  plugins: isDevelopment ? [] : [
      new RemoveEmptyScriptsPlugin(),
        new MiniCssExtractPlugin({
            filename: '[name].css',
            chunkFilename: '[id].css'
        }),
    ],
  module: {
    rules:[
      // Extracts the compiled CSS from the SASS files defined in the entry
      {
        test: /\.scss$/,
        use: isDevelopment ? 
        [
         'style-loader',
          {
            loader: 'css-loader',
            options: { sourceMap: true, importLoaders: 1, modules: false },
          },
          { 
            loader: 'postcss-loader', 
            options: { sourceMap: true } 
          },
          {
            loader: 'resolve-url-loader',
          },
          { 
            loader: 'sass-loader', 
            options: { sourceMap: true } 
          },
        ]
        : [
          {
            loader: MiniCssExtractPlugin.loader,
            options: {
              publicPath: (resourcePath, context) => {
                // publicPath is the relative path of the resource to the context
                // e.g. for ./css/admin/main.css the publicPath will be ../../
                // while for ./css/main.css the publicPath will be ../
                return path.relative(path.dirname(resourcePath), context) + "/";
              },
            },            
          },
          {
            loader: 'css-loader',
            options: {
              importLoaders: 2,
              modules: false,
              url: false,
            },
          },
          { 
            loader: 'postcss-loader', 
            options: 
            { 
              postcssOptions:
              {
                plugins: [
                  require('postcss-import'),
                  require('postcss-url')({
                    url: 'copy',
                    useHash: true,
                    hashOptions: { append: true },
                    assetsPath: path.resolve(__dirname, 'public/assets/')
                  })
                ]
              }
            } 
          },
          {
            loader: 'resolve-url-loader',
          },
          { 
            loader: 'sass-loader', 
            options: { sourceMap: true } 
          },
        ]
      },
      /* you may or may not need this
      {
        test: /\.(woff(2)?|ttf|eot|svg)$/,          
        use: [
          {
            loader: 'file-loader',
            options: {
              name: '[name].[ext]',
              outputPath: 'fonts/',
              esModule: false,
            }
          }
        ]
        
      },
      */      
    ],
  }
});
 
Sign up to request clarification or add additional context in comments.

3 Comments

So using what you showed me is there anyway to simplify this a bit maybe. I only have one css file. and its going to stay like that. I just want it minified and part of the bundle. I also keep running into this error whenever it runs into the @ in my css file for @import url You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loader even with the code above. Can the parser really not read @import url() in css? I didnt think it would be this hard to configure.
You may need to install postcss-url and postcss-import besides postcss itself. If you have just one CSS file - you can remove the unneeded entries in the entry object. Also, it's not clear what do you mean/expect by "css to be part of the bundle" - the output will be one or more minified CSS files, stored in the output folder. They won't be part of a JavaScript file, if that's what you mean by "bundle".
I thank you for your help and time. I have figured out a much simpler way of achieving what I desired.
1

use runs the loaders in order that they are put in the array. So 'style-loader' needs to be executed first. Here is a simple way of achieving the desired result.

const path = require('path');
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
const TerserPlugin = require("terser-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const RemoveEmptyScriptsPlugin = require('webpack-remove-empty-scripts'); 
const isDevelopment = process.env.NODE_ENV === 'development'

var JS_CONFIG = {
  entry:  {
    main: path.resolve(__dirname, 'src/js/main.js'),
    css: path.join(__dirname, 'src/css/main.css'),
  },
  resolve: {
    alias: {
      '/components': path.resolve(__dirname, 'src/components/'),
      '/js': path.resolve(__dirname, 'src/js/'),
      '/views': path.resolve(__dirname, 'src/views/'),
    },
  },
  module: {
    rules:[
      {
        test: /\.css$/,
        use:['style-loader','css-loader']
      },
    ],
  },
}; 

module.exports = [JS_CONFIG];

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.