webpack教程

一、webpack和npm的關系

  • npm是包管理器,及可以執(zhí)行命令包(webpack可以看成是功能強大的命令包,除了webpack還有其它如webpack-dev-server);
  • webpack可以看成是功能強大的命令包:它還可以執(zhí)行其它的功能包(裝載機,插件)

二、全局安裝/項目安裝?[1]

重點就在這個包是否要作為CMD命令來使用及本地項目是否都差不多,因此放在全局

  1. 這個包要作為CMD命令使用:要全局安裝 。如yarn cnpm webpack-dev-server等

即安裝到node_global,因為node_global在系統(tǒng)環(huán)境中配置了路徑,故而里面的腳本能在cmd中直接運行
此時這個命令的運行環(huán)境是全局環(huán)境:對應全局的webpack版本

  1. 不作為CMD命令使用:項目安裝

在package.json的scripts中也可以執(zhí)行命令包,此時通過npm run 命令別名來執(zhí)行
因為Npm會臨時把本地項目命令加載到系統(tǒng)環(huán)境path中,故而命令包放在本地也能通過npm run來執(zhí)行
如果本地有安裝,則執(zhí)行本地的。否則執(zhí)行的是全局的命令包。對應的執(zhí)行環(huán)境webpack也是一樣的。

三、打包前的準備工作(操作的webpack為3.8.1)

  • 創(chuàng)建項目: $ npm init
  • 全局安裝webpack:$ npm install webpack -g 及腳手架$ npm install webpack-cli -g

全局安裝是為了CMD使用webpack 命令

  • 本地安裝webpack: $ npm install webpack --save-dev

四、js的打包

方式①:$ webpack 源文件 目標文件 即:把源文件js打包到目標文件
如:$ webpack ./src/app.js ./dist/main.js

其它參數(shù):

  • --watch 開啟熱跟新
  • -p 壓縮目標文件
  • -d 調試時,方便定位源文件

問題:

  • 命令行太長,寫法比較復雜
  • 直接采用的是webpack命令,此時,運行環(huán)境為 全局的webpack包,并非項目的webpack版本,可能會產(chǎn)生和項目的一些沖突

方式②:通過配置文件,來簡化webpack命令

