Home > Mobile >  How to bundle and minimize JS and CSS files with webpack
How to bundle and minimize JS and CSS files with webpack

Time:04-15

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?

CodePudding user response:

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,
            }
          }
        ]
        
      },
      */      
    ],
  }
});
 

CodePudding user response:

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];
  • Related