www.qjdy.com-奇迹赌场 > www.qjdy.com官网 > 我说按模块划分好

原标题:我说按模块划分好

浏览次数:84 时间:2019-10-29

致我们一定会将组件化的Web

2015/11/25 · HTML5 · 1 评论 · 组件化

原稿出处: AlloyTeam   

那篇小说将从五年前的一遍技术争议起来。争辨的聚集就是下图的八个目录分层结构。我说按模块划分好,他说您傻逼啊,当然是按能源划分。

图片 1 《=》图片 2

”按模块划分“目录结构,把当前模块下的兼具逻辑和能源都放一块了,那对于多个人独自开荒和爱护个人模块不是很好呢?当然了,这争辨的结果是自身婴孩地改回主流的”按能源划分“的目录结构。因为,未有到位JS模块化和能源模块化,仅仅物理地点上的模块划分是不曾意义的,只会追加创设的花费而已。

固然如此他说得好有道理笔者无言以对,不过自身心不甘,等待他如今端组件化成熟了,再来世界一战!

而前些天正是自己屡屡正义的小日子!只是那个时候至极跟你撕逼的人不在。

模块化的贫乏

模块日常指可以独立拆分且通用的代码单元。由于JavaScript语言本身未有放手的模块机制(ES6有了!!),咱们日常会接纳CMD或ADM创设起模块机制。现在多数有个别大型一点的花色,都会动用requirejs也许seajs来促成JS的模块化。多人分工同盟开荒,其分别定义信任和暴露接口,维护功用模块间独立性,对于项指标开销功能和档案的次序早先时期扩张和维护,都以是有超大的推来推去成效。

但,麻烦大家不怎么略读一下底下的代码

JavaScript

require([ 'Tmpl!../tmpl/list.html','lib/qqapi','module/position','module/refresh','module/page','module/net' ], function(listTmpl, QQapi, Position, Refresh, Page, NET){ var foo = '', bar = []; QQapi.report(); Position.getLocaiton(function(data){ //... }); var init = function(){ bind(); NET.get('/cgi-bin/xxx/xxx',function(data){ renderA(data.banner); renderB(data.list); }); }; var processData = function(){ }; var bind = function(){ }; var renderA = function(){ }; var renderB = function(data){ listTmpl.render('#listContent',processData(data)); }; var refresh = function(){ Page.refresh(); }; // app start init(); });

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
require([
    'Tmpl!../tmpl/list.html','lib/qqapi','module/position','module/refresh','module/page','module/net'
], function(listTmpl, QQapi, Position, Refresh, Page, NET){
    var foo = '',
        bar = [];
    QQapi.report();
    Position.getLocaiton(function(data){
        //...
    });
    var init = function(){
        bind();
        NET.get('/cgi-bin/xxx/xxx',function(data){
            renderA(data.banner);
            renderB(data.list);
        });
    };
    var processData = function(){
    };
    var bind = function(){
    };
    var renderA = function(){
    };
    var renderB = function(data){
        listTmpl.render('#listContent',processData(data));
    };
    var refresh = function(){
        Page.refresh();
    };
    // app start
    init();
});

地点是切实有个别页面包车型大巴主js,已经封装了像Position,NET,Refresh等成效模块,但页面包车型客车主逻辑依然是”面向进程“的代码结构。所谓面向进程,是指遵照页面的渲染进度来编排代码结构。像:init -> getData -> processData -> bindevent -> report -> xxx 。 方法之间线性跳转,你大致也能感受那样代码破绽。随着页面逻辑更是复杂,那条”进度线“也会愈发长,而且更为绕。加之缺少专门的学问节制,别的门类成员依据各自须求,在”进度线“加插各自逻辑,最后那几个页面包车型地铁逻辑变得难以维护。

图片 3

支付须要严慎,生怕影响“进度线”前边寻常逻辑。而且每壹回加插或改动都是bug泛滥,无不令产品有关职员无不毛骨悚然。

 页面结构模块化

根据下面的面向进度的难点,行当内也可以有大多解决方案,而大家组织也计算出风流浪漫套成熟的解决方案:Abstractjs,页面结构模块化。大家能够把大家的页面想象为二个乐高机器人,须要不一样零件组装,如下图,假诺页面划分为tabContainer,listContainer和imgsContainer四个模块。最终把这一个模块add到终极的pageModel里面,最后利用rock方法让页面运维起来。

图片 4
(原经过线示例图)

图片 5
(页面结构化示例图)

上面是伪代码的达成

JavaScript

require([ 'Tmpl!../tmpl/list.html','Tmpl!../tmpl/imgs.html','lib/qqapi','module/refresh','module/page' ], function(listTmpl, imgsTmpl, QQapi, Refresh, Page ){ var tabContainer = new RenderModel({ renderContainer: '#tabWrap', data: {}, renderTmpl: "<li soda-repeat='item in data.tabs'>{{item}}</li>", event: function(){ // tab's event } }); var listContainer = new ScrollModel({ scrollEl: $.os.ios ? $('#Page') : window, renderContainer: '#listWrap', renderTmpl: listTmpl, cgiName: '/cgi-bin/index-list?num=1', processData: function(data) { //... }, event: function(){ // listElement's event }, error: function(data) { Page.show('数据重返卓殊[' data.retcode ']'); } }); var imgsContainer = new renderModel({ renderContainer: '#imgsWrap', renderTmpl: listTmpl, cgiName: '/cgi-bin/getPics', processData: function(data) { //... }, event: function(){ // imgsElement's event }, complete: function(data) { QQapi.report(); } }); var page = new PageModel(); page.add([tabContainer,listContainer,imgsContainer]); page.rock(); });

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
require([
    'Tmpl!../tmpl/list.html','Tmpl!../tmpl/imgs.html','lib/qqapi','module/refresh','module/page'
], function(listTmpl, imgsTmpl, QQapi, Refresh, Page ){
 
    var tabContainer = new RenderModel({
        renderContainer: '#tabWrap',
        data: {},
        renderTmpl: "<li soda-repeat='item in data.tabs'>{{item}}</li>",
        event: function(){
            // tab's event
        }
    });
 
    var listContainer = new ScrollModel({
        scrollEl: $.os.ios ? $('#Page') : window,
        renderContainer: '#listWrap',
        renderTmpl: listTmpl,
        cgiName: '/cgi-bin/index-list?num=1',
        processData: function(data) {
            //...
        },
        event: function(){
            // listElement's event
        },
        error: function(data) {
            Page.show('数据返回异常[' data.retcode ']');
        }
    });
 
    var imgsContainer = new renderModel({
        renderContainer: '#imgsWrap',
        renderTmpl: listTmpl,
        cgiName: '/cgi-bin/getPics',
        processData: function(data) {
            //...
        },
        event: function(){
            // imgsElement's event
        },
        complete: function(data) {
           QQapi.report();
        }
    });
 
    var page = new PageModel();
    page.add([tabContainer,listContainer,imgsContainer]);
    page.rock();
 
});

我们把那个常用的倡议CGI,管理多少,事件绑定,上报,容错管理等意气风发多元逻辑方式,以页面块为单位封装成四个Model模块。

那样的贰个浮泛层Model,我们得以清楚地看来该页面块,央求的CGI是怎么着,绑定了哪些风浪,做了哪些上报,出错怎么管理。新扩展的代码就应该放置在对应的模块上相应的情况方法(preload,process,event,complete…),杜绝了昔日的不可能规乱增代码的行文。并且,依照不一致专门的工作逻辑封装分歧类型的Model,如列表滚动的ScrollModel,滑块作用的SliderModel等等,能够进行中度封装,集中优化。

最近依附Model的页面结构开采,已经富含一点”组件化“的含意。各种Model都含有各自的数码,模板,逻辑。已经算是三个完完全全的效果与利益单元。但间距真正的WebComponent依旧有意气风发段间距,最少满意不断我的”理想目录结构“。

 WebComponents 标准

我们想起一下利用二个datapicker的jquery的插件,所要求的步奏:

  1. 引进插件js

  2. 引进插件所需的css(假若有)

  3. copy 组件的所需的html片段

  4. 增加代码触发组件运行

一时一刻的“组件”基本上只好到达是有个别作用单元上的会集。他的财富都是松散地分散在三种能源文件中,并且组件功效域揭穿在全局意义域下,缺乏内聚性比较轻便就能够跟其它零件爆发冲突,如最简便易行的css命名冲突。对于这种“组件”,还比不上上面的页面结构模块化。

于是乎W3C按耐不住了,制订一个WebComponents标准,为组件化的前程引导了明路。

上面以较为轻松的方法介绍那份正经,力求大家可以高效通晓完结组件化的剧情。(对那部分询问的同窗,能够跳过这一小节)

1. <template>模板本事

模板那东西大家最熟习然而了,二〇一八年见的非常多的沙盘性能战不着疼热artTemplate,juicer,tmpl,underscoretemplate等等。而明日又有mustachejs无逻辑模板引擎等新入选手。可是大家有没有想过,这么基础的工夫,原生HTML5是不扶助的(T_T)。

而前天WebComponent将在提供原生的模版才具

XHTML

<template id="datapcikerTmpl"> <div>笔者是原生的模板</div> </template>

1
2
3
<template id="datapcikerTmpl">
<div>我是原生的模板</div>
</template>

template标签钦点义了myTmpl的模板,必要运用的时候将在innerHTML= document.querySelector('#myTmpl').content;能够看出那个原生的沙盘够原始,模板占位符等成效都还未,对于动态数据渲染模板技术只好自力更新。

2. ShadowDom 封装组件独立的内部结构

ShadowDom能够领略为大器晚成份有独立成效域的html片段。那一个html片段的CSS情状和主文书档案隔绝的,各自作者保护持内部的独立性。也正是ShadowDom的独立天性,使得组件化成为了只怕。

JavaScript

var wrap = document.querySelector('#wrap'); var shadow = wrap.createShadowRoot(); shadow.innerHTML = '<p>you can not see me </p>'

1
2
3
var wrap = document.querySelector('#wrap');
var shadow = wrap.createShadowRoot();
shadow.innerHTML = '<p>you can not see me </p>'

在切切实实dom节点上选择createShadowRoot方法就能够生成其ShadowDom。就像在整份Html的屋企里面,新建了壹个shadow的房间。房间外的人都不明白房间内有怎么着,保持shadowDom的独立性。

3. 自定义原生标签

第意气风发接触Angularjs的directive指令功用,设定好组件的逻辑后,多个<Datepicker />就能够引进整个组件。如此狂酷炫炸碉堡天的意义,实在令人拍手称快,跃地三尺。

JavaScript

var tmpl = document.querySelector('#datapickerTmpl'); var datapickerProto = Object.create(HTMLElement.prototype); // 设置把大家模板内容大家的shadowDom datapickerProto.createdCallback = function() { var root = this.createShadowRoot(); root.appendChild(document.importNode(tmpl.content, true)); }; var datapicker = docuemnt.registerElement('datapicker',{ prototype: datapickerProto });

1
2
3
4
5
6
7
8
9
10
11
12
var tmpl = document.querySelector('#datapickerTmpl');
var datapickerProto = Object.create(HTMLElement.prototype);
 
// 设置把我们模板内容我们的shadowDom
datapickerProto.createdCallback = function() {
    var root = this.createShadowRoot();
    root.appendChild(document.importNode(tmpl.content, true));
};
 
var datapicker = docuemnt.registerElement('datapicker',{
    prototype: datapickerProto
});

Object.create方式三番伍遍HTMLElement.prototype,获得二个新的prototype。当拆解剖析器发掘大家在文书档案中标识它将检查是还是不是一个名字为createdCallback的不二诀要。假如找到这么些艺术它将任何时候运营它,所以大家把克隆模板的源委来创制的ShadowDom。

最终,registerElement的主意传递大家的prototype来注册自定义标签。

下面的代码开头略显复杂了,把前面四个力量“模板”“shadowDom”结合,变成组件的里边逻辑。最终通过registerElement的法子注册组件。之后方可愉悦地<datapicker></datapicker>的施用。

4. imports清除组件间的依赖性

XHTML

<link rel="import" href="datapciker.html">

1
<link rel="import" href="datapciker.html">

其风姿罗曼蒂克类php最常用的html导入功效,HTML原生也能支撑了。

WebComponents标准内容大致到这里,是的,笔者那边未有啥德姆o,也未有实行经验共享。由于webComponents新天性,基本上除了高版本的Chrome援助外,别的浏览器的支撑度甚少。尽管有polymer支持拉动webcompoents的仓库储存在,然而polymer本身的渴求版本也是相当高(IE10 )。所早先不久的中流砥柱并不是她。

我们简要来回想一下WebCompoents的四片段机能:

1 .<template>定义组件的HTML模板本事

  1. Shadow Dom封装组件的内部结构,而且维持其独立性

  2. Custom Element 对外提供组件的竹签,达成自定义标签

  3. import解决组件结合和依赖加载

 组件化实行方案

合法的正经八百看完了,大家观念一下。风姿洒脱份真正成熟笃定的组件化方案,须求有所的力量。

“能源高内聚”—— 组件财富内部高内聚,组件财富由本身加载调控

“效用域独立”—— 内部结构密闭,不与大局或其余零件产生震慑

“自定义标签”—— 定义组件的应用格局

“可相互结合”—— 组件正在有力的地点,组件间组装整合

“接口标准化”—— 组件接口有统生机勃勃规范,只怕是生命周期的管住

私家以为,模板本领是基础技术,跟是还是不是组件化未有强联系,所以并未有提议多少个大点。

既然如此是执行,现阶段WebComponent的协助度还不成熟,不能够作为方案的花招。而除此以外黄金年代套以高品质虚构Dom为切入点的组件框架React,在facebook的造势下,社区赢得了大力发展。其余一名骨干Webpack,担当消除组件财富内聚,同偶尔间跟React极其适合造成互补。

所以【Webpack】 【React】将会是那套方案的宗旨手艺。

不通晓您现在是“又是react webpack”感觉失望图片 6,照旧“太好了是react webpack”不用再学三遍新框架的欢腾图片 7。不论怎么着上面包车型大巴内容不会让您失望的。

意气风发,组件生命周期

图片 8

React天生就是强制性组件化的,所以能够从根本性上化解面向进程代码所推动的麻烦。React组件自己有生命周期方法,能够知足“接口规范化”技艺点。何况跟“页面结构模块化”的所封装抽离的多少个方法能挨个对应。其它react的jsx自带模板功能,把html页面片直接写在render方法内,组件内聚性特别严密。

鉴于React编写的JSX是会先生成设想Dom的,供给时机才真正插入到Dom树。使用React必定要知道组件的生命周期,其生命周期三个状态:

Mount: 插入Dom

Update: 更新Dom

Unmount: 拔出Dom

mount这单词翻译扩张,嵌入等。作者倒是建议“插入”越来越好驾驭。插入!拔出!插入!拔出!默念一回,懂了没?别少看黄段子的手艺,

图片 9

组件状态正是: 插入-> 更新 ->拔出。

然后每一个组件状态会有二种管理函数,生龙活虎前风流浪漫后,will函数和did函数。

componentWillMount()  盘算插入前

componentDidlMount()  插入后

componentWillUpdate() 希图更新前

componentDidUpdate()  更新后

componentWillUnmount() 计划拔出前

因为拔出后基本都以贤者形态(笔者说的是组件),所以并未有DidUnmount这么些方法。

除此以外React其它一个骨干:数据模型props和state,对应着也会有自个状态方法

getInitialState()     获取伊始化state。

getDefaultProps() 获取暗中认可props。对于那多少个还未有父组件传递的props,通过该措施设置暗中同意的props

componentWillReceiveProps()  已插入的零件收到新的props时调用

再有二个例外意况的管理函数,用于优化管理

shouldComponentUpdate():剖断组件是还是不是要求update调用

加上最关键的render方法,React自个儿带的格局刚刚好11个。对于初读书人的话是相比为难消食。但其实getInitialStatecomponentDidMountrender八个状态方法都能成就超过一半零部件,不必惧怕。

重返组件化的主旨。

三个页面结构模块化的机件,能独立包装整个组件的进度线

图片 10

咱俩换算成React生命周期方法:

图片 11

 

零件的情景方法流中,有两点必要特不要表明:

1,三回渲染:

由于React的虚构Dom特性,组件的render函数不需本人触发,依照props和state的改观自个通过差别算法,得出最优的渲染。

伸手CGI平时都以异步,所以一定带来二回渲染。只是空数据渲染的时候,有希望会被React优化掉。当数码回来,通过setState,触发三次render

 

2,componentWiillMount与componentDidMount的差别

和大好多React的教程文章不后生可畏致,ajax乞请作者建议在威尔Mount的主意内举办,实际不是组件伊始化成功之后的DidMount。那样能在“空数据渲染”阶段早前诉求数据,尽早地回降三次渲染的小运。

willMount只会施行三次,特别符合做init的业务。

didMount也只会施行壹次,何况这个时候真实的Dom已经变成,特别切合事件绑定和complete类的逻辑。

 

 二,JSX非常不好看,不过组件内聚的重要!

WebComponents的正统之生龙活虎,须求模板本事。本是感觉是大家熟习的模板才具,但React中的JSX那样的怪物依旧令人研商纷繁。React还尚未火起来的时候,大家就已经在和讯上狠狠地戏弄了“JSX写的代码那TM的丑”。那其实只是德姆o阶段JSX,等到实战的大型项目中的JSX,包涵多情形多数据多事件的时候,你会发觉………….JSX写的代码依然比极不好看。

图片 12
(固然用sublime-babel等插件高亮,逻辑和渲染耦合一同,阅读性依旧略差)

何以我们会感觉丑?因为大家早就经对“视图-样式-逻辑”抽离的做法潜濡默化。

根据维护性和可读性,以至质量,大家都不提出直接在Dom上边绑定事件也许直接写style属性。大家会在JS写事件代理,在CSS上写上classname,html上的正是鲜明的Dom结构。大家很好地掩护着MVC的设计方式,一切安好。直到JSX把他们都夹杂在联合,所守护的技艺栈受到入侵,难免存有抗拒。

 

只是从组件化的指标来看,这种高内聚的做法未尝不可。

上边包车型大巴代码,在此以前的“逻辑视图分离”格局,大家要求去找相应的js文件,相应的event函数体内,找到td-info的class所绑定的风浪。

对待起JSX的惊人内聚,不论什么事件逻辑就是在自己jsx文件内,绑定的就是自身的showInfo方法。组件化的特征能立时展现出来。

(注意:纵然写法上大家好疑似HTML的内联事件管理器,不过在React底层并不曾实际赋值相符onClick属性,内层依旧选拔形似事件代理的点子,高效地掩护着事件管理器)

再来看少年老成段style的jsx。其实jsx未有对体制有硬性规定,大家一同可依照以前的定义class的逻辑。任何生机勃勃段样式都应该用class来定义。在jsx你也截然能够这么做。但是出于组件的独立性,笔者建议部分独有“一遍性”的体裁直接使用style赋值越来越好。降低冗余的class。

XHTML

<div className="list" style={{background: "#ddd"}}> {list_html} </div>

1
2
3
<div className="list" style={{background: "#ddd"}}>
   {list_html}
</div>

唯恐JSX内部有负担繁杂的逻辑样式,可JSX的自定义标签技巧,组件的黑盒性立马能体会出来,是否转瞬之间美好了过多。

JavaScript

render: function(){ return ( <div> <Menus bannerNums={this.state.list.length}></Menus> <TableList data={this.state.list}></TableList> </div> ); }

1
2
3
4
5
6
7
8
render: function(){
    return (
      <div>
         <Menus bannerNums={this.state.list.length}></Menus>
         <TableList data={this.state.list}></TableList>
      </div>
   );
}

尽管JSX本质上是为着设想Dom而希图的,但这种逻辑和视图中度合风流倜傥对于组件化未尝不是意气风发件善事。

 

读书完React那些组件化框架后,看看组件化技艺点的产生情形

“能源高内聚”—— (33%)  html与js内聚

“成效域独立”—— (四分之二)  js的功效域独立

“自定义标签”—— (百分之百)jsx

“可互相结合”—— (二分之一)  可整合,但贫乏使得的加载方式

“接口标准化”—— (百分之百)组件生命周期方法

 

Webpack 能源组件化

对于组件化的能源独立性,平常的模块加载工具和创设流程视乎变得艰巨。组件化的创设筑工程程化,不再是事先大家普及的,css合二,js合三,而是体验在组件间的依赖于加载关系。webpack正好符合须要点,一方面填补组件化技巧点,另一方帮忙我们周密组件化的全体构建蒙受。

先是要申美素佳儿(Friso)点是,webpack是三个模块加载打包工具,用于管理你的模块能源信任打包难点。那跟大家理解的requirejs模块加载工具,和grunt/gulp营造筑工程具的概念,多多少少有个别出入又有一点雷同。

图片 13

先是webpak对于CommonJS与英特尔同一时候帮助,满意大家模块/组件的加载形式。

JavaScript

require("module"); require("../file.js"); exports.doStuff = function() {}; module.exports = someValue;

1
2
3
4
require("module");
require("../file.js");
exports.doStuff = function() {};
module.exports = someValue;

JavaScript

define("mymodule", ["dep1", "dep2"], function(d1, d2) { return someExportedValue; });

1
2
3
define("mymodule", ["dep1", "dep2"], function(d1, d2) {
    return someExportedValue;
});

本来最精锐的,最出色的,当然是模块打包功效。那多亏那风度翩翩效果,补充了组件化能源依赖,以致完整工程化的力量

基于webpack的设计观念,全部财富都以“模块”,webpack内部贯彻了风度翩翩套能源加运载飞机制,能够把想css,图片等能源等有依附关系的“模块”加载。那跟大家使用requirejs这种单纯管理js大大不相同。而那套加运载飞机制,通过三个个loader来完结。

 

JavaScript

// webpack.config.js module.exports = { entry: { entry: './index.jsx', }, output: { path: __dirname, filename: '[name].min.js' }, module: { loaders: [ {test: /.css$/, loader: 'style!css' }, {test: /.(jsx|js)?$/, loader: 'jsx?harmony', exclude: /node_modules/}, {test: /.(png|jpg|jpeg)$/, loader: 'url-loader?limit=10240'} ] } };

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// webpack.config.js
module.exports = {
    entry: {
     entry: './index.jsx',
    },
    output: {
        path: __dirname,
        filename: '[name].min.js'
    },
    module: {
        loaders: [
            {test: /.css$/, loader: 'style!css' },
            {test: /.(jsx|js)?$/, loader: 'jsx?harmony', exclude: /node_modules/},
            {test: /.(png|jpg|jpeg)$/, loader: 'url-loader?limit=10240'}
        ]
    }
};

地方生龙活虎份简单的webpack配置文件,留意loaders的计划,数组内多个object配置为大器晚成种模块能源的加载机制。test的正则为合作文件法则,loader的为相配到文件将由什么加载器管理,五个计算机之间用相隔,管理顺序从右到左。

 

style!css,css文件通过css-loader(管理css),再到style-loader(inline到html)的加工管理流。

jsx文件通过jsx-loader编译,‘?’开启加载参数,harmony援救ES6的语法。

图片能源通过url-loader加载器,配置参数limit,调控少于10KB的图形将会base64化。

 财富文件怎样被require?

JavaScript

// 加载组件自己css require('./slider.css'); // 加载组件注重的模块 var Clip = require('./clipitem.js'); // 加载图片财富 var spinnerImg = require('./loading.png');

1
2
3
4
5
6
// 加载组件自身css
require('./slider.css');
// 加载组件依赖的模块
var Clip = require('./clipitem.js');
// 加载图片资源
var spinnerImg = require('./loading.png');

在webpack的js文件中大家除了require大家平常的js文件,css和png等静态文件也能够被require进来。大家透过webpack命令,编写翻译之后,看看输出结果怎么样:

JavaScript

webpackJsonp([0], { /* 0 */ /***/ function(module, exports, __webpack_require__) { // 加载组件本身css __webpack_require__(1); // 加载组件重视的模块 var Clip = __webpack_require__(5); // 加载图片财富 var spinnerImg = __webpack_require__(6); /***/ }, /* 1 */ /***/ function(module, exports, __webpack_require__) { /***/ }, /* 2 */ /***/ function(module, exports, __webpack_require__) { exports = module.exports = __webpack_require__(3)(); exports.push([module.id, ".slider-wrap{rn position: relative;rn width: 100%;rn margin: 50px;rn background: #fff;rn}rnrn.slider-wrap li{rn text-align: center;rn line-height: 20px;rn}", ""]); /***/ }, /* 3 */ /***/ function(module, exports) { /***/ }, /* 4 */ /***/ function(module, exports, __webpack_require__) { /***/ }, /* 5 */ /***/ function(module, exports) { console.log('hello, here is clipitem.js') ; /***/ }, /* 6 */ /***/ function(module, exports) { module.exports = "data:image/png;base64,iVBORw0KGg......" /***/ } ]);

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
webpackJsonp([0], {
/* 0 */
/***/ function(module, exports, __webpack_require__) {
          // 加载组件自身css
          __webpack_require__(1);
          // 加载组件依赖的模块
          var Clip = __webpack_require__(5);
          // 加载图片资源
          var spinnerImg = __webpack_require__(6);
/***/ },
/* 1 */
/***/ function(module, exports, __webpack_require__) {
 
/***/ },
/* 2 */
/***/ function(module, exports, __webpack_require__) {
          exports = module.exports = __webpack_require__(3)();
          exports.push([module.id, ".slider-wrap{rn position: relative;rn width: 100%;rn margin: 50px;rn background: #fff;rn}rnrn.slider-wrap li{rn text-align: center;rn line-height: 20px;rn}", ""]);
 
/***/ },
/* 3 */
/***/ function(module, exports) {
 
/***/ },
 
/* 4 */
/***/ function(module, exports, __webpack_require__) {
/***/ },
 
/* 5 */
/***/ function(module, exports) {
          console.log('hello, here is clipitem.js') ;
/***/ },
/* 6 */
/***/ function(module, exports) {
          module.exports = "data:image/png;base64,iVBORw0KGg......"
/***/ }
]);

webpack编译之后,输出文件视乎乱糟糟的,但事实上每二个财富都被封装在贰个函数体内,并且以编号的花样标志(注释)。这个模块,由webpack的__webpack_require__其间方法加载。入口文件为编号0的函数index.js,能够看见__webpack_require__加载其余编号的模块。

css文件在编号1,由于选择css-loader和style-loader,编号1-4都是拍卖css。当中编号2咱们得以看大家的css的string体。最后会以内联的措施插入到html中。

图表文件在编号6,能够看出exports出base64化的图片。

 组件后生可畏体输出

JavaScript

// 加载组件自个儿css require('./slider.css'); // 加载组件信任的模块 var React = require('react'); var Clip = require('../ui/clipitem.jsx'); // 加载图片能源 var spinnerImg = require('./loading.png'); var Slider = React.createClass({ getInitialState: function() { // ... }, componentDidMount: function(){ // ... }, render: function() { return ( <div> <Clip data={this.props.imgs} /> <img className="loading" src={spinnerImg} /> </div> ); } }); module.exports = Slider;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// 加载组件自身css
require('./slider.css');
// 加载组件依赖的模块
var React = require('react');
var Clip = require('../ui/clipitem.jsx');
// 加载图片资源
var spinnerImg = require('./loading.png');
var Slider = React.createClass({
    getInitialState: function() {
        // ...
    },
    componentDidMount: function(){
        // ...
    },
    render: function() {
        return (
            <div>
               <Clip data={this.props.imgs} />
               <img className="loading" src={spinnerImg} />
            </div>
        );
    }
});
module.exports = Slider;

假设说,react使到html和js合为紧密。

那么丰盛webpack,两个结合一齐的话。js,css,png(base64),html 全体web能源都能合成贰个JS文件。这即是那套方案的主导所在:零件独立黄金时代体化。如若要援引八个组件,仅仅require('./slider.js') 就可以完结。

 

加盟webpack的模块加载器之后,大家组件的加载难点,内聚难题也都成功地消除掉

“能源高内聚”—— (百分百) 全数财富能够生机勃勃js输出

“可互相结合”—— (百分之百)  可组成可依附加载

 

 CSS模块化施行

很欢悦,你能读书到此处。前段时间大家的机件达成度极其的高,财富内聚,易于组合,成效域独立互不污染。。。。等等图片 14,视乎CSS模块的完毕度有不足。

那么近期组件达成度来看,CSS作用域其实是全局性的,并不是组件内部独立。下一步,大家要做得正是怎么着让大家组件内部的CSS功用域独立。

那儿也会有人立即跳出,大喊一句“德玛西亚!”,哦不,应该是“用sass啊傻逼!”。可是品种组件化之后,组件的个中封装已经很好了,其内部dom结议和css趋向轻易,独立,以至是破碎的。LESS和SASS的后生可畏体式样式框架的设计,他的嵌套,变量,include,函数等丰裕的成效对于全体大型项目标体制处理极其常有效。但对此一个功用单生机勃勃组件内部样式,视乎就变的略微水火不容。“无法为了框架而框架,合适才是最棒的”。视乎原生的css本领已经知足组件的样式须要,唯独就是位置的css功效域难点。

 

那边自身付诸考虑的方案: classname随意写,保持原生的秘诀。编写翻译阶段,依照组件在类型路径的唯生机勃勃性,由【组件classname 组件独一路线】打成md5,生成全局唯朝气蓬勃性classname。正当自个儿要写多个loader达成作者的主见的时候,发掘歪果仁已经早在先走一步了。。。。

这里具体方案参照他事他说加以考查作者事先博客的译文:

后边我们探讨过JS的模块。今后经过Webpack被加载的CSS财富叫做“CSS模块”?作者感觉依旧有题指标。现在style-loader插件的贯彻精气神上只是创办link[rel=stylesheet]要素插入到document中。这种作为和通常性引进JS模块特别不相同。引进另三个JS模块是调用它所提供的接口,但引进一个CSS却并不“调用”CSS。所以引进CSS自己对于JS程序来讲并不设有“模块化”意义,纯粹只是说明了意气风发种财富信任——即该零件所要完结的效应还亟需一些asset。

据此,这位歪果仁还增添了“CSS模块化”的定义,除了上边的大家供给一些成效域外,还应该有非常多效应,这里不详述。具体参照他事他说加以考察原作 

不行赞的少数,正是cssmodules已经被css-loader收纳。所以大家无需依赖额外的loader,基本的css-loader开启参数modules就能够

JavaScript

//webpack.config.js ... module: { loaders: [ {test: /.css$/, loader: 'style!css?modules&localIdentName=[local]__[name]_[hash:base64:5]' }, ] } ....

1
2
3
4
5
6
7
8
//webpack.config.js
...  
    module: {
        loaders: [
            {test: /.css$/, loader: 'style!css?modules&localIdentName=[local]__[name]_[hash:base64:5]' },
        ]  
    }
....

modules参数代表开启css-modules功效,loaclIdentName为设置我们编写翻译后的css名字,为了便利debug,我们把classname(local)和零部件名字(name)输出。当然能够在最后输出的版本为了节约提交,仅仅使用hash值就可以。其它在react中的用法大约如下。

JavaScript

var styles = require('./banner.css'); var Banner = new React.createClass({ ... render: function(){ return ( <div> <div className={styles.classA}></div> </div> ) } });

1
2
3
4
5
6
7
8
9
10
11
var styles = require('./banner.css');
var Banner = new React.createClass({
    ...
    render: function(){
        return (
            <div>
                <div className={styles.classA}></div>
            </div>
        )
    }
});

终极这里关于出于对CSS一些研究,

关于css-modules的别样成效,作者并不计划利用。在其间分享【大家竭忠尽智地让CSS变得复杂】中谈到:

大家项目中山大学部分的CSS都不会像boostrap那样须求变量来设置,身为一线开采者的大家大概能够感受到:设计员们改版UI,相对不是简约的换个色或改个间隔,而是万象更新的全新UI,那绝对不是三个变量所能解决的”维护性“。

反而项目实战进程中,真正要消除的是:在本子迭代进度中那么些淘汰掉的超时CSS,大量地堆积在等级次序此中。大家像极了家中的欧巴酱不舍得扬弃没用的事物,因为那不过大家应用sass或less编写出具备惊人的可维护性的,明确有复用的一天。

这么些堆叠的过期CSS(or sass)之间又有后生可畏都部队分信任,生龙活虎部分过期失效了,后生可畏部分又被新的样式复用了,导致没人敢动这一个历史样式。结果现网项目迭代还带着大批量三年前没用的体裁文件。

组件化之后,css的格局相近被改正了。或者postcss才是您未来手上最符合的工具,而不在是sass。

 

到此地,大家好不轻便把组件化最终二个难点也消除了。

“成效域独立”—— (百分百) 就好像shadowDom效能域独立

 

到那边,我们能够开意气风发瓶82年的Sprite,好好庆祝一下。不是吧?

图片 15

 

 组件化之路还在后续

webpack和react还恐怕有成都百货上千新极其重要的特色和效应,介于本文仅仅围绕着组件化的为骨干,未有各种演说。此外,配搭gulp/grunt补充webpack创设工夫,webpack的codeSplitting,react的零部件通信难点,开辟与生育境遇安插等等,都以任何大型项目方案的所不可不的,限于篇幅难题。能够等等笔者更新下篇,或我们能够自行查阅。

唯独,不能不再安利一下react-hotloader神器。热加载的支付格局相对是下一代前端开垦必备。严刻说,万生机勃勃未有了热加载,笔者会很坚决地放任那套方案,纵然那套方案再怎么好好,笔者都讨厌react供给5~6s的编写翻译时间。但是hotloader能够在本人不刷新页面包车型大巴状态下,动态改革代码,並且不单单是样式,连逻辑也是即时生效。

图片 16

如上在form表单内。使用热加载,表单不须要再行填写,改进submit的逻辑立即看到效果。那样的开荒功效真不是增长仅仅一个品位。必需安利一下。

 

只怕你发掘,使用组件化方案现在,整个才能栈都被更新了生机勃勃番。学习花费也不菲,并且能够预感觉,基于组件化的前端还恐怕会数不胜数不足的标题,比如质量优化方案须求再行考虑,甚至最中央的组件可复用性不必然高。前边相当短风姿洒脱段时间,要求大家不停磨砺与优化,探寻最优的前端组件化之道。

足足大家得以想象,不再忧虑自个儿写的代码跟有些何人何人冲突,不再为找某段逻辑在多个公文和方法间不停,不再copy一片片逻辑然后改改。我们每一回编写都以可选取,可组合,独立且内聚的机件。而各样页面将会由贰个个嵌套组合的零件,互相独立却相互成效。

 

对此这么的前端现在,有所指望,不是很好吧

现今,多谢您的读书。

1 赞 6 收藏 1 评论

图片 17

本文由www.qjdy.com-奇迹赌场发布于www.qjdy.com官网,转载请注明出处:我说按模块划分好

关键词: mg老虎机官网 HTML5

上一篇:在开始使用React之前你不需要掌握这些基础知识

下一篇:没有了