創(chuàng)建配置文件 webpack.config.js
module.exports={
   entry:'./src/app.js',
   output:{
      path: __dirname + '/dist', //__dirname 是Node的變量,表示根目錄。注意:path只能是絕對路徑
      filename: 'main.[hash:5].js' //[hash:5]表示取hash的5位,這邊是為了更新瀏覽器本地緩存
}
//json文件不能注釋,這邊是為了解釋說明用的

因為webpack會自動會查找webpack.config.js,且這邊已經(jīng)配置好了源文件及目標文件
此時可以:$ webpack 即可打包。或$ webpack --watch

問題:

  • 命令行還是不夠簡潔,一些參數(shù)還是沒辦法配置
  • (同上)直接采用的是webpack命令,此時,運行環(huán)境為 全局的webpack包,并非項目的webpack版本

方式③:通過package.json的scripts來運行腳本

修改package.json的scripts:
"scripts": {
     "build": "webpack --watch -d",
     "prod": "webpack -p"
 }

此時,可以直接$ npm run build$ npm run prod來運行腳本

優(yōu)點:

  • 命令全都由npm來運行,且命令簡潔明了(便于知道有哪些命令)
  • npm來運行,所以采用的是項目的腳本(包括其它的腳本也是一樣)

五、結合html

前面已經(jīng)學會js的打包,但畢竟運行在瀏覽器的入口是html,那怎么和html結合呢?

方式①:創(chuàng)建html,手動引入打包后的js。

問題:

  • 打包后的style,script標簽要手動寫入html。麻煩
  • 以及hash問題,每次生成的打包文件名還不一樣,又要重新寫入html。麻煩

方式②:使用html-webpack-plugin插件

作用:

  • 程序還是正常從entey入口開始打包
  • 然后,對html模板,引入<script src="打包后的js">,及其它操作(壓縮,hash等等)
安裝插件
$ npm install html-webpack-plugin --save-dev 

使用插件(在webpack.config.js中引入及掛載)

引入:
const HtmlWebpackPlugin = require('html-webpack-plugin');

掛載:
module.exports={
plugins: [
 new HtmlWebpackPlugin({
    template:"./src/index.html", //html的模版文件
    filename: 'one.html',    //生成目標html的名字
    minify: {collapseWhitespace:true} ,//壓縮html及配置壓縮類型
    hash:true//會在所有注入的靜態(tài)資源添加webpack每次編譯產(chǎn)生的唯一hash值
 })
]
}

//hash:true的效果
<script type="text/javascript" src="main.dce13.js?dce1306176497ad4a85d"></script></body>
可以發(fā)現(xiàn)dce13:為main.[hash:5]生成的hash值
?dce1306176497ad4a85d為這次生成的hash值,所有靜態(tài)文件都添加了這個

html-webpack-plugin詳細配置點擊查看
minify的詳細配置點擊查看


高級篇----多html的配置

  • 從實際意義出發(fā),肯定需要配置多入口
之前entry是string類型,這次我們采用array類型

entry: {
   "entry1":'./src/app.js', //其中,"entry1"作為chunk代碼塊
   "entry2":'./src/app1.js',
   "entry3":'./src/app2.js',
},

使用插件
plugins: [  //tips: plugins執(zhí)行順序也是從后到前執(zhí)行。即先執(zhí)行底下的插件,再上面的插件
 new HtmlWebpackPlugin({
    template:"./src/index_other.html",
    filename: 'two.html',      //這個是第二個html的出口
    minify: {collapseWhitespace:true} ,
    hash:true,
    chunks:['entry2','entry3']  //這邊測試處理兩個,也可以通過excludeChunk:['entry1'] 取余
 }),
 new HtmlWebpackPlugin({
    template:"./src/index.html",
    filename: 'one.html',    
    minify: {collapseWhitespace:true} ,
    hash:true,
    chunks:['entry1']   //這個配置是要處理的chunk代碼塊,默認為all即所有入口的都處理
 })
]
--------------------------------------------------------
說明:
chunks:[] //數(shù)組內的值為entry配置里面的key值。這邊即'entry1','entry2','entry3'
excludeChunk:[]//這個配置是除了數(shù)組內的chunk代碼塊會去處理。即取反

這邊還有個問題:多個html-webpack-plugin插件處理入口,于是會生成多個目標js。

之前:
output:{
    path: __dirname + '/dist',
    filename: 'main.[hash:5].js' //多html-webpack-plugin插件時,會生成多個同名的該文件,會同名覆蓋
}

改為=>
output:{
    path: __dirname + '/dist',
    filename: '[name].[hash:5].js' //name為對應entry的chunk名,同上
}

說明:[name]表示為對應entry的chunk名,同上

總結:對比一個html,區(qū)別在于:
需要多個入口,然后使用多個html-webpack-plugin插件處理入口對應的chunk,然后生成多html

六、結合css

前面學習了js的打包,以及把打包后的Js結合html,結合html我們采用插件來自動化幫我們處理一些事情。
但是怎么結合css呢,css不是瀏覽器入口,只能通過源js引入該css。再處理
但是webpack默認只認得js,因此要采用裝載機來處理css,再放到html中。

方式①:使用'style-loader', 'css-loader' 。這種是<style>樣式的方式

原理:

  • 在js中引入該css。import css from './one.css';
  • 然后,css-loader,實現(xiàn)從對應css文件導入文件到js中
  • 然后,style-loader,實現(xiàn)從js中,提取出css然后在html中,寫入<style>中
安裝裝載機
$ npm install css-loader style-loader --save-dev

使用裝載機(在webpack.config.js中掛載) 相比插件不用引進

module: {
   rules: [
     {
       test: /\.css$/,    //正則表達式,匹配對應的后綴文件,然后用底下對應的裝載機處理
       use: [ 'style-loader', 'css-loader' ]    //裝載順序為***從右到左***
     }
   ]
}

說明:

  • css-loader:即:編譯。加載.css文件,注入到js文件中,以字符串的形式存在
  • style-loader:即:提取。使用<style>將css-loader內部樣式注入到我們的HTML頁面
  • css-loader/style-loader詳細配置點擊查看
  • 這種方式在html生成的是<style>標簽

方式②:結合extract-text-webpack-plugin插件:實現(xiàn)css分離成文件。這種是<link>樣式的方式

安裝插件
$ npm install  extract-text-webpack-plugin  --save-dev

使用插件
 引入:
 const ExtractTextPlugin = require('extract-text-webpack-plugin');


//這邊對比css-loader/style-loader的區(qū)別
module: {
  rules: [
     {
       test: /\.css$/,
       use:ExtractTextPlugin.extract({
         fallback: 'style-loader',    //提取要用到的裝載機
         use: [ 'css-loader' ]    //編譯要用到的裝載機
       })
     }
   ]
}


以及配置plugins:

plugins{
  new ExtractTextPlugin('style.css')  //生成目標css的文件名為style.css
}

說明:

  • 通過extract-text-webpack-plugin插件實現(xiàn)了css的分離,而不是注入js中
  • extract-text-webpack-plugin詳細配置點擊查看
  • 和webpack4.0+ 不兼容
  • 這種方式在html生成的是<link>標簽
  • 所以和第一種方式的優(yōu)劣勢對比即為:<style>和<link>樣式的優(yōu)劣勢對比 及css有獨立hash等

這邊補充對于scss的css文件的處理

安裝scss裝載機:
$ npm install sass-loader node-sass --save-dev

方式一下使用sass-loader裝載機:
module: {
   rules: [
     {
       test: /\.scss$/,    //這邊匹配文件后綴為.scss
       use: [ 'style-loader', 'css-loader' ,"sass-loader"]    //只是這邊后面增加該裝載機
     }
   ]
}

------------------------------------------------------------------
方式二下使用sass-loader裝載機:
module: {
  rules: [
     {
       test: /\.scss$/,
       use:ExtractTextPlugin.extract({
         fallback: 'style-loader',    
         use: [ 'css-loader',"sass-loader" ]    
       })
     }
   ]
}


以及配置plugins:

plugins{
  new ExtractTextPlugin('style.css')  
}

其它補充

  • 添加hash: plugins: [new ExtractTextPlugin('style.[hash:5].css')]

七、webpack-dev-server插件的使用

前面有介紹CMD命令包對于全局安裝或本地安裝的選擇,點擊回顧
方式①:全局安裝 $ npm install webpack-dev-server -g
此時,在CMD即可使用該命令:$ webpack-dev-server //注意此時運行環(huán)境為全局的Webpack版本


方式②:項目安裝 $ npm install webpack-dev-server --save-dev
此時可以通過配置scripts可以讓npm來運行腳本

"scripts": {
  "dev": "webpack-dev-server"
}

此時,可以直接npm run dev來開啟本地服務


補充

webpack.config.js中配置

devServer: {
  port: 9000,  //這邊配置端口號
  open:true  //這邊會自動打開瀏覽器
},

說明

  • 配置webpack-dev-server 運行時報錯配置 Can't resolve 'webpack/hot/dev-server' 。說明項目中,沒有安裝webpack
  • webpack-dev-server生成的包并沒有放在你的真實目錄中,而是放在了內存中
  • 和webpack4.0+不兼容,這邊webpack@3.8.1安裝2.9.1
  • webpack-dev-server的詳細配置點擊查看
  • 對比webpack --watch避免了打包文件及實現(xiàn)了熱更新

八、

# babel6配置過程

九、區(qū)分生產(chǎn)環(huán)境和開發(fā)環(huán)境

  • 配置部分區(qū)分
  • 方式①:在webpack.json的scripts運行腳本時,增加變量并賦值

eg:"prod": " SET NODE_ENV=production & SET hcl=huchunlin && webpack -p",
配置部分使用:console.log(process.env.NODE_ENV);console.log(process.env.hcl);
說明:process.env.變量來訪問
window系統(tǒng)需要SET 。max系統(tǒng)不需要

  • 方式②:不同命令進入,即會執(zhí)行不同的配置文件

eg:"prod": " webpack -p --config ./config/prod.js",
即通過--config來執(zhí)行指定配置文件

  • 方式③:相結合
  • 源代碼(打包后的文件)區(qū)分

通過webpack.DefinePlugin來定義源代碼的全局變量。在編譯時會進行替換

 webpack.config.js中=>定義全局變量
-----------------------------------------------------------------
 plugins: [
   new webpack.DefinePlugin({
     "hcl": JSON.stringify('這個是在webpack.config定義的變量')
   })
 ]

源代碼中,比如在app.js中=>使用全局變量
-----------------------------------------------------------------
 console.log(hcl)
  • 配置文件和源代碼都要能區(qū)分:結合①和②

  1. 二、全局安裝/項目安裝 ?

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容