配置文件,按资源划分

作者: 前端  发布:2019-09-23

致我们必将组件化的Web

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

原来的小说出处: AlloyTeam   

那篇小说将从七年前的三回技巧争论起来。争论的聚焦正是下图的多少个目录分层结构。小编说按模块划分好,他说您傻逼啊,当然是按能源划分。

9159.com 1 《=》9159.com 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 。 方法之间线性跳转,你大概也能感受那样代码破绽。随着页面逻辑更是复杂,这条”进度线“也会进一步长,何况更加的绕。加之贫乏职业约束,别的连串成员根据各自需求,在”进程线“加插各自逻辑,最后那么些页面包车型大巴逻辑变得难以保证。

9159.com 3

付出须要稳重,生怕影响“进度线”前边符合规律逻辑。而且每一次加插或涂改都以bug泛滥,无不令产品有关人士无不忧心悄悄。

 页面结构模块化

听大人讲下面的面向进度的主题素材,行当内也是有大多化解方案,而大家团队也总计出一套成熟的减轻方案:Abstractjs,页面结构模块化。大家得以把大家的页面想象为四个乐高机器人,须要分歧零件组装,如下图,假使页面划分为tabContainer,listContainer和imgsContainer多个模块。最后把这个模块add到最终的pageModel里面,最终采纳rock方法让页面运维起来。

9159.com 4
(原经过线示例图)

9159.com 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”感觉失望9159.com 6,依然“太好了是react+webpack”不用再学一遍新框架的兴奋9159.com 7。无论怎样上面包车型大巴源委不会让您失望的。

一,组件生命周期

9159.com 8

React天生便是强制性组件化的,所以能够从根本性上消除面向进程代码所带来的难为。React组件自个儿有生命周期方法,能够满意“接口规范化”技巧点。何况跟“页面结构模块化”的所封装抽离的多少个格局能挨个对应。别的react的jsx自带模板成效,把html页面片直接写在render方法内,组件内聚性特别严俊。

出于React编写的JSX是会先生成设想Dom的,必要机会才真正插入到Dom树。使用React必供给精通组件的生命周期,其生命周期三个情景:

Mount: 插入Dom

Update: 更新Dom

Unmount: 拔出Dom

mount那单词翻译扩张,嵌入等。作者倒是建议“插入”更加好明白。插入!拔出!插入!拔出!默念二遍,懂了没?别少看黄段子的技能,

9159.com 9

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

下一场每一种组件状态会有三种管理函数,一前一后,will函数和did函数。

componentWillMount()  绸缪插入前

componentDidlMount()  插入后

componentWillUpdate() 企图更新前

componentDidUpdate()  更新后

componentWillUnmount() 希图拔出前

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

除此以外React其余贰个为主:数据模型props和state,对应着也可能有自个状态方法

getInitialState()     获取初步化state。

getDefaultProps() 获取暗中同意props。对于这一个并未有父组件传递的props,通过该格局设置私下认可的props

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

还会有一个奇怪处境的管理函数,用于优化管理

shouldComponentUpdate():判定组件是或不是须要update调用

充裕最要害的render方法,React自己带的法子刚刚好10个。对于初学者的话是比较为难消食。但实际上getInitialStatecomponentDidMountrender多个状态方法都能到位半数以上零部件,不必惧怕。

回到组件化的核心。

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

9159.com 10

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

9159.com 11

 

零件的景色方法流中,有两点必要独特表达:

1,三回渲染:

由于React的设想Dom性情,组件的render函数不需本人触发,依据props和state的改换自个通过差距算法,得出最优的渲染。

呼吁CGI一般都是异步,所以必然带来一遍渲染。只是空数据渲染的时候,有一点都不小希望会被React优化掉。当数码回来,通过setState,触发二遍render

 

2,componentWiillMount与componentDidMount的差别

和大许多React的课程作品不平等,ajax央浼作者建议在WillMount的主意内实行,实际不是组件开端化成功未来的DidMount。那样能在“空数据渲染”阶段从前哀告数据,尽早地缩减三次渲染的小运。

willMount只会实行壹遍,极度适合做init的事体。

didMount也只会执行一次,而且那时候真实的Dom已经产生,特别适合事件绑定和complete类的逻辑。

 

 二,JSX极难看,可是组件内聚的入眼!

WebComponents的正经之一,需求模板工夫。本是感到是咱们耳熟能详的沙盘工夫,但React中的JSX那样的怪物照旧令人议论纷纭。React还尚无火起来的时候,我们就已经在和讯上狠狠地作弄了“JSX写的代码那TM的丑”。那实际只是德姆o阶段JSX,等到实战的大型项目中的JSX,富含多情状许多据多事件的时候,你会开采………….JSX写的代码仍然极不好看。

9159.com 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正好适合供给点,一方面填补组件化技巧点,另一方扶助大家健全组件化的完好创设蒙受。

第一要申喜宝(Hipp)点是,webpack是二个模块加载打包工具,用于管理你的模块财富依赖打包问题。那跟咱们耳熟能详的requirejs模块加载工具,和grunt/gulp构建筑工程具的定义,多多少少有个别出入又有个别雷同。

9159.com 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模块化奉行

很喜欢,你能翻阅到那边。方今大家的组件达成度特别的高,能源内聚,易于组合,效用域独立互不污染。。。。等等9159.com 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年的Pepsi-Cola,好好庆祝一下。不是吧?

9159.com 15

 

 组件化之路还在承袭

webpack和react还会有非常多新极其关键的特征和作用,介于本文仅仅围绕着组件化的为主导,未有各类演讲。其他,配搭gulp/grunt补充webpack创设技能,webpack的codeSplitting,react的零件通讯难题,开拓与生育情形布署等等,都以全体大型项目方案的所不可不的,限于篇幅难点。能够等等作者更新下篇,或我们能够活动查阅。

只是,不得不再安利一下react-hotloader神器。热加载的费用格局相对是下一代前端开垦必备。严俊说,借使未有了热加载,笔者会很泼辣地屏弃那套方案,就算那套方案再怎么能够,笔者都讨厌react须要5~6s的编写翻译时间。不过hotloader能够在小编不刷新页面的意况下,动态修改代码,何况不单单是样式,连逻辑也是即时生效。

9159.com 16

如上在form表单内。使用热加载,表单无需再行填写,修改submit的逻辑立时见效。那样的支付功效真不是加强仅仅二个水平。必得安利一下。

 

或者你发掘,使用组件化方案以往,整个本事栈都被更新了一番。学习开销也十分多,并且可以预见到,基于组件化的前端还有可能会成千上万欠缺的难点,比如质量优化方案要求再度思虑,以致最中央的组件可复用性不自然高。后面非常长一段时间,要求我们不住陶冶与优化,搜求最优的前端组件化之道。

足足大家得以虚构,不再忧虑自身写的代码跟有个别哪个人何人争辨,不再为找某段逻辑在四个文件和方法间不停,不再copy一片片逻辑然后改改。我们每趟编写都是可选用,可结合,独立且内聚的机件。而各类页面将会由二个个嵌套组合的零件,互相独立却互相效用。

 

对此这么的前端以往,有所指望,不是很好啊

从这之后,多谢您的读书。

1 赞 6 收藏 1 评论

9159.com 17

