隨著前端項目複雜度的增加,其所依賴的資源也越來越多,從最初的HTML文件,CSS文件,JS文件發展到現在的各種預處理文件,模板文件等等。文件多了,項目大了,項目的維護就變得更加困難了,在這樣的背景下,webpack 這樣的打包工具就成了前段工程師必知必會的工具了。 ...
隨著前端項目複雜度的增加,其所依賴的資源也越來越多,從最初的HTML文件,CSS文件,JS文件發展到現在的各種預處理文件,模板文件等等。文件多了,項目大了,項目的維護就變得更加困難了,用戶載入頁面的速度也變得更慢了。在這樣的背景下,webpack 應運而生,webpack 的主要作用是資源的整合,打包,壓縮。使用 webpack,它會自動構建一個項目資源之間的依賴關係圖,其中包含項目需要的所有模塊,然後把這些資源全部整合打包成一個或多個(根據需要)bundle(包)。
一 準備工作
1,安裝 nodejs
在使用 webpack 之前,我們需要做一些準備工作。由於 webpack 工具是基於 nodejs 開發的,所以我們應該首先在電腦上安裝它。
nodejs 下載地址:https://nodejs.org/en/;根據自己的操作系統下載安裝即可。
裝好後它會在你的電腦上創建一個系統命令:node。使用如下命令可以常看當前安裝的 node 版本號,如果能正常查看,那麼你的 nodejs 就已經安裝成功了。
1 node -v
2,npm
通常情況下,安裝 nodejs 會自動安裝 npm 工具。npm 工具可以理解成一個平臺,安裝好後它會在你的電腦上創建一個系統命令:npm。這個工具的主要作用是:在命令行模式下,使用該命令從NPM伺服器下載一些包(各種框架等)。
同樣的,使用命令 npm -v 也可以查看當前安裝的 npm 工具版本號。如果查到了,那麼證明這個工具也安裝成功了。
npm有下麵一些常用的命令(在項目目錄下使用):
1 npm init
初始化項目,執行該命令後會有很多配置項,可以根據需要填寫,也可以在命令後面添加 -y 參數,使用預設配置。初始化完成後,項目目錄下會多一個 package.json 文件,這個文件記錄了該項目的所有配置信息,如果你不想使用預設的配置了,那麼你隨時可以到這裡來修改相關項。
1 npm install
根據 package.json 配置文件,自動配置項目,並載入項目依賴的包。
1 npm install 'bundle'
安裝(下載)你需要的包。比如你需要使用jQuery,你可以使用如下命令:npm install jquery。預設該命令會安裝最新版的包,你也可以通過 @ 符號指定版本,比如:npm install [email protected]。包安裝完成後,項目目錄下又會多一個node_modules 的目錄,這個目錄中存放的就是你安裝的所有包。
1 npm uninstall ‘bundle’
移除已安裝的包。
1 npm list
查看項目安裝了哪些包。
1 npm info ‘bundle’
查看包的詳情。
使用npm命令安裝包時,有以下一些可選參數:
-S 或 --save:包作用於生產環境。
-D 或 --save-dev:包作用於生產環境和開發環境(常用)。
-g 或 --global:全局安裝。
如果不帶參數 -g 則預設本地安裝,即安裝在當前項目下。如果使用了全局安裝。你可以使用npm root -g 查看全局安裝的目錄位置。
小技巧:npm預設下載伺服器是國外的,有時候速度難免有點慢,這時你可以使用淘寶在國內的鏡像平臺,有兩種方式實現:第一種,安裝cpmn,npm install cnpm -g。第二種,修改預設下載路徑,npm config set registry https://registry.npm.taobao.org。
3,自定義命令
package.json 文件中有一個 scripts 選項,該選項用於自定義 npm 命令,比如稍後我們要講到的 webpack 命令:
1 "scripts":{ 2 "bundle":'webpack' 3 } 4 //現在你可以使用 bundle 命令來替代 webpack 了
自定義命令的使用方式和原始命令有所區別:
1 npm run bundle 2 #通過 npm run 來啟動自定義命令
二 webpack
1,安裝
知道了怎麼通過 npm 安裝包,那麼接下來我們就要學習如何安裝 webpack 了,其實也很簡單,直接使用命令:
1 npm install webpack -g
通常 webpack 使用全局安裝,即使用參數 -g 。安裝成功後可以通過如下命令查看當前安裝的 webpack 版本號:
1 webpack -v
但有時候我們還是希望為某項目單獨使用特定版本的 webpack 工具,這時你可以選擇本地安裝,即不指定參數 -g,它會被安裝到 node_modules 目錄下 。但本地安裝會有一個問題:webpack 命令不能正常使用了。幸好,nodejs 為我們提供了 npx 命令,以在不修改全局目錄的情況下使用 webpack 命令。
1 npx webpack -v
2,簡單使用
webpack 工具安裝成功後,你就可以使用 webpack 命令對項目文件進行打包處理了,命令使用方式也很簡單:
1 webpack ‘url被打包文件’
文件打包成功後預設會在項目中新建一個目錄 dist,裡面會有一個和被打包文件同名的文件,這就是打包之後生成的了。
3,配置文件
如果希望使用更多 webpack 提供的功能,你需要使用配置文件 webpack.config.js。該文件向外暴露一個對象,供 nodejs 使用,nodejs 根據這個配置對象來決定如何打包文件。
配置文件有四個核心,他們分別是:入口(entry)、輸出(output)、載入器(loader)、插件(plugins)。文件的基本結構如下:
1 module.exports = { //node 語法,向外暴露一個對象 2 entry: '', 3 output:{}, 4 module:{ 5 rules:[] 6 }, 7 plugins:[] 8 };
entry 規定 webpack 從哪裡開始打包,並構建內部依賴關係圖。它的值是一個相對路徑,一般指向一個具體的文件。比如當前項目目錄下的 main.js:
1 entry: './main.js'
output 則是規定 webpack 輸出內容的配置對象,通常它需要兩個屬性:filename(輸出文件的名稱)和 path(輸出路徑):
1 const path = require('path');//node 的一個 path 模塊 2 module.exports = { 3 output:{ 4 filename:'main.bundle.js', 5 path:path.resolve('__dirname','dist') 6 //通過 path 模塊的 resolve 方法,在項目根目錄下生成一個 dist 目錄,這也是 node 的語法,有興趣的可以去學習 node,這裡只是介紹 webpack,所以不深究 7 } 8 }
module 用於指定 loader。由於 webpack 只認識 JS 文件,當碰到項目中需要打包其他文件,比如 CSS 文件,圖片,txt 文件或者其他編程語言文件等等,這時候就需要用到 loader了。loader 用於對模塊的源代碼進行轉換,以便瀏覽器最終能夠認識他們。
1 module: { 2 rules: [ 3 { test: /\.css$/, use: 'css-loader' }, 4 { test: /\.ts$/, use: 'ts-loader' } 5 ] 6 } 7 //每條規則通過 test 來判斷打包的是什麼類型的文件,如果匹配成功,將使用本規則 use 所指定的 loader。
事實上,每條規則可以使用多個 loader,這時 use 需要用數組來保存它們。每個 loader 都有不容的作用,也有一些不盡相同的可選項,如果需要,請查看 webpack 官方文檔 LOADER。
plugins 用於配置 webpack 插件,這些插件可以在打包的不同階段完成一些功能。比如 HtmlWebpackPlugin 插件,它的作用是在打包完成後,在輸出目錄自動生成一個 HTML 文件,並把打包好的文件引入該 HTML 文件中,下麵是它的用法:
1 var HtmlWebpackPlugin = require('html-webpack-plugin'); 2 var webpackConfig = { 3 plugins: [new HtmlWebpackPlugin({ 4 filename:'index.html', 5 template:'src/test.html' 6 })] 7 };
先在配置文件中引入插件,然後在 plugins 中創建插件實例,創建實例的時候可以給一個配置對象,指定生成的文件名稱,和使用什麼樣的 HTML 模板等。
註意:loader 和 plugin 都需要使用 npm 先安裝到本地才能如上述方式使用。
4,常用 loader 介紹
在一般項目中,最常用的 loader 包括 url-loader 和 (style-loader & css-loader)。前者用於圖片打包,後者用於樣式打包。
url-lorder 用法如下:
1 module:{ 2 rules:[ 3 test:/\.(jpg|png|gif)$/, //正則用於匹配圖片資源 4 use:{ 5 loader:'url-loader', 6 options:{ 7 name:'[name].[ext]', //占位符用於指定圖片的名稱和尾碼名 8 limit:2048, //規定圖片大於2048位元組則打包到指定目錄(下麵的outputPath),否則以Base64編碼形式直接打包到輸出 js 文件中 9 outputPath:'images/' //單獨指定圖片文件指定輸出路徑 10 } 11 } 12 ] 13 }
樣式 loader 用法:
1 module:{ 2 rules:{ 3 test:/\.scss$/, 4 use:[ 5 'style-loader', // 通過<style>標簽向HTML文檔註入css樣式 6 'css-loader', // 解析合併css樣式文件 7 'sass-loader' // 解析scss樣式文件,如果是其他類型的則需要安裝其他loader 8 ] 9 } 10 }
需要註意的是:使用多個 loader 解析時,webpack 調用順序是從後到前。比如上例中的樣式 loader,先使用 sass-loader 把 .scss 文件解析成標準 css 樣式,再調用 css-loader 檢查是否有多個 css文件,如果有,則將他們合併成一個,最後調用 style-loader 把這些代碼通過 <style> 標簽註入到 HTML 文檔中。
如果你不想用內聯方式引入 CSS 樣式,那麼你可以使用 <link> 標簽的方式:
1 import url from 'file.css'
1 module: { 2 rules: [ 3 { 4 test: /\.css$/, 5 use: [ 6 { loader: "style-loader/url" }, 7 { loader: "file-loader" } 8 ] 9 } 10 ] 11 }
這種方式最終將會在頁面中通過標簽 <link rel="stylesheet" href="path/to/file.css"> 向頁面引入樣式。
4,動態監聽打包文件
預設情況下,所有源文件的修改都需要重新運行 webpack 打包命令,這簡直太麻煩了。這時你需要動態的監聽所有需要被打包的文件,這樣,每當我們修改了源文件,webpack 都會自動的把它們重新打包到輸出文件。實現方式也很簡單:
1 module.exports = { 2 watch:true //預設值是 false,不開啟 3 }
另一種方式是在運行 webpack 命令時添加 --watch 參數:
1 webpack --watch
動態監聽固然不錯,但還是有些不盡人意,比如每次都要手動刷新頁面才能看到修改後的效果;不方便在伺服器運行頁面,像 ajax 請求等都不方便測試。
webpack 提供了 devServer 配置項,可以在打包後在記憶體中配置一個臨時伺服器,並把打包後的項目運行在該伺服器上。devServer 最強大的地方在於,它把輸出目錄也保存在記憶體中,這大大提高了其打包的效率。
1 module.exports = { 2 devServer:{ 3 contentBase:'./dist', //指定伺服器目錄 4 open:true //打包完成後立即在瀏覽器運行 5 } 6 } 7 //打包完成後預設運行在本地路徑8080埠,打包的時候別忘啦把 webpack 命令替換成 webpack-dev-server 哦
devServer 還有很多其他的配置項,你可以在需要的時候查閱 webpack 官網,根據需要配置你需要的選項。( 其實現在很多IDE開發工具都內置了相似的功能,根據需要選擇就可以了。)
5,bable 處理 ES6 語法
如果你在源代碼中使用了 ES6 的語法,可能很多老版本的瀏覽器並不能正確的執行。這時候你就需要 bable 來幫忙了,bable 是一款 JavaScript 編譯器,它的主要功能就是語法轉換,即把高版本的語法轉換成低版本的語法,用低版本的特性實現高版本的新特性。
在使用結合 webpack 使用 bable 之前,我們應該先安裝一些相關的包:
1 npm install --save-dev babel-loader @babel/core 2 # babel-loader用於連接webpack和bable,@babel/core是一個bable的核心庫,用於輔助語法轉換 3 npm install @babel/preset-env --save-dev
4 # @bable/preset-env 實際負責語法轉換 5 npm install --save @babel/polyfill 6 # @bable/polyfill 用於註入ES6 的一些新特性
webpack 中的配置:
1 module: { 2 rules: [ 3 { 4 test: /\.js$/, 5 exclude: /node_modules/, //排除node_modules中的文件 6 loader: "babel-loader", 7 options:{ 8 presets:[ 9 ["@babel/preset-env"], //負責實際的編譯工作 10 { 11 targets:{edge:"17",firefox:"60",chrom:"67",safari:"11"}, //設置運行環境瀏覽器版本臨界值,高於(包含)此版本將不使用 bable 編譯 12 useBuiltIns:"usage" //檢測源代碼,僅註入使用到的ES6新特性 13 } 14 ] 15 } 16 } 17 ] 18 }
源代碼中:
1 import "@bable/polyfill" 2 // some code
關於 webpack 常用的配置就先介紹到這裡了,事實上,webpack 還有許多其他的配置項,要全部記住是不太現實的,通常我麽建議瞭解即可,當我們需要某些功能時,知道怎麼去查詢配置詳情即可。
三 Vue-CLI
Vue-CLI 是基於 webpack 封裝而成的腳手架工具,專門用於 Vue 項目的管理,Vue-CLI 封裝了許多 webpack 的配置項,讓我們只需簡單的幾步就能實現 webpack 複雜的功能配置。Vue-CLI 極大的簡化了項目打包的配置,讓我們可以專註於項目本身,而不用過多的操心打包的事情。
1,安裝
1 npm install -g @vue/cli
2,創建項目
1 vue create "項目名稱"
執行創建命令後,如果選擇預設設置,將不需要人工干預,直接會成生一個項目的基本目錄。如果選擇手動設置,則需要人工干預,提供必要的信息。
預設設置中,Vue-CLI 會自動載入 Vue 項目需要的一些必要的包,後期可以根據需要再手動安裝其他的包就行了。Vue-CLI 預設提供了兩個命令:
1 npm run serve 2 #打包到記憶體並在虛擬伺服器啟動項目,實際使用了 webpack 的 devServer 配置項 3 npm run build 4 #打包項目
基本的項目目錄包括:
名稱 | 類型 | 說明 |
node_modules | 目錄 | 存放包 |
public | 目錄 | 存放公共資源 |
src | 目錄 | 存放源代碼 |
babel.config.js | 文件 | 引入babel插件 |
package.json | 文件 | 項目詳情 |
package-lock.json | 文件 | 包詳情 |
readme.md | 文件 | 自述文件 |
.gitignore | 文件 | git提交配置 |
當你運行了打包命令,預設還會創建一個 dist 目錄,部署項目時直接拷貝這個目錄到實際生產環境即可。
小技巧:Vue-CLI 打包的文件被認為將直接在伺服器運行,所以如果你使用 file 協議運行 dist 下的文件,將不會成功,Vue-CLI 官方推薦全局安裝 http-server (nodejs 靜態文件伺服器)(npm install serve -g;serve dist -s)或手動修改 publicPath 配置項為相對路徑,以對打包文件進行測試,我建議自己在本機搭建一個 web 伺服器來測試,這樣能更加貼近生產環境。
3,配置文件
預設情況下使用 Vue-CLI 創建的項目,不會包含配置文件,這是因為該腳手架工具的設計理念是儘量簡化打包相關的配置和操作,並且它已經封裝了常用的配置項,不需要我們額外再配置。如果你需要手動配置,你可以在項目根目錄下新建一個 vue.config.js 的配置文件,Vue-CLI 提供的配置項請點這裡查閱官網,這裡不一一舉例了。
如果確實遇到其封裝的配置不能滿足我們實際需要,Vue-CLI 也提供了一個 configureWebpack 這個配置選項,其值可以是一個對象或一個函數,如果你為其設置了一個對象,那麼你可以在這個對象中添加原生的 webpack 配置項。不過,Vue-CLI 建議,儘量不要在 configureWebpack 中配置已經封裝的選項,這樣做是因為 vue.config.js 中的值會被用在配置里的多個地方,以確保所有的部分都能正常工作在一起。
4,圖形界面
Vue-CLI 不僅提供了常規的命令行界面,還提供了圖形化操作界面,這真的是把它的理念貫徹到了極致。
1 vue ui 2 # 安裝好 vue-cli 後,直接使用此命令就可以打開圖形化界面了
圖形化界面我們一般戲稱是傻瓜式配置,只需要根據提示,用滑鼠點擊開啟或是關閉一些配置選項就行了,很少需要自己輸入什麼內容或命令,所以這裡就不多講了,有興趣的朋友可以自己試一下。
寫在最後:工具會用就行了(除非你是製造工具的人),工作當中的重心依然是業務,遇到工具方面的問題查閱文檔就可以了,畢竟互聯網發展的那麼快,但人的精力始終是有限的!如果內容有誤,歡迎指正!