一直想寫webpack的知識(shí)點(diǎn),卻發(fā)現(xiàn)webpack其實(shí)要將webpack說的具體內(nèi)容還是挺多的秘噪。而且網(wǎng)上上一搜webpack有好多人都有去寫webpack的知識(shí)點(diǎn)缆娃,所以本文中不再去重復(fù)別人的東西了贯要,就簡單記錄一下我對(duì)webpack的理解椭住。
一京郑、什么是webpack
1. webpack是什么些举?
webpack是一個(gè)模塊打包工具。
用vue項(xiàng)目來舉例:瀏覽器它是只認(rèn)識(shí)js驶臊,不認(rèn)識(shí)vue的关翎。而我們寫的代碼后綴大多是.vue的纵寝,在每個(gè).vue文件中都可能html星立、js绰垂、css甚至是圖片資源辕坝;并且由于組件化荐健,這些.vue文件之間還有錯(cuò)綜復(fù)雜的關(guān)系。所以項(xiàng)目要被瀏覽器識(shí)別窖逗,我們就要使用webpack將它們打包成js文件以及相應(yīng)的資源文件碎紊。
或者這么理解仗考,我們以vue項(xiàng)目的形式編寫項(xiàng)目邏輯词爬,瀏覽器以他理解的方式來運(yùn)行項(xiàng)目顿膨。webpack把我們的vue項(xiàng)目想表達(dá)的所有意圖傳遞給瀏覽器讓瀏覽器去運(yùn)行恋沃。
PS:webpack功能不止于此囊咏,但這個(gè)功能是讓我們項(xiàng)目能跑起來的必要條件!(個(gè)人理解研侣,如有錯(cuò)誤庶诡,還請(qǐng)批評(píng)指正)
2. 來個(gè)demo理解下
這里我們來理解下webpack是如何打包的~(轉(zhuǎn)譯會(huì)在loaders中提到)末誓。首先我們寫兩個(gè)最簡單的js
hello.js
console.log("hello~~")
app.js
console.log("hello app");
require("./hello.js")
app.js
中導(dǎo)入了hello.js
喇澡,它們之間有導(dǎo)入關(guān)系晴玖。我們假如直接將app.js
放到html中是會(huì)報(bào)錯(cuò)的呕屎。
hello app
Uncaught ReferenceError: require is not defined at app.js:2
如果我們要維持這種關(guān)系我們就必須使用打包工具進(jìn)行打包。在命令行中輸入:
// 安裝webpack
$ npm install webpack -g
// 打包app.js
$ webpack app.js bundle.js
然后我們會(huì)發(fā)現(xiàn)項(xiàng)目中多了一個(gè)bundle.js文件尔当,我們?cè)趆tml中導(dǎo)入這個(gè)js文件椭迎。
index.html
<!DOCTYPE html>
<html>
<head>
<title>demo01</title>
</head>
<body>
<h1>demo01</h1>
<script src="bundle.js"></script>
</body>
</html>
最后輸出正確結(jié)果
hello app
hello~~
二畜号、webpack.config.js
1. 定義
webpack.config.js文件是webpack的默認(rèn)配置文件弄兜。之前我們使用命令行$ webpack entry.js output.js
來實(shí)現(xiàn)打包替饿,其實(shí)webpack可以有更多的打包配置贸典,這些配置都是在webpack.config.js中完成的廊驼。下面是一個(gè)簡單的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/
},
]
}
}
個(gè)人覺得這三個(gè)東西是最最重要的了,所以必須單獨(dú)說說這三個(gè)配置酝掩。其他配置都可以去查閱資料慢慢來鳞芙。
2. entry&output
entry是配置webpack的入口文件,上面的代碼中我們將app目錄下的entry.js作為入口文件期虾。webpack會(huì)將與entry.js有關(guān)的資源都進(jìn)行打包原朝。
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",
},
};
大家可以動(dòng)手實(shí)踐一下御板,很好理解锥忿。打包出來的單個(gè)或者多個(gè)文件直接可以在html中使用。
<script src="./dist/entry.js"></script>
3. loaders
loader是webpack的加載器怠肋,可以幫我們處理各種非js文件。如css樣式淹朋,vue笙各、jsx、weex等后綴的代碼础芍,JPG杈抢、PNG圖片等。所以我們一般會(huì)在package.json中看到各種***-loader仑性。這些就是各類資源的loader加載器惶楼。
在module的loaders數(shù)組中可以有多個(gè)對(duì)象,每個(gè)對(duì)象就是一個(gè)加載器诊杆。下面是babel-loader的最簡單配置方式
module: {
loaders: [
{
test: /\.js$/,
loader: 'babel',
},
]
}
對(duì)象中的test是正則表達(dá)式歼捐,用于搜索后綴為.js的文件。loader是所用加載器名稱晨汹。
4. 使用babel來轉(zhuǎn)譯ES6代碼
下面我們來一步步使用babel-loader將ES6語法用于項(xiàng)目中豹储。
webpack打包的文件默認(rèn)是不支持ES6的,我們需要用babel轉(zhuǎn)譯淘这。
4.1 安裝babel
這個(gè)配置其實(shí)我是抄的vue-cli剥扣,個(gè)人對(duì)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
在項(xiàng)目根目錄下添加.babelrc文件钠怯,文件內(nèi)容為
{
"presets": ["es2015", "stage-2"],
"plugins": ["transform-runtime"],
"comments": false
}
4.4 使用ES6
import good from './good.js'
三、分析vue-cli
說了這么多曙聂,我的最終目的還是為了學(xué)習(xí)Vue.js晦炊。所以在對(duì)webpack有了一定的理解之后,就發(fā)現(xiàn)其實(shí)vue-cli并不是那么深不可測筹陵。
1. 結(jié)構(gòu)分析
- build —— 項(xiàng)目構(gòu)建文件夾
- build.js —— 打包構(gòu)建腳本(npm run build)
- check-versions.js —— npm和node版本的查詢
- dev-client.js ——
- dev-server.js —— 開發(fā)調(diào)試腳本(npm run dev)
- utils.js —— 工具類
- webpack.base.config.js —— Webpack配置文件
- webpack.dev.config.js —— 開發(fā)版本W(wǎng)ebpack配置文件刽锤,與webpack.base.config.js合并成完整的配置文件。
- webpack.prod.config.js —— 生產(chǎn)版本W(wǎng)ebpack配置文件朦佩,與webpack.base.config.js合并成完整的配置文件并思。
- config —— 配置文件夾,保存有各種配置參數(shù)(文件路徑语稠、服務(wù)器端口宋彼、功能開關(guān))
- src —— 代碼文件夾
- static
- .gitkeep —— 作用是將文件所在文件夾保留在git版本控制中弄砍。文件類型和.gitignore差不多。
- .babelrc —— babel配置文件
- .editorconfig —— 編輯配置输涕,確保使用各種編輯器時(shí)能有相同的編輯格式音婶。
- .gitignore —— git忽略文件
- index.html —— 頁面,最終顯示在這個(gè)html中
- package.json —— npm配置文件莱坎,包含了項(xiàng)目的信息衣式、腳本、依賴庫等重要信息檐什。
2. 創(chuàng)建簡易cli
理解完vue-cli的某些功能后碴卧,不難發(fā)現(xiàn)我們自己也可以搭建簡易的vue-cli了。
官方的腳手架中除了有webpack打包乃正,還包含了node腳本住册、開發(fā)和生產(chǎn)模式的切換、ESLint配置等功能瓮具。我們暫時(shí)不需要荧飞,將項(xiàng)目簡化來更好的理解webpack。
2.1 package.json
讓我們來自己建立一個(gè)cli名党,首先創(chuàng)建一個(gè)空文件夾叹阔。
$ mkdir demo05
$ cd demo05
初始化npm
$ npm init
然后復(fù)制vue-cli中的依賴庫到package.json中(直接復(fù)制啦,具體依賴庫的作用就不提啦~之后會(huì)寫博客補(bǔ)上的)兑巾。
"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配置文件中的部分內(nèi)容是從官方的 webpack.base.config.js
中復(fù)制出來的条获。正如我項(xiàng)目結(jié)構(gòu)中所說的,vue-cli中的 webpack.base.config.js
是基礎(chǔ)的配置文件蒋歌。vue-cli中的 webpack.dev.config.js
和 webpack.prod.config.js
分別代表了開發(fā)和生產(chǎn)版本的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
直接復(fù)制過來吱窝。
還有,由于懶得寫邏輯代碼迫靖,這里我將 src
文件夾中所有內(nèi)容也直接復(fù)制過來院峡。
復(fù)制按成后進(jìn)行webpack打包。
$ webpack
打包完成就會(huì)出現(xiàn)一個(gè)在 dist
目錄下有一個(gè) bundle.js
文件系宜。有了打包文件照激,我們還需要?jiǎng)?chuàng)建一個(gè) index.html
來顯示效果,這個(gè)之后再說盹牧。
所以俩垃,最后的項(xiàng)目結(jié)構(gòu)如下圖
2.4 index.html
現(xiàn)在励幼,到了呈現(xiàn)效果的時(shí)候了。
<!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>
很簡單口柳,創(chuàng)建一個(gè)id為app的div元素用于顯示Vue組件內(nèi)容苹粟,然后將打包好的bundle.js引用進(jìn)去。
現(xiàn)在跃闹,到項(xiàng)目目錄中找到 index.html
頁面嵌削,瀏覽器打開就可以看到效果啦~
四、相關(guān)資料推薦
這里推薦一下我學(xué)習(xí)webpack中發(fā)現(xiàn)的一些好的網(wǎng)站辣卒,分享一下掷贾。
https://github.com/webpack-china/awesome-webpack-cn
http://blog.guowenfh.com/2016/03/24/vue-webpack-01-base/