webpack进阶(二)
到目前为止,我们已经知道了,对于模块,Webpack能提供非常强大的处理功能,那哪些是模块呢?
一切皆模块
Webpack有一个不可不说的优点,它把所有的文件都都当做模块处理,JavaScript代码,CSS和fonts以及图片等等通过合适的loader都可以被处理。
继续上面的例子
//安装 npm install --save-dev style-loader css-loader
//使用 module.exports = { ... module: { rules: [ { test: /(\.jsx|\.js)$/, use: { loader: "babel-loader" }, exclude: /node_modules/ }, { test: /\.css$/, use: [ { loader: "style-loader" }, { loader: "css-loader" } ] }
接下来,在app文件夹里创建一个名字为"main.css"的文件,对一些元素设置样式
/* main.css */ 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 “中,如下:
//main.js
import React from 'react';
import {render} from 'react-dom';
import Greeter from './Greeter';
import './main.css';//使用require导入css文件
render(<Greeter />, document.getElementById('root'));
通常情况下,css会和js打包到同一个文件中,并不会打包为一个单独的css文件,不过通过合适的配置webpack也可以把css打包为单独的文件的。
上面的代码说明webpack是怎么把css当做模块看待的,下面将讲述一个更加真实的css模块实践。
CSS module
在过去的一些年里,JavaScript通过一些新的语言特性,更好的工具以及更好的实践方法(比如说模块化)发展得非常迅速。模块使得开发者把复杂的代码转化为小的,干净的,依赖声明明确的单元,配合优化工具,依赖管理和加载管理可以自动完成。
不过前端的另外一部分,CSS发展就相对慢一些,大多的样式表却依旧巨大且充满了全局类名,维护和修改都非常困难。
被称为CSS modules
的技术意在把JS的模块化思想带入CSS中来,通过CSS模块,所有的类名,动画名默认都只作用于当前模块。Webpack对CSS模块化提供了非常好的支持,只需要在CSS loader中进行简单配置即可,然后就可以直接把CSS的类名传递到组件的代码中,这样做有效避免了全局污染。具体的代码如下:
module.exports = { ... 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的类名格式 } } ] } ] } };
我们在app文件夹下创建一个Greeter.css
文件来进行一下测试
/* Greeter.css */ .root { background-color: #eee; padding: 10px; border: 3px solid #ccc; }
导入.root
到Greeter.js中
import React, {Component} from 'react'; import config from './config.json'; import styles from './Greeter.css';//导入 class Greeter extends Component{ render() { return ( <div className={styles.root}> //使用cssModule添加类名的方法 {config.greetText} </div> ); } } export default Greeter
用这种方式,相同的类名也不会造成不同组件之间的污染。
CSS预处理器
Sass
和 Less
之类的预处理器是对原生CSS的拓展,它们允许你使用类似于variables
, nesting
, mixins
, inheritance
等不存在于CSS中的特性来写CSS,CSS预处理器可以这些特殊类型的语句转化为浏览器可识别的CSS语句。
在webpack里使用相关loaders进行配置就可以使用了,以下是常用的CSS 处理loaders
:
Less Loader
Sass Loader
Stylus Loader
不过其实也存在一个CSS的处理平台-PostCSS
,它可以帮助你的CSS实现更多的功能,在其官方文档可了解更多相关知识。
举例来说如何使用PostCSS,我们使用PostCSS来为CSS代码自动添加适应不同浏览器的CSS前缀。
首先安装postcss-loader
和 autoprefixer
(自动添加前缀的插件)。
npm install --save-dev postcss-loader autoprefixer
接下来,在webpack配置文件中添加postcss-loader
,在根目录新建postcss.config.js
,并添加如下代码之后,重新使用npm start
打包时,你写的css会自动根据Can i use里的数据添加不同前缀了。
//webpack.config.js module.exports = { ... module: { rules: [ { test: /(\.jsx|\.js)$/, use: { loader: "babel-loader" }, exclude: /node_modules/ }, { test: /\.css$/, use: [ { loader: "style-loader" }, { loader: "css-loader", options: { modules: true } }, { loader: "postcss-loader" } ] } ] } }
// postcss.config.js module.exports = { plugins: [ require('autoprefixer') ] }
插件(Plugins)
插件(Plugins)是用来拓展Webpack功能的,它们会在整个构建过程中生效,执行相关的任务。
Loaders和Plugins常常被弄混,但是他们其实是完全不同的东西,可以这么来说,loaders是在打包构建过程中用来处理源文件的(JSX,Scss,Less..),一次处理一个,插件并不直接操作单个文件,它直接对整个构建过程起作用。
Webpack有很多内置插件,同时也有很多第三方插件,可以让我们完成更加丰富的功能。
要使用某个插件,我们需要通过npm
安装它,然后要做的就是在webpack配置中的plugins关键字部分添加该插件的一个实例(plugins是一个数组)继续上面的例子,我们添加了一个给打包后代码添加版权声明的插件。
const webpack = require('webpack'); module.exports = { ... module: { rules: [ { test: /(\.jsx|\.js)$/, use: { loader: "babel-loader" }, exclude: /node_modules/ }, { test: /\.css$/, use: [ { loader: "style-loader" }, { loader: "css-loader", options: { modules: true } }, { loader: "postcss-loader" } ] } ] }, plugins: [ new webpack.BannerPlugin('版权所有,翻版必究') ], };