本篇文章主要是我在開發前研究了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,感興趣的童鞋可以去了解下。