在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及字體處理等等。
願各位早日成爲一名合格的前端高手,加油!