Vue.js學習系列四——Webpack打包工具的使用(裝修中……)
這兩週一直想寫webpack的知識點,卻發現webpack其實要說的很具體內容挺多的。而且稀土掘金上一搜webpack有好多人都有去寫webpack的知識點,所以本文中不再去重複別人的東西了,就簡單記錄一下我對webpack的理解。並按照老規矩附上demo以及我收藏的幾篇不錯的webpack入門文章以供學習參考~
一、什麼是webpack
1. webpack是蝦米?
webpack是一個模組打包工具。
用vue專案來舉例:瀏覽器它是隻認識js,不認識vue的。而我們寫的程式碼字尾大多是.vue的,在每個.vue檔案中都可能html、js、css甚至是圖片資源;並且由於元件化,這些.vue檔案之間還有錯綜複雜的關係。所以專案要被瀏覽器識別,我們就要使用webpack將它們打包成js檔案以及相應的資原始檔。
或者這麼理解,我們以vue專案的形式編寫專案邏輯,瀏覽器以他理解的方式來執行專案。webpack把我們的vue專案想表達的所有意圖傳遞給瀏覽器讓瀏覽器去執行。
PS:webpack功能不止於此,但這個功能是讓我們專案能跑起來的必要條件!(個人理解,如有錯誤,還請批評指正)
2. 來個demo理解下
這裡我們來理解下webpack是如何打包的~(轉譯會在loaders中提到)。首先我們寫兩個最簡單的js
hello.js
console.log("hello~~")
app.js
console.log("hello app");
require("./hello.js")
app.js
中匯入了hello.js
,它們之間有匯入關係。我們假如直接將app.js
放到html中是會報錯的。
hello app
Uncaught ReferenceError: require is not defined at app.js:2
如果我們要維持這種關係我們就必須使用打包工具進行打包。在命令列中輸入:
// 安裝webpack
$ npm install webpack -g
// 打包app.js
$ webpack app.js bundle.js
然後我們會發現專案中多了一個bundle.js檔案,我們在html中匯入這個js檔案。
index.html
<!DOCTYPE html>
<html>
<head>
<title>demo01</title>
</head>
<body>
<h1>demo01</h1>
<script src="bundle.js" ></script>
</body>
</html>
最後輸出正確結果
hello app
hello~~
二、webpack.config.js
1. 定義
webpack.config.js檔案是webpack的預設配置檔案。之前我們使用命令列$ webpack entry.js
output.js
來實現打包,其實webpack可以有更多的打包配置,這些配置都是在webpack.config.js中完成的。下面是一個簡單的webpack.config.js。
const webpack = require("webpack")
module.exports = {
entry: {
entry: "./app/entry.js",
},
output:
{
path: __dirname + "/dist",
filename: 'bundle.js',
},
module: {
loaders: [
{
test: /\.js$/,
loader: 'babel',
exclude: /node_modules/
},
]
}
}
個人覺得這三個東西是最最重要的了,所以必須單獨說說這三個配置。其他配置都可以去查閱資料慢慢來。
2. entry&output
entry是配置webpack的入口檔案,上面的程式碼中我們將app目錄下的entry.js作為入口檔案。webpack會將與entry.js有關的資源都進行打包。
output是出口檔案,即打包好的檔案的存放地址和檔名。
這裡有幾種檔案的輸入輸出情況。引用自Webpack 2 入門教程。
2.1 單檔案,單輸出
const webpack = require("webpack");
module.exports = {
context: __dirname + "/src",
entry: {
app: "./app.js",
},
output: {
path: __dirname + "/dist",
filename: "[name].bundle.js",
},
};
2.2 多檔案,單輸出
const webpack = require("webpack");
module.exports = {
context: __dirname + "/src",
entry: {
app: ["./home.js", "./events.js", "./vendor.js"],
},
output: {
path: __dirname + "/dist",
filename: "[name].bundle.js",
},
};
2.3 多檔案,多輸出
const webpack = require("webpack");
module.exports = {
context: __dirname + "/src",
entry: {
home: "./home.js",
events: "./events.js",
contact: "./contact.js",
},
output: {
path: __dirname + "/dist",
filename: "[name].bundle.js",
},
};
大家可以動手實踐一下,很好理解。打包出來的單個或者多個檔案直接可以在html中使用。
<script src="./dist/entry.js"></script>
3. loaders
loader是webpack的載入器,可以幫我們處理各種非js檔案。如css樣式,vue、jsx、weex等字尾的程式碼,JPG、PNG圖片等。所以我們一般會在package.json中看到各種*-loader。這些就是各類資源的loader載入器。
在module的loaders陣列中可以有多個物件,每個物件就是一個載入器。下面是babel-loader的最簡單配置方式
module: {
loaders: [
{
test: /\.js$/,
loader: 'babel',
},
]
}
物件中的test是正則表示式,用於搜尋字尾為.js的檔案。loader是所用載入器名稱。
4. 使用babel來轉譯ES6程式碼
下面我們來一步步使用babel-loader將ES6語法用於專案中。
webpack打包的檔案預設是不支援ES6的,我們需要用babel轉譯。
4.1 安裝babel
這個配置其實我是抄的vue-cli,個人對babel用法還不是很熟。
在package.json中新增依賴。
"devDependencies": {
...
"babel-core": "^6.22.1",
"babel-loader": "^6.2.10",
"babel-plugin-transform-runtime": "^6.22.0",
"babel-preset-es2015": "^6.0.0",
"babel-preset-stage-2": "^6.0.0",
"babel-register": "^6.0.0",
"webpack": "^1.14.0"
...
}
npm安裝
$ npm install
4.2 在webpack.config.js中新增babel-loader的配置
module: {
loaders: [
{
test: /\.js$/,
loader: 'babel',
},
]
}
4.3 新增.babelrc
在專案根目錄下新增.babelrc檔案,檔案內容為
{
"presets": ["es2015", "stage-2"],
"plugins": ["transform-runtime"],
"comments": false
}
4.4 使用ES6
import good from './good.js'
三、分析vue-cli
說了這麼多,我的最終目的還是為了學號Vue.js。所以在對webpack有了一定的理解之後,就發現其實vue-cli並不是那麼深不可測。
1. 結構分析
- build —— 專案構建資料夾
- build.js —— 打包構建指令碼(npm run build)
- check-versions.js —— npm和node版本的查詢
- dev-client.js ——
- dev-server.js —— 開發除錯指令碼(npm run dev)
- utils.js —— 工具類
- webpack.base.config.js —— Webpack配置檔案
- webpack.dev.config.js —— 開發版本Webpack配置檔案,與webpack.base.config.js合併成完整的配置檔案。
- webpack.prod.config.js —— 生產版本Webpack配置檔案,與webpack.base.config.js合併成完整的配置檔案。
- config —— 配置資料夾,儲存有各種配置引數(檔案路徑、伺服器埠、功能開關)
- src —— 程式碼資料夾
- static
- .gitkeep —— 作用是將檔案所在資料夾保留在git版本控制中。檔案型別和.gitignore差不多。
- .babelrc —— babel配置檔案
- .editorconfig —— 編輯配置,確保使用各種編輯器時能有相同的編輯格式。
- .gitignore —— git忽略檔案
- index.html —— 頁面,最終顯示在這個html中
- package.json —— npm配置檔案,包含了專案的資訊、指令碼、依賴庫等重要資訊。
2. 建立簡易cli
理解完vue-cli的某些功能後,不難發現我們自己也可以搭建簡易的vue-cli了。
官方的腳手架中除了有webpack打包,還包含了node指令碼、開發和生產模式的切換、ESLint配置等功能。我們暫時不需要,將專案簡化來更好的理解webpack。
2.1 package.json
讓我們來自己建立一個cli,首先建立一個空資料夾。
$ mkdir demo05
$ cd demo05
初始化npm
$ npm init
然後複製vue-cli中的依賴庫到package.json中(直接複製啦,具體依賴庫的作用就不提啦~之後會寫部落格補上的)。
"dependencies": {
"vue": "^2.1.0"
},
"devDependencies": {
"autoprefixer": "^6.4.0",
"babel-core": "^6.0.0",
"babel-loader": "^6.0.0",
"babel-plugin-transform-runtime": "^6.0.0",
"babel-preset-es2015": "^6.0.0",
"babel-preset-stage-2": "^6.0.0",
"babel-register": "^6.0.0",
"chalk": "^1.1.3",
"connect-history-api-fallback": "^1.1.0",
"css-loader": "^0.25.0",
"eventsource-polyfill": "^0.9.6",
"express": "^4.13.3",
"extract-text-webpack-plugin": "^1.0.1",
"file-loader": "^0.9.0",
"friendly-errors-webpack-plugin": "^1.1.2",
"function-bind": "^1.0.2",
"html-webpack-plugin": "^2.8.1",
"http-proxy-middleware": "^0.17.2",
"json-loader": "^0.5.4",
"semver": "^5.3.0",
"opn": "^4.0.2",
"ora": "^0.3.0",
"shelljs": "^0.7.4",
"url-loader": "^0.5.7",
"vue-loader": "^10.0.0",
"vue-style-loader": "^1.0.0",
"vue-template-compiler": "^2.1.0",
"webpack": "^1.13.2",
"webpack-dev-middleware": "^1.8.3",
"webpack-hot-middleware": "^2.12.2",
"webpack-merge": "^0.14.1"
},
2.2 webpack.config.js
這裡的webpack配置檔案中的部分內容是從官方的 webpack.base.config.js
中複製出來的。正如我專案結構中所說的,vue-cli中的 webpack.base.config.js
是基礎的配置檔案。vue-cli中的 webpack.dev.config.js
和 webpack.prod.config.js
分別代表了開發和生產版本的webpack配置檔案,他們與 webpack.base.config.js
合併成最後的webpack配置檔案。這裡我們只要找到 webpack.base.config.js
即可。
下面是完整配置程式碼。
var path = require("path")
var projectRoot = path.resolve(__dirname, '../')
module.exports = {
// 入口檔案
entry: "./src/main.js",
// 輸出檔案
output: {
filename: "./dist/bundle.js"
},
// 別名
resolve: {
extensions: ['', '.js', '.vue', '.json'],
fallback: [path.join(__dirname, '../node_modules')],
alias: {
'vue$': 'vue/dist/vue.common.js',
'src': path.resolve(__dirname, '../src'),
'assets': path.resolve(__dirname, '../src/assets'),
'components': path.resolve(__dirname, '../src/components')
}
},
module: {
// 載入器
loaders: [
{
test: /\.vue$/,
loader: 'vue'
},
{
test: /\.js$/,
loader: 'babel',
exclude: /node_modules/
},
{
test: /\.json$/,
loader: 'json'
},
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
loader: 'url',
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
loader: 'url',
}
]
},
}
2.3 新增必要檔案
由於使用git、babel,所以我將vue-cli中的 .gitignore
和 .babelrc
直接複製過來。
還有,由於懶得寫邏輯程式碼,這裡我將 src
資料夾中所有內容也直接複製過來。
複製按成後進行webpack打包。
$ webpack
打包完成就會出現一個在 dist
目錄下有一個 bundle.js
檔案。有了打包檔案,我們還需要建立一個 index.html
來顯示效果,這個之後再說。
所以,最後的專案結構如下圖
專案結構
2.4 index.html
現在,到了呈現效果的時候了。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo3</title>
</head>
<body>
<div id="app">
</div>
<script src="./dist/bundle.js"></script>
</body>
</html>
很簡單,建立一個id為app的div元素用於顯示Vue元件內容,然後將打包好的bundle.js引用進去。
現在,到專案目錄中找到 index.html
頁面,瀏覽器開啟就可以看到效果啦~
效果圖
注:簡易cli專案的原始碼在 VueStudyDemos\WebpackDemos\demo5中
四、相關資料推薦
寫在最後
在這裡,首先祝大家新年快樂。拖了一個春節,終於把webpack的部落格給寫出來了。感覺在寫完部落格之後對webpack的理解深刻了許多,再次證明了“教是最好的學”這個理論,推薦朋友們都去試著將所掌握的知識寫出來,會有新的收穫的喲。新的一年,堅持寫部落格,享受分享帶來的快樂。
之後計劃學習一下eslint以及一些測試工具。然後試著用element和mint做兩個小demo分享出來。然後瞭解一下node。系統的學習Vue.js的知識。
最後,感謝你看完這篇部落格,如果有什麼建議或者意見,可以在下方評論或者傳送簡信給我。