自从第一次知道React的那天起,每次的meetup上都有他的身影,中间几次了解又几次放弃,但是每次遇到他的主题还是会忍不住去听。我和文博一直抱怨,angular最近真是没人聊啊,难道大家的生产环境已经都是React了喂?不过最近遇到一个项目,有一个需要特别频繁被移动设备访问的页面,我的第一想法便是如何加快速度,减少资源大小,后来就想用React吧,于是顺便也用起了webpack。

我并没有从零开始,而是在Github上找了一个starter-kit,感觉这个比较适合我,只有基本的webpack+react+react-router+redux, 我觉得目前我也只能先把这些搞懂。

在使用中经历了不少的痛楚,以后可以总结,但是有两个与css编译有关的奇怪现象,我觉得还是有必要先记下来

@keyframes被默认为 :local 作用域

这样的一段代码

1
2
3
4
/* core.scss, 编译主入口 */
:global {
@import 'base';
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/* base.scss */
@keyframes animation1 {
0% {
transform: rotate(0deg);
}
50% {
transform: rotate(180deg);
}
100% {
transform: rotate(360deg);
}
}

.rotate {
animation: animation1 1s infinite ease-in-out;
}

被webpack编译后,会变成类似如下形式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@keyframes core_animation1_local_abcdef {
0% {
transform: rotate(0deg);
}
50% {
transform: rotate(180deg);
}
100% {
transform: rotate(360deg);
}
}

.rotate {
animation: animation1 1s infinite ease-in-out;
}

可以看到,keyframes animation 被重命名了,这其实是为了方便实现css namespace。 我一时间不是很明白,因为既然把animation重命名了,怎么不把.rotate中的animation-name也给重命名掉呢。其实在css-loader的Github主页测试用例中,他们有关于keyframes and animations的测试用例,里面是可以将animation-name给重命名掉的。

后来我注意到命名后,keyframes带有’local’关键字,难道说默认应该是local? 于是我把.rotate加上了:local关键字

1
2
3
:local(.rotate) {
animation: animation1 1s infinite ease-in-out;
}

结果,在编译期就报错,提示:local不能包裹在:global里面,回头看才发现该文件base.css是被core.scss引入的,而且是在:global中引入。那么将keyframes再显示声明为:global呢?

1
2
3
4
5
6
7
8
9
10
11
@keyframes :global(animation1) {
0% {
transform: rotate(0deg);
}
50% {
transform: rotate(180deg);
}
100% {
transform: rotate(360deg);
}
}

结果没有重命名了,问题解决。奇怪的是为什么这里的@keyframes会被当做是:local的?

@font-face编译后内容生成了重复的花括号{}

由于项目使用了Material-UI,所以想引入Robot字体文件。自己从网络上下载了Roboto自己放在项目文件夹下,并配置如下

1
2
3
4
5

/* core.scss */
:global{
@import 'base';
};
1
2
3
4
5
6
7
/* 还是在base.scss中,被core.scss @import */
@font-face {
font-family: 'Roboto';
src: url('../static/fonts/RobotoCondensed-Light.ttf') format('truetype');
font-weight: 400;
font-style: normal;
}

但是编译后字体一直没有生效,查看编译后的源代码,发现@font-face被编译成了这样→_→

1
@font-face{{font-family: 'Roboto';src: url('../static/fonts/RobotoCondensed.ttf') format('truetype');font-weight: 400;font-style: normal;}}

也就是说,编译后的@font-face被包裹上了两层花括号{}。很奇怪,后来也是经历了长时间的谷歌,都忘了从哪得到了这个提示,将@font-face放到整个文件的前面,包括:global

1
2
3
4
5
6
7
8
9
10
11
/* core.scss, 编译入口 */
@font-face {
font-family: 'Roboto';
src: url('../static/fonts/RobotoCondensed-Light.ttf') format('truetype');
font-weight: 400;
font-style: normal;
}

:global{
@import 'base';
};

这样@font-face终于生效了。