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

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

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 postPxtorem = require('postcss-pxtorem');
const postUse = require('postcss-use');
const spritescore = require('postcss-sprites/lib/core');
const config = require('../package.json');
const devInfo = require('./dev-info.js');
const distDir = path.join(__dirname, `../public/dist/${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 group = file.url.split('/')[1];
                let entry = path.basename(file.styleFilePath);

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

                if (group) {
                    group = entry + '.' + group;
                }
                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, '../public/img/'), path.join(__dirname, '../public/font/')],
            baseUrl: devInfo.publicPath,
            basePath: 'public/'
        };

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

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

                if (!/^_/.test(name)) {
                    id = path.dirname(id) + '/_' + name;
                }
                return id;
            }
        }),
        precss(),
        postSprites(sprites),
        postAssets(assets),
        postCalc(),
        postPxtorem({
            rootValue: 40,
            unitPrecision: 5, // 保留5位小数字
            minPixelValue: 2, // 小于 2 时,不转换
            selectorBlackList: [], // 选择器黑名单,可以使用正则
            propWhiteList: [] // 属性名称为空,表示替换所有属性的值
        }),
        autoprefixer({
            browsers: ['> 1%', 'android >=4', 'ios >=8']
        }),
        postUse({
            modules: ['postcss-clearfix', 'postcss-crip', 'postcss-short', 'postcss-center', 'postcss-position']
        })
    ];

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