webpack打包avalon


webpack打包avalon+oniui+jquery

隨着avalon的發展壯大,我根據CSDN的統計數字,中國前端大概有1%的人在使用avalon了。

avalon的最大優勢是能兼容IE6,並且其API是非常穩定,只是在1.3.7 對ms-duplex的攔截器做了一次改動(但這次改動也向下兼容),1.5中去除avalon.define的舊風格支持,廢掉ms-widget指令改成更強大的自定義標簽指令。相對於其他MVVM框架來說,是非常的良心。此外,配套是非常完善,尤其是oniui,也支持到IE6。至於對移動端啊,微信啊,支持也非常好,難怪每天加群的人這么多。

不過,一個問題是,avalon沒有提供打包機制,雖然官網有教如何用requirejs打包avalon(比如滴滴出行,他們則是用fis3打包avalon ),但也有一些小公司,因為前端團隊實力不濟,無法實現打包。因此就有了這篇文章了。

本文是使用當今最強大的構建工具webpack實現的,各種看官首先得裝上npm。

建立一個新工程(我是將此工程起名為oni), 然后用npm初始化它,目的是建立一個package.json文件:

然后全局安裝以下東西

$ npm install webpack -g
$ npm install style-loader css-loader url-loader text-loader -g

然后再到oni目錄下執行npm link命令

$ npm link webpack style-loader css-loader text-loader

雖然看似報了一大堆錯,但好歹也裝上了:

然后 我們安裝avalon依賴,由於要用oniui,只能使用1.4.* 版本,並且只能沒有加載器的版本(帶shim字樣的),請到這里下載https://github.com/RubyLouvre/avalon/tree/master/dist ,將里面的avalon.shim.js下載回來,放到dev/avalon目錄下。

然后 我們開始裝oniui。oniui是一個龐大的UI庫,為了滿足去哪兒各條業務線千奇百計的需求,組件非常豐富,功能強大無比! 我們沒有必要將它們全部裝上。我們可以在這里(https://github.com/RubyLouvre/avalon.oniui)一覽其全貌,挑選自己需要的組件(readme里有中文名)

比如,我們用手風琴(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!"
})
avalon.define({
  $id: "test",
  aaa: "Hello Avalon!",
  $opts:{
    data: [{
        'title': '標題1',
        'content': '正文1<p>fasdfsdaf</p>'
    }, {
        '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': '正文1<p>fasdfsdaf</p>'
    }, {
        '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(){
    $("<div>這是jQuery生成的</div>").appendTo("body")
})

重新運行webpack命令,jquery就打包進去!

不過,我其實不希望大家將jquery與avalon都打包進去的,因為這兩個庫比較常用,幾乎每個頁面都有,建立放到CDN中,用script獨立引入。詳見 《Webpack 性能優化 (一)(使用別名做重定向)》一文。

至此,本文完畢。我是希望avalon社區能使用更強大的工具進行打包,而不是用requriejs之流了


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM