2
votes

I am working on a project with Svelte and Tailwindcss. I use Webpack as my bundle. I obviously use postcss and purgess to reduce the size of my css.

While in development mode, I don't purge anything, it works just fine but when I want to build the project everything breaks.

The tailwind classes I directly use in my template work, they end up in the final css bundle. The custom css I write inside are purged.

postcss.config.js

const purgecss = require('@fullhuman/postcss-purgecss');

const production = process.env.NODE_ENV === 'production';

module.exports = ({ file, options, env }) => ({
  plugins: [
    require('postcss-import'),
    require('postcss-preset-env'),
    require('tailwindcss'),
    require('autoprefixer'),
    production &&
      purgecss({
        content: ['./src/**/*.svelte'],
        defaultExtractor: content => {
          return content.match(/[A-Za-z0-9-_:/]+/g) || [];
        }
      }),
    production && require('cssnano')
  ]
});

webpack.common.js

const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');

const PATHS = require('./paths');

module.exports = {
  entry: {
    app: PATHS.src,
    background: PATHS.src + '/background.js'
  },
  output: {
    path: PATHS.build,
    filename: '[name].js'
  },
  resolve: {
    alias: {
      svelte: PATHS.modules + '/svelte'
    },
    extensions: ['.mjs', '.js', '.svelte'],
    mainFields: ['svelte', 'browser', 'module', 'main']
  },
  module: {
    rules: [
      {
        test: /\.(html|svelte)$/,
        exclude: /node_modules/,
        use: {
          loader: 'svelte-loader',
          options: {
            emitCss: true
          }
        }
      },
      {
        test: /\.(png|jpe?g|gif)$/i,
        use: [
          {
            loader: 'file-loader',
            options: {
              outputPath: 'images',
              name: '[name].[ext]'
            }
          }
        ]
      }
    ]
  },
  plugins: [
    new CleanWebpackPlugin(),
    new CopyWebpackPlugin([
      {
        from: PATHS.public,
        to: PATHS.build
      }
    ]),
    new HtmlWebpackPlugin({
      title: 'Hanzi xiaobai',
      inject: false,
      template: require('html-webpack-template'),
      appMountId: 'root',
      lang: 'en',
      mobile: true
    })
  ]
};

webpack.production.js

const merge = require('webpack-merge');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

const common = require('./webpack.common');

module.exports = merge(common, {
  mode: 'production',
  devtool: 'source-map',
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          {
            loader: MiniCssExtractPlugin.loader
          },
          {
            loader: 'css-loader',
            options: {
              importLoaders: 1
            }
          },
          'postcss-loader'
        ]
      }
    ]
  },
  plugins: [
    new MiniCssExtractPlugin({
      filename: '[name].css'
    })
  ]
});

exemple.svelte

<style type="type/postcss">
  h1 {
    @apply text-gray-200 font-bold uppercase text-2xl antialiased
  }
</style>

<div class="h-48 flex flex-col items-center">
  <h1>Title</h1>
</div>

In this example h-48 flex flex-col items-center are correctly output and applied. But text-gray-200 font-bold uppercase text-2xl antialiased are not.

I tried using svelte-preprocess-postcss and other stuff, but I am more or less tweaking things without a clue about what I am doing.

1

1 Answers

0
votes

This is a guess; but could it be that you need a whitelist prop in the purgecss declaration to protect the svelte generated classes? Something like this....

const purgecss = require('@fullhuman/postcss-purgecss')({
 content: [
   './**/**/*.html',
   './**/**/*.svelte'
 ],

 whitelistPatterns: [/svelte-/],

 defaultExtractor: content => content.match(/[\w-/:]+(?<!:)/g) || []
});