create-react-app 创建项目有关 less 的若干问题

在上篇文章使用Eject方式在 create-react-app 中使用 Ant Design of React中, 使用create-react-app创建了React项目,并使用 Eject方式暴露出了Webpack的配置,并成功按需引入了antd。本文主要内容:解决create-react-app创建项目后less不生效的问题;antd按需引入less源文件,以及遇到的bezierEasing.less文件报错问题;antd本地字体的配置方法;less使用css module的配置。

直接引入less样式不生效

创建test.less,并在App.js中引入

1
2
3
.test {
color: red;
}
1
2
3
4
5
6
7
// App.js
...
import './test.less'
...
<div className="test">test</div>
<Button type="primary">Button</Button>
...

发现test的颜色并没有生效

安装 lessless-loader ,并修改Webpack配置

1
$ cnpm i less less-loader --save-dev

修改webpack配置
修改 webpack.config.dev.jswebpack.config-prod.js 配置文件, 增加less文件配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// webpack.config.dev.js
...
{
test: /\.less$/,
use: [
require.resolve('style-loader'),
{
loader: require.resolve('css-loader'),
options: {
importLoaders: 1,
},
},
{
loader: require.resolve('less-loader') // compiles Less to CSS
}
],
},
...

重启项目后,less样式已经生效

antd 的样式使用 less 源文件方式引入

babel-plugin-import 中对style有这样对说明:

["import", { "libraryName": "antd" }] : import js modularly

["import", { "libraryName": "antd", "style": true }] : import js and css modularly (LESS/Sass source files)

["import", { "libraryName": "antd", "style": "css" }] : import js and css modularly (css built files)

修改package.json,将style的值改为true

1
2
3
4
5
6
7
8
9
10
11
...
"babel": {
"presets": [
"react-app"
]
],
"plugins": [
["import", { "libraryName": "antd", "libraryDirectory": "es", "style": true }]
]
}
...

重启之后,编译错误,提示bezierEasing.less文件的.bezierEasingMixin()方法报错:

按照报错提供的issue地址查看 : https://github.com/ant-design/ant-motion/issues/44
主要有2种解决方式

  • 将 less 版本降到 3.0 以下, 应该可行,降级的方法感觉不太好,没有测试
  • less loader 增加配置,开启 JavaScript :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    // webpack.config.dev.js
    ...
    {
    - loader: require.resolve('less-loader') // compiles Less to CSS
    + loader: require.resolve('less-loader'), // compiles Less to CSS
    + options: {
    + javascriptEnabled: true
    + }

    }
    重新npm start ,项目可以正常启动。

antd使用本地字体 iconfont

2018年9月5日更新,9月开学季, ant design 系列迎来了一系列的重大更新。umi 迎来了 2.0 版本, 随之而来的是 ant design pro 使用 umi 2.0 构建的 2.0 版本。 今天注意到 ant design 的 3.9.0 版本一个重大的更新是对 Icon 进行了重构, 使用 SVG 代替之前的 css font icon。所以如果使用 ant design 3.9.0 以上的版本, 就不会存在离线找不到字体文件的问题了。如果你使用的 ant design 在 3.9.0 版本以下,可以参考下文离线使用 iconfont 的方式。

Ant Design 默认的 iconfont 文件托管在 iconfont.cn 并默认使用平台提供的 alicdn 地址,公网可访问使用。

由于 alicdn 对部分域名有访问限制,或者需要内网环境使用,需要将字体下载到本地

最新的 iconfont 文件可以到 此链接 下载。

下载后将字体文件放入 public/iconfont/ 路径下

由于项目使用的是create-react-app创建项目,且antd的样式使用babel-plugin-import按需加载样式,所以只能采用 定制主题中的less-loadermodifyVars配置来覆盖原来的样式变量。

具体改动
修改 webpack.config.dev.jswebpack.config-prod.js 配置文件

