1. 程式人生 > >webpack+vue 實現多頁面開發

webpack+vue 實現多頁面開發

首先,要大概知道webpack是什麼,webpack的外掛都是做什麼用的,vue是什麼,然後看完之後也可以去補充一下這些方面的知識。

第一步:安裝環境

需要安裝的有:

  1. nodejs,並新增入環境變數PATH
  2. 使用nodejs安裝webpack和webpack-dev-server 
    參考內容: 
    http://webpack.github.io/docs/tutorials/getting-started/ 
    使用命令: 

    npm install webpack -g 

    之所以要在全域性安裝webpack是因為使用webpack的命令列方便,不需要在每一個專案中到node_module中呼叫。
  3. Atom編輯器 
    這個從網上下載,
    https://atom.io/
    。這是一個開源的編輯器軟體,之所以選擇atom,是因為它集合了sublimeText和其他一些編輯器的優點。最大的好處是可以使用package外掛的形式對atom編輯器進行自定義擴充套件。

第二步:建立專案模板

vue init wepack vue-multipage-demo
  • 1
  • 1

如上所示,這條命令的意思是使用vue的init命令,建立一個基於webpack元件化管理的專案。這將會在D:\WS_WebStorm目錄下建立新目錄vue-multipage-demo。 
 
圖2 
如圖2,在經過設定之後,可以看到已經生成了一個專案vue-multipage-demo,接下來需要切換到專案目錄下進行操作。在資源管理器中,我們可以看到已經生成了這樣的目錄: 
生成的檔案結構

 
圖3 
如圖3,各個資料夾和檔案分別是: 
build webpack構建過程的設定檔案,包括除錯和釋出版本以及一些工具函式 
config 這裡是webpack-dev-server的一些設定,關於webpack和webpack-dev-server的設定,詳見官方文件 
src 專案的原始檔所在,按照你需要的樣子寫js和html檔案,webpack將打包成瀏覽器可識別的,如ES6 
static 這裡是存放靜態資源的地方,在build之後會生成dist資料夾,這個資料夾中的檔案會原封不動放進去 
.babelrc webpack外掛babel的設定 
.editorconfig 這是atom編輯器生成的配置檔案,在各個專案中可以自由配置 
.eslintignore 使用eslint檢測程式碼是否符合規則的忽略目錄,用於eslint設定 
.gitignore 使用
Git
版本管理時需要忽略的目錄,用於git設定 
index.html 專案生成後的入口頁面,因為vue預設是使用單頁面的,所以在webpack中同時也只有這一個入口 
package.json nodejs的配置 
README.md 說明檔案,其中說明了使用vue-cli建立專案之後應該怎麼做 
dist build之後生成的目錄,其中存放webpack打包之後的結果,webpack中需要指定build規則 
表1 
npm install 
圖4 
如圖4,執行這兩條命令,切換到專案目錄下,使用npm的安裝命令,對已經生成的package.json所依賴的元件進行安裝。當然,我們之後還會安裝一些其他的外掛。

第三步:補充需要的外掛

雖然說,在專案開發中,外掛的補充是根據需求進行增減的,但是在這個專案中,有一些基本的需要新增的外掛,我在這裡提出。package.json中的程式碼如下:

