云顶娱乐-云顶娱乐游戏平台官网
做最好的网站
当前位置: 云顶娱乐 > 云顶娱乐 > 正文

【云顶娱乐】后面一个重构方案精晓一下,是个

时间:2019-10-09 20:22来源:云顶娱乐
减少首屏时间,“直出”是个怎么样概念? 2015/12/31 · HTML5 · 2评论 ·首屏 初稿出处: VaJoy Larn    早几年前端还处于刀耕火种、JQuery独竖一帜的一代,前后端代码的耦合度非常高,三个

减少首屏时间,“直出”是个怎么样概念?

2015/12/31 · HTML5 · 2 评论 · 首屏

初稿出处: VaJoy Larn   

早几年前端还处于刀耕火种、JQuery独竖一帜的一代,前后端代码的耦合度非常高,三个web页面文件的代码或者是那般的:

云顶娱乐 1

云顶娱乐 2

这意味后端的程序猿往往得承受一部分修改HTML、编写脚本的劳作,而前面二个开采者也得询问页面上设有的服务端代码含义。

神迹某处页面逻辑的改观,鉴于代码的混合着搭配,恐怕都不分明相应请后端照旧前面四个来改动(即使他们都能管理)。

云顶娱乐 3

后者框架热潮

有句俗话说的好——“人啊,如若擅于开口‘关作者屁事’和‘关你屁事’那俩句,可以省去人生中的超越四分之二时间”。

乘机那五年被 angular 牵头带起的各样前端MV*框架的流行,后端能够毋须再于静态页面开销心绪,只供给全身心开拓数据接口供前端选拔就可以。得益于此,前后端终于得以告慰地互相道一声“关自家屁事”或“关你屁事”了。

以 avalon 为例,前端只需求在页面加载时发送个ajax央浼获得数据绑定到vm,然后做view层渲染就可以:

var vm = avalon.define({ $id: "wrap", list: [] }); fetch('data/list.php') //向后端接口发出央浼 .then(res => res.json()) .then(json => { vm.list = json; //数据注入vm avalon.scan(); //渲染view层 });

1
2
3
4
5
6
7
8
9
10
11
var vm = avalon.define({
    $id: "wrap",
    list: []
});
 
fetch('data/list.php')   //向后端接口发出请求
    .then(res => res.json())
    .then(json => {
        vm.list = json; //数据注入vm
        avalon.scan();  //渲染view层
    });

静态页面包车型客车代码也由前端一手精通,原来服务端的代码换来了 avalaon 的专用属性与插值表明式:

ul ms-controller="wrap"> li ms-repeat="list">{el.name}li> ul>

1
2
3
ul ms-controller="wrap">
    li ms-repeat="list">{el.name}li>
ul>

左右端代码隔开的花样大大升级了类其余可维护性和付出效用,已经变为一种web开采的主流情势。它解放了后端程序猿的双臂,也将越来越多的调节权转移给前端人士(当然前端也就此供给多学学有个别框架知识)。

云顶娱乐 4

弊端

内外端隔开的情势即便给开采带来了便于,但相比较不分互相的旧方式,页面首屏的多少要求在加载的时候向服务端发去央浼本事获得,多了乞请等候的岁月(RTT)。

那意味顾客访谈页面包车型大巴时候,这段“等待后端重回数据”的时延会处在白屏状态,若是客商网速差,那么这段首屏等候时间会是比很差的感受。

本来拉到数据后,还得做 view 层渲染(顾客端引擎的管理还是十分的快的,忽视渲染的时日),那又凭仗于框架本人,即框架要先被下载下来技能管理这几个视图渲染操作。那么好东西,三个angular.min.js 就达到了 120 多KB,用着渣时限信号的顾客得多等上一两秒来下载它。

如此那般看来,单纯前后端隔断的方式存在首屏时间较长的难题,除非现在平均网速达到上G/s,不然都以不佳好的感受。

其余利用前端框架的页面也不平价SEO,其实应该说不便中华民国内这一个渣寻找引擎的SEO,Google已经能从内部存款和储蓄器中去抓数据(顾客端渲染后的DOM数据)。

so 如何做?相信广大恋人猜到了——用 node 来助阵。

云顶娱乐 5

直出和同构

直出大约其实正是“服务端渲染并出口”,跟最初大家提起的左右端一碗水端平的支出格局基本类似,只是后端语言我们换到了 node 。

09年初阶冒头的 node 今后成了当红炸子鸡,包罗Ali、Tencent在内的各大公司都布满地把 node 用到项目上,前后端整而为一,假诺 node 的表征适用于您的项目,那么何乐而不为呢。

大家在那边也聊起了二个“同构”的定义,即上下端(这里的“后端”指的是直出端,数据接口不断定由node开采)运用同样套代码方案,方便维护。

当前 node 在服务端有着众多主流抑或社会的遗弃者的框架,包涵express、koa、thinkjs 等,能够比较快上手,利用各样中间件得以扩充快速开拓。

除此以外诸如 ejs、jade 那样的渲染模板能让我们轻便地把首屏内容(数据或渲染好的DOM树)注入页面中。

如此顾客访谈到的正是早就满含首屏内容的页面,大大收缩了守候时间,升高了体验。

云顶娱乐 6

示例

在此处我们以 koa + ejs + React 的服务端渲染为例,来探视四个简约的“直出”方案是何等完结的。该示例也得以在我的github左右载到。

类型的目录结构如下:

+---data //模拟数据接口,放了叁个.json文件 +---dist //文件创设后(gulp/webpack)存放处 | +---css | | +---common | | ---page | +---js | | +---component | | ---page | ---views | +---common | ---home +---modules //一些机关封装的通用业务模块 +---routes //路由安顿 ---src //未创设的文件夹 +---css | +---common | +---component | ---page +---js | +---component //React组件 | ---page //页面入口文件 ---views //ejs模板 +---common ---home

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
+---data   //模拟数据接口,放了一个.json文件
+---dist  //文件构建后(gulp/webpack)存放处
|   +---css
|   |   +---common
|   |   ---page
|   +---js
|   |   +---component
|   |   ---page
|   ---views
|       +---common
|       ---home
+---modules  //一些自行封装的通用业务模块
+---routes  //路由配置
---src  //未构建的文件夹
    +---css
    |   +---common
    |   +---component
    |   ---page
    +---js
    |   +---component //React组件
    |   ---page //页面入口文件
    ---views  //ejs模板
        +---common
        ---home

1. node 端 jsx 深入分析管理