其他:
1、shimming :
在 英特尔/CMD 中,大家需求对不符合标准的模块(比方有些从来回到全局变量的插件)举行shim 管理,那时候大家要求动用 exports-loader 来提携:
{ test: require.resolve(“./src/js/tool/swipe.js”), loader: “exports?swipe”}
随后在剧本中必要援用该模块的时候,这么简单地来采用就可以了:
require(‘./tool/swipe.js’);
swipe();
2、自定义公共模块提取:
在篇章初始我们运用了 CommonsChunkPlugin 插件来领取多个页面之间的共用模块,并将该模块打包为 common.js 。
但奇迹我们期望能更加的特性化一些,大家得以这样布置:
var CommonsChunkPlugin = require("webpack/lib/optimize/CommonsChunkPlugin");
module.exports = {
entry: {
p1: "./page1",
p2: "./page2",
p3: "./page3",
ap1: "./admin/page1",
ap2: "./admin/page2"
},
output: {
filename: "[name].js"
},
plugins: [
new CommonsChunkPlugin("admin-commons.js", ["ap1", "ap2"]),
new CommonsChunkPlugin("commons.js", ["p1", "p2", "admin-commons.js"])
]
};
// <script>s required:
// page1.html: commons.js, p1.js
// page2.html: commons.js, p2.js
// page3.html: p3.js
// admin-page1.html: commons.js, admin-commons.js, ap1.js
// admin-page2.html: commons.js, admin-commons.js, ap2.js
3、独立包装样式:
奇迹或许希望项指标样式能毫无被打包到脚本中,而是独立出来作为.css,然后在页面中以标签引进。那时候我们须求extract-text-webpack-plugin 来帮忙:
var webpack = require('webpack');
var commonsPlugin = new webpack.optimize.CommonsChunkPlugin('common.js');
var ExtractTextPlugin = require("extract-text-webpack-plugin");
module.exports = {
plugins: [9159.com ,commonsPlugin, new ExtractTextPlugin("[name].css")],
entry: {
//...省略另外配置
最后 webpack 实施后会乖乖地把体制文件提收取来:
4、使用CDN远程文件:
突发性大家意在某个模块走CDN并以<script>的花样挂载到页面上来加载,但又愿意能在 webpack 的模块中动用上。
那儿大家得以在安插文件里选用 externals 属性来协理:
{
externals: {
// require("jquery") 是引用自外界模块的
// 对应全局变量 jQuery
"jquery": "jQuery"
}
}
需求留神的是,得保障 CDN 文件必须在 webpack 打包文件引进以前先引进。
大家倒也足以行使 script.js 在本子中来加载大家的模块:
var $script = require("scriptjs");
$script("//ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js", function() {
$('body').html('It works!')
});
5、与grunt/gulp相结合:
gulp.task("webpack", function(callback) {
// run webpack
webpack({
// configuration
}, function(err, stats) {
if(err) throw new gutil.PluginError("webpack", err);
gutil.log("[webpack]", stats.toString({
// output options
}));
callback();
});
});
自然我们只要求把布置写到 webpack({ … }) 中去就可以,无须再写 webpack.config.js 了。

document.getElementById("box").innerHTML=index.main();

  • 169 hidden modules
    浏览器中开辟 index.html 会呈现 Hello World

一、什么是webpack:webpack是一款模块加载兼打包工具,它能够将js、jsx、coffee、样式sass、less,图片等作为模块来选择和管理。
二、优势:1、以commonJS的款型来书写脚本,对英特尔、CMD的支持也很周全,方便旧项指标动员搬迁。2、能被模块化的不仅仅是JS了。3、能代替部分grunt/gulp的劳作,举个例子打包,压缩混淆,图片转base64等。3、扩大性强,插件机制周详,协理React热拔插(react-hot-loader)
三、安装和配备:
1、安装:直接使用npm来举办安装
$ npm install webpack -g
将依靠写入package.json包
$ npm init
$ npm install webpack --save-dev
2、配置:
各样门类必需配备一个webpack.config.js,功用就像是gulpfile.js/Gruntfile.js,二个计划项,告诉webpack要做什么样。
示例:
var webpack = require('webpack');
var commonsPlugin = new webpack.optimize.CommonsChunkPlugin('common.js');
module.exports = {
//插件项
plugins: [commonsPlugin],
//页面入口文件配置
entry: {
index : './src/js/page/index.js'
},
//入口文件输出配置
output: {
path: 'dist/js/page',
filename: '[name].js'
},
module: {
//加载器配置
loaders: [
{ test: /.css$/, loader: 'style-loader!css-loader' },
{ test: /.js$/, loader: 'jsx-loader?harmony' },
{ test: /.scss$/, loader: 'style!css!sass?sourceMap'},
{ test: /.(png|jpg)$/, loader: 'url-loader?limit=8192'}
]
},
//其它施工方案安排
resolve: {
root: 'E:/github/flux-example/src', //相对路径
extensions: ['', '.js', '.json', '.scss'],
alias: {
AppStore : 'js/stores/AppStores.js',
ActionType : 'js/actions/ActionType.js',
AppAction : 'js/actions/AppAction.js'
}
}
};
(1)plugins是插件项,这里运用了一个CommonsChunkPlugin的插件,它用于提取八个输入文件的共用脚本有的,然后生成多个common.js来方便多页面之间的复用。
(2)entry是页面包车型客车进口文件配置,output是呼应的出口项配置
{
entry: {
page1: "./page1",
//协助数组情势,将加载数组中的全部模块,但以最终叁个模块作为出口
page2: ["./entry1", "./entry2"]
},
output: {
path: "dist/js/page",
filename: "[name].bundle.js"
}
}
该代码会转换三个page1.bundle.js和page2.bundle.js,并贮存在./dist/js/page文件夹下。
(3)module.loaders,告知webpack每一项文件都供给怎么着加载器来拍卖
module: {
//加载器配置
loaders: [
//.css 文件使用 style-loader 和 css-loader 来拍卖
{ test: /.css$/, loader: 'style-loader!css-loader' },
//.js 文件使用 jsx-loader 来编写翻译管理
{ test: /.js$/, loader: 'jsx-loader?harmony' },
//.scss 文件使用 style-loader、css-loader 和 sass-loader 来编写翻译管理
{ test: /.scss$/, loader: 'style!css!sass?sourceMap'},
//图片文件使用 url-loader 来拍卖,小于8kb的一直转为base64
{ test: /.(png|jpg)$/, loader: 'url-loader?limit=8192'}
]
}
-loader可以不写,四个loader之间用“!”连接起来。全部的加载器都急需通过npm来加载。
比如最终一个url-loader,它会将样式中援引到的图片转为模块来管理。使用前开展设置:
$ npm install url-loader -save-dev
布局新闻的参数:“?limit=8192”表示将装有小于8kb的图形都转为base64格局(当先8kb的才使用url-loader来映射到文件,不然转为data url方式)
(4)resolve配置,
resolve: {
//查找module的话从那边开首查找
root: 'E:/github/flux-example/src', //绝对路径
//自动扩大文件后缀名,意味着我们require模块能够简轻巧单不写后缀名
extensions: ['', '.js', '.json', '.scss'],
//模块别称定义,方便后续直接援用小名,无须多写长长的地址
alias: {
AppStore : 'js/stores/AppStores.js',//后续直接 require('AppStore') 就能够
ActionType : 'js/actions/ActionType.js',
AppAction : 'js/actions/AppAction.js'
}
}
四、运维webpack,直接实行:
$ webpack --display-error-details
前边的参数 “-display-error-details”推荐加上,方便出错开上下班时间能通晓到更详细的新闻。其余首要参数:
$ webpack --config XXX.js //使用另一份配置文件(比如webpack.config2.js)来打包
$ webpack --watch //监听变动并自动打包
$ webpack -p //压缩混淆脚本,这些那一个可怜关键!
$ webpack -d //生成map映射文件,告知哪些模块被最后包装到哪个地方了
-p是很要紧的参数,曾经三个未压缩的 700kb 的文件,压缩后间接降到 180kb(主借使体制那块一句就占领一行脚本,导致未压缩脚本变得比非常大)。
五、模块引入:
1、在HTML页面引进:引进webpack最后生成的剧本就能够:
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>demo</title>
</head>
<body>
<script src="dist/js/page/common.js"></script>
<script src="dist/js/page/index.js"></script>
</body>
</html>
能够见见大家连样式都不要引进,毕竟脚本施行时会动态生成style并标签打到head里。
2、JS引进:各脚本模块可以选择common.js来书写,并得以一向引进未经编写翻译的模块,比方:jsx,coffee,sass,只要在webpack.config.js中配备好了对应的加载器就行。
编写翻译页面包车型客车进口文件:
require('../../css/reset.scss'); //加载初阶化样式
require('../../css/allComponent.scss'); //加载组件样式
var React = require('react');
var AppWrap = require('../component/AppWrap'); //加载组件
var createRedux = require('redux').createRedux;
var Provider = require('redux/react').Provider;
var stores = require('AppStore');
var redux = createRedux(stores);
var App = React.createClass({
render: function() {
return (
<Provider redux={redux}>
{function() { return <AppWrap />; }}
</Provider>
);
}
});
React.render(
<App />, document.body
);

var path = require('path');

为了利用 webpack,先新建二个空前未有端项目,创立八个索引,目录结构如下:

*加载CSS

{
plugins: [
new BellOnBundlerErrorPlugin()
]
}
plugin 也是多少个 npm 模块,安装二个 plugin :

*安装

  • 第五步:Develop Server 工具 (可选)

module.exports = "It works from content.js.";//nodejs中的暴光方式

<script src="dist/vendor.bundle.js"></script>
<script src="dist/index.js"></script>
修改 index.html 过后能够见到科学结果

npm i react-dom --save

// 初阶化 package.json, 依据提醒填写 package.json 的连锁音信
$ npm init

假诺急需浏览器自动刷新你必要在铺排中扩充叁个入口点。
webpack.config.js
**entry: [ 'webpack/hot/dev-server', 'webpack-dev-server/client?http://localhost:8080', path.resolve(__dirname, 'app/main.js') ],

2.2.7 webpack 开拓条件与生产条件

entry: "./js/entry.js",

output: {

output: {
path: './dist/',
filename: '[name].js',
publicPath: '/dist'
// webpack-dev-server 运转目录是 /, /dist 目录是包装的目的目录相对于运营目录的门路
},
重复起动

index.html
js / 你的js文件
dist / 你打包的文本(也正是您JS目录下的公文打包后的公文)
手动打包方法

loader 功能
loader 管道:在同样种等级次序的源文件上,能够何况执行多少个 loader , loader 的进行格局得以邻近管道的点子,管道施行的主意是从右到左的主意loader 能够帮衬同步和异步
loader 基本上能用安插参数

*露马网络模特块使用案例

热加载 (hot module replacement)

import MyModule from './modules/MyModule.js';//es6

webpack 使用

步向到您的花色 将webpack安装到品种的借助中,那样就可以动用项目本地版本的webpack
npm install webpack@1.12.x--save-dev(这种格式是安装钦赐版本)

$ npm install xx-loader --save-dev

*暴露模块

        { test: /.css$/, loader: "style!css" },
        { test: /.css$/, loaders: ["style", "css"] },
        // => .css 文件应用  "style" 和 "css" loader  
    ]
}

扩展:

// -g 参数表示全局安装
$ npm install webpack -g
其三步:新建空前端项目

{ "scripts": { "build": "webpack", "dev": "webpack-dev-server --devtool eval --progress --colors --hot --content-base build" }}

彰显的调用 require 会扩张模块的耦合度,应尽量防止这种措施

npm i webpack-dev-server --save
npm run dev 在http://localhost:8080监听文件修改
"dev": "webpack-dev-server --devtool eval --progress --colors --hot --content-base build"

当存在多个输入时 ,能够使用 Array 的方法,譬喻依据第三方库 bootstrap ,最后 bootstrap 会被追加到打包好的 index.js 中,数组中的最后一个会被 export。

npm install babel-loader babel-core babel-preset-es2015 babel-preset-react --save-dev

// },
/
1 /
/
/ function(module, exports) {

path: './dist',

webpack 是多个模块打包工具,输入为富含信赖关系的模块集,输出为包装合併的前端静态能源。在上一节的前端工程化中,已经介绍过,webpack 是同有时候支持 速龙 和 CommonJs 的模块定义格局,不止如此,webpack 可以将另外前端能源视为模块,如 css,图片,文本。

export default Girls;//ES6

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Hello React!</title>
</head>
<body>
<div id="AppRoot"></div>
<script src="dist/index.js"></script>
</body>
</html>
index.js 内容为:

*loader理解

以命令实行的措施需求填写十分短的参数,所以 webpack 提供了通过安插的不二诀窍实践,在项目目录下开创 webpack.config.js 如下:

在package.json 设置它的scripts npm run build===webpack(这里是运维打包)

$ webpack-dev-server --content-base ./
--content-base ./ 参数表示将当前目录作为 server 根目录。 命令运行过后,会在 8080 端口运转二个 http 服务,通过访谈http://localhost:8080/index.html 能够访问 index.html 内容。

*目录

loader 和 webpack 同样都以 Node.js 完毕,发表到 npm 在这之中,必要运用 loader 的时候,只供给

    publicPath: './dist/',

    filename: "bundle.js"

},

module: {

    loaders: [

        { test: /.css$/, loader: "style!css" }

    ]

}

其余一种方法是直接 require, 修改 src/index.js:

四个入口文件

在前端开采的长河中,通常须求运转四个服务器,把开垦打包好的前端代码放在服务器上,通过访问服务器访谈并测量检验(因为能够稍微景况必要ajax 央求)。 webpack 提供了一个基于 node.js Express 的服务器 - webpack-dev-server 来帮助我们简化服务器的搭建,并提供服务器能源访谈的一部分粗略安顿。

*npm install --save 与 npm install --save-dev 的区别

loader 定义

};

代码监察和控制

npm i webpack-dev-server --save

// babel 相关的模块
$ npm install babel-loader babel-preset-es2015 babel-preset-stage-0 babel-preset-react babel-polyfill --save-dev

var MyModule = require('./MyModule.js');//commonjs

按需加载: webapp 的优化关键在于代码体量,当使用容积增大,达成代码的按需加载是刚需,这也是 webpack 出现的根本原因

*注意事项

src/index.js 内容改为:

webpack-dev-server 自动监听(此时还不能活动刷新浏览器)ctrl+C退出服务

2.2.5 webpack 支持 Jsx

module: { //加载器配置 loaders: [ { test: /.css$/, loader: 'style-loader!css-loader' }, { test: /.js$/, loader: 'jsx-loader?harmony' }, { test: /.scss$/, loader: 'style!css!sass?sourceMap'}, { test: /.(png|jpg)$/, loader: 'url-loader?limit=8192'} ] },

webpack 是什么

webpack require 一切
require("./content.js"); // 添加content.js

webpack 是什么

npm install webpack --save-dev

{
module: {
loaders: [
{ test: /.jade$/, loader: "jade" },
// => .jade 文件应用 "jade" loader

module.exports = {

    ]
}
  • 在 localhost:8080 建设构造三个 Web 服务器
    --devtool eval
  • 为您的代码创造源地址。当有其他报错的时候能够令你尤其可信赖地定位到文件和行号
    --progress
  • 突显合併代码进度
    --colors
  • Yay,命令行中呈现颜色!
    --content-base build
  • 本着设置的出口目录

第一步:Node.js

此间须要在output模块里面安装publicPath否则CSS背景图片等出口十分

修改 webpack.config.js

**

安装 webpack-dev-server

手动打包: webpack 源文件路线 打包路线(webpack ./entry.js ./bundle.js)//这里是未曾配置webpack.config.js
$ webpack --watch //监听变动并机关打包 监视webpack.config.js 的改观$ webpack -p //压缩混淆脚本,那个可怜可怜关键!

{
entry: [String | Array | Object], // 入口模块
output: {
path: String, // 输出路线
filename: String // 输著名称或称谓 pattern
publicPath: String // 钦点静态能源的职位
... // 其余布置
}
}
单纯性入口

import "../css/main.css";//ES6引进格局

loader 定义

webpack.config.js 以下是主导配备
单个入口文件
var path = require('path');

.
├── a.js
└── index.js
文件名称 pattern

entry: {

    page1:["./js/entry.js","./js/double.js"]

},

output: {

增加产量 loader 可以在 webpack.config.js 的 module.loaders 数组中新扩充三个loader 配置。

页面要引进打包后的路线的JS文件

$ npm install bell-on-bundler-error-plugin --save-dev
2.2.9 webpack 分割 vendor 代码和选择职业代码

是模块和财富的转变器,它自身是一个函数,接受源文件作为参数,再次来到调换的结果。这样,我们就足以经过 require 来加载任何类型的模块或文件,譬喻CoffeeScriptJSXLESS图片

/***/ }
/******/ ]);
在浏览器中开采 index.html :

安装css-loader : npm install css-loader style-loader
require("style!css!
../css/main.css")//加载CSS style!css!是声称这一个模块是CSS style!css!可以不写 在loaders里面配备音讯就能够

2.2.2 安装配备

贰个位居package.json 的dependencies , 几个身处devDependencies里面

为何引进新的包裹工具

加载器配置

异步加载 -> 按需加载,优化首屏加载时间

var index={//那是增多content.js
main:function(){
var html="1111111";
return html;
}
}
module.exports=index;

启航 webpack-dev-server 的时候增多 --inline 参数

};

修改 webpack.config.js 的 output.publicPath:

path: './dist',

loader 能够经过正则表达式也许文件后缀钦赐特定类型的源文件

*布署文件

安装 webpack-dev-server

module.exports = {

利用被放到了二个 iframe 内部,页面顶上部分能够显示打包进程音讯

npm install react --save

其余资源也得以定义为模块

    publicPath: './dist/',

    filename: "bundle.js"

},

module: {

    loaders: [

        { test: /.css$/, loader: "style!css" }

    ]

}

代码监察和控制

*引进模块

2.2.10 webpack develop server

//那是在另四个文书
var index=require("./content.js"); // 添加content.js

可定制化 -> 能够融为一炉第三方库,能够定制化打包进度

webpack-dev-server

entry 和 output

entry: {
page1: "./page1",//单个文件方式帮助数组情势,将加载数组中的全体模块,但以最后二个模块作为出口
page2: ["./entry1", "./entry2"]
},//数组形式 假如应用上面你的写法 无法用上面的这种
output: {
path: "dist/js/page",
filename: "[name].bundle.js"
}

{
entry: {
index: './src/index.js',
a: './src/a.js'
},
output: {
path: './dist/',
filename: '[name].js'
},
module: {
loaders: [{
test: /.js$/,
exclude: /node_modules/,
loader: 'babel',
query: {
presets: ['es2015', 'stage-0', 'react']
}
}]
}
}
第三步: 修改 index.js 为 React 的语法

例如访谈提醒报错:

Hash: f1256dc00b9d4bde8f7f
Version: webpack 1.13.1
Time: 1459ms
Asset Size Chunks Chunk Names
a.js 109 bytes 0 [emitted] a
index.js 10.9 kB 1 [emitted] index
vendor.bundle.js 702 kB 2 [emitted] vendor
[0] multi vendor 40 bytes {2} [built]
[0] multi index 40 bytes {1} [built]

var Hello = React.createClass({
render: function render() {
return <div>Hello {this.props.name}</div>;
}
});

alert('hello world webpack');

插件能够提要求 loader 更加多效果与利益

2.2.1 webpack 介绍

// },
/
2 /
/
/ function(module, exports) {
// bootstrap 的内容被追加到模块中
console.log('bootstrap file');

末尾的编写翻译结果为:

Hash: 9a8e7e83864a07c0842f
Version: webpack 1.13.1
Time: 37ms
Asset Size Chunks Chunk Names
index.js 1.42 kB 0 [emitted] main
[0] ./src/index.js 29 bytes {0} [built]
能够查看 dist/index.js 的编写翻译结果:

Hash: ae2a037c191c18195b6a
Version: webpack 1.13.1
Time: 1016ms
Asset Size Chunks Chunk Names
a.js 1.42 kB 0 [emitted] a
index.js 700 kB 1 [emitted] index

webpack 介绍

loader 配置

/******/ (function(modules) { // webpackBootstrap
// .......... UMD 定义内容
/******/ })
/************************************************************************/
/******/ ([
/* 0 /
/
**/ function(module, exports) {
// index.js 的开始和结果被打包进去
alert('hello world webpack');

[name] entry 对应的名目

四个入口

webpack 开采条件与生产条件

$ webpack --config webpack.config.prod.js
在本章长远 webpack 小节中会更加多的介绍生产意况中的优化

webpack develop server

在头里创立的目录下施行:

{
entry: {
index: './src/index.js',
a: './src/a.js'
},
output: {
path: './dist/',
filename: '[name].js'
},
module: {
loaders: [{
test: /.js$/,
exclude: /node_modules/,
loader: 'babel',
query: {
presets: ['es2015', 'stage-0', 'react']
}
}, {
test: /.css$/,
loader: "style-loader!css-loader"
}]
}
}
第三步:使用

[chunkhash] chunk 的 hash

// 下载 webpack 依赖
// --save-dev 代表将依赖增多到 package.json 中的 'devDependencies' 对象中
$ npm install webpack --save-dev

访问 node.js API

不需求非常布置,只用修改路线

dev server 能够兑现一个基于 node + express 的前端 server

$ webpack-dev-server
webpack-dev-server 还提供了别的的一对效果与利益, 如:

在地方的 jsx 配置中,我们将 React 和 ReactDOM 一起打包进了品种代码。为了落实职业代码和第三方代码的分手,大家得以行使
CommonsChunkPlugin 插件.

webpack 此前的包裹工具工具功效单一,只可以变成一定的天职,然则 web 前端工程是复杂的,贰个 webapp 对于事情代码的须要可能有:

// eg css loader
$ npm install css-loader style-loader --save-dev
第二步:修改配置

Es6 的学识在背后的章节中等教育授,近来大家有的时候以 Es5 的不二诀窍来写,不过配置已经支撑了 Es6 的编写翻译,熟识 Es6 的读者也得以间接写 Es6

故此为了不一样,我们能够成立七个公文:

}
使用 loader

....
function(module, exports, webpack_require) {
exports = module.exports = webpack_require(171)();
exports.push([module.id, "nbody {n background: red;n color: white;n}n", ""]);
}
....
能够看看 css 被转接为了 javascript, 在页面中不用调用 <link rel="stylesheet" href=""> 的情势, 而是使用 inline 的<style>.....</style>

援助多个 bundler 输出 -> 化解代码分块难点

Iframe 模式

热加载 (hot module replacement)

entry: {
index: ['./src/index.js', './src/style.css']
}
实行 webpack 命令然后展开 index.html 会看到页面背景被改为革命。

webpack.config.prod.js // 生产条件

配置文件

也便是说在 webpack 中,通过 loader 能够完毕 JSX 、Es6、CoffeeScript 等的转换

webpack 提供插件机制,能够对每一遍 build 的结果开展管理。配置 plugin 的不二等秘书技为在 webpack.config.js 中加上:

{
entry: {
index: './src/index.js',
a: './src/a.js',
// 第三方包
vendor: [
'react',
'react-dom'
]
},
output: {
path: './dist/',
filename: '[name].js'
},
module: {
loaders: [{
test: /.js$/,
exclude: /node_modules/,
loader: 'babel',
query: {
presets: ['es2015', 'stage-0', 'react']
}
}, {
test: /.css$/,
loader: "style-loader!css-loader"
}]
},
plugins: [
new webpack.optimize.CommonsChunkPlugin(/* chunkName= /"vendor", / filename= */"vendor.bundle.js")
]
}
施行 webpack 命令,输出日志:

webpack 的多个主导:

inline 模式

一声令下行调用

webpack-dev-server 还提供了模块热加载的方法,在不刷新浏览器的条件下,应用新型的代码更新,运转webpack-dev-server 的时候增添 --inline --hot 参数就能够感受。

明天我们已经得以应用 webpack 来打包基于 CommonJs 的 Javascript 模块了,不过还没办法解析 JSX 语法和 Es6 语法。上面大家将应用 Babel 让 webpack 能够剖析 Es6 和 Babel

在安插文件中配备

单纯入口

webpack 分割 vendor 代码和利用工作代码

在布置 JSX 的进程中,使用到了 loader, 前边早就介绍过 webpack 的大旨功效包蕴 loader,通过 loader 能够将轻便财富转化为 javascript 模块。

对于模块打包工具,单一的支撑 CommonJs 的打包在大型项目中是远远不够用的,为了满意叁个大型项指标前端需要,那么三个装进工具应该包罗部分这几个作用:

.
├── index.html // 入口 HTML
├── dist // dist 目录放置编写翻译过后的公文文件
└── src // src 目录放置源文件
└── index.js // 入口 js
其中 html 内容:

var css = require("css!./style.css");
编写翻译结果一律。

webpack.config.js // 开垦条件

修改 style.css 中的内容为:

Node.js 安装好以后,张开命令行终端,通过 npm 命令安装:

2.2.6 webpack loaders

{
entry: {
index: './src/index.js',
a: './src/a.js'
},
output: {
path: './dist/',
filename: '[name].js'
}
}
终极会卷入出:

webpack 安装

webpack 支持 Jsx 和 Es6

可定制化: 任何三个工具都不或然化解全部标题,提供技术方案才是最有效的,webpack 基于可定制化的视角创设,通过插件系统,配置文件,能够达成大型项指标定制需要。

因为 iframe 的涉及,如果运用有五个页面,不能够看到如今接纳的 url 音信

$ webpack-dev-server --inline --hot
修改代码在浏览器调节新竹会看到这么的日记输出:

src/style.css

// 第一种 String
{
entry: './src/index.js',
output: {
path: './dist/',
filename: 'index.js'
}
}

var webpack = require('webpack')
module.exports = {
entry: './src/index.js',
output: {
path: './dist/',
filename: 'index.js'
}
}
执行:

插件系统: webpack 的可定制化在于其插件系统,其自己的很多职能也是因而插件的点子贯彻,插件系统变成了 webpack 的生态,是的能够应用过多开源的第三方插件。

启动 webpack-dev-server

内需集成一些第三方库

以 css-loader 为例子,在档案的次序 src 上面成立贰个 css

修改访谈的路线: http://localhost:8080/index.html -> http://localhost:8080/webpack-dev-server/index.html 。那年每一次修改代码,打包完成未来都会自行刷新页面。

  • 173 hidden modules
    index.js 容量变小了,多出了 vendor.bundle.js

配置 proxy

{
// 通过扩大名称和正则表明式来配独财富文件
test: String ,
// 匹配到的能源会应用 loader, loader 可以为 string 也足感到数组
loader: String | Array
}
感叹号和数组能够定义 loader 管道:

Loaders are transformations that are applied on a resource file of your app.
(Loaders 是运用中源码文件的编写翻译调换器)

[168] ./~/react/lib/renderSubtreeIntoContainer.js 466 bytes {2} [built]
webpack: bundle is now VALID.
webpack: bundle is now INVALID.
Hash: cc7d7720b1a0fcbef972
Version: webpack 1.13.0
Time: 76ms
chunk {0} a.js (a) 32 bytes {2}

alert('hello world webpack');
第四步:在项目中安装 webpack

{
entry: ['./src/index.js', './vendor/bootstrap.min.js'],
output: {
path: './dist',
filename: "index.js"
}
}
最终的输出结果如:

和水保的 node 服务集成

指令行调用

// react 相关的模块
$ npm install react react-dom --save
第二步:webpack.config.js 中添加 babel loader 配置

body {
background: whitesmoke;
color: #333;
font-size: 100px;
}
能够看到输出以下日志:

不曾最上部音讯提醒条,提醒新闻在调控新北表现

代码能够分块,实现按需加载

智能的模块分析: webpack 能够很轻巧将第三方库转化为模块集成到品种代码中,模块的重视能够用表明式的法子(这在其他包裹工具中是尚未辅助的),这种模块重视叫做动态模块重视。

万物皆模块:在 webpack 的世界中,除了 Javascript,其他任何财富都可以看成模块的艺术援引

webpack 核心思想

// 通过 require 的办法依赖 React,ReactDOM
var React = require('react');
var ReactDOM = require('react-dom');

使用 loader

基于这一个意义能够兑现无数自定义的铺排。

/******/ ([
/* 0 /
/
**/ function(module, exports, webpack_require) {

loader 功能

plugins: [
new webpack.optimize.CommonsChunkPlugin(
/* chunkName= /"vendor",
/
filename= */"vendor.bundle.js", Infinity),
// 需求手动增加 HotModuleReplacementPlugin , 命令行的艺术会自动抬高
new webpack.HotModuleReplacementPlugin()
],
devServer: {
hot: true,
inline: true
}
不加参数直接试行 webpack-dev-server

来得的经过 require 调用

为了让编写翻译的结果名称是独一的,能够动用 hash 。

webpack 配置参数

// 第三种 Object
{
entry: {
index: './src/index.js',
},
output: {
path: './dist/',
filename: 'index.js'
}
}
五个输入文件

$ npm install webpack-dev-server --save-dev
2.2.3 webpack 使用

生产境遇 build 用如下命令:

ReactDOM.render(
<Hello name="World" />,
document.getElementById('AppRoot')
);
第四步:运行 webpack

webpack loaders

[HMR] Waiting for update signal from WDS...
vendor.bundle.js:670 [WDS] Hot Module Replacement enabled.
2vendor.bundle.js:673 [WDS] App updated. Recompiling...
vendor.bundle.js:738 [WDS] App hot update...
vendor.bundle.js:8152 [HMR] Checking for updates on the server...
vendor.bundle.js:8186 [HMR] Updated modules:
vendor.bundle.js:8188 [HMR] - 245
vendor.bundle.js:8138 [HMR] App is up to date.
在 webpack.config.js 中配置 webpack develop server

__webpack_require__(1);

// export 最后一个
module.exports = __webpack_require__(2);

loader 配置

// 第二种 Array
{
entry: ['./src/index.js'],
output: {
path: './dist/',
filename: 'index.js'
}
}

只要唯有一个进口文件,能够有如下两种配备格局

首屏加载时间要尽量收缩

地点的布局已经能成功自动监控代码,每一次修改完代码,刷新浏览器就足以看到最新结果,但是webpack-dev-server 还提供了活动刷新功用,有三种格局。

$ ctrl + c 为止进度
$ webpack-dev-server
修改 style.css 再刷新页面,修改的剧情会显示出来。

四个包裹指标

webpack 核心境想

修改 webpack.config.js 添加:

Loaders: Webpack 自个儿只会处理Javascript,为了完成将别的资源也定义为模块,并转化为 Javascript, Webpack 定义 loaders , 不一样的 loader 能够将相应的能源转化为 Javascript 模块。

Uncaught ReferenceError: webpackJsonp is not defined
案由是 html 中并未有引用 vendor.bundle.js, 修改 html :

前边我们早已选取过 jsx loader 了, loader 的使用办法有各种

在 webpack.config.js 中配置 webpack develop server

  • 1 hidden modules
    chunk {1} index.js (index) 10.3 kB {2}
    [170] ./~/css-loader!./src/style.css 230 bytes {1} [built]
  • 5 hidden modules
    chunk {2} vendor.bundle.js (vendor) 665 kB
  • 168 hidden modules
    webpack: bundle is now VALID.
    那一年证实代码已经修改了,可是那个时候刷新浏览器过后,背景是一向不改变动的,原因是 webpack-dev-server 的打包结果是献身内部存款和储蓄器的,查看 dist/index.js 的从头到尾的经过其实是未有改观的,那怎么访问内部存储器中的打包内容呢?

指令行调用

webpack 的产出正式为了消除这么些难题,在 webpack 中,提供了一晃那一个职能:

$ webpack
实施结果:

自动刷新

}
loader 能够配备参数

entry 和 output

活动刷新

body {
background: red;
color: white;
}
修改 webpack 配置 entry 添加

代码分块: webpack 有三种类型的模块重视,一种是手拉手的,一种是异步的。在包装的进程中能够将代码输出为代码块(chunk),代码块可以兑现按需加载。 异步加载的代码块通过分割点(spliting point)来鲜明。

亟需增添 --inline 配置参数

第一步:npm install 注重模块

上边的例子中都是包裹出三个 index.js 文件,要是项目有八个页面,那么必要打包出八个文件,webpack 能够用对象的主意配置多少个包装文件

第二步:webpack-cli

前端开拓情状一般分为两种,开采条件和调换意况,在开辟情形中,恐怕大家须求日志输出,sourcemap ,错误报告等职能,在转移情状中,须求做代码压缩,hash 值生成。三种情形在其余的一些布署上也也许分化。

2.2.4 webpack 配置

$ webpack src/index.js dist/index.js
实践成功未来会产出如下音讯:

第一步: 安装

webpack 的布局中至关心重视要的八个布局 key 是,entry 和 output。

loader 除了做文件调换以外,还足以创制额外的公文

干什么要引进新的卷入工具

webpack 是 Node 达成,首先须要到 Node.js 下载安装最新版本的 Node.js

[hash] webpack 命令施行结果呈现的 Hash 值

webpack-dev-server 除了提供 server 服务以外, 还有可能会监察和控制源文件的修改,假如源文件改造了,会调用 webpack 重新打包

{
module: {
loaders: [
// => url-loader 配置 mimetype=image/png 参数
{
test: /.png$/,
loader: "url-loader?mimetype=image/png"
}, {
test: /.png$/,
loader: "url-loader",
query: { mimetype: "image/png" }
}

多个 loader 的配置为:

$ npm install webpack-dev-server -g
启动 webpack-dev-server

webpack is a module bundler. webpack takes modules with dependencies and generates static assets representing those modules

安顿文件

$ webpack
会和由此命令实行有平等的输出

2.2.8 webpack 插件

/***/ }
/******/ ])
多少个包装指标

在 webpack 出现此前,已经有了一部分包装工具,如 Browserify, 那为什么不优化这一个工具,而是重复造轮子?

本文由9159.com发布于前端,转载请注明出处:配置文件,按资源划分

关键词:

上一篇:中间一列宽度自适应,右边自适应宽度
下一篇:没有了