我們可以在js中引入樣式檔案
require(`myStyle.css`)
複製程式碼
這時我們便需要引入相應的webpack loader來幫助我們解析這段程式碼。
css-loader搭配style-loader
首先,我們可以引入css-loader和style-loader來處理css的解析,其中,css-loader是用來解析css檔案,style-loader是用來將css檔案嵌入到js檔案裡
var path = require(`path`)
module.exports = {
context: path.join(__dirname, `src`)
entry: `./`,
module: {
rules: [
{
test: /.css$/,
include: [
path.join(__dirname, `src`)
],
use: [`style-loader`, `css-loader`]
}
]
},
output: {
path: path.join(__dirname, `dist`),
filename: `[name].bundle.[hash].js`
}
}
複製程式碼
在上面的程式碼裡,解析順序是從右到左解析,先使用css-loader解析出css檔案之後,再使用style-loader嵌入到js程式碼裡。
如果你使用less來寫樣式的話,則需要先用less-loader來編譯樣式檔案為css檔案,再繼續使用css-loader與style-loader。另外,loader載入器可以省略後面的-loader。所以上面的程式碼可以縮寫成
module: {
rules: [
{
test: /.css$/,
include: [
path.join(__dirname, `src`)
],
use: [`style`, `css`, `less`]
}
]
}
複製程式碼
一般在測試環境裡為了快點編譯css,會用這種方式多一點,但是這樣子編譯出來的js檔案會比較大,不大適合在生產環境裡使用。
編譯成單獨的檔案
上面的做法會把css和js打包在一起,減少實際請求的次數,但是由於編譯出來的js檔案比較大,浪費頻寬。因此,我們使用extract-text-webpack-plugin外掛,把css檔案編譯成獨立的檔案。我們就可以利用CDN把這個檔案推送到節點伺服器,或者根據視情況按需載入,進而優化客戶請求鏈路,加速頁面響應。
var path = require(`path`),
ExtractTextPlugin = require(`extract-text-webpack-plugin`)
module.exports = {
context: path.join(__dirname, `src`),
entry: `./`,
module: {
rules: [{
test: /.css$/,
include: [
path.join(__dirname, `src`)
],
use: ExtractTextPlugin.extract({
fallback: `style`,
use: `css`
})
}]
},
output: {
path: path.join(__dirname, `dist`),
filename: `[name].bundle.[hash].js`
},
plugins: [
new ExtractTextPlugin(`[name].css`)
]
}
複製程式碼
通過上面的程式碼,我們使用extract-text-webpack-plugin外掛處理src目錄下所有的css檔案,先使用css-loader外掛解析出css程式碼,如果解析失敗,使用style-loader外掛解析,最終在dist目錄下生成對應的js檔案
相容舊瀏覽器
以前我們寫樣式時,有些樣式不同瀏覽器需要加不同的字首,如-webkit-。現在有了構建工具,我們便不需要再去關注這些字首了,構建工具會自動幫我們加上這些字首。
對於webpack我們自然想到需要使用loader或者plugin來幫助我們做這些事情,查了下發現autoprefixer-loader已經廢棄不再維護了,推薦使用posscss
postcss是用於在js中轉換css樣式的js外掛,需要搭配其他外掛一起使用,這點和babel6一樣,本身只是個轉換器,並不提供程式碼解析功能。
這裡我們需要autoprefixer外掛來為我們的樣式新增字首。首先下載該模組。
npm install -D autoprefixer
複製程式碼
接著便可以配置webpack了
var autoprefixer = require(`autoprefixer`)
module.exports = {
...
module: {
loaders: [
...
{
{
test: /.css$/,
loader: ExtractTextPlugin.extract(["css", "postcss"])
},
}
]
},
postcss: [autoprefixer()],
...
}
複製程式碼
檢視一下抽取出來的樣式檔案便可以發現已經加上了字首
a {
display: flex;
}
/*compiles to:*/
a {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex
}
複製程式碼
另外autoprefixer還可以根據目標瀏覽器版本生成不同的字首個數,例如你的應用的使用使用者如果大多數是使用比較新版本的瀏覽器,那麼便可以做如下配置。
postcss: [autoprefixer({ browsers: [`last 2 versions`] })]
這是生成的樣式便會有些不一樣,還是上面的例子
a {
display: flex;
}
/*compiles to:*/
a {
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
}
複製程式碼
樣式壓縮
壓縮程式碼我們可以使用webpack的內建外掛UglifyJsPlugin來做,它既可以壓縮js程式碼也可以壓縮css程式碼。
plugins: [
...
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false
}
}),
...
]
複製程式碼
其實並不能說是在壓縮css程式碼,本質來說還是壓縮js程式碼,再將這塊程式碼輸出到css檔案中。
使用CommonsChunkPlugin抽取公共程式碼
首先要明確一點CommonsChunkPlugin是在有多個entry時使用的,即在有多個入口檔案時,這些入口檔案可能會有一些共同的程式碼,我們便可以將這些共同的程式碼抽取出來成獨立的檔案。明白這一點非常重要。(搞了很久才明白的一點,唉~~~~)
如果在多個entry中require了相同的css檔案,我們便可以使用CommonsChunkPlugin來將這些共同的樣式檔案抽取出來為獨立的樣式檔案。
module.exports = {
entry: {
"A": "./src/entry.js",
"B": "./src/entry2.js"
},
...
plugins: [
new webpack.optimize.CommonsChunkPlugin({
name: "commons", filename: "commons.js"
}),
...
]
}
複製程式碼
當然,這裡不止會抽取共同的css,如果有共同的js程式碼,也會抽取成為commons.js。
這裡有個有趣的現象,抽取出來的css檔案的命名將會是引數中name的值,而js檔名則會是filename的值。
CommonsChunkPlugin好像只會將所有chunk中都共有的模組抽取出來,如果存在如下的依賴
// entry1.js
var style1 = require(`./style/myStyle.css`)
var style2 = require(`./style/style.css`)
// entry2.js
require("./style/myStyle.css")
require("./style/myStyle2.css")
// entry3.js
require("./style/myStyle2.css")
複製程式碼
使用外掛後會發現,根本沒有生成commons.css檔案。
如果我們只需要取前兩個chunk的共同程式碼,我們可以這麼做
module.exports = {
entry: {
"A": "./src/entry.js",
"B": "./src/entry2.js",
"C": "./src/entry3.js"
},
...
plugins: [
new webpack.optimize.CommonsChunkPlugin({
name: "commons", filename: "commons.js", chunks: [`A`, `B`]
}),
...
]
}
複製程式碼