Webpack変換less、CSS Modulesを開いた後に背景のピクチャーは失効します

4860 ワード

開発の背景create-react-appを使用してReactプロジェクトを作成すると、react-app-rewiredによってless変換の機能が開始されます.
しかし、react-app-rewire-css-modulesモジュールをパクリしてCSS Modulesを開くと、*.module.lessの中の背景画像が失効し、../yourdir/yourImageの経路を変更する必要があります(前の階層のディレクトリに入り、現在のフォルダディレクトリに入ります).
issuesにも似たような問題がありますCSS background img path error
ソリューション
変換lessの後にloaderを追加する必要があります.名前はresolve-url-loaderです.sassであれば、上記のissuesを参照して問題を修復できます.react-app-rewiredシナリオ、コードは次のとおりです.
/**
 * less
 *   :https://github.com/codebandits/react-app-rewire-css-modules
 */
const path = require('path');
const cloneDeep = require('lodash.clonedeep');

const ruleChildren = loader =>
    loader.use ||
    loader.oneOf ||
    (Array.isArray(loader.loader) && loader.loader) ||
    [];

const findIndexAndRules = (rulesSource, ruleMatcher) => {
    let result = undefined;
    const rules = Array.isArray(rulesSource)
        ? rulesSource
        : ruleChildren(rulesSource);
    rules.some(
        (rule, index) =>
            (result = ruleMatcher(rule)
                ? { index, rules }
                : findIndexAndRules(ruleChildren(rule), ruleMatcher))
    );
    return result;
};

const findRule = (rulesSource, ruleMatcher) => {
    const { index, rules } = findIndexAndRules(rulesSource, ruleMatcher);
    return rules[index];
};

const cssRuleMatcher = rule =>
    rule.test && String(rule.test) === String(/\.css$/);

const createLoaderMatcher = loader => rule =>
    rule.loader &&
    rule.loader.indexOf(`${path.sep}${loader}${path.sep}`) !== -1;
const cssLoaderMatcher = createLoaderMatcher('css-loader');
const postcssLoaderMatcher = createLoaderMatcher('postcss-loader');
const fileLoaderMatcher = createLoaderMatcher('file-loader');

const addAfterRule = (rulesSource, ruleMatcher, value) => {
    const { index, rules } = findIndexAndRules(rulesSource, ruleMatcher);
    rules.splice(index + 1, 0, value);
};

const addBeforeRule = (rulesSource, ruleMatcher, value) => {
    const { index, rules } = findIndexAndRules(rulesSource, ruleMatcher);
    rules.splice(index, 0, value);
};

function createRewireLess({
    localIdentName = `[local]___[hash:base64:5]`,
    lessLoaderOptions = {}
}) {
    return function(config, env) {
        const cssRule = findRule(config.module.rules, cssRuleMatcher);
        const sassRule = cloneDeep(cssRule);
        const cssModulesRule = cloneDeep(cssRule);

        cssRule.exclude = /\.module\.css$/;

        const cssModulesRuleCssLoader = findRule(
            cssModulesRule,
            cssLoaderMatcher
        );
        cssModulesRuleCssLoader.options = Object.assign(
            { modules: true, localIdentName },
            cssModulesRuleCssLoader.options
        );
        addBeforeRule(config.module.rules, fileLoaderMatcher, cssModulesRule);

        sassRule.test = /\.less$/;
        sassRule.exclude = /\.module\.less$/;
        addAfterRule(sassRule, postcssLoaderMatcher, {
            loader: require.resolve('less-loader'),
            options: lessLoaderOptions
        });

        addBeforeRule(config.module.rules, fileLoaderMatcher, sassRule);

        const sassModulesRule = cloneDeep(cssModulesRule);
        sassModulesRule.test = /\.module\.less$/;
        // sassModulesRule.exclude = path.resolve(__dirname, 'node_modules');
        // fix image url
        addAfterRule(sassModulesRule, postcssLoaderMatcher, {
            loader: require.resolve('resolve-url-loader')
        });
        addAfterRule(sassModulesRule, postcssLoaderMatcher, {
            loader: require.resolve('less-loader'),
            options: lessLoaderOptions
        });
        addBeforeRule(config.module.rules, fileLoaderMatcher, sassModulesRule);

        return config;
    };
}

const rewireLess = createRewireLess({});

rewireLess.withLoaderOptions = createRewireLess;

module.exports = rewireLess;    
webpackの構成であれば、次のようになります.
let module = {
    importLoaders: 3,
    modules: true,
    localIdentName: '[name]_[local]_[hash:base64:5]'
};
let loaders = [
    {
        loader: 'css-loader',
        options: module
    },
    {
        loader: 'postcss-loader',
        options: {
            plugins: [require('autoprefixer')('last 100 versions')]
        }
    },
    {
        loader: 'resolve-url-loader'
    },
    {
        loader: 'less-loader',
        options: {
            javascriptEnabled: true,
            modifyVars: { '@primary-color': '#1DA57A' }
        }
    }
];

译文1:webpack変換less、CSS Modulesを開いた後に背景のピクチャーは失効します