在webpack3.0小案例webpack初体验 一文中,咱们从总体了解了webpack相关特性并手动初步实现了一个可执行编译的webpack环境,这一节,将在此基础上继续探讨如下功能的实现:css
css最基本的编译要依靠于style-loader、css-loader这两个加载器,所谓最基本,就是在不考虑使用css预处理器以及css后处理器的状况。预处理器包括less、scss、sass、stylus,后处理器如postcss的autoprefixer等。首先咱们先弄明白各加载器的做用:html
了解了这些加载器各自的职能,那咱们如今先小试牛刀,用代码来体验一下。前端
一、首先,咱们在src项目文件夹下新建css文件夹,并新增同样式文件common.css,并写一些全局的cssnode
html,
body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
background: linear-gradient(to bottom, #abcdef, #f3f5f7);
}复制代码
二、安装css-loader和style-loader,进入到命令行,执行webpack
cnpm i style-loader css-loader --save-dev复制代码
三、如今咱们在入口文件app.js中去引入咱们的common.css:css3
//app.js
import './css/common.css';
...复制代码
四、webpack配置,打开webpack.config.js,新增module配置项:es6
let path = require('path');
...
module.exports = {
entry: path.resolve(__dirname, './src/main.js'),//入口文件地址
output: {
path: path.resolve(__dirname, './dist'),
filename: 'js/[name]-[chunkhash].js'
},
module: {
rules: [ {
test: /\.css$/,//匹配全部css文件
use: [
{ loader: "style-loader" },
{ loader: "css-loader" }
]//指定加载器
exclude: /node_modules///排除对node_module文件夹下面的全部资源的匹配
}]
},
...
}复制代码
须要注意,在指定加载器的时候,要注意各加载器的顺序,webpack中loader的解析是从右往左的顺序进行的,以当前为例,css文件首先是要经过css-loader进行处理,在将处理好的css交由style-loader,所以在指定加载器的时候,首先应该是style-loader,其次是css-loader。web
如今,咱们再次执行webpack编译命令,在浏览器中打开生成的index.html,发现页面背景已经如咱们设置改变了,而且html文档中css也已经以style模式注入到head中了。chrome
上文咱们已经说过,autoprefixer是css后处理器postcss提供的一个对css3中个别属性在不一样浏览器下须要添加浏览器前缀的样式处理工具,所以在使用autoprefixer以前,咱们须要安装postcss-loader来加载它。npm
cnpm i postcss-loader autoprefixer --save-dev复制代码
一、如今,咱们打开webpack.config.js配置文件,在module下配置autoprefixer
...
module: {
rules: [{
test: /\.css$/,
use: [
{ loader: "style-loader" },
{ loader: "css-loader" },
{ loader: "postcss-loader" }//指定postcss加载器
],
exclude: /node_modules/
}]
}
...复制代码
在配置postcss-loader以后,咱们须要注意,因为css-loader处理文件导入的方式,所以加载器postcss-loader不能与CSS模块一块儿使用。 为了使它们正常工做,能够添加css-loader的importLoaders选项。。
...
module: {
rules: [{
test: /\.css$/,
use: [
{ loader: "style-loader" },
{ loader: "css-loader",options: { importLoaders: 1 } },//importLoaders解决因为css-loader处理文件导入的方式致使postcss-loader不能正常使用的问题
{ loader: "postcss-loader" }//指定postcss加载器
],
exclude: /node_modules/
}]
}
...复制代码
二、接下来,咱们要给postcss-loader指定加载autoprefixer的操做,在根目录新建postcss.config.js
//postcss.config.js
module.exports = {
plugins: [
require("autoprefixer")()
]
}复制代码
在postcss.config.js配置文件中,咱们给引入了autoprefixer,这样一来,在postcss-loader加载的时候,就会自动去读取该配置文件里面的配置项,加载autoprefixer了。
三、全部配置项已经完成,如今咱们在原有的common.css文件中去添加样式,用来测试autoprefixer
html,
body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
background: linear-gradient(to bottom, #abcdef, #f3f5f7);
}
.flexbox {
display: flex;
background: linear-gradient(to bottom, #abcdef, #096)
}复制代码
添加完成后,运行webpack命令进行编译,并在浏览器中打开index.html,打开控制台查看head标签下生成的style标签,已经能够看到autoprefixer已经自动为咱们添加了浏览器前缀
autoprefixer 为咱们提供了能够根据需求配置的参数,例如我么可让它最终生成的css兼容最近的N个版本就好,但这不是咱们本次讨论的重点,有兴趣的同窗能够本身去官网查看。
//postcss.config.js 设置给最近5个版本的浏览器加前缀
module.exports = {
plugins: [
require("autoprefixer")({browsers:'last 5 version'})
]
}复制代码
一、在src/css文件夹下新建style.less文件,并添加样式做为测试,并在入口文件app.js中引用该less文件
@base: #f938ab;
.box-shadow(@style, @c) when (iscolor(@c)) {
-webkit-box-shadow: @style @c;
box-shadow: @style @c;
}
.box-shadow(@style, @alpha: 50%) when (isnumber(@alpha)) {
.box-shadow(@style, rgba(0, 0, 0, @alpha));
}
.box {
color: saturate(@base, 5%);
border-color: lighten(@base, 30%);
div { .box-shadow(0 0 5px, 30%) }
}复制代码
//app.js
import './css/common.css';//引入css
import './css/style.less';//引入less复制代码
二、安装less以及less-loader,并在webpack配置项中进行配置。
cnpm i less less-loader --save-dev复制代码
在module配置项中新增一条对less文件处理的规则:
...
module: {
rules: [{
test: /\.css$/,
use: [
{ loader: "style-loader" },
{ loader: "css-loader", options: { importLoaders: 1 } },
{ loader: "postcss-loader" },
],
exclude: /node_modules/
}, {
test: /\.less$/,
use: [
{ loader: "style-loader" },
{ loader: "css-loader", options: { importLoaders: 1 } },
{ loader: "postcss-loader" },
{ loader: "less-loader" }//less放在最后,由于要最早加载(loader从右往左加载的规则)
]
}]
},
...复制代码
配置完成后,再次运行webpack命令,并在浏览器中查看效果,能够看到在head标签内又新增了一个style标签,而且已经将less编译成css了
babel是一个js的转码器,将ES6或者ES7转换成ES5或者ES3;babel编译主要依靠于核心库babel-core,也就是说,用ES6进行编程而不须要担忧浏览器环境是否支持。
在此以前,我猜想有不少的同窗使用Babel的时候,preset必然会选择ES2015,可是最近babel官方推出了babel-preset-env,并建议在使用的时候选择env代替以前的ES20**。env为咱们提供了更智能的编译选择,在此咱们就不展开,有兴趣的同窗能够去官网深刻了解。
一、首先,咱们安装babel-loader、babel-core以及babel-preset-env,并在入口文件app.js中新增一段带ES6语法的js。
cnpm install --save-dev babel-loader babel-core babel-preset-env复制代码
import './css/common.css';
import './css/style.less';
//生成一个整数随机值,数值大于4则返回成功的Promise对象,不然返回错误的promise对象
function getData() {
let promise = new Promise((resolve, reject) => {
let key = ~~(Math.random() * 10);
let temp = ['es6','babel']
if (key >= 5) {
let obj = {
msg: "ok",
data: [key,...temp]
};
resolve.call(this, obj);
} else {
let obj = {
msg: "error",
data: [key,...temp]
};
reject.call(this, obj);
}
})
return promise
}
//找到页面中的Dom
let container = document.querySelector('#app');
//获取返回的结果并打印到界面
getData().then((data) => {
container.innerHTML = JSON.stringify(data)
}, (err) => {
container.innerHTML = JSON.stringify(err)
})复制代码
在这段代码中,我么使用了Promise来返回最后生成的结果,并将结果打印到界面中,其中运用了Promise、箭头函数、解构赋值等ES6的语法
二、如今,咱们去webpack配置文件中新增一条规则:
...
module: {
rules: [{
test: /\.css$/,
use: [
{ loader: "style-loader" },
{ loader: "css-loader", options: { importLoaders: 1 } },
{ loader: "postcss-loader" }
],
exclude: /node_modules/
}, {
test: /\.less$/,
use: [
{ loader: "style-loader" },
{ loader: "css-loader", options: { importLoaders: 1 } },
{ loader: "postcss-loader" },
{ loader: "less-loader" }
]
},
//新增规则,编译js
{
test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules/
}]
},复制代码
而且在根目录下新增.babelrc文件,用来存放babel相关的配置:
//.babelrc
{
"presets": [
["env",{
"targets": {
"chrome": 52,
"browsers": ["last 2 versions", "safari 7"]
}
}]
]//设置编译场景,并配置目标结果兼容到chrome52版本以上等等。
}复制代码
三、而后咱们去根目录下的index.html里面,新增一个div,而且给这个div的id取名app。
...
<body>
<div id="app"></div>
</body>
...复制代码
如今咱们在命令行运行webpack命令,并在浏览器中刷新界面,能够看到页面输出了咱们结果。
...
//编译后的js
function getData() {
var _this = this;
var promise = new Promise(function (resolve, reject) {
var key = ~~(Math.random() * 10);
var temp = ['es6', 'babel'];
if (key >= 5) {
var obj = {
msg: "ok",
data: [key].concat(temp)
};
resolve.call(_this, obj);
} else {
var _obj = {
msg: "error",
data: [key].concat(temp)
};
reject.call(_this, _obj);
}
});
return promise;
}
var container = document.querySelector('#app');
getData().then(function (data) {
container.innerHTML = JSON.stringify(data);
}, function (err) {
container.innerHTML = JSON.stringify(err);
});
...复制代码
到此,经过babel编译js就基本完成,固然,babel提供了不少的插件和配置项,有兴趣的同窗能够深刻了解,本文暂不作深层次探讨。
经过上面的操做,咱们已经能够成功的将css和js进行编译打包,可是当咱们再次去查看打包后的js文件时,发现js体积很大(目前js大小22kb),咱们只是写了几行js而已啊,那么这又是怎么回事?
实际上,webpack在打包的时候,会把全部的模块,最终打包在一个文件里面,这也是为何咱们的js文件会如此之大,但却没看到有相应的css文件的缘由。
extract-text-webpack-plugin用来实现不一样文件的分离,其用法也和以前插件的用法同样。
一、安装插件
cnpm i extract-text-webpack-plugin --save-dev复制代码
二、在webpack配置项中对以前咱们的css编译规则进行更改:
...
//引入插件
let extractTextPlugin = require('extract-text-webpack-plugin');
//初始化两个实例用于两处规则分别加载
let extractCSS = new extractTextPlugin('css/[name]-one.css');
let extractLESS = new extractTextPlugin('css/[name]-two.css');
...
module: {
rules: [{
test: /\.css$/,
exclude: /node_modules/,
//extractCSS实例对css进行操做
use: extractCSS.extract([
// { loader: "style-loader" },//style-loader不能和插件一块儿使用
{ loader: "css-loader", options: { importLoaders: 1 } },
{ loader: "postcss-loader" }
])
}, {
test: /\.less$/,
exclude: /node_modules/,
//extractLESS实例对less进行操做
use: extractLESS.extract([
// { loader: "style-loader" },
{ loader: "css-loader", options: { importLoaders: 1 } },
{ loader: "postcss-loader" },
{ loader: "less-loader" }
])
}, {
test: /\.js$/,
use: [{ loader: "babel-loader" }],
exclude: /node_modules/
}]
},
...
plugins: [
//注册插件
extractCSS,
extractLESS
]复制代码
在配置中须要注意一下几点:
最后,咱们再看咱们生成的js文件,已经只有4kb大小,减小了接近5倍的体积,可想而知,分离出css是颇有必要的。
本节咱们队webpack的加载器模块相关配置进行实战演练,学习完这一节后,您应该了解一下几点:
下一节,咱们将继续探讨webpack处理文件资源的方法,包括图片加载、图片转base6四、icon及字体处理等等。
愿各位早日成为一名合格的前端高手,加油!