node 端是不会协和分辨 React 的 jsx 语法的,故大家要求在项目文件中引进 node-jsx ,即便明天能够安装 babel-cli 后(并丰硕预设)使用 babel-node 命令代替node,但前者用起来总会出标题,故一时仍旧选择 node-jsx 方案:

//app.js require('node-jsx').install({ //让node端能深入分析jsx extension: '.js' }); var fs = require('fs'), koa = require('koa'), compress = require('koa-compress'), render = require('koa-ejs'), mime = require('mime-types'), r_home = require('./routes/home'), limit = require('koa-better-ratelimit'), getData = require('./modules/getData'); var app = koa(); app.use(limit({ duration: 1000*10 , max: 500, accessLimited : "您的伸手太过多次,请稍后重试"}) ); app.use(compress({ threshold: 50, flush: require('zlib').Z_SYNC_FLUSH })); render(app, { //ejs渲染配置 root: './dist/views', layout: false , viewExt: 'ejs', cache: false, debug: true }); getData(app); //首页路由 r_home(app); app.use(function*(next){ var p = this.path; this.type = mime.lookup(p); this.body = fs.createReadStream('.'+p); }); app.listen(3300);

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
//app.js
require('node-jsx').install({  //让node端能解析jsx
    extension: '.js'
});
 
var fs = require('fs'),
    koa = require('koa'),
    compress = require('koa-compress'),
    render = require('koa-ejs'),
    mime = require('mime-types'),
    r_home = require('./routes/home'),
    limit = require('koa-better-ratelimit'),
    getData = require('./modules/getData');
 
var app = koa();
 
app.use(limit({ duration: 1000*10 ,
    max: 500, accessLimited : "您的请求太过频繁,请稍后重试"})
);
app.use(compress({
    threshold: 50,
    flush: require('zlib').Z_SYNC_FLUSH
}));
 
render(app, {  //ejs渲染配置
    root: './dist/views',
    layout: false ,
    viewExt: 'ejs',
    cache: false,
    debug: true
});
 
getData(app);
 
//首页路由
r_home(app);
 
app.use(function*(next){
    var p = this.path;
    this.type = mime.lookup(p);
    this.body = fs.createReadStream('.'+p);
});
 
app.listen(3300);

2. 首页路由(’./routes/home’)配置

