webpack的常用loder和插件 loder和插件是什麼,現在暫且不表,看到後面你就懂了 引入css問題 直接用link標簽導入css 在前面的講解中,相信已經對webpack有一定瞭解了,相比很多朋友已經躍躍欲試了,準備要搞一個自己的小 ...
webpack的常用loder和插件
loder和插件是什麼,現在暫且不表,看到後面你就懂了
引入css問題
直接用link標簽導入css
在前面的 vue(7)—— 組件化開發 — webpack(1) 講解中,相信已經對webpack有一定瞭解了,想必很多朋友已經躍躍欲試了,準備要搞一個自己的小網站出來了,寫上css,調整好代碼,準備說乾就乾:
同樣的,因為以後的開發中,肯定會有很多個css文件,可能一個vue組件就需要一個css文件,然後你又跟前面的js文件引入一樣,在html文件里用link標簽引入一堆的css嗎?
這還是那個用戶體驗的問題。
在組件文件里用import導入css
所以,這裡的解決方法還是同js文件一樣,用導包的方式: import ‘./XX.css’
註意:導入css通常情況下是在入口組件里導入,而不是隨便哪裡都可以導入,當然最準確的還是根據自己的代碼邏輯做相應調整
index.html:
已把link標簽刪除掉,通過導入編譯好的bundle.js來插入css
好,在終端,使用命令npm run dev編譯一下,發現報錯了
提示的意思是說你需要一個loader組件來控制這個css格式類型的文件
這裡要補充下,webpack.config.js是js文件,我們定義的vue局部組件尾碼也是js,而webpack預設只識別js文件,不能識別處理非js的文件,所以需要一個loder引導識別。所以在前面沒遇到這個問題,現在遇到了
所以這裡需要安裝一個css的loader,是的,以上都是引子,就是為了引出這個loader
css-loader安裝
安裝的時候記得安裝兩個,一個是css-loder這個是識別css尾碼的文件,還要安裝一個style-loader,這個是識別<style>標簽的
npm i css-loader style-loader -D:
安裝完成後,package.json的開發環境里已經自動寫入:
在webpack配置文件裡加入如下,webpack.dev.config.js
註意
- module,test,loader都是固定的鍵,不能更改
- style-loder!css-loader,意思是先載入css-loder,再載入style-loder
關於這個很好理解,肯定是先有css文件,再有的css樣式對吧,主要就是這裡的【!】是先取後面個的意思
module.exports = {
entry: { //入口
name: './dist/app.js' //鍵名隨意,值為項目入口js
},
output: { //出口
filename: './bundle.js' //鍵名必須為filename,值為項目編譯好的js
},
watch: true,
module:{
loaders:[
{
test:/\.css$/,
loader:'style-loader!css-loader'
}
]
}
}
另外的webpack.prod.config.js配置是暫且不管,當然你也可以設置成一樣的,記得把watch屬性刪掉
現在再使用命令 npm run dev 編譯看看
編譯成功,再次打開index.html文件:
link標簽和style標簽都是bundle自動加上去的
完美吧,終於可以顯示css了
如果你在編譯的時候遇到問題,比如遇到以下問題,請檢查你的webpack.dev.config.js文件與css相關的配置是否有問題
註意:如果你遇到這樣的寫法,不是loders而是rules,不是loder而是use,這種也可行,這是新版的寫法,不重要,效果是一樣的
高級css語言
如果你的代碼里有使用高級的css語言,比如less之類的,你同樣需要重新安裝一次loder,less對應的是less-loder,sass對應的是sass-loder,其他的就不多說了,可以去npm官網查
css里的url問題
在寫css時,肯定會有引入一張圖片的樣式,比如這裡:
給入口的div綁定了一個id為main屬性:
我事先在項目的根目錄放了一張圖片,1.jpg,寫上css樣式,比如:
當完成以上操作的時候,這邊的實時監聽的已經報錯了:
是的,又需要安裝一個針對url的loader, npm i file-loader url-loader -D,網不好的話你可以使用前面說過的nrm來安裝
安裝完,package.json文件里又自動多了兩個參數:
再在webpack.dev.config.js里配置如下,圖片格式有png,jpg,gif,jpeg,bmp,png,所以寫瞭如下
註意:只添加url-loder,不用給file-loder
將那個錯誤的卡住的編譯程式按ctrl+c終止掉,重新運行,沒有報錯:
打開網頁:
右邊的css樣式就是url-loder把圖片自動做base64編碼了,然後通過瀏覽器讀取base64編碼,藉此顯示圖片
直接複製按個base64編碼地址,另起一個瀏覽器視窗,是可以直接打開的:
完美
在loder部分還可以給參數
因為圖片用的base64編碼,那麼就可以稍微做限制,webpack.dev.config.js:
module.exports = {
entry: { //入口
name: './dist/app.js' //鍵名隨意,值為項目入口js
},
output: { //出口
filename: './bundle.js' //鍵名必須為filename,值為項目編譯好的js
},
watch: true,
module: {
loaders: [
{
test: /\.css$/,
loader: 'style-loader!css-loader'
},
{
test:/\.(jpg|jpeg|png|gif|bmp)$/,
loader:'url-loader?limit=20&name=[hash:8]-[name].[ext]'
}
]
}
}
打開網頁:
我添加的那幾個參數的意思:
- limit:瓶頸顯示,limit=20,limit單位是bytes,如果超過給定的值則不會作為base64編碼,如果沒超過則作為base64編碼
- name:指圖片將被編碼的名字,[hash:8]指取hash值前8個,[name]即原來的圖片的名字,[ext]指原來的圖片的尾碼名。此時的圖片,原來的就是1.jpg,所以這裡是 558c08ec-1.jpg
-
如果不給name屬性,webpack會按自己的規則設定,把文件名取hash值,預設取32位,作為最後的名字
引入bootsrap庫
首先使用npm安裝bootstrap:
導入bootsrap
作為入口的app.js,這裡說明一下,如果是引入下載的插件,不用寫文件的路徑,只有引入自己寫的文件才需要寫文件路徑
webpack配置
webpack配置文件不用變,同上
module.exports = {
entry: { //入口
name: './dist/app.js' //鍵名隨意,值為項目入口js
},
output: { //出口
filename: './bundle.js' //鍵名必須為filename,值為項目編譯好的js
},
watch: true,
module: {
loaders: [
{
test: /\.css$/,
loader: 'style-loader!css-loader'
},
{
test:/\.(jpg|jpeg|png|gif|bmp)$/,
loader:'url-loader?limit=20&name=[hash:8]-[name].[ext]'
}
]
}
}
webpack配置
入口組件app.js
在app.js入口組件里寫入bootstrap的樣式,給了幾個比較簡單的class名:
最後index.html顯示結果:
當然你會發現,在項目根目錄有編譯過的圖片文件:
引入字體
字體就不用多說了,其實字體也是個url,所以用url-loader就行了,webpack配置:
然後你就可以在css樣式里寫入你需要的字體樣式就行了,這裡就不展示示例了,自己體會了
處理es6語法
在前面已經瞭解了,瀏覽器預設不識別es6的語法,es即ECMAscript6,比如class定義類,瀏覽器就不識別,不知道後續的瀏覽器會不會識別這些了。
我在code1.js上定義了一個es6的類:
這邊已經報錯了:
此時怎麼辦呢?對了,還是用loder
安裝插件
安裝兩個插件:npm i babel-preset-env babel-preset-stage-0 -D
註:如果babel-preset-stage-0用不了,可以卸載了安裝babel-preset-stage-es2015,babelrc部分相應的也要改動對應的stage
安裝另外一套插件:npm i babel-core babel-loader bable-plugin-transform-runtime -D
註:
1.如果你的webpack版本比較低,安裝的babel-loader無法使用(因為預設安裝的最新版)
你可以安裝指定版本,npm i babel-loader@7,我安裝的7可用
2.如果你在安裝 npm i babel-core babel-loader bable-plugin-transform-runtime -D 時出錯:
多試幾次,或者切換下npm安裝源試試
設置bable
好的,安裝完成之後。直接在項目的根目錄,創建一個【.babelrc】文件,寫入如下參數:
{
"presets":["env","stage-es2015"],
"plugins": ["transform-runtime"]
}
註意對應你安裝的stage版本,我安裝stage-0用不了,已經切換了stage-es2015
webpack配置文件
如下修改:
module.exports = {
entry: { //入口
name: './dist/app.js' //鍵名隨意,值為項目入口js
},
output: { //出口
filename: './bundle.js' //鍵名必須為filename,值為項目編譯好的js
},
watch: true,
module: {
loaders: [
{
test: /\.css$/,
loader: 'style-loader!css-loader'
},
{
test:/\.(jpg|jpeg|png|gif|bmp)$/,
loader:'url-loader?limit=20&name=[hash:8]-[name].[ext]'
},
{
test:/\.(ttf|eot|svg|woff|woff2)$/,
loader:'url-loader'
},
{
test:/\.js$/,
loader:'babel-loader',
exclude:/node_modules/
}
]
}
}
webpack配置文件
其實用path組件也可以,這個path組件是內置的,如下寫也可以:
var path = require('path')
module.exports = {
entry: { //入口
name: './dist/app.js' //鍵名隨意,值為項目入口js
},
output: { //出口
filename: './bundle.js' //鍵名必須為filename,值為項目編譯好的js
},
watch: true,
module: {
loaders: [
{
test: /\.css$/,
loader: 'style-loader!css-loader'
},
{
test:/\.(jpg|jpeg|png|gif|bmp)$/,
loader:'url-loader?limit=20&name=[hash:8]-[name].[ext]'
},
{
test:/\.(ttf|eot|svg|woff|woff2)$/,
loader:'url-loader'
},
{
test:/\.js$/,
loader:'babel-loader',
exclude:path.resolve('./node_modules')
}
]
}
}
webpack-path
exclude的意思是排除根目錄下node_modules里的js文件,因為不排除的話,babel就會去編譯node_modules里的js,消耗資源不說,編譯了用不了
編譯運行
現在運行npm run dev再看:
如果編譯時報錯:
意思就是說最後那個‘./node_module’無法識別。
所以在exclude部分,你要嘛用path.resolve('./node_modules'),要嘛用/node_modules/,其他的寫法都是錯的
正確編譯:
其實已經識別了,但是說我這有語法錯誤
好的,我稍微修改一下,立馬不報錯了
好的,這裡這個babel算是比較高級的用法了,以後還會用到,就不多解釋了。目前你就記住,babel是把es6的高級語法編譯成瀏覽器可識別的低級語法就行了
html-webpack-plugin插件
在以後的開發中,可能有這種需求:
當我們已經確定把項目碼好,準備把代碼輸出來,然後直接把輸出來的相關文文檔拷走即可,這樣的需求,怎麼辦?
完全可以讓webpack編譯的時候自動生成html文件,而不是我們自己去手動的設置,因為我們改動的目前只是開發環境,有些東西其實對於生產環境來說是不需要的,所以這個怎麼操作呢?
安裝html-webpack-plugin
webpack配置
然後在webpack.prod.config.js文件里作如下配置:註意這次是生產環境的那個webpack配置文件了:
var path = require('path')
var htmlwebpackplugin = require('html-webpack-plugin')
module.exports = {
entry: { //入口
name: './dist/app.js' //鍵名隨意,值為項目入口js
},
output: { //出口
path:path.resolve('./src'),//相對轉絕對,設定一個輸出文件路徑
filename: './bundle.js' //鍵名必須為filename,值為項目編譯好的js
},
plugins:[
new htmlwebpackplugin({
template:`./index.html` // html文件參照物,即開發環境下的html文件
})
],
module: {
loaders: [
{
test: /\.css$/,
loader: 'style-loader!css-loader'
},
{
test:/\.(jpg|jpeg|png|gif|bmp)$/,
loader:'url-loader?limit=20&name=[hash:8]-[name].[ext]'
},
{
test:/\.(ttf|eot|svg|woff|woff2)$/,
loader:'url-loader'
},
{
test:/\.js$/,
loader:'babel-loader',
exclude:/node_modules/
}
]
}
}
webpack.prod.config.js
編譯運行
其他不用變,把剛纔的測試環境卡住的npm run dev停掉,用npm run build:
之後則會在根目錄下自動生成一個src文件夾:
打開index.html,發現一個小問題,出現了兩個bundle。
問題解決
因為使用npm run build時,會自動給我們配置一個bundle,但是我們的參照的那個index.html文件里本來就有了一個bundle,所以,把參照物里的bundle刪除:
再次使用npm run build編譯:
這下正常了,完美
所以,這個 var htmlwebpackplugin = require('html-webpack-plugin')有兩個作用:
1.參照開發環境的文件打包
2.自動編譯好並把打包好的bundlue.js文件添加進html文件里
http-server插件
最後還有個插件,一個偽伺服器插件 http-server。如果你使用的是pycharm開發的話,pycharm自帶了這個功能,在html文件直接點右上角的瀏覽器圖標即可自動掛載在本地埠。詳細的就不多說了
安裝插件
因為一會兒要直接調用命令使用,所以安裝在了全局
啟動
使用命令 hs -o -p 8888,意思是通過8888埠啟動
如果你設置預設的瀏覽器的話,會自動啟動預設瀏覽器,然後自動開始一個新視窗直接打開:
換了一個瀏覽器,正常訪問:
webpack-dev-server插件
又來個問題了,如果你每改一次都要刷新一次嗎?很煩對不對,所以有必要有一個工具當我們改完代碼,不用刷新瀏覽器頁面,自動的更新,類似剛纔我們用的webpack配置文件,實時監聽的效果:
安裝webpack-dev-server插件
註意,安裝webpack-dev-server時,由於新版需要webpack-cli(cli即腳手架,後面會講到)的支持,所以最好安裝低版本的:
webpack配置
webpack.dev.config.js:
其實跟上面的一樣沒有變,註意是開發環境下的配置文件,不是生產環境下的配置文件
module.exports = {
entry: { //入口
name: './dist/app.js' //鍵名隨意,值為項目入口js
},
output: { //出口
filename: './bundle.js' //鍵名必須為filename,值為項目編譯好的js
},
watch: true,
module: {
loaders: [
{
test: /\.css$/,
loader: 'style-loader!css-loader'
},
{
test:/\.(jpg|jpeg|png|gif|bmp)$/,
loader:'url-loader?limit=20&name=[hash:8]-[name].[ext]'
},
{
test:/\.(ttf|eot|svg|woff|woff2)$/,
loader:'url-loader'
},
{
test:/\.js$/,
loader:'babel-loader',
exclude:/node_modules/
}
]
}
}
webpack.dev.config.js
package文件修改
package.json配置文件作如下修改:
"scripts": {
"dev": "webpack-dev-server --open --hot --inline --config ./webpack.dev.config.js",
"build": "webpack --config ./webpack.prod.config.js"
},
去掉之前用過的bundle
其實這一步不用做也可以,因為不影響,但是為了和後面要說的原理對應,所以改了文件名
把之前bundle文件改為:bundle.backup.js:
編譯運行
現在再用命令 npm run dev啟動編譯
自動打開瀏覽器:
修改代碼
我現在修改一下文字的顏色,因為背景圖顏色和字體顏色有點不搭配我改成黑色:
這邊的watch 發生變化,自動在重新編譯:
再次打開瀏覽器,根本不用刷新,已經自動運用上css了,完美,這才是我們希望的開發環境
而此時,項目目錄下根本沒有bundle.js文件:
剛纔我們用的bundle.js文件已經改名了,所以不可能是之前我們生成的bundle文件產生的效果
這就是webpack-dev-server的特性:
自動監聽編譯,並且生成了一個虛擬的bundle.js文件在記憶體上,並且在項目的根目錄中虛擬存在
另一種寫法
設定熱更新還有另一種寫法:
代碼:
var path = require('path') var htmlwebpackplugin = require('html-webpack-plugin') module.exports = { entry: { //入口 name: './dist/app.js' //鍵名隨意,值為項目入口js }, output: { //出口 path:path.resolve('./src'),//相對轉絕對,設定一個輸出文件路徑 filename: './bundle.js' //鍵名必須為filename,值為項目編譯好的js }, plugins:[ new htmlwebpackplugin({ template:`./index.html` // html文件參照物,即開發環境下的html文件 }) ], module: { loaders: [ { test: /\.css$/, loader: 'style-loader!css-loader' }, { test:/\.(jpg|jpeg|png|gif|bmp)$/, loader:'url-loader?limit=20&name=[hash:8]-[name].[ext]' }, { test:/\.(ttf|eot|svg|woff|woff2)$/, loader:'url-loader' }, { test:/\.js$/, loader:'babel-loader', exclude:/node_modules/ } ] } }webpack.dev.config.js
package.json文件直接一個webpack 不用給任何參數:
"scripts": { "dev": "webpack-dev-server --config ./webpack.dev.config.js", "build": "webpack --config ./webpack.prod.config.js" },
npm run dev:
自動打開瀏覽器:
但是這種方式相對前面那個更有難度一點,效果一樣的
代碼打包
以上所有相關代碼打包整合:點我 (因為博客園文件限制最大為10M,我全部代碼打包已經超過了,所以node_modules文件自行初始化自行安裝第三方插件)
總結:
本節說了很多插件,有點繁瑣,但是基本都是後面會用到的,多看多熟悉