Skip to content
返回

将组件合并成一个文件

先来说说我对“组件”的定义。

前端开发过程中,可能会用到一些第三方插件,比如 jBox 或者 asDatepicker:这些插件会附带一个 css 文件用来定义样式。于是我们在使用这些插件的时候,页面看上去是这样的:

<link rel="stylesheet" href="jBox.css">
<script src="jBox.js"></script>

这里有一个小问题:既然需要加载 jBox.js 的时候总是需要加载 jBox.css 的,那为什么不将 jBox.css 写进 jBox.js 呢?这样可以减少一次 HTTP 请求。

但是总所周知,在 js 里的长文本是很难维护的,所以最好的解决方案是:开发时分成多个文件,但在生产环境时合并成一个文件;相关的文件最好放在一处,比如说放在同一个文件夹下——这就是我所认为的“组件”的定义。

require.js 配合 text插件r.js 文件组合工具就可以实现上面的需求了,只是 r.js 的配置有点繁琐:它是奔着将所有的依赖文件都合并在一起的目标去的,而我这里的需求是只想合并组件而已,为此我不得不为每一个组件进行单独配置,这肯定是不利于维护的。

于是,我自己动手写了一个小工具:requirejs-components-combine,它的作用单一而简单,但可以很好的满足我的需求。

举个例子。我有一个组件叫 modal-box,这个组件的作用是取代浏览器的 alert()confirm() 方法,它的文件结构如下:

modal-box/
    |----- template.html(模板)
    |----- modal.css(样式)
    ------ index.js (逻辑)

下面简单列出这三个文件的内容: template.html

<!-- 前略 -->
<body>
    <div class="modal-box">Hello World</div>
</body></html>

modal.css

.modal-box { color:red; display:none }

index.js

define(['jquery', 'text!template.html!strip', 'text!modal.css'], function ($, HTML, CSS) {
     var $modal = $( HTML ).appendTo( 'body' );
    $('<style>' + CSS + '</style>').appendTo( 'head' );
    return {
        show: function () { $modal.show(); } ,
        hide: function () { $midal.hide(); }
    };
} );

最后,我们在代码里应该是这样使用它的: test.js

require( ['modal-box/index'] , function (modal) {
    modal.show();
});

这样,开发时避免了将模板与样式直接写进 index.js 里,而在上线前,就可以使用我的小工具进行合并了,合并之后的文件结构是这样的:

modal-box/
    |----- template.html(模板)
    |----- modal.css(样式)
    ------ index.js (逻辑)
modal-box.js(合并后的文件)

modal-box.js 的内容是:

define('_template.html',function(){return'<div class="modal-box">Hello World</div>'});
define('_modal.css',function(){return'.modal-box { color:red; display:none }'});
define( [ 'jquery' , '_template.html' , '_modal.css' ] , function (  $ , HTML , CSS ) {
     var $modal = $( HTML ).appendTo( 'body' );
    $('<style>' + CSS + '</style>').appendTo( 'head' );
    return {
        show:function () { $modal.show(); } ,
        hide:function () { $midal.hide(); }
    };
} );

最后,我们还需要将 test.js 里面的引用从 modal-box/index 改成 modal-box;我们可以在开发时就写一个“代理模块”,避免每次组合完成后都需要更改模块引用: 开发时就先写一个 modal-box.js

define(['modal-box/index'],function (m) { return m; });

组件合并工具会覆盖这个“代理模块”,那么在开发时,test.js就可以放心的引用 modal-box ,不需要更改模块引用了。

就是这样了!


分享这篇文章:

上一篇
你好,AngularJS
下一篇
登录进 NPM 花了我两个小时