[TOC]javascript
前言:css
webpack是前端目前最流行的打包工具,爲了節省學習webpack的時間,下面我將以一個案例的形式來介紹webpack的使用,畢竟學習webpack就是要知道怎麼使用,介紹案例的過程,遇到相關的知識點,我也會作相應的介紹,本案例使用的開發工具是vscodehtml
基礎知識前端
只要你安裝了node環境,npm就自動安裝好vue
在node裝完以後,全局就有一個npm命令可使用了,可是npm下載各類包默認的服務器在國外,下載速度大受影響,有時還會致使一些環境問題,所以咱們能夠選擇從國內的服務器下載包,這要感謝淘寶團隊的付出,爲國內開發者提供了npm各種包的鏡像java
執行如下命令,安裝淘寶npm包下載工具node
npm i -g cnpm --registry=https://registry.npm.taobao.org
複製代碼
在下載包時,使用如下命令,使用關鍵詞cnpm
,如jquery
cnpm i vue --save
複製代碼
注意:在使用cnpm下載包的過程可能會出現一些警告的信息,但並不影響實際包的使用,可是想要查看安裝完成以後的包的依賴信息時,可能查找不到,什麼是依賴?後面會介紹到webpack
因此建議使用包管理工具,來設置npm從哪一個服務器下載包程序員
執行如下命令安裝nrm
npm install nrm -g
複製代碼
查看可用的服務器列表 nrm ls
查看當前正在使用的服務器 nrm current
切換到指定的服務器 nrm use 服務器名稱
測速命令
nrm test
nrm test
指定的服務器名稱
經過上面的講解,npm的最優使用方案:
安裝nrm,將npm下載包的服務器設置爲淘寶
下載包(本地安裝) 下載的包會放到當前項目中的node_modules文件夾中!
npm install 包名
npm install 包名@版本號
簡寫:
npm i 包名
npm i 包名@版本號
npm install 包名 包名1 包名2
卸載包 npm uninstall 包名
全局安裝
當要使用一個包,這個包會提供一個全局命令的時候,這個包就須要被全局安裝!
命令 npm install 包名 -g
npm install 包名 --global
在網頁中會引用哪些常見的靜態資源?
若是咱們按照傳統的方式引入這些文件會形成什麼問題?
注意:
開客戶端中打開
執行命令:
npm install nrm -g
複製代碼
切換到指定的服務器
nrm use taobao
複製代碼
npm init
複製代碼
這時文件的目錄結構變成了這樣
下面介紹一下目錄中的一些文件類型
package.json
文件:
package.json
文件就是用來描述一個包的信息的!
只要一個文件夾中有一個合格的pacakge.json
文件,那麼這個文件夾就能夠被稱爲是一個包!
合格的定義: 必須包含兩個屬性 name version
版本號說明
通常的版本號都會包含3個數字,中間用.隔開 格式: 主版本號.次版本號.修訂版本號
主版本號: 當代碼功能更新,更新以後,不兼容以前的版本了,那麼須要更新主版本號! 此版本號: 當代碼功能更新,更新以後,依然兼容以前的版本,只是新增了某些功能,那麼須要更新次版本號 修訂版本號: 當代碼更新,更新的只是修復了某些BUG,或者優化了某些功能,那麼這個時候只須要更新 修訂版本號就能夠了
jquery: 1.x 2.x 3.x 1.10.1 1.12.4 1.12.1 1.12.4
dependencies 和 devDependencies 的說明
這兩個屬性中保存的都是當前包全部的依賴信息。
dependencies: 運行時依賴項,在將代碼上傳到服務器時,這個包仍被須要 devDependencies: 開發時依賴項,這個依賴項只須要在開發時時候,上傳到服務器的時候不須要!
問題: 爲何要將依賴項信息存儲起來呢??? 主要目的是爲了代碼共享的時候,比較方便!
在進行代碼分享的時候,不須要分享node_modules,只須要分享本身的代碼和pacakge.json便可,另外的程序員拿到代碼以後,本身根據pacakge.json下載全部的依賴項便可!
npm install
這條命令會自動根據package.json中保存的包信息進行下載 (devDependencies+dependencies)
只下載運行時依賴項可使用命令npm install --production
如何將依賴項的信息保存到dependencies 和 devDependencies中
在早期版本的npm中,依賴項信息不會自動保存!
npm install 包 --save
npm install 包 -S
npm install 包 --save-dev
npm install 包 -D
通過初始化的目錄,會生成package.json文件,該文件會記錄本文件夾的一些相關的信息,好比入口文件,項目名,安裝了哪些依賴包等,注意項目名不能爲webpack,搭建目錄結構那步我已經講了,不然,在以後的安裝打包工具會報錯
index.html
<ul>
<li>測試專用</li>
<li>測試專用</li>
<li>測試專用</li>
<li>測試專用</li>
<li>測試專用</li>
<li>測試專用</li>
<li>測試專用</li>
<li>測試專用</li>
</ul>
複製代碼
main.js
//導入jQuery包
import $ from 'jquery'//這裏須要安裝庫類
// 設置偶數行背景色,索引從0開始,0是偶數
$('li:even').css('backgroundColor','lightblue');
// 設置奇數行背景色
$('li:odd').css('backgroundColor','pink');
複製代碼
cnpm i jquery --save
複製代碼
這時咱們按照常規的方法在index.html頁面引入main.js文件,是會報錯的,由於,main.js文件中的import $ from 'jquery'
是屬於高級語法,瀏覽器是沒法識別的,因此要使用打包工具來對main.js文件進行處理,編譯成另外一個文件,再在頁面中引入編譯後的文件,便可
npm i webpack webpack-cli -g
npm i webpack webpack-cli -D
複製代碼
新建一個與package.json同級的配置文件webpack.config.js,設置打包模式
module.exports={
mode:"development"
}
複製代碼
運行,打包代碼
webpack src/main.js dist/bundle.js
複製代碼
上面代碼的是對main.js進行打包,變成bundle.js文件,在頁面中引入該文件,瀏覽器就不存在高級語法不識別的問題了,可是在本案例中,對main.js進行打包後變成的是dist/main.js,而不是dist/bundle.js文件,因此在頁面中引入的是dist/main.js,這是咱們就能看到main.js起做用了
注意,到了這一步,每次修改js文件都要從新執行上面的打包代碼,這樣才能生效,十分麻煩,爲了解決這個問題,咱們能夠採用實時打包,方法見後面
webpack.config.js
中配置這兩個路徑:// 導入處理路徑的模塊
var path = require('path');
// 導出一個配置對象,未來webpack在啓動的時候,會默認來查找webpack.config.js,並讀取這個文件中導出的配置對象,來進行打包處理
module.exports = {
entry: path.resolve(__dirname, 'src/js/main.js'), // 項目入口文件
output: { // 配置輸出選項
path: path.resolve(__dirname, 'dist'), // 配置輸出的路徑
filename: 'bundle.js' // 配置輸出的文件名
},
mode: 'development'
}
複製代碼
注意:
webpack
命令便可從新打包webpack.config.js
指定了出口文件是:dist/bundle.js
,因此咱們要在index.html中將以前引入的 打包編譯後的文件dist/main.js
改成dist/bundle.js
便可看到效果這裏補充一個知識點:
node 的path模塊中 path.resolve()和path.join()的區別
1、path模塊的引入。
直接引用。node中自帶的模塊
const path = require('path');
2、path.join(path1,path2,path3.......)
做用:將路徑片斷使用特定的分隔符(window:\)鏈接起來造成路徑,並規範化生成的路徑。若任意一個路徑片斷類型錯誤,會報錯。
const path = require('path');
let myPath = path.join(__dirname,'/img/so');
let myPath2 = path.join(__dirname,'./img/so');
let myPath3=path.join('/foo', 'bar', 'baz/asdf', 'quux', '..');
console.log(__dirname);//__dirname,文件路徑
console.log(myPath);
console.log(myPath2);
console.log(myPath3);
3、path.resolve([from...],to)
做用:把一個路徑或路徑片斷的序列解析爲一個絕對路徑。至關於執行cd操做。
/被解析爲根目錄。
let myPath = path.resolve(__dirname,'/img/so');
let myPath2 = path.resolve(__dirname,'./img/so');
let myPath3=path.resolve('/foo/bar', './baz');
let myPath4=path.resolve('/foo/bar', '/tmp/file/');
console.log(__dirname);
console.log(myPath);
console.log(myPath2);
console.log(myPath3);
console.log(myPath4);
複製代碼
即便是咱們簡化了打包工具,可是每次修改了main.js,仍是要從新輸入命令webpack
來進行打包,爲了解決這一麻煩,下面咱們裝一個插件來進行實時打包,每次修改後,自動進行打包,多好
運行cnpm i webpack-dev-server --save-dev
安裝到開發依賴
安裝完成以後,在命令行直接運行webpack-dev-server
來進行打包,發現報錯,報錯內容爲:'webpack-dev-server' 不是內部或外部命令,也不是可運行的程序或批處理文件。
此時須要藉助於package.json
文件中的指令,來進行運行webpack-dev-server
命令,在scripts
節點下新增"dev": "webpack-dev-server"
指令
執行該條命令:npm run dev
發現能夠進行實時打包,可是dist目錄下並無生成bundle.js
文件,這是由於webpack-dev-server
將打包好的文件放在了內存中,把bundle.js
放在內存中的好處是:因爲須要實時打包編譯,因此放在內存中速度會很是快
這個時候訪問webpack-dev-server啓動的http://localhost:8080/
網站,發現是一個文件夾的面板,須要點擊到src目錄下,才能打開咱們的index首頁,
此時引用不到bundle.js文件,須要修改index.html中script的src屬性爲:<script src="../bundle.js"></script>
,由於bundle.js文件在內存中
爲了能在執行npm run dev
訪問http://localhost:8080/
的時候直接訪問到index首頁,修改dev指令爲"dev": "webpack-dev-server --contentBase src --open"
,指定啓動的根目錄
同時修改index頁面中script的src屬性爲<script src="bundle.js"> </script>
html-webpack-plugin
插件配置啓動頁面爲何要安裝這個插件:去掉index頁中對js文件的請求
因爲使用--contentBase
指令的過程比較繁瑣,須要指定啓動的目錄,同時還須要修改index.html中script標籤的src屬性,因此推薦你們使用html-webpack-plugin
插件配置啓動頁面.
cnpm i html-webpack-plugin --save-dev
安裝到開發依賴webpack.config.js
配置文件以下:// 導入處理路徑的模塊
var path = require('path');
// 導入自動生成HTMl文件的插件
var htmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: path.resolve(__dirname, 'src/js/main.js'), // 項目入口文件
output: { // 配置輸出選項
path: path.resolve(__dirname, 'dist'), // 配置輸出的路徑
filename: 'bundle.js' // 配置輸出的文件名
},
plugins:[ // 添加plugins節點配置插件
new htmlWebpackPlugin({
template:path.resolve(__dirname, 'src/index.html'),//模板路徑
filename:'index.html'//自動生成的HTML文件的名稱
})
]
}
複製代碼
package.json
中script
節點中的dev指令以下:"dev": "webpack-dev-server --open"
複製代碼
html-webpack-plugin
插件會自動把bundle.js注入到index.html頁面中!好了,到了這一步,咱們在打開一個項目文件,啓動服務端,執行:npm run dev
命令,便可自動打開index.html,每次修改入口文件,在保存以後變回自動打包,頁面自動刷新,下面繼續介紹,webpack是如何打包其餘類型的文件的
注意:熱更新在JS中表現的不明顯,能夠從一下子要講到的CSS身上進行介紹說明!
方式一:
package.json
的script節點以下,其中--open
表示自動打開瀏覽器,--port 4321
表示打開的端口號爲4321,--hot
表示啓用瀏覽器熱更新:"dev": "webpack-dev-server --hot --port 4321 --open"
複製代碼
方式二:
webpack.config.js
文件,新增devServer
節點以下:devServer:{
hot:true,
open:true,
port:4321
}
複製代碼
webpack
模塊:var webpack = require('webpack');
複製代碼
plugins
節點下新增:new webpack.HotModuleReplacementPlugin()
複製代碼
cnpm i style-loader css-loader --save-dev
webpack.config.js
這個配置文件:module: { // 用來配置第三方loader模塊的
rules: [ // 文件的匹配規則
{ test: /\.css$/, use: ['style-loader', 'css-loader'] }//處理css文件的規則
]
}
複製代碼
use
表示使用哪些模塊來處理test
所匹配到的文件;use
中相關loader模塊的調用順序是從後向前調用的;import "./css/index.css"
複製代碼
index.less
ul{
padding: 0;
margin: 0;
}
複製代碼
cnpm i less-loader less -D
webpack.config.js
這個配置文件:{ test: /\.less$/, use: ['style-loader', 'css-loader', 'less-loader'] },
複製代碼
index.scss//注意後綴爲scss
html, body{
margin: 0;
padding: 0;
li{
font-size: 12px;
line-height: 30px;
}
}
複製代碼
cnpm i sass-loader node-sass --save-dev
webpack.config.js
中添加處理sass文件的loader模塊:{ test: /\.scss$/, use: ['style-loader', 'css-loader', 'sass-loader'] }
複製代碼
cnpm i url-loader file-loader --save-dev
webpack.config.js
中添加處理url路徑的loader模塊:{ test: /\.(png|jpg|gif)$/, use: 'url-loader' }
複製代碼
limit
指定進行base64編碼的圖片大小;只有小於指定字節(byte)的圖片纔會進行base64編碼:{ test: /\.(png|jpg|gif)$/, use: 'url-loader?limit=43960' },
複製代碼
cnpm i babel-core babel-loader babel-plugin-transform-runtime --save-dev
安裝babel的相關loader包cnpm i babel-preset-es2015 babel-preset-stage-0 --save-dev
安裝babel轉換的語法webpack.config.js
中添加相關loader模塊,其中須要注意的是,必定要把node_modules
文件夾添加到排除項:{ test: /\.js$/, use: 'babel-loader', exclude: /node_modules/ }
複製代碼
.babelrc
文件,並修改這個配置文件以下:{
"presets":["es2015", "stage-0"],
"plugins":["transform-runtime"]
}
複製代碼
babel-preset-es2015
能夠更新爲babel-preset-env
,它包含了全部的ES相關的語法;後言:
以上就是webpack打包工具應用的案例了,這個案例也能夠做爲一個項目的基本打包模板,你們在學習這一塊內容的時候,要掌握一些基礎的知識,不然,遇到了報錯問題,可能就無從下手解決了,webpack還有其餘的一些難懂的知識點,建議你們看官方文檔