Webpack有一个不可不说的优点,它把所有的文件都都当做模块处理,JavaScript代码,CSS和fonts以及图片等等通过合适的loader都可以被处理

CSS

webpack提供两个工具处理样式表,css-loader 和 style-loader,二者处理的任务不同,css-loader使你能够使用类似@import 和 url(…)的方法实现 require()的功能,style-loader将所有的计算后的样式加入页面中,二者组合在一起使你能够把样式表嵌入webpack打包后的JS文件中

  • 安装,运行yarn add style-loader css-loader -D
  • 配置webpack.config.js:
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
module.exports = {
devtool: 'eval-source-map', // 构建source maps,生产环境需要去掉此选项
mode: 'development', // 声明当前环境为生产环境还是开发环境
entry: __dirname + '/src/main.js', // 已多次提及的唯一入口文件
output: {
path: __dirname + '/public', // 打包后的文件存放的地方
filename: 'bundle.js' // 打包后输出文件的文件名
},
devServer: {
contentBase: './public', // 本地服务器所加载的页面所在的目录
port: 8080, // 默认端口
historyApiFallback: true, // 不跳转
inline: true // 实时刷新
},
module: {
rules: [{
test: /(\.jsx|\.js)$/,
use: {
loader: 'babel-loader'
},
exclude: /node_modules/
},
{
test: /\.css$/,
use: [{
loader: 'style-loader'
}, {
loader: 'css-loader'
}]
}
]
}
}

注意这里对同一个文件引入多个loader的方法

  • 增加一个main.css文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
html {
box-sizing: border-box;
-ms-text-size-adjust: 100%;
-webkit-text-size-adjust: 100%;
}

*, *:before, *:after {
box-sizing: inherit;
}

body {
margin: 0;
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
}

h1, h2, h3, h4, h5, h6, p, ul {
margin: 0;
padding: 0;
}
  • 我们这里例子中用到的webpack只有单一的入口,其它的模块需要通过 import, require, url等与入口文件建立其关联,为了让webpack能找到”main.css“文件,我们把它导入”main.js “中,如下:
1
2
3
4
5
6
7
import React from 'react'
import {render} from 'react-dom'
import Greeter from './Greeter'

import './main.css'

render(<Greeter />, document.getElementById('root'))

通常情况下,css会和js打包到同一个文件中,并不会打包为一个单独的css文件,不过通过合适的配置webpack也可以把css打包为单独的文件的

CSS mouidule

CSS modules的技术意在把JS的模块化思想带入CSS中来,通过CSS模块,所有的类名,动画名默认都只作用于当前模块。Webpack对CSS模块化提供了非常好的支持,只需要在CSS loader中进行简单配置即可,然后就可以直接把CSS的类名传递到组件的代码中,这样做有效避免了全局污染

  • 具体修改webpack.config.js如下:
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
module.exports = {
devtool: 'eval-source-map', // 构建source maps,生产环境需要去掉此选项
mode: 'development', // 声明当前环境为生产环境还是开发环境
entry: __dirname + '/src/main.js', // 已多次提及的唯一入口文件
output: {
path: __dirname + '/public', // 打包后的文件存放的地方
filename: 'bundle.js' // 打包后输出文件的文件名
},
devServer: {
contentBase: './public', // 本地服务器所加载的页面所在的目录
port: 8080, // 默认端口
historyApiFallback: true, // 不跳转
inline: true // 实时刷新
},
module: {
rules: [{
test: /(\.jsx|\.js)$/,
use: {
loader: 'babel-loader'
},
exclude: /node_modules/
},
{
test: /\.css$/,
use: [{
loader: 'style-loader'
}, {
loader: 'css-loader',
options: {
modules: true, // 指定启用css modules
localIdentName: '[name]__[local]--[hash:base64:5]' // 指定css的类名格式
}
}]
}
]
}
}
  • 在src下新建一个Greeter.css的文件来进行测试
1
2
3
4
5
.root {
background-color: #eee;
padding: 10px;
border: 3px solid #ccc;
}
  • 将样式应用到Greeter组件中
1
2
3
4
5
6
7
8
9
10
11
12
13
14
import React, {Component} from 'react'
import styles from './Greeter.css'

class Greeter extends Component{
render() {
return (
<div className={styles.root}>
Hi there and greetings from JSON!
</div>
)
}
}

export default Greeter
  • 运行npm start 或 npm run dev看一下吧,如何?相同类名也不会造成污染了。

CSS 预处理器

ass 和 Less 之类的预处理器是对原生CSS的拓展,它们允许你使用类似于variables, nesting, mixins, inheritance等不存在于CSS中的特性来写CSS,CSS预处理器可以这些特殊类型的语句转化为浏览器可识别的CSS语句,比较常用的css预处理loaders是:

  • Less Loader
  • Sass Loader
  • Stylus Loader
    除了上述loader,我们还有一个非常实用的处理平台PostCSS,它可以帮助你实现更多的功能,比如:自动添加适应不同浏览器的css前缀:
  • 首先安装postcss-loader 和 autoprefixer(自动添加前缀的插件)
    运行 yarn add postcss-loader autoprefixer -D
  • 增加postcss.config.js
1
2
3
4
5
module.exports = {
plugins: [
require('autoprefixer')
]
}
  • 增加webpack.config.js
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
39
module.exports = {
devtool: 'eval-source-map', // 构建source maps,生产环境需要去掉此选项
mode: 'development', // 声明当前环境为生产环境还是开发环境
entry: __dirname + '/src/main.js', // 已多次提及的唯一入口文件
output: {
path: __dirname + '/public', // 打包后的文件存放的地方
filename: 'bundle.js' // 打包后输出文件的文件名
},
devServer: {
contentBase: './public', // 本地服务器所加载的页面所在的目录
port: 8080, // 默认端口
historyApiFallback: true, // 不跳转
inline: true // 实时刷新
},
module: {
rules: [{
test: /(\.jsx|\.js)$/,
use: {
loader: 'babel-loader'
},
exclude: /node_modules/
},
{
test: /\.css$/,
use: [{
loader: 'style-loader'
}, {
loader: 'css-loader',
options: {
modules: true, // 指定启用css modules
localIdentName: '[name]__[local]--[hash:base64:5]' // 指定css的类名格式
}
}, {
loader: 'postcss-loader'
}]
}
]
}
}