Little-Gee / blog

15 stars 11 forks source link

create-react-app 中配置 css module(less)、ant design 及 ant design 按需加载与自定义主题 #1

Open Little-Gee opened 5 years ago

Little-Gee commented 5 years ago

版本:

create-react-app: 3.0.1
"react": "^16.8.6",
"webpack": "4.29.6",
"less": "^3.9.0",
"less-loader": "^5.0.0",

首先将配置暴露出来(不可逆)

npm run eject

然后就可以看到package.json中多了很多东西

安装lessless-loader插件

npm install less less-loader --save-dev

less配置

打开config/webpack.config.js,仿照原有的正则添加less的正则

const cssRegex = /\.css$/;
const cssModuleRegex = /\.module\.css$/;
const lessRegex = /\.less$/;
const lessModuleRegex = /\.module\.less$/; // 这个不用也没事
const sassRegex = /\.(scss|sass)$/;
const sassModuleRegex = /\.module\.(scss|sass)$/;

然后在module下的rules里的oneOf中添加规则(可以搜一下sassRegex,对照着复制一遍)

{
    test: lessRegex,
    exclude: lessModuleRegex,
    use: getStyleLoaders(
        {
            importLoaders: 2,
            sourceMap: isEnvProduction && shouldUseSourceMap,
        },
        'less-loader'
    ),
    sideEffects: true,
},
{
    test: lessModuleRegex,
    use: getStyleLoaders(
        {
            importLoaders: 2,
            sourceMap: isEnvProduction && shouldUseSourceMap,
            modules: true,
            getLocalIdent: getCSSModuleLocalIdent,
        },
        'less-loader'
    ),
},

然后就可以愉快地使用less

// App.js
import React from "react";
import "./App.less";

function App() {
    return (
        <div className="App">
            <div className="text">文字</div>
        </div>
    );
}

export default App;
// App.less
.App {
    background: skyblue;

    .text {
        color: red;
    }
}

css module配置

我们在浏览器里看到的确是这样的

1

这样可能会出现重名的问题,所以要开启css module,就是一种给样式名添加哈希值方式来保证唯一性,其实上面的less配置中已经开启了,只不过文件命名需要改一下

更改文件名 App.less => App.module.less,同时更改App.js中的引用和使用方式

// App.js
import React from "react";
import styles from "./App.module.less";

function App() {
    return (
        <div className={styles.App}>
            <div className={styles.text}>文字</div>
        </div>
    );
}

export default App;

这里要注意的是,改成css module的写法后,样式写法要从中划线变成小驼峰,例如top-text=>topText

此时效果如下图:

2

样式名变成了文件名_样式名__哈希值,如果想更改,可以更改上文webpack配置中的getLocalIdent字段后的规则

因为写样式都要写.module比较繁琐,也不符合自己的习惯,所以我一般直接让less文件开启css module

即:

{
    test: lessRegex,
    use: getStyleLoaders(
        {
            importLoaders: 2,
            sourceMap: isEnvProduction && shouldUseSourceMap,
            modules: true,
            getLocalIdent: getCSSModuleLocalIdent,
        },
        'less-loader'
    ),
    sideEffects: true,
},

这样也就不需要lessModuleRegex了,简单方便

ant design配置

接下来我们加入ant design

npm install antd --save

安装完成后就可以使用了

// App.js
import React from "react";
import styles from "./App.less";
import Button from "antd/lib/button";
import "antd/dist/antd.css";

function App() {
    return (
        <div className={styles.App}>
            <div className={styles.text}>文字</div>
            <Button type="primary">Button</Button>
        </div>
    );
}

export default App;

但是这样你肯定会觉得每次引用都好麻烦,并且一下子加载了全部的antd组件的样式,肯定很不合理,于是就有了按需加载的方式,具体可以看官网,此处采用babel-plugin-import

安装babel-plugin-import插件

npm install babel-plugin-import --save-dev

package.json中添加bebel的插件配置

"babel": {
    "presets": [
        "react-app"
    ],
    "plugins": [
        [
            "import",
            {
                "libraryName": "antd",
                "style": true
            }
        ]
    ]
}

webpack中添加配置:

if (preProcessor) {
    loaders.push({
        loader: require.resolve(preProcessor),
        options: {
            sourceMap: isEnvProduction && shouldUseSourceMap,
            javascriptEnabled:true // 加上这行
        },
    });
}

但是这里还有个有个问题,就是开启css moduleant design的样式没有了,因为css moduleant design的样式也添加了哈希值,造成了样式失效,将它们排除出去即可

修改webpack配置:

{
    test: lessRegex,
    include: /node_modules/,
    use: getStyleLoaders(
        {
            importLoaders: 1,
            sourceMap: isEnvProduction && shouldUseSourceMap,
        },
        'less-loader'
    ),
    sideEffects: true,
},
{
    test: lessRegex,
    exclude: /node_modules/,
    use: getStyleLoaders(
        {
            importLoaders: 2,
            sourceMap: isEnvProduction && shouldUseSourceMap,
            modules: true,
            getLocalIdent: getCSSModuleLocalIdent,
        },
        'less-loader'
    ),
    sideEffects: true,
},

现在就可以正常使用了

// App.js
import React from "react";
import styles from "./App.less";
import { Button } from "antd";

function App() {
    return (
        <div className={styles.App}>
            <div className={styles.text}>文字</div>
            <Button type="primary">Button</Button>
        </div>
    );
}

export default App;

ant design主题更改

其实上面的做完,主题更改就很简单了,直接在webpack中添加想更改的部分即可

例如

if (preProcessor) {
    loaders.push({
        loader: require.resolve(preProcessor),
        options: {
            sourceMap: isEnvProduction && shouldUseSourceMap,
            // 添加modifyVars,具体样式自己配,此处是骚气的基佬紫
            modifyVars: {
                "primary-color": "#7546C9",
                "link-color": "#1DA57A",
                "border-radius-base": "2px"
            },
            javascriptEnabled:true
        },
    });
}

自己动手配一遍,还是能学到很多东西的,遇到很多问题,查了很多解决办法,对以前一窍不通的webpack也能有一些了解吧

项目参考地址