1
2
3
4
5
6
7
8
9
10
11
// webpack.config.dev.js
...
{
loader: require.resolve('less-loader'), // compiles Less to CSS
options: {
javascriptEnabled: true
modifyVars: {
"icon-url": "'/public/iconfont/iconfont'"
}
}
}

重启项目,成功引入了本地字体

需要注意的是webpack.config-prod.js文件中的icon-url路径需要将public替换为生产环境项目文件路径,打包之后public中的文件和文件夹直接复制到bulid路径下。使用相对路径会报错无法编译,这点不知道有没有更好的处理方式,希望读者大神们提供更好的方式。

1
2
3
4
5
6
7
8
9
10
11
// webpack.config-prod.js
...
{
loader: require.resolve('less-loader'), // compiles Less to CSS
options: {
javascriptEnabled: true
modifyVars: {
"icon-url": "'/your-project-name/iconfont/iconfont'"
}
}
}

css module 形式引入less

增加css-loader的配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
          {
test: /\.less$/,
// exclude: [/node_modules/],
use: [
require.resolve('style-loader'),
{
loader: require.resolve('css-loader'),
options: {
importLoaders: 1,
+ modules: true
},
},
{
loader: require.resolve('less-loader'), // compiles Less to CSS
options: {
javascriptEnabled: true,
modifyVars: {
"icon-url": "'/public/iconfont/iconfont'"
}
}
}
],
},

修改App.js,使用css module方式引入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
- import './test.less'
+ import styles from './test.less'

class App extends Component {
render() {
return (
<div className="App">
- <div className="test">test</div>
+ <div className={styles.test}>test</div>
<Button type="primary">Button</Button>
</div>
);
}
}

重启项目,css module引入的test样式生效了,但是antd的按钮样式失效了

需要修改 webpack.config.dev.js,只对src中的less文件开启css module,这里写法有点麻烦,应该有更好的方式。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
// webpack.config.dev.js
...
{
test: /\.less$/,
use: [
require.resolve('style-loader'),
{
loader: require.resolve('css-loader'),
options: {
importLoaders: 1
},
},
{
loader: require.resolve('less-loader'), // compiles Less to CSS
options: {
javascriptEnabled: true,
modifyVars: {
"icon-url": "'/public/iconfont/iconfont'"
}
}
}
],
},
{
test: /\.less$/,
include: [/src/],
use: [
require.resolve('style-loader'),
{
loader: require.resolve('css-loader'),
options: {
importLoaders: 1,
modules: true
},
}
],
},
...

2018-08-02更新,评论区有兄弟留言说重新npm install后,css module引入的样式失效了,今天测试了一下确实有这个问题,试着改了上面的对less文件处理的loader顺序可以解决这个问题,但是原理不是很清楚,还请了解原理的兄弟帮忙指点,多谢

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
// webpack.config.dev.js
...
{
test: /\.less$/,
include: [/src/],
use: [
require.resolve('style-loader'),
{
loader: require.resolve('css-loader'),
options: {
importLoaders: 1,
modules: true
},
}
],
},
{
test: /\.less$/,
use: [
require.resolve('style-loader'),
{
loader: require.resolve('css-loader'),
options: {
importLoaders: 1
},
},
{
loader: require.resolve('less-loader'), // compiles Less to CSS
options: {
javascriptEnabled: true,
modifyVars: {
"icon-url": "'/public/iconfont/iconfont'"
}
}
}
],
},
...

总结

本文在ejectcreate-react-app的项目基础上,按需引入了antd,遇到了有关less的若干问题:解决了less文件不生效的问题,内网环境使用本地iconfont的配置方式,css module的配置方式。本文还有一些配置方式不是最优的方式,希望各位能够给出更好的方案。

最近在起步React,准备记录以下自己的学习和踩坑过程。下一篇文章应该是dva的使用。

参考资料

create-react-app 创建项目有关 less 的若干问题

https://ivocin.github.io/2018/07/30/create_react_app_less_issues/

作者

清秋

发布于

2018-07-30

更新于

2021-03-13

许可协议

评论