webpack打包avalon+oniui+jquery

随着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': '正文1

fasdfsdaf

' }, { '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

fasdfsdaf

' }, { '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之流了。

相关文章
相关标签/搜索