Alien ZHOU
Alien ZHOU
> 你真的了解前端模块化么? ## 告别「webpack配置工程师」 webpack是一个强大而复杂的前端自动化工具。其中一个特点就是配置复杂,这也使得「webpack配置工程师」这种戏谑的称呼开始流行🤷但是,难道你真的只满足于玩转webpack配置么? 显然不是。在学习如何使用webpack之外,我们更需要深入webpack内部,探索各部分的设计与实现。万变不离其宗,即使有一天webpack“过气”了,但它的某些设计与实现却仍会有学习价值与借鉴意义。因此,在学习webpack过程中,我会总结一系列【webpack进阶】的文章和大家分享。 欢迎感兴趣的同学多多交流与关注! ## 1. 引言 下面进入正题。一直以来,在前端领域,开发人员日益增长的语言能力需求和落后的JavaScript规范形成了一大矛盾。例如,我们会用babel来进行ES6到ES5的语法转换,会使用各种polyfill来兼容老式上的新特性……而我们本文的主角 —— 模块化也是如此。 由于JavaScript在设计之初就没有考虑这一点,加之模块化规范的迟到,导致社区中涌现出一系列前端运行时的模块化方案,例如RequireJS、seaJS等。以及与之对应的编译期模块依赖解决方案,例如browserify、rollup和本文的主角webpack。 但是我们要知道,``还存在一定的兼容性与使用问题。  在更通用的范围内来讲,浏览器原生实际是不支持所谓的CommonJS或ESM模块化规范的。那么webpack是如何在打包出的代码中实现模块化的呢? ## 2. NodeJS中的模块化 在探究webpack打包后代码的模块化实现前,我们先来看一下Node中的模块化。 NodeJS(以下简称为Node)在模块化上基本是遵循的CommonJS规范,而webpack打包出来的代码所实现模块化的方式,也类似于CommonJS。因此,我们先以熟悉的Node(这里主要参考Node v10)作为引子,简单介绍它的模块化实现,帮助我们接下来理解webpack的实现。 Node中的模块引入会经历下面几个步骤: 1. 路径分析 2. 文件定位 3. 编译执行...
> 往期文章: > - [【webpack进阶】前端运行时的模块化设计与实现](https://github.com/alienzhou/blog/issues/19) > - [【webpack进阶】使用babel避免webpack编译运行时模块依赖](https://github.com/alienzhou/blog/issues/18) > - [【webpack进阶】可视化展示webpack内部插件与钩子关系📈](https://github.com/alienzhou/blog/issues/20) ## 1. loader 十问 在我学习webpack loader的过程中,也阅读了网上很多相关文章,收获不少。但是大多都只介绍了loader的配置方式或者loader的编写方式,对其中参数、api及其他细节的介绍并不清晰。 这里有一个「loader十问」,是我在阅读loader源码前心中的部分疑问: 1. webpack默认配置是在哪处理的,loader有什么默认配置么? 2. webpack中有一个resolver的概念,用于解析模块文件的真实绝对路径,那么loader和普通模块的resolver使用的是同一个么? 3. 我们知道,除了config中的loader,还可以写inline的loader,那么inline loader和normal config loader执行的先后顺序是什么? 4. 配置中的`module.rules`在webpack中是如何生效与实现的? 5....
 ## 1. 什么是多页应用 相信很多人都知道单页面应用SPA(single page web application),那么与其相对的就是多页面应用,或者说是这种更为传统的站点——通过后端路由控制,访问不同url会由服务器吐出不同的页面与页面资源。由于SEO等一些因素,这种多页面的应用(或者说是站点更合适)如今仍然是一种非常重要的形式。 由于近期的项目形态就是这样的,而在项目中最后选择使用了gulp作为自动化工具,但是网上的各类相关博文都比较零碎,不够系统;同时在实际应用中尤其是多页面站点中遇到的一些问题也没有特别好的实践,因此,将项目中遇到的问题和解决方案整理了一下。 同时,借着项目中碰到的问题,也读了gulp及其一些相关库的源码,之后也会考虑写一些短文来进行交流。 ## 2. 什么是Gulp 相信大家对Gulp应该不会太陌生,用一句Gulp官方的话来说: > Gulp就是基于流的前端自动化构建工具 如果你完全不了解gulp,建议可以先简单浏览一下[gulp的官网](https://gulpjs.com/) > gulp是前端开发过程中对代码进行构建的工具,是自动化项目的构建利器;它不仅能对网站资源进行优化,而且在开发过程中很多重复的任务能够使用正确的工具自动完成;使用它,我们不仅可以很愉快的编写代码,而且大大提高我们的工作效率。 开发者可以在文件读取与输出中进行相应的操作与处理,从而使输出的文件满足生产要求,实现自动化。其核心部分主要有两块:vinyl与vinyl-fs组成的基于文件的一种objectMode流及其相关操作,以及orchestrator这个任务以来与控制系统(但是gulp4.0好像已经舍弃了它)。当然,本文不会来介绍这两部分的原理或者实现(这部分内容会放在之后的文章里),而是聚焦于其实际的项目应用。 ## 3. 在多页应用开发中,我们要解决什么问题 首先,在项目开发中,我们肯定会遇到各种依赖关系的管理。然而如果不用一些前端的依赖管理框架,浏览器是无法原生支持各种模块化规范的,而自动化工具的一大目标就是实现它们(或者说让你开发起来感觉像是实现了)。  上图就是我们需要面对的繁杂的依赖关系。不像单页(SPA)应用中所有的JavaScript模块都会打包为一个文件(当然可能会有一些代码拆分之类的工作,但其本质上还是将整个站点的路由等页面控制的逻辑前置到了浏览器端);与之对应的,多页面应用则可以说是一种更为传统,通过后端路由来进行页面的跳转。 因此与单页应用最大的不同就在于,其打包出的文件决不能是一个单一的文件(一个JavaScript文件和一个CSS文件)。页面可能会包含一些公共部分,但每个页面至少需要对应一个独立的JavaScript与一个独立的CSS文件。因此,在各种复杂的处理后,对于多页面应用,我们需要做的就是显现下图的效果。  其次,在管理模块化依赖之外,我们可能需要预处理一些文件。例如:将less文件编译为css文件,通过babel来使我们的es6代码能运行在不支持es6的浏览器等等。 此外,类似在单页应用中遇到的问题,我们在多页面的情况下也会要处理。例如替换HTML中的环境变量,处理CSS中的雪碧图,甚至规避一些代码检查等等。...
> 2018 眼看就要过去了,今年的你相较去年技术上有怎样的收获呢? 记得年初的时候我给自己制定了一个学习计划,现在回顾来看完成度还不错。但仍有些遗憾,一些技术点没有时间去好好学习。 在学习中我发现,像文章这样的知识往往是碎片化的,而前端涉及到的面很多,如果不将这些知识有效梳理,则无法形成体系、相互串联。最后有一种东懂一块,西了解一点的感觉。因此,我结合工作体会抽象出了一些前端基础技术能力,并将这段时间学习或产出的一些不错的内容根据这些能力进行整理,形成了一份前端技术清单([github 地址](https://github.com/alienzhou/frontend-tech-list))。 不论你是正在自学前端遇到了瓶颈,还是对某些技术熟练掌握但某些还未涉足,都希望这份清单能对你有所帮助。 > 由于个人精力有限,一些技术点的归纳可能有失偏颇,或者目前并未纳入进来,因此 [github 上的清单内容](https://github.com/alienzhou/frontend-tech-list) 也会不断更新。目前只包含纯前端基础内容,NodeJS 、客户端泛前端、小程序、可视化等内容先留着坑吧。 清单内容↓↓↓ ## 0. 年度报告 - [2018 前端工具调查报告](https://ashleynolan.co.uk/blog/frontend-tooling-survey-2018-results) - [2018 JavaScript 调查报告](https://2018.stateofjs.com/) ## 1. 基础拾遗 > 温故而知新,不知则习之,是以牢固根基。 ###...
## 前言 服务器推(Server Push)是一类特定技术的总称。一般情况,客户端与服务器的交互方式是:客户端发起请求,服务器收到请求返回响应结果,客户端接收响应结果进行处理。从上述的交互过程中可以看出,客户端想要获取数据,需要自主地向服务端发起请求,获取相关数据。 在大多数场景下,客户端的“主动式”行为已经可以满足需求了。然而,在一些场景下,需要服务器“主动”向客户端推送数据。例如: - 聊天室或者对话类应用 - 实时的数据监控与统计 - 股票财经类看板等等 这类应用有几个重要特点:要求较高的实时性,同时客户端无法预期数据更新周期,在服务端获取最新数据时,需要将信息同步给客户端。这类应用场景被称为“服务器推”(Server Push)。 “服务器推”技术由来已久,从最初的简单轮询,到后来基于长轮询的COMET,到HTML5规范的SSE,以及实现全双工的WebSocket协议,“服务器推”的技术不断发展。本文会介绍这些技术的基本原理以及实现方式,来帮助大家迅速了解与掌握“服务器推”各类技术的基本原理。文末会附上完整的demo地址。 ## 1. 简易轮询 简易轮询是“解决”该问题最简陋的一个技术方式。 简易轮询本质上就是在前端创建一个定时器,每隔一定的时间去查询后端服务,如果有数据则进行相应的处理。 ```javascript function polling() { fetch(url).then(data => { process(data); return; }).catch(err =>...
CSS是一门几十分钟就能入门,但是却需要很长的时间才能掌握好的语言。它有着它自身的一些复杂性与局限性。其中非常重要的一点就是,本身不具备真正的模块化能力。 > 系列文章链接 ↓ ↓ > - [【CSS模块化之路1】使用BEM与命名空间来规范CSS](https://github.com/alienzhou/blog/issues/14) > - [【CSS模块化之路2】webpack中的Local Scope](https://github.com/alienzhou/blog/issues/15) > - [【CSS模块化之路3】 使用💅styled-components来进行react开发](https://github.com/alienzhou/blog/issues/16) ## 1. 面临的问题 CSS中虽然有`@import`功能。然而,我们都知道,这里的`@import`仅仅是表示引入相应的CSS文件,但其模块化核心问题并未解决——CSS文件中的任何一个选择器都会作用在整个文档范围里。 而如今的前端项目规模越来越大,已经不是过去随便几个css、js文件就可以搞定的时代。与此同时的,对于一个大型的应用,前端开发团队往往也不再是一两个人。随着项目与团队规模的扩大,甚至是项目过程中人员的变动,如何更好进行代码开发的管理已经成为了一个重要问题。用CSS实现一些样式往往并不是最困难的所在,难的是使用一套合理的CSS架构来支持团队的合作与后续的维护。 > What we want is to be able to...
CSS是一门几十分钟就能入门,但是却需要很长的时间才能掌握好的语言。它有着它自身的一些复杂性与局限性。其中非常重要的一点就是,本身不具备真正的模块化能力。 ## 1. 面临的问题 你可能会说,CSS有`@import`功能。然而,我们都知道,这里的`@import`仅仅是表示引入相应的CSS文件,但其模块化核心问题并未解决——CSS文件中的任何一个选择器都会作用在整个文档范围里。 因此,其实我们面临的最大问题就是——所有的选择器都是在一个全局作用域内的。一旦引入一个新的CSS文件,就有着与预期不符的样式表现的风险(因为一些不可预测的选择器)。 而如今的前端项目规模越来越大,已经不是过去随便几个css、js文件就可以搞定的时代。与此同时的,对于一个大型的应用,前端开发团队往往也不再是一两个人。随着项目与团队规模的扩大,甚至是项目过程中人员的变动,如何更好进行代码开发的管理已经成为了一个重要问题。 回想一下,有多少次: - 我们讨论着如何对class进行有效的命名,以避免协作开发时的冲突; - 我们面对一段别人写的css、html代码,想要去修改,然后疯狂查找、猜测每个类都是什么作用,哪些是可以去掉的,哪些是可以修改的——到最后我们选择重新添加一个新的class; - 我们准备重构代码时,重构也就成了重写 - …… 用CSS实现一些样式往往并不是最困难的所在,难的是使用一套合理的CSS架构来支持团队的合作与后续的维护。 > What we want is to be able to write code that is...
CSS是一门几十分钟就能入门,但是却需要很长的时间才能掌握好的语言。它有着它自身的一些复杂性与局限性。其中非常重要的一点就是,本身不具备真正的模块化能力。 ## 1. 面临的问题 CSS中虽然有`@import`功能。然而,我们都知道,这里的`@import`仅仅是表示引入相应的CSS文件,但其模块化核心问题并未解决——CSS文件中的任何一个选择器都会作用在整个文档范围里。 因此,其实我们面临的最大问题就是——所有的选择器都是在一个全局作用域内的。一旦引入一个新的CSS文件,就有着与预期不符的样式表现的风险(因为一些不可预测的选择器)。 而如今的前端项目规模越来越大,已经不是过去随便几个css、js文件就可以搞定的时代。与此同时的,对于一个大型的应用,前端开发团队往往也不再是一两个人。随着项目与团队规模的扩大,甚至是项目过程中人员的变动,如何更好进行代码开发的管理已经成为了一个重要问题。 回想一下,有多少次: - 我们讨论着如何对class进行有效的命名,以避免协作开发时的冲突; - 我们面对一段别人写的css、html代码,想要去修改,然后疯狂查找、猜测每个类都是什么作用,哪些是可以去掉的,哪些是可以修改的——到最后我们选择重新添加一个新的class; - 我们准备重构代码时,重构也就成了重写 - …… 用CSS实现一些样式往往并不是最困难的所在,难的是使用一套合理的CSS架构来支持团队的合作与后续的维护。 > What we want is to be able to write code that is...
> 本文来自SmashingMagazine上一篇非常不错的CSS布局综述类文章,汇总了各类CSS布局技术,并提供了这些技术深度阅读的链接。故而翻译过来和大家分享,原文链接在文末,感谢作者Rachel Andrew。 ## 引言 无论你是一个想要学习CSS布局的新手,还是一个比较有经验但想要进一步巩固与了解最新CSS布局知识的前端开发者,这篇指南都能帮你全面了解如今CSS布局发展的现状。 在过去的许多年中,正如翻天覆地的前端开发一般,CSS布局也产生了巨大的变化。现在我们有需要可选的CSS布局方式来开发我们的网站,这也就要求我们对这些方式作出选择。在这片文章里,我会介绍各种CSS布局的基本使用方式以及使用的目的。 如果你还是CSS方面的新手并且想要了解什么是最好的布局方法,这篇文章正式你所需要的;当然,如果你是一位比较有经验的开发者,想要了解一些关于CSS布局的最新知识,这篇文章也不容错过。当然,我不会将各类技术的细枝末节都放到这篇文章里(否则可以写一本书了),而是对各类技术做一个基本的概述,同时会给大家提供相关链接来进一步学习。 --- ## 1. 正常文档流(Normal Flow) 如果你打开一个没有用任何CSS来改变页面布局的网页,那么网页元素就会排列在一个正常流(normal flow)之中。在正常流中,元素盒子(boxes)会基于文档的写作模式(writing mode)一个接一个地排列。这就意味着,如果你的写作模式是水平方向的(句子是从左到右或从右到左书写),正常流会垂直地一个接一个排列页面的块级元素。 当然,如果你是在一个垂直方向的写作模式下,句子是垂直方向书写的,所以块级元素会水平方法排列。  正常流是一种最基础的布局:当你为文档应用了CSS、创建了某些CSS布局,你其实是让这些块做了一个正常文档流之外的“事”。 ### 1.1. 通过页面结构来发挥正常文档流的优势 通过确保你书写的页面具有良好的页面结构(well-structured...
## 1. 引言 使用MongoDB,可以以单机模式提供服务。但在实际的生产环境中,单机模式将面临很大的风险,一旦单点数据库服务出现故障,就会导致服务调用出现错误甚至崩溃。因此,在实际生产环境下,需要对MongoDB做相应的主备处理,提高数据库服务的可用性。 对于提高可用性,一些博文里提到了使用[主从模式(master-slaver)](https://docs.mongodb.com/manual/core/master-slave/)。 > WARNING: Deprecated since version 3.2: MongoDB 3.2 deprecates the use of master-slave replication for components of sharded clusters. 主从模式是高可用的一种方案。**然而上面这段警告里提到,在高版本的MongoDB(3.2以上)的一些场景中,官方已经不推荐使用主从模式,取而代之的,是使用复制集(Replica Set)的方式做主备处理。** > IMPORTANT: Replica sets...