var router = require('koa-router'), getHost = require('../modules/getHost'), apiRouter = new router(); var React = require('react/lib/ReactElement'), ReactDOMServer = require('react-dom/server'); var List = React.createFactory(require('../dist/js/component/List')); module.exports = function (app) { var data = this.getDataSync('../data/names.json'), //取首屏数据 json = JSON.parse(data); var lis = json.map(function(item, i){ return ( <li>{item.name}</li> ) }), props = {color: 'red'}; apiRouter.get('/', function *() { //首页 yield this.render('home/index', { title: "serverRender", syncData: { names: json, //将取到的首屏数据注入ejs模板 props: props }, reactHtml: ReactDOMServer.renderToString(List(props, lis)), dirpath: getHost(this) }); }); app.use(apiRouter.routes()); };

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
var router = require('koa-router'),
    getHost = require('../modules/getHost'),
    apiRouter = new router();
 
var React = require('react/lib/ReactElement'),
    ReactDOMServer = require('react-dom/server');
var List = React.createFactory(require('../dist/js/component/List'));
 
module.exports = function (app) {
 
    var data = this.getDataSync('../data/names.json'),  //取首屏数据
        json = JSON.parse(data);
 
    var lis = json.map(function(item, i){
       return (
           <li>{item.name}</li>
       )
    }),
        props = {color: 'red'};
 
    apiRouter.get('/', function *() {  //首页
        yield this.render('home/index', {
            title: "serverRender",
            syncData: {
                names: json,  //将取到的首屏数据注入ejs模板
                props: props
            },
            reactHtml:  ReactDOMServer.renderToString(List(props, lis)),
            dirpath: getHost(this)
        });
    });
 
    app.use(apiRouter.routes());
 
};

在意这里大家运用了 ReactDOMServer.renderToString 来渲染 React 组件为纯 HTML 字符串,注意 List(props, lis) ,大家还传来了 props 和 children。

其在 ejs 模板中的应用为:

div class="wrap" id="wrap">-reactHtml%>div>

1
div class="wrap" id="wrap">-reactHtml%>div>

就好像此轻松地成功了服务端渲染的管理,但还也有一处难题,就算组件中绑定了平地风波,顾客端不会感知。

于是在顾客端大家也急需再做二回与服务端一致的渲染操作,鉴于服务端生成的DOM会被打上 data-react-id 标记,故在顾客端渲染的话,react 会通过该标志位的自己检查自纠来制止冗余的render,并绑定上相应的平地风波。

那也是我们把所要注入组件中的数据(syncData)传入 ejs 的原因,大家将把它看做客商端的多少个全局变量来行使,方便客商端挂载组件的时候用上:

ejs上注入直出多少:

script> syncData = JSON.parse(''); script>

1
2
3
  script>
    syncData = JSON.parse('');
  script>

页面入口文件(js/page/home.js)挂载组件:

import React from 'react'; import ReactDOM from 'react-dom'; var List = require('../component/List'); var lis = syncData.names.map(function(item, i){ return ( <li>{item.name}</li> ) }); ReactDOM.render( <List {...syncData.props}> {lis} </List>, document.getElementById('wrap') );

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import React from 'react';
import ReactDOM from 'react-dom';
var List = require('../component/List');
 
var lis = syncData.names.map(function(item, i){  
    return (
        <li>{item.name}</li>
    )
});
ReactDOM.render(
    <List {...syncData.props}>
        {lis}
    </List>,
    document.getElementById('wrap')
);

3. 协助理工科程师具

为了玩鲜,在一些模块里写了 es二〇一六 的语法,然后使用 babel 来做转换管理,在 gulp 和 webpack 中都有接纳到,具体可参谋它们的布署。

别的是因为服务端对 es2014 的特色扶助不完整,合作 babel-core/register 大概选用 babel-node 命令都存在宽容难点,故针对具备要求在服务端引进到的模块(比如React组件),在koa运转前先做gulp管理转为es5(那几个营造模块仅在服务端会用到,客商端走webpack直接引用未改变模块就能够)。

ejs文件中样式或脚本的内联管理本人使用了和煦支付的 gulp-embed ,有意思味的相恋的人能够玩一玩。

4. issue

说真的 React 的服务端渲染处理一体化支出是没难点的,正是开荒体验相当不够好,主要缘由照旧各省点对 es二〇一四 援救不成就导致的。

虽说在服务端运转前,我们在gulp中动用babel对相关模块举行改动,但像 export default XXX 那样的语法转变后也许不能棉被和衣服务端扶助,只好降级写为 module.exports = XXX。但如此写,在任何模块就没有办法 import XXX from ‘X’ 了(改为 require(‘X’)代替),不问可以看到不耿直。只可以希望后续 node(其实应当说V8) 再迭代一些本子能更加好地匡助 es二零一四 的性状。

别的假设 React 组件涉及列表项,常规大家会加上 key 的props天性来进步渲染效能,但正是前后端传入同样的key值,最后 React 渲染出来的 key 值是不等同的,会招致客商端挂载组件时再做二次渲染管理。

对于这一点小编个人提议是,假使是静态的列表,那么统一都不加 key ,借使是动态的,那么就加吧,客商端再渲染一回认为也没多大点事。(可能您有越来越好方案请留言哈~)

5. 其它

临时服务端引进的模块里面,有些东西是唯有必要在客商端应用到的,大家以那个示例中的组件component/List为例,里面包车型客车体制文件

require('css/component/List');

1
require('css/component/List');

不应有在服务端推行的时候利用到,但由于同构,前后端用的一套东西,这么些怎么消除呢?其实很好办,通过 window 对象来判定就可以(只要未有何样中间件给你在服务端也加了window接口)

var isNode = typeof window === 'undefined'; if(!isNode){ require('css/component/List'); }

1
2
3
4
5
var isNode = typeof window === 'undefined';
 
if(!isNode){
    require('css/component/List');
}

只是请留意,这里本身通过 webpack 把组件的样式也打包进了顾客端的页面入口文件,其实不安妥。因为经过直出,页面在响应的时候就曾经把组件的DOM树都先出示出来了,但以此时候是还并未有取到样式的(样式打包到进口脚本了),须求等到进口脚本加载的时候才干收看科学的体制,那么些历程会有三个眨眼的历程,是种不舒服的感受。

据此走直出的话,提议把首屏的体制抽离出来内联到底部去。

1 赞 2 收藏 2 评论

云顶娱乐 7

CSS Modules 详解及 React 中实践

2016/01/18 · CSS · CSS Modules, React

最早的文章出处: pure render - camsong   

云顶娱乐 8

CSS 是后面一个领域中提升最慢的一块。由于 ES二零一六/二〇一四 的连忙遍布和 Babel/Webpack 等工具的迅猛发展,CSS 被远远甩在了前边,渐渐成为大型项目工程化的痛点。也产生了后面一个走向绝望模块化前必需化解的难点。

CSS 模块化的实施方案有那个,但最首要有两类。一类是通透到底放任 CSS,使用 JS 或 JSON 来写样式。Radium,jsxstyle,react-style 属于这一类。优点是能给 CSS 提供 JS 同样壮大的模块化技术;短处是不能够动用成熟的 CSS 预管理器(或后计算机) Sass/Less/PostCSS,:hover:active 伪类管理起来复杂。另一类是照旧使用 CSS,但利用 JS 来保管体制信任,代表是 CSS Modules。CSS Modules 能最大化地结合现成 CSS 生态和 JS 模块化技能,API 简洁到差比少之又少零上学习话费用。发表时仍然编译出单身的 JS 和 CSS。它并不借助于 React,只要您利用 Webpack,能够在 Vue/Angular/jQuery 中接纳。是自身以为近来最佳的 CSS 模块消除决方案。前段时间在项目中山大学量施用,上面具体享受下施行中的细节和想方设法。

 

HTML 自定义成分教程

2017/06/22 · HTML5 · 自定义成分

初稿出处: 阮一峰   

组件是 Web 开垦的动向,以往的紧俏是 JavaScript 组件,可是 HTML 组件今后讲不定更有非常的大希望。

本文就介绍 HTML 组件的基础知识:自定义成分(custom elements)。

云顶娱乐 9

一、浏览器管理

咱俩日常都利用专门的学业的 HTML 成分。

XHTML

<p>Hello World</p>

1
<p>Hello World</p>

下边代码中,``

``正是正统的 HTML 元素。

【云顶娱乐】后面一个重构方案精晓一下,是个什么样概念。万一利用非规范的自定义成分,会有如何结果?

XHTML

<greeting>Hello World</greeting>

1
<greeting>Hello World</greeting>

地点代码中,`就是非标准元素,浏览器不认识它。这段代码的[运行结果](http://jsbin.com/rifozonomu/edit?html,output)是,浏览器照常显示Hello World`,那表明浏览器并从未过滤这些因素。

云顶娱乐 10

前些天,为自定义成分加上样式。

JavaScript

greeting { display: block; font-size: 36px; color: red; }

1
2
3
4
5
greeting {
  display: block;
  font-size: 36px;
  color: red;
}

运转结果如下。

云顶娱乐 11

跟着,使用脚本操作那个因素。

JavaScript

function customTag(tagName, fn){ Array .from(document.getElementsByTagName(tagName)) .forEach(fn); } function greetingHandler(element) { element.innerHTML = '你好,世界'; } customTag('greeting', greetingHandler);

1
2
3
4
5
6
7
8
9
10
11
function customTag(tagName, fn){
  Array
    .from(document.getElementsByTagName(tagName))
    .forEach(fn);
}
 
function greetingHandler(element) {
  element.innerHTML = '你好,世界';
}  
 
customTag('greeting', greetingHandler);

运作结果如下。

云顶娱乐 12

那证明,浏览器看待自定义成分,就如对待专门的学问成分同样,只是未有默许的样式和表现。这种管理格局是写入 HTML5 标准的。

“User agents must treat elements and attributes that they do not understand as semantically neutral; leaving them in the DOM (for DOM processors), and styling them according to CSS (for CSS processors), but not inferring any meaning from them.”

上面这段话的意趣是,浏览器务必将自定义元素保留在 DOM 之中,但不会别的语义。除了这几个之外,自定义成分与正统成分都一模一样。

实际上,浏览器提供了三个HTMLUnknownElement对象,全体自定义成分都是该目的的实例。

JavaScript

var tabs = document.createElement('tabs'); tabs instanceof HTMLUnknownElement // true tabs instanceof HTMLElement // true

1
2
3
4
var tabs = document.createElement('tabs');
 
tabs instanceof HTMLUnknownElement // true
tabs instanceof HTMLElement // true

地方代码中,tabs是二个自定义成分,同期继续了HTMLUnknownElementHTMLElement接口。

前端重构方案通晓一下

2018/06/09 · 基础本事 · 重构

原稿出处: 吃草龙珠不吐西红柿皮   

JS平日般的网页重构能够动用Node.js做些什么

2016/06/07 · JavaScript · 3 评论 · 重构

原稿出处: 张鑫旭(@张鑫旭)   

CSS 模块化碰着了怎么着难点?

CSS 模块化主要的是要化解好些个个难题:CSS 样式的导入和导出。灵活按需导入以便复用代码;导出时要力所能致隐蔽其间效率域,防止导致全局污染。Sass/Less/PostCSS 等继续试图减轻 CSS 编制程序技巧弱的难点,结果它们做的也真正雅观,但那并未缓慢解决模块化最注重的标题。推特(Twitter)(照片墙)程序猿 Vjeux 首先抛出了 React 开荒中遇到的一层层 CSS 相关难题。加上自身个人的见识,总括如下:

  1. 全局污染

CSS 使用全局选拔器机制来设置样式,优点是便利重写样式。劣点是具有的样式都以大局生效,样式大概被错误覆盖,由此发生了丰富难看的 !important,甚至 inline !important 和复杂性的[选取器权重计数表](Selectors Level 3),进步犯错概率和行使花费。Web Components 标准中的 Shadow DOM 能通透到底消除这么些主题素材,但它的做法有一点极端,样式彻底局地化,变成外界不可能重写样式,损失了灵活性。

  1. 取名混乱

 

出于全局污染的难点,多个人一块开荒时为了幸免样式冲突,选择器越来越复杂,轻巧产生不一致的命名风格,很难统一。样式变多后,命老将特别混乱。

  1. 借助管理不干净

零件应该相互独立,引进二个零件时,应该只引进它所必要的 CSS 样式。但现在的做法是除了要引进 JS,还要再引进它的 CSS,并且 Saas/Less 很难实现对各样组件都编写翻译出单身的 CSS,引进全数模块的 CSS 又导致浪费。JS 的模块化已经非常成熟,假设能让 JS 来管理 CSS 信赖是很好的消除办法。Webpack 的 css-loader 提供了这种手艺。

  1. 不大概分享变量

复杂组件要利用 JS 和 CSS 来共同管理体制,就能够导致有个别变量在 JS 和 CSS 中冗余,Sass/PostCSS/CSS 等都不提供跨 JS 和 CSS 分享变量这种技艺。

  1. 代码压缩不深透

由于移动端互联网的不分明性,现在对 CSS 压缩已经到了变态的水平。相当多压缩工具为了节省四个字节会把 ’16px’ 转成 ‘1pc’。但对那三个长的 class 名却心有余而力不足,力未有用到刀刃上。

上边的标题即使只凭 CSS 本身是心余力绌消除的,假诺是透过 JS 来治本 CSS 就很好解决,因而 Vjuex 给出的实施方案是全然的 CSS in JS,但这一定于完全放任CSS,在 JS 中以 Object 语法来写 CSS,猜想刚见到的同伴都惊动了。直到出现了 CSS Modules。

 

二、HTML import

有了自定义成分,就能够写出语义性相当好的 HTML 代码。

XHTML

<share-buttons> <social-button type="weibo"> <a href="...">微博</a> </social-button> <social-button type="weixin"> <a href="...">微信</a> </social-button> </share-buttons>

1
2
3
4
5
6
7
8
<share-buttons>
  <social-button type="weibo">
    <a href="...">微博</a>
  </social-button>
  <social-button type="weixin">
    <a href="...">微信</a>
  </social-button>
</share-buttons>

地点的代码,一眼就会观看语义。

如果将`元素的样式与脚本,封装在一个 HTML 文件share-buttons.html`之中,这些因素就足以复用了。

选择的时候,先引进share-buttons.html

<link rel="import" href="share-buttons.html">

1
<link rel="import" href="share-buttons.html">

接下来,就足以在网页中央银行使``了。

XHTML

<article> <h1>Title</h1> <share-buttons/> ... ... </article>

1
2
3
4
5
<article>
  <h1>Title</h1>
  <share-buttons/>
  ... ...
</article>

HTML imports 的更加多用法能够参照教程(1,2)。目前独有Chrome 浏览器协助这么些语法。

前言

前端技能进步高速,很多种类面前际遇前端部分重构,相当的慢乐能够让本身实行本次项近期端的重构方案编写制定,在考虑的同期参谋了网络广大材质,希望本篇重构方案有一定的完整性,能够带给我们某个在面对重构时有用的东西,同期期望经过的大牌小牛不领赐教,能给自家略微指点下重构相关的点,在下谢谢不尽~


一、非Computer背景前端怎样高效了然Node.js?

做前端的应该都听过Node.js,偏开采背景的童鞋应该都玩过。

对于一些平素不计算机背景的,事行业内部容以静态页面突显为主的前端,可能未有把玩过Node.js,且很有希望对Node.js都并未有四个比较立体的认知——知道那玩意能够跑服务,营造比比较多前端工具,看上去非常的棒的楷模,不过,可能就只限于此了。

“这是或不是片言一字总结Node.js的满目呢?”
“不可!”
“那怎么做?”
“这就六言四语!”

第一,要知道,Node.js叁个JavaScript运转条件(runtime),没有错,正是用来运作Javascript. 从前JavaScript只好在浏览器那个小世界里称王称霸。比较多前端小同伙或然就JS那门程序语言熟一点,其余C++, .net之类的就呵呵了。要是是过去,要是浏览器一觉醒来杜绝了,很五个人就能够失掉工作。就好像食品单一的物种一旦这种食品没了,就坐等灭亡是二个道理。

而是,以往,不要担忧了,Node.js让JavaScript造成杂食的了,也正是除了网页行为,能够和另外C++等语言一样,创设服务,操作文件等等。

作者们应该都利用过.exe后缀的文书,双击一下,就能够掩盖个病毒什么的;大家只怕还利用过.bat后缀的批管理文件,一点击,文件夹里面包车型的士图纸整体重命名;那么一旦是.js后缀的公文呢(假如你的系统已经安装了Node.js景况),双击一下则……当当当当……会打开编辑器看见JS代码,双击是从来不用的!

云顶娱乐 13

我们得以打开命令行工具,cd到钦命目录,然后输入(尽管JS文件名称为test.js):

node test

1
node test

然后test.js个中的代码就能够愉悦地跑起来啦!

对此“页面仔”来说,精晓那样多就够了!

  1. 安装后Node.js环境;
  2. 用大家蹩脚的JS写贰个倒霉管理的.js文件;
  3. node执行下。

简轻易单三部曲,大家就变身成了具有开垦味道的前端从业人士了。云顶娱乐 14

CSS Modules 模块化方案

云顶娱乐 15

CSS Modules 内部通过 [ICSS](css-modules/icss · GitHub) 来化解体制导入和导出那多少个难题。分别对应 :import:export 五个新扩充的伪类。

JavaScript

:import("path/to/dep.css") { localAlias: keyFromDep; /* ... */ } :export { exportedKey: exportedValue; /* ... */ }

1
2
3
4
5
6
7
8
:import("path/to/dep.css") {
  localAlias: keyFromDep;
  /* ... */
}
:export {
  exportedKey: exportedValue;
  /* ... */
}

 

但一向利用那四个至关心敬重要字编制程序太难为,实际项目中少之甚少会平素运用它们,大家要求的是用 JS 来管理 CSS 的技能。结合 Webpack 的 css-loader 后,就能够在 CSS 中定义样式,在 JS 中程导弹入。
启用 CSS Modules

JavaScript

// webpack.config.js css?modules&localIdentName=[name]__[local]-[hash:base64:5]

1
2
// webpack.config.js
css?modules&localIdentName=[name]__[local]-[hash:base64:5]

加上 modules 即为启用,localIdentName 是安装生成样式的命名准则。

JavaScript

/* components/Button.css */ .normal { /* normal 相关的具有样式 */ } .disabled { /* disabled 相关的富有样式 */ }

1
2
3
/* components/Button.css */
.normal { /* normal 相关的所有样式 */ }
.disabled { /* disabled 相关的所有样式 */ }

JavaScript

// components/Button.js import styles from './Button.css'; console.log(styles); buttonElem.outerHTML = `<button class=${styles.normal}>Submit</button>`

1
2
3
4
// components/Button.js
import styles from './Button.css';
console.log(styles);
buttonElem.outerHTML = `<button class=${styles.normal}>Submit</button>`

生成的 HTML 是

<button class="button--normal-abc53">Submit</button>

1
<button class="button--normal-abc53">Submit</button>

 

注意到 button--normal-abc53 是 CSS Modules 按照 localIdentName 自动生成的 class 名。在那之中的 abc53 是依照给定算法生成的类别码。经过这样模糊管理后,class 名基本就是有一无二的,大大裁减了项目中样式覆盖的概率。同期在生育条件下修改准则,生成越来越短的 class 名,能够增加 CSS 的压缩率。

上例中 console 打字与印刷的结果是:

JavaScript

Object { normal: 'button--normal-abc53', disabled: 'button--disabled-def886', }

1
2
3
4
Object {
  normal: 'button--normal-abc53',
  disabled: 'button--disabled-def886',
}

CSS Modules 对 CSS 中的 class 名都做了拍卖,使用对象来保存原 class 和混淆后 class 的呼应关系。

由此那些总结的管理,CSS Modules 完毕了以下几点:

  • 抱有样式都以 local 的,消除了命名冲突和大局污染难题
  • class 名生成法则配置灵活,能够此来减弱 class 名
  • 只需征引组件的 JS 就能够解决组件全部的 JS 和 CSS
  • 照例是 CSS,差相当的少 0 学习成本

体制暗中同意局地

运用了 CSS Modules 后,就一定于给每一个 class 名外加加了叁个 :local,以此来兑现样式的局地化,要是您想切换来全局情势,使用相应的 :global

:local:global 的区分是 CSS Modules 只会对 :local 块的 class 样式做 localIdentName 法则管理,:global 的体制编译后不改变。

JavaScript

.normal { color: green; } /* 以上与下部等价 */ :local(.normal) { color: green; } /* 定义全局样式 */ :global(.btn) { color: red; } /* 定义多个全局样式 */ :global { .link { color: green; } .box { color: yellow; } }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
.normal {
  color: green;
}
 
/* 以上与下面等价 */
:local(.normal) {
  color: green;
}
 
/* 定义全局样式 */
:global(.btn) {
  color: red;
}
 
/* 定义多个全局样式 */
:global {
  .link {
    color: green;
  }
  .box {
    color: yellow;
  }
}

Compose 来组合样式

对于样式复用,CSS Modules 只提供了独一的秘技来拍卖:composes 组合

JavaScript

/* components/Button.css */ .base { /* 全部通用的样式 */ } .normal { composes: base; /* normal 别的样式 */ } .disabled { composes: base; /* disabled 另外样式 */ }

1
2
3
4
5
6
7
8
9
10
11
12
/* components/Button.css */
.base { /* 所有通用的样式 */ }
 
.normal {
  composes: base;
  /* normal 其它样式 */
}
 
.disabled {
  composes: base;
  /* disabled 其它样式 */
}

JavaScript

import styles from './Button.css'; buttonElem.outerHTML = `<button class=${styles.normal}>Submit</button>`

1
2
3
import styles from './Button.css';
 
buttonElem.outerHTML = `<button class=${styles.normal}>Submit</button>`

生成的 HTML 变为

<button class="button--base-fec26 button--normal-abc53">Submit</button>

1
<button class="button--base-fec26 button--normal-abc53">Submit</button>

由于在 .normal 中 composes 了 .base,编写翻译后会 normal 会形成三个class。

composes 还足以构成外界文件中的样式。

JavaScript

/* settings.css */ .primary-color { color: #f40; } /* components/Button.css */ .base { /* 全部通用的体裁 */ } .primary { composes: base; composes: primary-color from './settings.css'; /* primary 别的样式 */ }

1
2
3
4
5
6
7
8
9
10
11
12
13
/* settings.css */
.primary-color {
  color: #f40;
}
 
/* components/Button.css */
.base { /* 所有通用的样式 */ }
 
.primary {
  composes: base;
  composes: primary-color from './settings.css';
  /* primary 其它样式 */
}

 

对此大部分项目,有了 composes 后曾经不复必要Sass/Less/PostCSS。但若是你想用的话,由于 composes 不是正式的 CSS 语法,编译时会报错。就不得不动用预管理器自个儿的语法来做样式复用了。
class 命名才具

CSS Modules 的命名标准是从 BEM 增添而来。BEM 把体制名分为 3 个等第,分别是:

  • Block:对应模块名,如 Dialog
  • Element:对应模块中的节点名 Confirm Button
  • Modifier:对应节点相关的图景,如 disabled、highlight

综上,BEM 最终得到的 class 名叫 dialog__confirm-button--highlight。使用双标记 __-- 是为了和区块内单词间的相间符区分开来。固然看起来有些奇异,但 BEM 被百般多的大型项目和团队利用。大家进行下来也很承认这种命超方式。

CSS Modules 中 CSS 文件名正要对应 Block 名,只供给再思量 Element 和 Modifier。BEM 对应到 CSS Modules 的做法是:

JavaScript

/* .dialog.css */ .ConfirmButton--disabled { /* ... */ }

1
2
3
4
/* .dialog.css */
.ConfirmButton--disabled {
  /* ... */
}

您也足以不根据完全的命名标准,使用 camelCase 的写法把 Block 和 Modifier 放到一同:

JavaScript

/* .dialog.css */ .disabledConfirmButton { }

1
2
3
/* .dialog.css */
.disabledConfirmButton {
}

怎么样促成CSS,JS变量分享

注:CSS Modules 中绝非变量的概念,这里的 CSS 变量指的是 Sass 中的变量。

下面提到的 :export 关键字能够把 CSS 中的 变量输出到 JS 中。上边演示如何在 JS 中读取 Sass 变量:

JavaScript

/* config.scss */ $primary-color: #f40; :export { primaryColor: $primary-color; }

1
2
3
4
5
6
/* config.scss */
$primary-color: #f40;
 
:export {
  primaryColor: $primary-color;
}

 

JavaScript

/* app.js */ import style from 'config.scss'; // 会输出 #F40 console.log(style.primaryColor);

1
2
3
4
5
/* app.js */
import style from 'config.scss';
 
// 会输出 #F40
console.log(style.primaryColor);

三、Custom Elements 标准

HTML5 标准规定了自定义成分是法定的。然后,W3C 就为自定义成分拟定了三个独自的 Custom Elements 标准。

它与另外八个正规放在一同—- HTML Imports,HTML Template、Shadow DOM—-统称为 Web Components 标准。近些日子,那一个规范独有 Chrome 浏览器支持。

云顶娱乐 16

Custom Elements 标准对自定义成分的名字做了限制。

“自定义成分的名字必须带有一个破折号(-)所以都是正确的名字,而和``是不得法的。那样的限定使得 HTML 深入分析器能够识别那二个是典型成分,哪些是自定义成分。”

云顶娱乐 17

潜心,一旦名字之中使用了破折号,自定义元素就不是HTMLUnknownElement的实例了。

JavaScript

var xTabs = document.createElement('x-tabs'); xTabs instanceof HTMLUnknownElement // false xTabs instanceof HTMLElement // true

1
2
3
4
var xTabs = document.createElement('x-tabs');
 
xTabs instanceof HTMLUnknownElement // false
xTabs instanceof HTMLElement // true

Custom Elements 规范规定了,自定义成分的定义能够运用 ES6 的class语法。

JavaScript

// 定义三个 class MyElement extends HTMLElement {...} window.customElements.define('my-element', MyElement);

1
2
3
// 定义一个
class MyElement extends HTMLElement {...}
window.customElements.define('my-element', MyElement);

下面代码中,原生的window.customElements对象的define措施用来定义 Custom Element。该措施接受四个参数,第贰个参数是自定义成分的名字,第一个参数是二个ES6 的class

这个class使用getset主意定义 Custom Element 的某部属性。

JavaScript

class MyElement extends HTMLElement { get content() { return this.getAttribute('content'); } set content(val) { this.setAttribute('content', val); } }

1
2
3
4
5
6
7
8
9
class MyElement extends HTMLElement {
  get content() {
    return this.getAttribute('content');
  }
 
  set content(val) {
    this.setAttribute('content', val);
  }
}

有了这些概念,网页之中就足以插入``了。

JavaScript

<my-element content="Custom Element"> Hello </my-element>

1
2
3
<my-element content="Custom Element">
  Hello
</my-element>

管理脚本如下。

JavaScript

function customTag(tagName, fn){ Array .from(document.getElementsByTagName(tagName)) .forEach(fn); } function myElementHandler(element) { element.textConent = element.content; } customTag('my-element', myElementHandler);

1
2
3
4
5
6
7
8
9
10
11
function customTag(tagName, fn){
  Array
    .from(document.getElementsByTagName(tagName))
    .forEach(fn);
}
 
function myElementHandler(element) {
  element.textConent = element.content;
}
 
customTag('my-element', myElementHandler);

运营结果如下。

云顶娱乐 18

ES6 Class 的二个利润是,能够很轻巧地写出承接类。

JavaScript

class MyNewElement extends MyElement { // ... } customElements.define('my-new-element', MyNewElement);

1
2
3
4
5
class MyNewElement extends MyElement {
  // ...
}
 
customElements.define('my-new-element', MyNewElement);

前天的教程就到此处,更加多用法请参照他事他说加以考察谷歌(Google)的合法教程。

一、原项目梳理

第一对原先项目做二个大意的梳理,既然是重构,当然很多事物是能够继续拿来利用的。

二、蹩脚JS下的Node.js初体验

绝大数工厂都是小厂,十分大多数小厂都独有四个前端,比非常多前端的JS其实都相似般。

领域里面常常把“前端施工方案”挂在嘴边的,实际上都是有前端共青团和少先队的,因为有集体, 手艺显价值。

“前端建设方案”是好,不过,假使真的关心行当发展,应该理解,能够在一个大团队里面玩耍的实际是小部分人,有不菲广大的同伴都是孤军作战,那套东西或者反而阻挠了长足和灵活;有为数不菲居多的伴儿在二三四线城市,是野生的前端开采,底子相当不够,那套庞杂的东西很难驾驭;有广大广大的项目就是多少个静态活动页面,没须要回回使用高射炮打蚊子。

此时,往往须求的是定制化很强的小而美的管理。有同学恐怕会存疑,哎哎,小编JS水平相比菜,自造工具这种工作会不会有一些基本啊。实际上,固然你JS平时般,借助Node.js创设一些小工具进步自身的前端开采作用这种工作,完全不言而谕。

前端那东西,有个博尔特都认账的风味,就是上心灵!

第一,大家需求一份Node.js API文书档案,大家选拔“动物搜索”,搜一下:
云顶娱乐 19

就率先个吗,步入会看出一长排的API列表内容: 云顶娱乐 20

无须怕,我们只供给那二个就足以,没有错,就一个文件系统(fs)!云顶娱乐 21 别的都无需管,那一个都以盛名游戏者玩的:
云顶娱乐 22

点击去,又是成千上万洒洒,一堆API:云顶娱乐 23
云顶娱乐 24

毫不怕,大家只供给……淡定,不是一个,是多少个正规的增加和删除读写重命名文件就足以了。云顶娱乐 25

好了,然后只须求一些次于的JS,我们就足以玩起来了。

玩怎么吧?容我看集动漫想一想……

设计员给的Logo重命名
身体力行的设计员送来了香饽饽的小图片素材,不过,连接字符是下划线_,恰巧,此时,前端童鞋的处女病发错,其余自身管理的图形全都以短横线-连日的,这里Logo全部是下划线受不住,想要全部轮换为短横线,怎么做?

云顶娱乐 26

假设就一八个Logo辛亏,大不断手动修改,可是,假诺如上截图,设计员一口气给了56个Logo,小编去,要改到头皮发麻了啊~倒不是岁月难点,而是重复劳动带来的这种枯燥和不乐意会耳熏目染职业的刺激,况兼这种劳动用完就没了,相当小概复用,且不可能同日而语业绩(笔者得以5分钟完结九十六个文件的重命名,有个卵用~)。

那会儿,Node.js就足以闪亮上场了,有了Node.js遇到,大家即使寥寥几行JS代码,就足以完全秒杀了,很简短,读取文件夹里面包车型客车有所图片,然后把称呼里面全数的下划线_替换成短横线-, 假诺大家的.js文本和须求管理的小图标文件夹结构如下:
云顶娱乐 27

underscore2dash.js内容如下:

// 引入fs文件管理模块 var fs = require("fs"); // 今后大家要关怀的是'icons'文件夹 // 大家无妨用变量表示那些文件夹名称,方便日后保险和管制 var src = 'icons'; // API文档中中找到遍历文件夹的API // 找到了,是fs.readdir(path, callback) // 文书档案中有描述: // 读取 path 路线所在目录的剧情。 回调函数 (callback) 接受四个参数 (err, files) 此中 files 是八个积累目录中所富含的文件名称的数组 // 由此: fs.readdir(src, function(err, files) { // files是称呼数组,因而 // 能够利用forEach遍历哈, 此处为ES5 JS一点知识 // 即使不清楚,也得以运用for循环哈 files.forEach(function(filename) { // 上面正是文件名称重命名 // API文书档案中找到重命名的API,如下 // fs.rename(oldPath, newPath, callback) // 上边,我们就能够依葫芦画瓢,鲜明新旧文件名称: var oldPath = src + '/' + filename, newPath = src + '/' + filename.replace(/_/g, '-'); // 重命名走起 fs.rename(oldPath, newPath, function(err) { if (!err) { console.log(filename + '下划线替换到功!'); } }) }); });

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
// 引入fs文件处理模块
var fs = require("fs");
// 现在我们要关心的是'icons'文件夹
// 我们不妨用变量表示这个文件夹名称,方便日后维护和管理
var src = 'icons';
 
// API文档中中找到遍历文件夹的API
// 找到了,是fs.readdir(path, callback)
// 文档中有叙述:
// 读取 path 路径所在目录的内容。 回调函数 (callback) 接受两个参数 (err, files) 其中 files 是一个存储目录中所包含的文件名称的数组
// 因此:
fs.readdir(src, function(err, files) {
    // files是名称数组,因此
    // 可以使用forEach遍历哈, 此处为ES5 JS一点知识
    // 如果不清楚,也可以使用for循环哈
    files.forEach(function(filename) {
        // 下面就是文件名称重命名
        // API文档中找到重命名的API,如下
        // fs.rename(oldPath, newPath, callback)      
        // 下面,我们就可以依葫芦画瓢,确定新旧文件名称:
        var oldPath = src + '/' + filename, newPath = src + '/' + filename.replace(/_/g, '-');
        // 重命名走起
        fs.rename(oldPath, newPath, function(err) {
            if (!err) {
                console.log(filename + '下划线替换成功!');
            }      
        })
    });
});

window系统比方,我们选择cmd恐怕PowerShell,在相应文件夹目录下实践下该JS文件:

node underscore2dash

1
node underscore2dash

结果:
云顶娱乐 28

这时候的文书夹的图样们:
云顶娱乐 29

这里的文件名批量替换不止适用于图片,实际上适用于率个性式的文书。

眼下,对命名的批量管理不止如此,还包罗合併前缀(举个例子icon_*云顶娱乐,),此时只要把newPath =后满的代码改成src + '/icon_' + filename。或然非开拓必要,举个例子说批量下载的小摄像名称从1依次以往排,则……依然自身管理下呢,forEach主意第叁个参数是数组序号值,能够向来拿来用,就当课后学业了,看好你呀!

本文件夹批量管理例子,抛开详尽的笺注,大致10行出头JS代码,用到的JS方法也都以特别非常基本的,对啊,数组遍历forEach和字符替换replace格局,别的就是套API走套路,纵然自身爱妻(非IT领域)亲自参加竞技,也都得以弄出来。简单,何况风趣。

本人生硬建议高校的次序支付入门课程就学JavaScript,跑web网页,跑Node.js, 简单且所见即所得,轻易激情学习的乐趣,要比枯燥不知干嘛用的C语言更适合广大和入门。

CSS Modules 使用本领

CSS Modules 是对现有的 CSS 做减法。为了追求**回顾可控**,笔者提出遵照如下原则:

  • 不采取采用器,只使用 class 名来定义样式
  • 不层叠七个 class,只利用贰个 class 把具有样式定义好
  • 不嵌套
  • 使用 composes 组合来兑现复用

地点两条准则也正是减弱了体制中最灵敏的一部分,初使用者很难接受。第一条实施起来难度比十分小,但第二条借使模块状态过多时,class 数量将倍加上涨。

无可置疑要清楚,上边之所以称为建议,是因为 CSS Modules 并不强制你早晚要这么做。听上去有一点点水火不容,由于好些个 CSS 项目设有深厚的野史遗留难点,过多的范围就代表扩充迁移花费和与外表合作的财力。前期使用中必将必要部分低头。幸运的是,CSS Modules 那一点做的很好:

1. 倘使本人对三个成分运用八个 class 呢?

没难点,样式依旧生效。

2. 怎么样本身在多个 style 文件中接纳同名 class 呢?

没问题,这么些同名 class 编写翻译后就算可能是随机码,但仍是同名的。

3. 一旦本人在 style 文件中动用了 id 选择器,伪类,标签选用器等啊?

没难题,全部这个选拔器将不被转移,一点儿也不动的出现在编写翻译后的 css 中。也等于说 CSS Modules 只会调换 class 名相关样式。

但注意,上面 3 个“假设”尽量不要产生

四、参照他事他说加以考察链接

  • John Negoita, Extending HTML by Creating Custom Tags
  • StackOverflow, Are custom elements valid HTML5?
  • Eric Bidelman, Custom Elements v1: Reusable Web Components

 

1 赞 1 收藏 评论

云顶娱乐 30

1.1页面结构

作者那边担任的PC端的重构,所以先把页面结构及中间的涉及梳理了贰次,并用xmind画好布局图,注重作用做上标识,因为vue是渐进式框架,所以作者会优先重构首要的局地
xmind结构图小编就不上了,专门的职业情操还是要的

三、蹩脚JS下的Node.js初体验二周目

我们写页面实际的支出要求必然不知文件批量重命名这么轻易,作者明白有多个供给点,特别常常写静态原型页面包车型客车伴儿一定感兴趣的。

不畏HTML页面也能够如动态语言,如php同样,种种模块能够直接include进去。未来广泛存在那样多少个难点,某项目,重构人士哗啦啦编写了20多少个静态页面,不过,由于HTML无法直接include公用的尾部尾部和侧面栏,导致,那18个页面包车型客车头尾都以独立的,平日底部内容发生了变动,呵呵,揣度就要求助理编辑辑器来个批量交替什么的了。

那是还是不是痛点?显明是!所有事痛点都以能够做出贡献体现和睦价值的地点。

没有错,大家专门的学业正是绝对页面,大家的JS还不错扶上墙,但,就是这么的大家,只要你有那么些心,意识到难题所在,同期领悟Node.js能够帮你完了那或多或少,三个实用的工具其实已经到位了概况上。参照API文书档案,东拼拼,西凑凑,肯定能够弄出三个起码自己用得很high的东西,剩下的六分之三就疑似此简轻便单续上了。

实例示例暗示
有叁个原本的HTML页面,头尾都利用了相近上边代码的专门的职业HTML5 import导入:

<link rel="import" href="header.html"/>

1
<link rel="import" href="header.html"/>

但是,实际上,rel="import"include是一心不雷同的定义,import跻身实际上是个独立的document!可是那是后话了,反正大家又不是直接浏览这一个页面,由此,大家不要介怀那些细节。

云顶娱乐 31

HTML多少个文本结构涉及如下暗示:
云顶娱乐 32

这时,我们就足以正视Node.js以致大家那点点JS知识,把rel="import"那行HTML替换到对应的导入的HTML页面内容。

原理其实一点也不细略:

  1. 读import-example.html页面;
  2. href="header.html"这行HTML替换成header.html的内容;
  3. 监察和控制import-example.html页面,一有浮动,即时生成;
  4. done!

上边为本例子的JS代码import.js:

// 引进fs文件管理模块 var fs = require("fs"); // 测量检验用的HTML页文件夹地址和文件名称 var src = 'import', filename = 'import-example.html'; var fnImportExample = function(src, filename) { // 读取HTML页面数据 // 使用API文书档案中的fs.readFile(filename, [options], callback) fs.readFile(src + '/' + filename, { // 需求钦点编码格局,不然重返原生buffer encoding: 'utf8' }, function(err, data) { // 上边要做的事情正是把 // // 这段HTML替换来href文件中的内容 // 能够求助万能的正则 var dataReplace = data.replace(//gi, function(matchs, m1) { // m1正是相称的路线地址了 // 然后就可以读文件了 return fs.readFileSync(src + '/' + m1, { encoding: 'utf8' }); }); // 由于我们要把文件放在更上一流目录,因而,一些相持地址要拍卖下 // 在本例子中,就相比轻便,对../举办轮换 dataReplace = dataReplace.replace(/"..//g, '"'); // 于是生成新的HTML文件 // 文书档案找一找,发掘了fs.writeFile(filename, data, [options], callback) fs.writeFile(filename, dataReplace, { encoding: 'utf8' }, function(err) { if (err) throw err; console.log(filename + '生成成功!'); }); }); }; // 暗许先实施一遍 fnImportExample(src, filename); // 监察和控制文件,改动后又一次生成 fs.watch(src + '/' + filename, function(event, filename) { if (event == 'change') { console.log(src + '/' + filename + '爆发了改变,重新生成...'); fnImportExample(src, filename); } });

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
50
// 引入fs文件处理模块
var fs = require("fs");
 
// 测试用的HTML页文件夹地址和文件名称
var src = 'import', filename = 'import-example.html';
 
var fnImportExample = function(src, filename) {
    // 读取HTML页面数据
    // 使用API文档中的fs.readFile(filename, [options], callback)
    fs.readFile(src + '/' + filename, {
        // 需要指定编码方式,否则返回原生buffer
        encoding: 'utf8'
    }, function(err, data) {
        // 下面要做的事情就是把
        //
        // 这段HTML替换成href文件中的内容
        // 可以求助万能的正则
        var dataReplace = data.replace(//gi, function(matchs, m1) {
            // m1就是匹配的路径地址了
            // 然后就可以读文件了
            return fs.readFileSync(src + '/' + m1, {
                encoding: 'utf8'
            });
        });
 
        // 由于我们要把文件放在更上一级目录,因此,一些相对地址要处理下
        // 在本例子中,就比较简单,对../进行替换
        dataReplace = dataReplace.replace(/"..//g, '"');
 
        // 于是生成新的HTML文件
        // 文档找一找,发现了fs.writeFile(filename, data, [options], callback)
        fs.writeFile(filename, dataReplace, {
            encoding: 'utf8'
        }, function(err) {
            if (err) throw err;
            console.log(filename + '生成成功!');
        });
    });
};
 
// 默认先执行一次
fnImportExample(src, filename);
 
// 监控文件,变更后重新生成
fs.watch(src + '/' + filename, function(event, filename) {
    if (event == 'change') {
        console.log(src + '/' + filename + '发生了改变,重新生成...');
        fnImportExample(src, filename);
    }
});

大家那时候node run一下:

node import

1
node import

结果:
云顶娱乐 33

那时的文件夹:
云顶娱乐 34

箭头所指正是新生成的HTML页面,此时的开始和结果是:
云顶娱乐 35

我们做客此页面:
云顶娱乐 36

连广告都突显能够!

那儿,node实际上是实时监督检查原始HTML是还是不是产生变化的,文书档案中的fs.watch()方式,比如,大家把图片地址的mm1换到mm2,则:
云顶娱乐 37

那儿页面产生了:
云顶娱乐 38

于是乎,一个每一日自动编写翻译import导入HTML页面包车型大巴小工具的雏形就好了。

页面重构的友人,就毫无操心20三个原型页面公用部分修改贰遍要改20多处的标题了,直接将公用的模块import进来,20四个页面分分钟编写翻译为HTML页面完全部。

当今,我们再向后看上边包车型地铁HTML扶助模块引进的小工具,正是多少个大致的Node.js API和几行轻便的JS. 我们又不是开源就融洽用用,比比较多错综相连现象根本就绝不去考虑,所以,这么轻松就足足了!

编辑:云顶娱乐 本文来源:【云顶娱乐】后面一个重构方案精晓一下,是个

关键词: