柯森(Cosen)
柯森(Cosen)
## 引言 前一段时间我把`webpack`源码大概读了一遍,`webpack` 到`4.x`版本后,其源码已经比较庞大,对各种开发场景进行了高度抽象,阅读成本也愈发昂贵。 过度分析源码对于大家并没有太大的帮助。本文主要是想通过分析`webpack`的构建流程以及实现一个简单的`webpack`来让大家对`webpack`的内部原理有一个大概的了解。(保证能看懂,不懂你打我 🙈)  ## webpack 构建流程分析 首先,无须多言,上图~  `webpack` 的运行流程是一个串行的过程,从启动到结束会依次执行以下流程:首先会从配置文件和 `Shell` 语句中读取与合并参数,并初始化需要使用的插件和配置插件等执行环境所需要的参数;初始化完成后会调用`Compiler`的`run`来真正启动`webpack`编译构建过程,`webpack`的构建流程包括`compile`、`make`、`build`、`seal`、`emit`阶段,执行完这些阶段就完成了构建过程。 ### 初始化 #### entry-options 启动 从配置文件和 `Shell` 语句中读取与合并参数,得出最终的参数。 #### run 实例化 `compiler`:用上一步得到的参数初始化 `Compiler` 对象,加载所有配置的插件,执行对象的...
## 引言(文末有福利)🏂 算法一直是大厂前端面试常问的一块,而大家往往准备这方面的面试都是通过`leetcode`刷题。 我特地整理了几道`leetcode`中「`很有意思`」而且非常「`高频`」的算法题目,分别给出了思路分析(带图解)和代码实现。 认真仔细的阅读完本文,相信对于你在算法方面的面试一定会有不小的帮助!🤠 ## 两数之和 🦊 > 题目难度`easy`,涉及到的算法知识有数组、哈希表 ### 题目描述 给定一个整数数组 `nums` 和一个目标值 `target`,请你在该数组中找出和为目标值的那`两个`整数,并返回他们的数组下标。 你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。 示例: ```js 给定 nums = [2, 7, 11, 15], target = 9 因为...
## 前言 项目中一直用的都是`webpack`,前一段需要开发几个类库供其他平台使用,本来打算继续用`webpack`的,但感觉`webpack`用来开发`js`库,不仅繁琐而且打包后的文件体积也比较大。正好之前看`vue`源码,知道`vue`也是通过`rollup`打包的。这次又是开发类库的,于是就快速上手了`rollup`。 本篇文章是我有了一定的项目实践后,回过来给大家分享一下如何从零快速上手`rollup`。 ## 什么是`rollup`? 系统的了解`rollup`之前,我们先来简单了解下`What is rollup?` 关于`rollup`的介绍,官方文档已经写的很清楚了: > Rollup 是一个 JavaScript 模块打包器,可以将小块代码编译成大块复杂的代码,例如 library 或应用程序。 与`Webpack`偏向于应用打包的定位不同,`rollup.js`更专注于`Javascript`类库打包。 我们熟知的`Vue`、`React`等诸多知名框架或类库都是通过`rollup.js`进行打包的。 ## 为什么是`rollup`? `webpack`我相信做前端的同学大家都用过,那么为什么有些场景还要使用`rollup`呢?这里我简单对`webpack`和`rollup`做一个比较: 总体来说`webpack`和`rollup`在不同场景下,都能发挥自身优势作用。`webpack`对于代码分割和静态资源导入有着“先天优势”,并且支持热模块替换(`HMR`),而`rollup`并不支持。 所以当开发应用时可以优先选择`webpack`,但是`rollup`对于代码的`Tree-shaking`和`ES6`模块有着算法优势上的支持,若你项目只需要打包出一个简单的`bundle`包,并是基于`ES6`模块开发的,可以考虑使用`rollup`。 其实`webpack`从`2.0`开始就已经支持`Tree-shaking`,并在使用`babel-loader`的情况下还可以支持`es6 module`的打包。实际上,`rollup`已经在渐渐地失去了当初的优势了。但是它并没有被抛弃,反而因其简单的`API`、使用方式被许多库开发者青睐,如`React`、`Vue`等,都是使用`rollup`作为构建工具的。 ## 快速上手 我们先花大概十分钟左右的时间来了解下`rollup`的基本使用以及完成一个`hello world`。...
## 引言 🏂 我们平时的工作中,`github`是必不可少的代码托管平台,但是大多数同学也只是把它做为了托管代码的地方,并没有合理的去运用。 其实`github`里面有非常多好玩或者有趣的地方的。当然,这些技巧也能对你的工作效率有很大的提升。 我整理了一些自己平时用的比较多的一些功能/技巧,也希望能给你的工作带来一些帮助! ## Gist 🍓 可能很多人并没有听过`Gist`。它在`github`首页的子目录下:  这是`github`提供的一个非常有用的功能。`Gist`作为一个粘贴数据的工具,就像 `Pastie` 网站一样,可以很容易地将数据粘贴在`Gist`网站中,并在其他网页中引用`Gist`中粘贴的数据。 作为`GitHub`的一个子网站,很自然地,`Gist`使用`Git`版本库对粘贴数据进行维护,这是非常方便的。 进入`Gist`网站的首页,就会看到一个大大的数据粘贴对话框. 只要提供一行简单的描述、文件名,并粘贴文件内容,即可创建一个新的粘贴。  每一个新的粘贴称为一个`Gist`,并拥有一个单独的`URL`。 当一个粘贴创建完毕后,会显示新建立的`Gist`页面, 点击其中的`embed`(嵌入)按钮,就会显示一段用于嵌入其他网页的`JavaScript`代码,将上面的`JavaScript`代码嵌入到网页中,即可在相应的网页中嵌入来自`Gist`的数据,并保持语法高亮等功能。  ## 通过 web 界面创建文件 🍋 在有些时候,我们可能不太想用本地创建文件,然后通过`git`推送到远程这种方式去创建文件,那么有没有简单高效的一种做法呢? 很简单,通过`github`提供的 web...
## 引言 前两节我带大家分别分析了`依赖收集`和`派发更新`。在上一节的最后,提到了`nextTick`,这一节我们一起来看下`nextTick` 的源码实现。 ## 为什么要异步更新 我们先思考一个问题:`Vue`为什么要引入异步更新队列这一概念? 其实这块,在上一节有提到。如果渲染 `Watcher` 的回调是同步执行的,那执行流程是这样子的:在修改一个属性值的时候,会触发它的 `setter` ,然后就马上去触发渲染 `Watcher` 的回调,引起页面的重新渲染,乍看好像没有什么问题。 但是我们在实际开发中经常会在一个函数内修改多个属性,也就是说这些属性是同时或者说几乎同时被修改了,那实际上渲染 `Watcher` 完全可以等同一时间点的所有属性都修改完了再去执行回调重新渲染。 而这对于同步 `Watcher` 是无法实现的,有几个属性修改它就会被触发渲染页面几次,显然这会造成严重的性能问题。 这也就是引入异步更新队列的意义所在,在数据修改时,不会直接触发 `Watcher` 的回调,而是先把它放入一个异步队列中,并且我们可以通过相关逻辑控制当有多个属性同时修改时同个 `Watcher` 不会被重复添加到队列中。 因为有 `nextTick` 的存在,`Watcher` 的回调是异步执行的,所以它会一直等待同一时刻被修改的属性的 `setter`...
## 引言 `webpack`的打包优化一直是个老生常谈的话题,常规的无非就分块、拆包、压缩等。 本文以我自己的经验向大家分享如何通过一些分析工具、插件以及`webpack`新版本中的一些新特性来显著提升`webpack`的打包速度和改善包体积,学会分析打包的瓶颈以及问题所在。 本文演示代码,[仓库地址](https://github.com/Jack-cool/webpack4) ## 速度分析 🏂 webpack 有时候打包很慢,而我们在项目中可能用了很多的 `plugin` 和 `loader`,想知道到底是哪个环节慢,下面这个插件可以计算 `plugin` 和 `loader` 的耗时。 ```js yarn add -D speed-measure-webpack-plugin ``` 配置也很简单,把 `webpack` 配置对象包裹起来即可: ```js const SpeedMeasurePlugin =...
最近在开发一款桌面端应用,用到了`Electron`和`React`。  `React`作为日常使用比较频繁的框架,这里就不详细说明了,这里主要是想通过几篇文章让大家快速上手`Electron`以及与`React`完美融合。 本篇是系列文章的第一篇,主要是给大家分享`Electron`的一些概念,让大家对`Electron`有一个初步的认知。 先来了解一下什么是`Electron`吧,可能很多小伙伴还没有听过`Electron`,相信很多小伙伴此时的表情是这样的:  看下官网的自我介绍: `Electron` 是一个可以使用 `Web` 技术如 `JavaScript`、`HTML` 和 `CSS` 来创建跨平台原生桌面应用的框架。借助 `Electron`,我们可以使用纯 `JavaScript` 来调用丰富的原生 `APIs`。 `Electron`用 `web` 页面作为它的 `GUI`,而不是绑定了 `GUI` 库的 `JavaScript`。它结合了 `Chromium`、`Node.js` 和用于调用操作系统本地功能的 `APIs`(如打开文件窗口、通知、图标等)。 ...
## 引言 React v16.8 引入了 Hooks,它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性。这些功能可以在应用程序中的各个组件之间使用,从而易于共享逻辑。Hook 令人兴奋并迅速被采用,React 团队甚至想象它们最终将替换类组件。 以前在 React 中,共享逻辑的方法是通过高阶组件和 props 渲染。Hooks 提供了一种更简单方便的方法来重用代码并使组件可塑形更强。 本文将展示 TypeScript 与 React 集成后的一些变化,以及如何将类型添加到 Hooks 以及你的自定义 Hooks 上。 ...
## 引言 近几年前端对 TypeScript的呼声越来越高,Typescript也成为了前端必备的技能。TypeScript 是 JS类型的超集,并支持了泛型、类型、命名空间、枚举等特性,弥补了 JS 在大型应用开发中的不足。 在单独学习 TypeScript时,你会感觉很多概念还是比较好理解的,但是和一些框架结合使用的话坑还是比较多的,例如使用 React、Vue 这些框架的时候与 TypeScript 的结合会成为一大障碍,需要去查看框架提供的.d.ts的声明文件中一些复杂类型的定义、组件的书写方式等都要做出不小的调整。 本篇文章主要是结合我的经验和大家聊一下如何在`Vue`中平滑的从`js`过渡到`ts`,阅读本文建议对 TypeScript 有一定了解,因为文中对于一些 TypeScript 的基础的知识不会有太过于详细的讲解。(具体可以参考官方文档`https://www.w3cschool.cn/typescript/typescript-tutorial.html`,官方文档就是最好的入门手册) ## 构建 通过官方脚手架构建安装 ``` # 1. 如果没有安装 Vue CLI 就先安装 npm...
上一篇解析了`React`在进入`work`流程之前会把产生了更新的`FiberRoot`通过`addRootToSchedule`添加到一个调度队列中去,这个调度队列是一个环形的链表。之后在`performWork`方法中,递归的调用`findHighestPriorityRoot`方法找到队列中`expirationTime`最大的那个`fiberRoot`,并将`expirationtime`为`noWork`的`fiberRoot`从队列中剔除,并将这个`FiberRoot`设置为全局变量`nextFlushedRoot`,将优先级最高的`expirationTime`设置为全局变量`nextFlushedExpirationTime`,之后调用`performWorkOnRoot`方法进入`renderRoot`流程。 ```js /** * 渲染FiberRoot节点 * * @param {FiberRoot} root 需要被渲染的FiberFRoot * @param {boolean} isYieldy 任务是否可以被中断 * @returns {void} */ function renderRoot(root: FiberRoot, isYieldy: boolean): void { invariant( !isWorking, "renderRoot...