本篇文章主要是我在開發前研究了webpack+vue.js的單頁面應用,因為需要用到node的npm,所以確保安裝了node,建議官網安裝最新的穩定版本。並且在專案中需要載入一些npm包,由於npm的伺服器在國外,可能我們下載的過程會比較慢,所以建議用阿里的映象cnpm安裝,10分鐘實時更新一次npm的映象。具體的下載配置參考阿里的cnpm官網。本文章只是和大家探討怎麼利用webpack配合vue.js做一個單頁面應用,具體關於vue裡面的內容怎麼寫並不在本篇文章的介紹範圍。
1. 定義我們demo的基本目錄
├── README.md
├── index.html // 專案入口檔案
├── package.json // 專案配置檔案
├── src // 生產目錄
│ ├── vue // 元件
│ | ├──home.vue
│ | ├──blog.vue
│ | ├──about.vue
│ | ├──topic.vue
│ ├── components // 各種元件
│ ├── views // css檔案
│ ├── scss //scss檔案
│ └── main.js // Webpack 預編譯入口
└── webpack.js // Webpack 配置檔案
2. 配置一下我們的webpack.js檔案
在介紹怎麼配置之前你需要掌握一個命令 npm install <模組> --save-dev
這個命令的意思是這個命名的意思是我們安裝了這個包並且把它的基本資訊寫入目錄的package.json檔案。還有一個命令是我們直接執行cnpm install會自動下載package.json裡面寫入的包.
在webpack的配置檔案我們需要用到四個npm的模組分別是:path
,webpack
,extract-text-webpack-plugin
,vue-loader
記得先下載包在用require命令引入進來
//node的路徑模組
var path=require('path');
//我們是webpack當然要引入這個
var webpack = require('webpack');
//這個是構建頁面資源的外掛
var ExtractTextPlugin = require('extract-text-webpack-plugin');
//因為我們是vue.js的應用,把各個元件當做一個頁面.vue字尾,所以引入這個可以編譯這些檔案
var vue = require("vue-loader");
好了,我們已經把需要的模組引入進來了,接下來我們定義一些接下來要用到的一些資料夾路徑
//__dirname是node裡面的一個變數,指向的是當前資料夾目錄
var ROOT_PATH = path.resolve(__dirname);
//這個我們的檔案入口,等下我們就會從main.js這個檔案作為入口
var APP_PATH = path.resolve(ROOT_PATH, 'src/main.js');
//這個是檔案打包出來的輸出路徑
var BUILD_PATH = path.resolve(ROOT_PATH, 'build');
基本的檔案路徑我們已經定義好了,接下來我們要用到extract-text-webpack-plugin
這個外掛了
var plugins = [
//提公用js到common.js檔案中
new webpack.optimize.CommonsChunkPlugin('common.js'),
//將樣式統一發布到style.css中
new ExtractTextPlugin("style.css"),
// 使用 ProvidePlugin 載入使用率高的依賴庫
new webpack.ProvidePlugin({
$: 'webpack-zepto'
})
];
接下來是webpack的重點了loader,webpack的思想是把每個靜態資原始檔當做一個模組載入,我們需要做一些配置,在這裡我們需要用到編譯css,sass模組,多以我們還需要安裝'css-loader','style-loader','node-sass','md5'
module.exports = {
//檔案的入口,還可以寫成多陣列的形式,具體自己擴充套件
entry:[APP_PATH],
//輸出
output:{
//輸出路徑
path: BUILD_PATH,
//打包的js命名
filename:build.js'
// 指向非同步載入的路徑
publicPath : __dirname + '/build/',
// 非主檔案的命名規則,加快取用到md5
chunkFilename: '[id].build.js?[chunkhash]'
},
module: {
loaders: [
{
test: /\.vue$/,
loader: 'vue',
},
{
test: /\.scss$/,
loader: ExtractTextPlugin.extract("style-loader", 'css-loader')
},
{
test: /\.css$/,
loader: ExtractTextPlugin.extract("style-loader", "css-loader")
},
{
test: /\.(png|jpg)$/,
loader: 'url?limit=40000'
}
]
},
//這個特別說明下,vue提倡把一個元件當做一個頁面,所以可能在一個頁面寫html,style,javascript,也可以引入和寫scss檔案
vue: {
css: ExtractTextPlugin.extract("css"),
sass: ExtractTextPlugin.extract("css!sass-loader")
},
plugins: plugins
}
3. 配置我們的入口檔案main.js
這裡我們需要三個npm模組,vue,vue-router,vue-resource三個模組,我們依次安裝然後在引入
//vue的應用當然要引,等下要用它來註冊
var Vue = require('vue')
//這個是路由,spa應用必要哦
var VueRouter = require('vue-router');
//這個是類似ajax請求,肯定要拉去資料啦,所以也下載吧
var VueResource = require('vue-resource');
在vue裡面宣告並註冊個空元件
Vue.use(VueRouter);
Vue.use(VueResource);
var app = Vue.extend({});
例項化VueRounter
var router = new VueRouter({
// 當hashbang的值為true時,所有的路徑都會被格式化已#!開頭,
hashbang: true,
history: false,
saveScrollPosition: true,
transitionOnLoad: true
});
接下來寫下我們的路由路徑,也可以單獨把路由寫在一個檔案,我們這邊只是個demo所以寫一起了,不打緊,關於這塊路由的寫法可以具體參考下vue-router的文件http://router.vuejs.org/zh-cn...,將的很詳細。
這裡有必要將一下,webpack提供了非同步載入功能,配合vue-router的路由使用,當哪個元件需要渲染是,會載入它依賴的元件,並且非同步載入進來。是不是很棒。
router.map({
'/':{ //首頁
component: function (resolve) {
require(['./vue/home.vue'],resolve)
}
},
'/home':{
name : 'home', //首頁
component: function (resolve) {
require(['./vue/home.vue'],resolve)
}
},
'/blog':{
name : 'blog', //部落格列表
component: function (resolve) {
require(['./vue/blog.vue'],resolve)
}
},
'/blog/topic':{
name : 'topic',
//文章詳情
component: function (resolve) {
require(['./vue/topic.vue'],resolve)
}
},
'/about':{
name : 'about',
//關於
component: function (resolve) {
require(['./vue/about.vue'],resolve)
}
}
})
再加句程式碼,測試訪問路由訪問是否成功
router.afterEach(function (transition) {
console.log('成功瀏覽到: ' + transition.to.path)
})
最後我們註冊下vue
router.start(app, "#app");
4. 填充下index.html檔案的結構
<router-view> 用於渲染匹配的元件,它基於 Vue 的動態元件系統。我們的index.html結構是這樣子的
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>個人站</title>
<link rel="stylesheet" href="./build/style.css">
</head>
<body>
<div id="app">
<router-view></router-view>
</div>
<script src="./build/common.js"></script>
<script src="./build/build.js"></script>
</body>
</html>
5. 怎麼寫一個元件
關於元件,vue提倡一個模組寫一個具體的元件比如列表元件可以list.vue,然後根據路由載入具體的元件,元件之間也可以相互的引用,具體參考vue文件。
為了方便我們測試,我們以home為例,其他元件也類似,方便等下測試,等專案能完整跑起來你在自己去新增元件裡面的內容。
<template>
<div>home</div>
</template>
<script>
// js
</script>
<style>
/*style*/
</style>
6. 執行webpack
關於一個單頁面的大體的框架我們已經搭建好了,現在直接執行webpack就能把檔案載出來了。然後開啟index.html直接測試就好了。更詳細的demo已經提交到github上了 demo,還有本人使用webpack+vue+es6+sass的技術棧重構的Cnode中文網單頁面應用,感興趣的可以圍觀下,歡迎star。
7.開發模式
在實際開發過程中我們肯定不是每一次修改儲存,然後在執行一下webpack命令,那樣就太麻煩了,所以我們用到了熱替換,webpack-dev-server這個包,安裝好這個包後在pack.json加上
"scripts": {
"start": "webpack-dev-server --hot --inline"
}
並且把webpack.config.js這前我們配置好的
// 指向非同步載入的路徑
publicPath : __dirname + '/build/';
替換為
// 指向非同步載入的路徑
publicPath : '/build/';
為什麼這樣做呢?因為我們這前用webpack是把元件非同步載入在本地上,而我們用了熱替換後是地址委託到了http://localhost:8080/埠了,所以要去掉__dirname(指向本地根目錄),一切準備完畢了,接下來直接執行npm start,然後開啟http://localhost:8080/就可以訪問,試著修改內容儲存可以看看頁面實時的在重新整理,是不是省了很多的開發時間呢!
關於vue-cli
vue.js的原作者為了方便我們做專案前期花費時間配置這些自動化構建工具,出了一個vue-cli的腳手架,可以自動生成專案的一系列基本配置。vue-cli的github地址為https://github.com/vuejs/vue-cli,感興趣的童鞋可以去了解下。