alibaba-fusion / next-theme-loader

A webpack loader for injecting scss variables of theme package to scss file.
MIT License
7 stars 3 forks source link

create-react-app 脚手架在webpack v4中配置主题无效 #2

Closed devfpy closed 5 years ago

devfpy commented 5 years ago

我使用的是 create-react-app 脚手架创建的项目,webpack的版本是4+ extract-text-webpack-plugin这个组件不支持webpack v4.

请问如何在webpack v4中配置主题。

bindoon commented 5 years ago

参考这个项目 https://github.com/alibaba-fusion/materials/tree/master/scaffolds/next-single-page

devfpy commented 5 years ago

已经解决,谢谢!

package.json

{
  "name": "change-theme-demo",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@alifd/next": "^1.12.6",
    "@alifd/next-theme-loader": "^1.3.0",
    "@alifd/next-theme-webpack-plugin": "^1.0.1",
    "@alifd/theme-1": "^0.0.9",
    "@alifd/theme-2": "^0.0.16",
    "@alifd/theme-3": "^0.0.9",
    "@alifd/theme-4": "^0.0.7",
    "autoprefixer": "^9.4.8",
    "babel-plugin-import": "^1.11.0",
    "customize-cra": "^0.2.11",
    "happypack": "^5.0.1",
    "less-loader": "^4.1.0",
    "moment": "^2.24.0",
    "node-sass": "^4.11.0",
    "react": "^16.8.2",
    "react-app-rewired": "^2.1.0",
    "react-dom": "^16.8.2",
    "react-scripts": "2.1.5",
    "sass-loader": "^7.1.0"
  },
  "scripts": {
    "start": "react-app-rewired start --display-error-details --progress --color",
    "build": "react-app-rewired build",
    "test": "react-app-rewired test",
    "eject": "react-app-rewired eject"
  },
  "eslintConfig": {
    "extends": "react-app"
  },
  "browserslist": [
    ">0.2%",
    "not dead",
    "not ie <= 11",
    "not op_mini all"
  ],
  "buildConfig": {
    "theme": "@alifd/theme-4"
  }
}

config-overrides

const { override, fixBabelImports, addLessLoader } = require('customize-cra');
const ThemePlugin = require('@alifd/next-theme-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const os = require('os');
const HappyPack = require('happypack');
const happyThreadPool = HappyPack.ThreadPool({ size: os.cpus().length });

// 获取 package.json 中的主题配置文件
let theme = '';
try {
    const pkg = require('./package.json');
    if (pkg && pkg.buildConfig && pkg.buildConfig.theme) {
        theme = pkg.buildConfig.theme;
    }
} catch (e) {
    console.log("read theme config error ", e);
    console.log(`请在 package.json 中配置
    buildConfig:{
        theme: '@alife/dpl-主题包名'
    }`);
}

let scssLoader = [
    {
        loader: 'css-loader',
        options: {
            minimize: true,
            sourceMap: false,
        },
    },
    // {
    //     loader: require.resolve('postcss-loader'),//'postcss-loader',
    //     options: {
    //         indent: 'postcss',
    //         plugins: () => [
    //             require('autoprefixer')(),
    //         ],
    //         sourceMap: false,
    //     },
    // },
    {
        loader: 'sass-loader',
        options: {
            sourceMap: false,
        },
    },
];

const addThemeLoader = config => {
    if (theme) {
        console.log(`NOTICE: 注入 ${theme}/variables.scss 到每个 scss 文件`.green);
        scssLoader.push({
            loader: '@alifd/next-theme-loader',
            options: {
                theme
            },
        });
    }

    config.module.rules[2].oneOf[5] = {
        test: /\.(scss|sass)$/,
        exclude: /\.module\.(scss|sass)$/,
        use: [
            MiniCssExtractPlugin.loader,
            'happypack/loader?id=scss',
        ],
    };

    config.module.rules[2].oneOf[6] = {
        test: /\.module\.(scss|sass)$/,
        use: [
            MiniCssExtractPlugin.loader,
            'happypack/loader?id=scss',
        ],
    };

    return config;
}

const addHappyPackPlugin = config => {
    config.plugins.push(
        new HappyPack({
            id: 'scss',
            threadPool: happyThreadPool,
            loaders: scssLoader,
        })
    )

    return config;
}

const addThemePlugin = config => {
    config.plugins.push(new ThemePlugin({ theme }))
    return config
}

const addMiniCssExtractPlugin = config => {
    config.plugins.push(
        new MiniCssExtractPlugin({
            filename: '[name].bundle.css',
            chunkFilename: '[name].bundle.css',
        })
    )
    return config;
}

module.exports = override(
    addThemeLoader,
    addHappyPackPlugin,
    addThemePlugin,
    addMiniCssExtractPlugin,
    fixBabelImports('import', {
        libraryName: '@alifd/next',
        libraryDirectory: 'es',
        style: true
    }),
);