Webpack 3 Sass cssnano Autoprefixer Workflow II

Sass

Install the loaders to preprocess the Sass files.

SASS Loader compiles Sass to CSS, also requires node-sass.

npm install --save-dev sass-loader node-sass

PostCSS Loader processes CSS with PostCSS.

npm install --save-dev postcss-loader

CSS Loader resolves import at-rules and url functions in the CSS.

npm install --save-dev css-loader

Style Loader inlines <style></style> in the DOM.

npm install --save-dev style-loader

URL Loader and Resolve URL Loader handle relative paths. For example, slick-theme Sass fonts and images.

npm install --save-dev url-loader resolve-url-loader

Extract Text Plugin

In this first example, extract the CSS from the Webpack bundle into a style.css file with the Extract Text Plugin.

npm install --save-dev extract-text-webpack-plugin

In the constants block at the top of the Webpack configuration, require the extract-text-webpack-plugin.

webpack.config.js
...
const ExtractTextPlugin = require('extract-text-webpack-plugin')

Define Plugin & Loaders

Update the module.exports to process the Sass (.scss) and extract into the style.css file.

Since loaders act like functions, order them from bottom to top. For example, css-loader(postcss-loader(sass-loader(resource)))

webpack.config.js
...
module.exports = {
context: path.resolve(__dirname, './src'),
    entry: {
    app: './js/index.js'
    },
    output: {
    path: path.resolve(__dirname, './dist'),
    publicPath: '/dist/',
    filename: '[name].js'
    },
    module: {
    rules: [
    {
        test: /\.(css|scss)$/,
        use: ExtractTextPlugin.extract({
        fallback: 'style-loader',
        use: [
            {
            loader: 'css-loader',
            options: {
                minimize: true || {/* CSSNano Options */}
            }
            },
            {
            loader: 'postcss-loader'
            },
            {
            /* for ~slick-carousel/slick/slick-theme.scss */
            loader: 'resolve-url-loader'
            },
            {
            /* for resolve-url-loader:
                source maps must be enabled on any preceding loader */
            loader: 'sass-loader?sourceMap'
            }
        ]
        })
    },
    {
        test: /\.js$/,
        exclude: /node_modules/,
        use: 'babel-loader'
    },
    { /* for ~slick-carousel/slick/slick-theme.scss */
        test: /\.(eot|woff|woff2|ttf|svg|png|jpg|gif)$/,
        loader: 'url-loader?limit=30000&name=[name]-[hash].[ext]'
    }
    ]
    },
    plugins: [
    new ExtractTextPlugin('style.css')
    ],
    devtool: '#eval-source-map'
}

To output the style.css file into the project root, use new ExtractTextPlugin('../style.css') for the plugins configuration. This is useful when developing WordPress themes.

Autoprefixer

Autoprefixer evaluates the CSS and adds or removes vendor prefixes such as -webkit and -moz using caniuse.com data.

Install the autoprefixer PostCSS plugin.

npm install --save-dev autoprefixer

In the package.json file, add a browserslist configuration that lists minimum browser support for autoprefixer.

package.json
{
    "name": "project",
    "version": "1.0.0",
    "description": "",
    "main": "index.js",
    "browserslist": [
    "> 1%",
    "ie > 9"
    ],
    ...
}

Create a PostCSS configuration module in the project root for requiring the autoprefixer plugin.

postcss.config.js
module.exports = {
    plugins: [
    require('autoprefixer')
    ]
}

Add Some Sass & Build

Create these .scss files in the src/sass/modules folder.

Pretty self expalnatory, this Sass partial is for common or global styles.

_common.scss
body {
    font-family: Verdana,"Helvetica Neue","Helvetica","Arial",sans-serif;
}

img { // responsive
    max-width: 100%;
    height: auto;
}

The leading underscore in the filename denotes that the file is a Sass partial and therefore will only be processed if imported.

This Sass partial imports the slick carousel styles that were installed and provides a few tweaks to the slider.

_slider.scss
/* node_modules */
@import "~slick-carousel/slick/slick.scss";
@import "~slick-carousel/slick/slick-theme.scss";

.slider {
    li {
    text-align: center;
    }
    img { // center
    margin: auto;
    }

    .slick-next,
    .slick-prev {
    &:before {
        color: #000;
    }
    }

    .slick-next {
    right: 0;
    }
    .slick-prev {
    left: 0;
    }
}

Create an entry point main.scss file in the src/sass folder.

main.scss
@import 'modules/common';
@import 'modules/slider';

Here is how the project is structured at this point.

  • project
    • .babelrc
    • index.html
    • package.json
    • postcss.config.js
    • webpack.config.js
    • src
      • js
        • index.js
      • sass
        • main.scss
        • modules
          • _common.scss
          • _slider.scss

Run the build.

npm run build

Refresh the browser to verify.

  • http-server a simple command-line server I use for testing and local development.
Source Code
comments powered by Disqus