隨着avalon的發展壯大,我根據CSDN的統計數字,中國前端大概有1%的人在使用avalon了。javascript
avalon的最大優點是能兼容IE6,而且其API是很是穩定,只是在1.3.7 對ms-duplex的攔截器作了一次改動(但此次改動也向下兼容),1.5中去除avalon.define的舊風格支持,廢掉ms-widget指令改爲更強大的自定義標籤指令。相對於其餘MVVM框架來講,是很是的良心。此外,配套是很是完善,尤爲是oniui,也支持到IE6。至於對移動端啊,微信啊,支持也很是好,難怪天天加羣的人這麼多。css
不過,一個問題是,avalon沒有提供打包機制,雖然官網有教如何用requirejs打包avalon(好比滴滴出行,他們則是用fis3打包avalon ),但也有一些小公司,由於前端團隊實力不濟,沒法實現打包。所以就有了這篇文章了。html
本文是使用當今最強大的構建工具webpack實現的,各類看官首先得裝上npm。前端
創建一個新工程(我是將此工程起名爲oni), 而後用npm初始化它,目的是創建一個package.json文件:java
而後全局安裝如下東西node
$ npm install webpack -g $ npm install style-loader css-loader url-loader text-loader -g
而後再到oni目錄下執行npm link命令jquery
$ npm link webpack style-loader css-loader text-loader
雖然看似報了一大堆錯,但好歹也裝上了:webpack
而後 咱們安裝avalon依賴,因爲要用oniui,只能使用1.4.* 版本,而且只能沒有加載器的版本(帶shim字樣的),請到這裏下載https://github.com/RubyLouvre/avalon/tree/master/dist ,將裏面的avalon.shim.js下載回來,放到dev/avalon目錄下。git
而後 咱們開始裝oniui。oniui是一個龐大的UI庫,爲了知足去哪兒各條業務線千奇百計的需求,組件很是豐富,功能強大無比! 咱們沒有必要將它們所有裝上。咱們能夠在這裏(https://github.com/RubyLouvre/avalon.oniui)一覽其全貌,挑選本身須要的組件(readme裏有中文名)github
好比,咱們用手風琴(accordion)組件,那麼打開裏面的avalon.accordion.js的源碼,看其依賴狀況:
會發現它依賴於avalon.getModel.js,這是在它的上級目錄;還有它的模板文件,與它同目錄; 還有一些樣式。accordion的目錄下有許多東西,爲了節省時間,咱們能夠所有拷下來放到dev目錄下。
而後 咱們在oni的根目錄下創建webpack的配置文件webpack.package.js,內容以下:
var webpack = require("webpack"); var path = require("path"); module.exports = { entry: "./dev/index", //咱們開發時的入口文件 output: {path: path.join(__dirname, "dist"), filename: "bundle.js"}, //頁面引用的文件 module: { loaders: [ {test: /\.css$/, loader: 'style-loader!css-loader'} ] }, resolve: { extensions: ['.js',"",".css"], alias: { avalon: './avalon/avalon.shim',//在正常狀況下咱們以CommonJS風格引用avalon,以require('avalon') "../avalon": './avalon/avalon.shim'//因爲oniui都以是../avalon來引用avalon的,須要在這裏進行別名 } } }
dev下的index.js是這樣的:
var avalon = require("avalon") require("./accordion/avalon.accordion") avalon.define({ $id: "test", aaa: "Hello Avalon!" }) // 具體參考這裏 https://github.com/RubyLouvre/avalon.oniui/blob/master/accordion/avalon.accordion.ex1.html avalon.define({ $id: "test", aaa: "Hello Avalon!", $opts:{ data: [{ 'title': '標題1', 'content': '正文1fasdfsdaf
' }, { 'title': '標題2', 'content': '正文2' }], accordionClass: "oni-accordion-customClass", initIndex: 1, width: "500", onBeforeSwitch: function() { avalon.log(this); avalon.log(arguments); avalon.log("onBeforeSwitch callback"); }, onSwitch: function() { avalon.log("onSwitch callback"); }, multiple: true } })
而後咱們在控制檯下,定位到oni目錄下,輸入webpack開始打包,報了一堆錯誤
其實我對webpack也不怎麼熟,主要是參考以下中文教程開始玩的
我思度一下,估計沒有像我這樣混用CommonJS與AMD兩種風格,問題是出在加載CSS上,難道正則有問題嗎?試了很久,沒有辦法,本身寫預加載器,從avalon.accordion的源碼中幹掉css!字樣。
具體過程以下,在oni/node_modules目錄下創建一個amdcss-loader目錄,結構以下:
package.json內容以下(這個不能少)
{ "author": { "name": "RubyLouvre" }, "dependencies": {}, "description": "Webpack的預處理器,處理AMD風格的模塊依賴列表中的css!字符串", "license": "MIT", "main": "index.js", "name": "amdcss-loader", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "version": "0.0.1" }
index.js內容以下:
module.exports = function (source) { this.cacheable && this.cacheable(); source = source.replace(/css\!/g, "") this.callback(null, source); };
將webpack.config.js修改以下:
var webpack = require("webpack"); var path = require("path"); module.exports = { entry: './dev/index', //咱們開發時的入口文件 output: {path: path.join(__dirname, "dist"), filename: "bundle.js"}, //頁面引用的文件 module: { loaders: [ {test: /\.css$/, loader: 'style-loader!css-loader'} ], preLoaders: [ {test: /\.js$/, loader: "amdcss-loader"} ] }, resolve: { extensions: ['.js', "", ".css"], alias: { avalon: './avalon/avalon.shim', //在正常狀況下咱們以CommonJS風格引用avalon,以require('avalon') "../avalon": './avalon/avalon.shim'//因爲oniui都以是../avalon來引用avalon的,須要在這裏進行別名 } } }
再打包就成功了!
好了,咱們須要一個頁面看一下效果。oniui目錄下,創建一個index.html
<!DOCTYPE html> <html> <head> <title>TODO supply a title</title> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <script src="dist/bundle.js"></script> <style> body{ padding:2em; } </style> </head> <body ms-controller="test"> <h1>{{aaa}}</h1> <div ms-widget="accordion,$,$opts"></div> </body> </html>
而後打開你的頁面就行看到效果了(我是使用netBeans直接運行,你們也能夠試一下webpack-dev-server)
咱們再看一下如何結合jquery一塊兒使用,jquery咱們仍是使用兼容IE6的版本,能夠到這裏下回來,放到dev/jquery目錄下!
咱們繼續修改webpack.config.js
var webpack = require("webpack"); var path = require("path"); module.exports = { entry: './dev/index', //咱們開發時的入口文件 output: {path: path.join(__dirname, "dist"), filename: "bundle.js"}, //頁面引用的文件 module: { loaders: [ {test: /\.css$/, loader: 'style-loader!css-loader'} ], preLoaders: [ {test: /\.js$/, loader: "amdcss-loader"} ] }, resolve: { extensions: ['.js', "", ".css"], alias: { jquery: "./jquery/jquery.js", avalon: './avalon/avalon.shim', //在正常狀況下咱們以CommonJS風格引用avalon,以require('avalon') "../avalon": './avalon/avalon.shim'//因爲oniui都以是../avalon來引用avalon的,須要在這裏進行別名 } } }
而後修改dev/index.js
var avalon = require("avalon") require("./accordion/avalon.accordion") var $ = require("jquery") avalon.define({ $id: "test", aaa: "Hello Avalon!", $opts:{ data: [{ 'title': '標題1', 'content': '正文1fasdfsdaf
' }, { 'title': '標題2', 'content': '正文2' }], accordionClass: "oni-accordion-customClass", initIndex: 1, width: "500", onBeforeSwitch: function() { avalon.log(this); avalon.log(arguments); avalon.log("onBeforeSwitch callback"); }, onSwitch: function() { avalon.log("onSwitch callback"); }, multiple: true } }) $(function(){ $("這是jQuery生成的").appendTo("body") })
從新運行webpack命令,jquery就打包進去!
不過,我其實不但願你們將jquery與avalon都打包進去的,由於這兩個庫比較經常使用,幾乎每一個頁面都有,創建放到CDN中,用script獨立引入。詳見 《Webpack 性能優化 (一)(使用別名作重定向)》一文。
至此,本文完畢。我是但願avalon社區能使用更強大的工具進行打包,而不是用requriejs之流了。