postcss.config.js 3.47 KB
'use strict';

/**
 * postcss plugins for both dev and pro
 */

const _ = require('lodash');
const path = require('path');
const precss = require('precss');
const cssnano = require('cssnano');
const autoprefixer = require('autoprefixer');
const postSprites = require('postcss-sprites');
const postImport = require('postcss-import');
const postAssets = require('postcss-assets');
const postCalc = require('postcss-calc');
const postUse = require('postcss-use');
const opacity = require('postcss-opacity');
const spritescore = require('postcss-sprites/lib/core');
const config = require('../../package.json');
const devInfo = require('./dev-info.js');
const distDir = path.join(__dirname, `../../dist/statics/${config.name}/${config.version}`);
const dist = {
    img: distDir + '/img',
    font: distDir + '/font'
};

exports.postcssPlugin = (et) => {
    let sprites = {
            spritesmith: {
                padding: 8
            },
            filterBy(file) {
                // base64 的图片没有 url 过滤掉
                if (file.url) {
                    return Promise.resolve();
                }
                return Promise.reject();
            },
            groupBy(file) {
                let dir = _.slice(file.styleFilePath.split(path.sep), -2);
                let group = dir[0];

                file.retina = true;
                file.radio = 2;

                return group ? Promise.resolve(group) : Promise.reject('yoho');
            },
            hooks: {
                onUpdateRule: function(rule, comment, image) {
                    if (et === 'pro') {
                        image.spriteUrl += ('?t=' + new Date().getTime());
                    } else {
                        image.spriteUrl = devInfo.publicPath + image.spriteUrl;
                    }
                    spritescore.updateRule(rule, comment, image);
                }
            }
        },
        assets,
        plugins;

    // assets & sprites config in both dev and pro
    if (et === 'pro') {
        assets = {
            loadPaths: [dist.img, dist.font],
            relativeTo: distDir,
            cachebuster: true
        };

        Object.assign(sprites, {
            basePath: dist.img,
            stylesheetPath: distDir,
            spritePath: dist.img
        });
    } else if (et === 'dev') {
        assets = {
            loadPaths: [path.join(__dirname, '../img/'), path.join(__dirname, '../font/')],
            baseUrl: devInfo.publicPath,
            basePath: 'public/'
        };

        Object.assign(sprites, {
            basePath: path.join(__dirname, '../img/'),
            stylesheetPath: path.join(__dirname, './bundle'),
            spritePath: path.join(__dirname, './bundle')
        });
    }

    plugins = [
        postImport({
            path: [path.join(__dirname, '../scss')],
            resolve(id) {
                let name = path.basename(id);

                if (!/^_/.test(name)) {
                    id = path.dirname(id) + '/_' + name;
                }
                return id;
            }
        }),
        precss(),
        postSprites(sprites),
        postAssets(assets),
        postCalc(),
        autoprefixer({
            browsers: ['> 1%']
        }),
        opacity(),
        postUse({
            modules: ['postcss-clearfix', 'postcss-crip', 'postcss-short', 'postcss-center', 'postcss-position']
        })
    ];

    if (et === 'pro') {
        plugins.push(cssnano({
            safe: true
        }));
    }
    return plugins;
};