"dependencies": {
    "babel-runtime": "^6.0.0",
    "bootstrap": "^3.3.7",
    "bootstrap-table": "^1.11.0",
    "font-awesome": "^4.6.3",
    "jquery": "^3.1.0",
    "node-glob": "^1.2.0",
    "vue": "^1.0.21",
    "vue-resource": "^0.9.3"
  },
  "devDependencies": {
    "babel-core": "^6.0.0",
    "babel-eslint": "^6.1.2",
    "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",
    "bootstrap-loader": "^2.0.0-beta.9",
    "connect-history-api-fallback": "^1.1.0",
    "css-loader": "^0.23.0",
    "dynamics.js": "^1.1.5",
    "eslint": "^2.10.2",
    "eslint-config-standard": "^5.1.0",
    "eslint-friendly-formatter": "^2.0.5",
    "eslint-loader": "^1.3.0",
    "eslint-plugin-html": "^1.3.0",
    "eslint-plugin-promise": "^1.0.8",
    "eslint-plugin-standard": "^1.3.2",
    "eventsource-polyfill": "^0.9.6",
    "express": "^4.13.3",
    "extract-text-webpack-plugin": "^1.0.1",
    "file-loader": "^0.8.4",
    "function-bind": "^1.0.2",
    "html-webpack-plugin": "^2.8.1",
    "http-proxy-middleware": "^0.12.0",
    "json-loader": "^0.5.4",
    "ora": "^0.2.0",
    "shelljs": "^0.6.0",
    "url-loader": "^0.5.7",
    "vue-hot-reload-api": "^1.2.0",
    "vue-html-loader": "^1.0.0",
    "vue-loader": "^8.3.0",
    "vue-style-loader": "^1.0.0",
    "webpack": "^1.13.2",
    "webpack-dev-middleware": "^1.4.0",
    "webpack-hot-middleware": "^2.6.0",
    "webpack-merge": "^0.8.3"
  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49

其中包括了由專案自動生成的一些外掛。 
我梳理一下,主要有下面這些,其中標註紅色的是我自己用來開發依賴的: 
dependencies: 
babel-runtime 
bootstrap 
bootstrap-table 
font-awesome 
jQuery 
node-glob 
vue 
devDependencies: 
bootstrap-loader 
dynamics.js 
那麼主要就是新增一下node-glob和vue,其他的如果需要再進行新增。nodej-glob是用來獲取路徑的,vue是需要依賴的主要部分。

第四步:修改專案

這一步最重要。 
在我們沒有動過之前,src目錄是這個樣子的,如圖5: 
沒動過的src 
圖5 
首先,建立如下目錄結構: 
src 

—–module 

—–index 

—–index.html 
—–main.js 
將之前外面的index.html放進來,main.js放入index,改名為index.js,此處一定注意名稱要相同,否則後面尋找路徑時是找不到對應檔案的。然後將App.vue放入components。最後是這樣的,如圖6: 
修改之後的src 
圖6 
這時候需要對檔案進行一定的修改。首先是index.js,對App的呼叫,路徑修改,如圖7 
[圖片]

[圖片] 
圖7

修改完了上面的資源,我們要修改webpack的配置。 
我們介紹一下webpack在這個專案中原本的順序:由於webpack將所有的js,css/less,html等都視為js的可引入資源,所以入口就成了js檔案。那麼webpack需要設定一個入口的js檔案,這個入口的js檔案就是main.js,在webpack中有一個外掛,叫做html-webpack-plugin,這個是用來將js和html對應起來,也就是若干js對應一個html,在原來的專案中html就是index.html。 
在執行npm run dev 或者build之後,就會將檔案打包,由於dev的時候檔案是在記憶體中,所以build可以看得比較清楚,在dist目錄中,會有一個index.html,其中已經打包進了

webpack.base.conf

新增下面兩行在這裡,圖8中位置,

var glob = require('glob');
var entries = getEntry('./src/module/**/*.js'); // 獲得入口js檔案
  • 1
  • 2
  • 1
  • 2

[圖片] 
圖8 
這裡的glob,就是前面提到的node-glob。將entry修改為這個,圖9中位置, 
[圖片] 
圖9

然後在下面新增getEntry方法。

function getEntry(globPath) {
  var entries = {},
    basename, tmp, pathname;

  glob.sync(globPath).forEach(function (entry) {
    basename = path.basename(entry, path.extname(entry));
    tmp = entry.split('/').splice(-3);
    pathname = tmp.splice(0, 1) + '/' + basename; // 正確輸出js和html的路徑
    entries[pathname] = entry;
  });
  console.log("base-entrys:");
  console.log(entries);
  return entries;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

因為我們的想法是要將所有的業務模組放在module中,這樣一來的話,就在module中細分,最後輸出html都在dist的module下。這裡的字串操作也是和路徑的情況相匹配的,如果有需要進行其他方式的設定,注意在這裡修改路徑的識別。

webpack.dev.conf.js

在開啟後,我們會發現在這裡有一個外掛的設定,如圖10: 
[圖片] 
圖10 
這個 外掛就是剛才提到的將輸出html頁面build結果的地方。 
首先,新增

var path = require('path');
var glob = require('glob');
  • 1
  • 2
  • 1
  • 2

用來引入path和glob工具。 
將圖10中的那一段去掉,因為我們要自己來新增這個外掛。 
同樣的,在這個檔案中也需要新增這個函式,放在檔案的下面,

function getEntry(globPath) {
  var entries = {},
    basename, tmp, pathname;

  glob.sync(globPath).forEach(function(entry) {
    basename = path.basename(entry, path.extname(entry));
    tmp = entry.split('/').splice(-3);
    pathname = tmp.splice(0, 1) + '/' + basename; // 正確輸出js和html的路徑
    entries[pathname] = entry;
  });
  console.log("dev-entrys:");
  console.log(entries);
  return entries;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

然後再新增這一段,

var pages = getEntry('./src/module/**/*.html');
console.log("dev pages----------------------");
for (var pathname in pages) {
  console.log("filename:" + pathname + '.html');
  console.log("template:" + pages[pathname]);
  // 配置生成的html檔案,定義路徑等
  var conf = {
    filename: pathname + '.html',
    template: pages[pathname], // 模板路徑
    minify: { //傳遞 html-minifier 選項給 minify 輸出
      removeComments: true
    },
    inject: 'body', // js插入位置
    chunks: [pathname, "vendor", "manifest"] // 每個html引用的js模組,也可以在這裡加上vendor等公用模組
  };
  // 需要生成幾個html檔案,就配置幾個HtmlWebpackPlugin物件
  module.exports.plugins.push(new HtmlWebpackPlugin(conf));
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

這個同樣是通過指定的路徑,按照我之前的預想,進行html的迭代獲取,然後對每一個html進行設定。我們的多頁面輸出關鍵也就在這個地方。 
html-webpack-plugin這個外掛可以為一個html輸出打包對應的js模組。chunks就是對應的js模組,也就是webpack的入口,包括entries和使用了webpack.optimize.CommonsChunkPlugin外掛聲稱的公共js模組。這些模組都有各自的名字,entries的名字就是前面通過getEntry函式生成的一組入口元件名稱和路徑。 
通過上面的修改,就做成了這樣一件事情:為webpack提供多個js入口,而這些js入口和html頁面是在同一個資料夾下的,那麼它們的key或者說name就是相同的。這樣在迴圈的時候,就會獲取到對應的js和html,通過迴圈建立多個html-webpack-plugin來將不同的js模組打包進對應的html,並通過webpack批量構建,在dist中就會產生我們需要的一組html檔案。而這些html檔案都是已經經過壓縮的,js程式碼也經過了壓縮處理。

webpack.prod.conf.js

和webpack.dev.conf.js中做類似的處理,先註釋掉原來的HtmlWebpackPlugin,然後在下面新增函式,通過迭代插入多個HtmlWebpackPlugin。

HtmlWebpackPlugin更多的設定,到webpack的官網上檢視。

然後使用npm run dev或者npm run build來構建。在構建的過程中,可能會出現一些依賴外掛不存在的錯誤,需要先使用npm install –save-dev 外掛名 來安裝相應的依賴外掛。

這樣,index.html就被構建到了dist/module/index.html中。 
但功能是一模一樣的。 
vue的使用在這裡不贅述。這裡說明一下,我們的module中,是系統的業務模組,components中是功能模組和細分的程式碼模組,也就是vue元件。由於webpack這裡帶了babel,所以在js原始檔中可以使用ES6的寫法。在業務js中,就可以通過匯入,組合,自定義vue元件,來實現相應的業務需求。

其他

比如在我現在拆分的這個網頁中,包括這麼幾個部分: 
[圖片]

[圖片]

[圖片] 
這是對一個bootstrap網站模板index頁面進行拆分後的結果,css,html都放在對應的vue中,當然,我也引入了jquery。 
vue的元件可以實現繼承和mixin。能夠很好的進行元件化開發,而通過webpack將src的原始碼進行構建變成瀏覽器能夠識別的正常檔案。這樣就大大降低了前端開發的重複性。