前端知识提升-学习路径表(每周更新补充内部知识点)

354 阅读10分钟

打开印象笔记才发现这一前端知识提升的目录表,这还是2019年初领导开会发出来的,题目为:2019工作思路+学习路径,并附上以下前端知识提升列表。总是能被新事物给覆盖,于是我不敢立flag深怕自己被打脸。但是连flag都不敢立,又有什么能坚持下去呢。 转眼2020年已过去一半,今天是一个无比特殊之年,疫情+大环境+身边大幅度裁员等等。思想也不断受到冲击,从疫情开始到现在,迷茫或焦虑或制定计划重新出发。 虽然是2019的计划表,2019年已过去,但是知识点还是一样重要的,2020年还有半年让我重新出发,好好学习~fighting~ 对于前端学习我现在需要的是一个正确的方向和明确的目标和计划,加油~阿源你阔以的!

先列出这份表,接下来每周更新里面的两个知识点文章。

前端知识提升

1、调用堆栈

2、作用域闭包

3、this全面解析

4、深拷贝原理

5、原型Prototype

6、高阶函数

7、事件机制

8、Event Loop原理

9、Promise 原理

10、Async/Await原理

11、防抖/节流原理

12、模块化详解

13、ES6重难点

ES6重难点是什么?闭上眼睛想一想,无非就是Promise吧?那还有其他的吗,似乎ES6平日里常用到的就是箭头函数,模板字符串,class,Promise,let,const,async/await?还有其他的吗?我这暴脾气想不起来了。看来对ES6的学习和使用的并不是很深刻啊!!吓得我赶紧去搜一下 ES6重难点是啥!!以下是别人家整理发布过的出现最多的几个。

1.Promise
2、let和const
3、Set和Map
4、Generator和yield
5、Promise、async/await介绍
6、Proxy代理器
7、ES6对象和ES5对象

想要知道重难点,首先要知道ES6有什么?那就系统的学习一边吧。在对以上列出的重难点进行一个详细的总结整理。

----------------- 持续更新哦------------

ES6学习之一: let和const命令:https://juejin.cn/post/6844904192054657038

---- 2020.06.22 更新部分start ---- ES6学习之二: Promise对象:https://juejin.cn/post/6844904197452726285 ---- 2020.06.22 更新部分 end ----

14、计算机网络概述

15、浏览器渲染原理

16、webpack概念

一、配置

webpack.config.js

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin'); //使用前需要先npm install 此依赖包
const webpack = require('webpack');//访问内置插件

module.exports = {
	entry:'./path/to/my/entry/file.js', //文件入口
	output:{  //文件出口
		path:path.resolve(__dirname,'dist'),
		filename:'my-first-webpack.bundle.js'
	},
	mode:'production',
	module:{
		rules:[{
			test:/\.txt$/, //应转换的文件
			use:'raw-loader' //所需用的加载器进行转换
		}]
	},
	plugins:[ //插件配置插件有三种方法,数组、对象、字符串
		new HtmlWebpackPlugin({
			template:'./src/index.html'
		})
	]
};

Entry入口点

Output出口点

Loaders加载器

Plugins插件

Mode环境 通过将mode参数设置成:开发环境:development、生生产环境:productionnone,可以启动与每个环境对应的webpack内置优化。默认值是:production

Browser Compatibility 浏览器兼容性 webpack支持所有符合ES5标准的浏览器(不支持ie8以下版本),webpack需要 Promise for import()require.ensure()。如果要支持旧版本浏览器,则需要在使用这些表达式前加载polyfill

二、入口点(entry points)

单个入口点情况

配置方法有:entry:string|Array<string> webpack.config.js

module.exports = {
	entry:'./path/to/my/entry/file.js' //单个入口点配置
};

或者
module.exports = {
	entry:{
		main:'./path/to/my/entry/file.js'
	}
};

将数组传入入口后:一组文件路径传递给entry属性会创建所谓的”多主条目“。当如果想将多个依赖文件一起注入并将它们的依赖关系映射到一个”块“时,会非常有用。

数组形式配置入口点缺点:语法扩展或扩展配置的灵活性不大。

对象语法配置

Usage: entry:{[entryChunkName:string]:string|Array<string>}

webpack.config.js

module.exports = {
	entry:{
		app:'./src/app.js',
		adminApp:'./src/adminApp.js'
	}
};

对象语法配置入口点,更加详细,是配置多个入口点的最具扩展性的方法。

“可扩展性的Webpack配置”是可以重用并与其他部分配置组合的配置。它是一种流行的技术,用于安装环境,构建项目和运行时分离关注点。然后用webpack-merge等合并

多页面应用程序

webpack.config.js

module.exports = {
	entry:{
		pageOne:'./src/pageOne/index.js',
		pageTwo:'./src/pageTwo/index.js',
		pageThree:'./src/pageThree/index.js'
	}
};

三个独立的依赖关系

因为在多页面应用程序中,服务器将提取新的HTML文档,该页面重新加载此新文档,并且资源已重新加载。可以做多件事的独特机会: 使用optimization.splitChunks在每个页面之间创建共享应用程序代码包。随着入口点数量的增加,在入口点之间重用大量代码/模块的多页面应用程序可以从这些技术中得到好处。

根据经验:对于每个HTML文档,只使用个一个入口点。

三、出口点(output):

配置output配置项会告诉webpack如何将编译的文件写入磁盘。注意:虽然可以有多个入口点,但是指定只能有一个输出配置。

用法

webpack配置中输出属性的最低要求是将其值设置为对象,包括以下内容:用于输出文件的文件名。 webpack.config.js

module.exports = {
	output:{
		filename:'bundle.js'
	}
};

此配置会将单个bundle.js文件输出后到dist目录中 当配置创建了多个“块”(与多个入口点时,或使用CommonsChunkPlugin等插件时),则应使用替换来确保每个文件都具有唯一名称。

webpack.config.js

module.exports = {
	entry:{
		app:'./src/app.js',
		search:'./src/search/js'
	},
	output:{
		filename:'[name].js',
		path:__dirname+'/dist',
	}
};
// ./dist/app.js 、 ./dist/search.js将会被写入磁盘
高级配置

以下是使用CDN和哈希的更复杂示例: webpack.config.js

module.exports = {
	output:{
		path:'/home/proj/cdn/assets/[hash]',
		publicPath:'https://cdn.example.com/assets/[hash]/'
	}
}

如果在编译时未知输出文件的最终publicPath,则可以将其留空并在运行时通过入口点文件中的__webpack_public_path__ 变量动态设置。

__webpack_public_path__ = myRuntimePublicPath;

四、模式mode

通过mode配置选项告诉webpack相应地使用其内置优化。 配置用法采用string类型

用法

webpack.config.js 1】在配置文件中配置

module.exports = {
	mode:'production'	
};

2】作为CLI参数传递:

webpack --mode=production

可选值有三种 1、development:开发模式 将DefinePlugin上的process.env.NODE_ENV的值设置为:开发。启用NamedChunksPluginNamedModulesPlugin

2、production:生产模式。 默认值 将DefinePlugin上的process.env.NODE_ENV的值设置为:生产。 启用FlagDependencyUsagePlugin, ModuleConcatenationPlugin, ModuleConcatenationPlugin, NoEmitOnErrorsPlugin, OccurrenceOrderPlugin, SideEffectsFlagPluginTerserPlugin

3、none:选择退出默认mode配置。

设置NODE_ENV不会自动设置模式。

Mode:development
//webpack.development.config.js

module.exports = {
	+ mode:'development'

	- devtool:'eval',
	- cache:true,
	- performance:{
	-     hints:false
	- },
	- output:{
	-     pathinfo:true
	- },
	- optimization:{
	-     nameModules:true,
	-     namedChunks:true,
	-     nodeEnv:'development',
	-     flagIncludedChunks:false,
	-     occurrenceOrder:false,
	-     sideEffects:false,
	-     usedExports:false,
	-     concatenateModules:false,
	-     splitChunks:{
	-        hidePathInfo:false,
	-        minSize:10000,
	-        maxAsyncRequests:Infinity,
	-        maxInitialRequests:Infinity,
	-     },
	-     noEmitOnErrors:false,
	-     checkWasmTypes:false,
	-     minimize:false,
	- },
	- plugins:[
	-     new webpack.NamedModulesPlugin(),
	-     new webpack.NamedChunksPlugin(),
	-     new webpack.DefinePlugin({"process.env.NODE_ENV":JSON.stringify("development")})
	- ]
};
Mode:production
//webpack.production.config.js

module.exports = {
	+ mode:'production',
	- performance:{
	-     hints:'warning'
	- },
	- output:{
	-     pathinfo:false
	- },
	- optimization:{
	-     namedModules:false,
	-     namedChunks:false,
	-     nodeEnv:'production',
	-     flagIncludedChunks:true,
	-     occurrenceOrder:true,
	-     sideEffects:true,
	-     usedExports:true,
	-     concatenateModules:true,
	-     splitChunks:{
	-        hidePathInfo:true,
	-        minSize:30000,
	-        maxAsyncRequests:5,
	-        maxInitialRequests:3,
	-     },
	-     noEmitOnErrors:true,
	-     checkWasmTypes:true,
	-     minimize:true,
	- },
	- plugins:[
	-     new TerserPlugin(/*...*/),
	-     new webpack.DefinePlugin({"process.env.NODE_ENV":JSON.stringify("production")});
	-     new webpack.optimize.ModuleConcatenationPlugin(),
	-     new webpack.NoEmitOnErrorsPlugin()
	- ]
}
Mode:none
//webpack.custom.config.js
module.exports = {
	+ mode:'none',
	- performance:{
	-    hints:false
	- },
	- optimization:{
	-    flagIncludedChunks:false,
	-    occurrenceOrder:false,
	-    sideEffects:false,
	-    usedExports:false,
	-    concatenateModules:false,
	-    splitChunks:{
	-       hidePathInfo:false,
	-       minSize:10000,
	-       maxAsyncRequests:Infinity,
	-       maxInitialRequests:Infinity,
	-    },
	-    noEmitOnErrors:false,
	-    checkWasmTypes:false,
	-    minimize:false,
	- },
	- plugins:[]
}

如果要根据webpack.config.js中的mode变量更改行为,则必须到出函数而不是对象:

var config = {
	entry:'./app/js'
	//...
};

module.exports = (env,argv) =>{
	if(argv.mode === 'development'){
		config.devtool = 'source-map';
	}
	if(argv.mode === 'production'){
		//...
	}
	return config;
};

五、loader

loader 用于对模块的源代码进行转换。loader可以使你在import或“加载”模块时预处理文件,因此,loader类似于其他构建工具中“任务(task)”,并提供了处理前端构建步骤的强大方法。loader可以将文件从不同的语言(TypeScript)转换为JavaScript,或将内联图像转换为data URL。loader 甚至允许你直接在JavaScript模块中 import 样式文件。

示例: 你可以使用 loader 告诉 WebPack 加载 CSS 文件,或者将 TypeScript 转为 JavaScript。为此,首先安装相对应的 loader:

npm install --save-dev css-loader
npm install --save-dev ts-loader

然后指示webpack对每个 .css使用css-loader,以及对所有.ts使用ts-loader:

webpack.config.js

module.exports = {
	module:{
		rules:[
			{ test:/\.css$/,use:'css-loader'},
			{ test:/\.ts$/,use:'ts-loader'},
		]
	}
}

使用loader: 在你的应用程序中,有三种使用loader的方式:

  • 配置(推荐):在webpack.config.js文件中指定loader。
  • 内联:在每个import语句中显示指定loader。
  • CLI:在shell命令中指定它们。

配置Configuration

module.rules允许你在webpack配置中指定多个loader。这是展示loader的一种简明方式,并有助于使代码变得简洁。同时让你对各个loader有个全局概览:

module:{
	rules:[
		{
			test:/\.css$/,
			use:[
				{loader:'style-loader'},
				{
				  loader:'css-loader',
				  options:{
					modules:true,
				  }
				}
			]
		}
	]
}

内联 可以在import语句或任何等效于import的方式中指定loader。使用!将资源中的loader分开。分开的每个部分都相对于当前目录解析。

import Styles from 'style-loader!css-loader?modules!./styles.css';

通过配置所有规则及使用 !,可以对应覆盖到配置中的任意loader。 选项课可以传递查询参数,例如 ?key=value&foo=bar,或者一个JSON对象,例如{"key":"value","foo":"bar"}.

尽可能使用module.rules,因为这样可以减少源代码中的代码量,并且可以在出错时,更快地调试和定位loader中的问题。

CLI 也可以通过CLI使用loader:

webpack --module-bind jade-loader --module-bind 'css=style-loader!css-loader'

这会对.jade文件使用jade-loader,对.css文件使用style-loadercss-loader

loader特性
  • loader 支持链式传递。能够对资源使用流水线(pipeline)。一组链式的loader将按照相反的顺序执行。loader链中的第一个loader返回值给下一个loader。在最后一个loader,返回webpack所预期的JavaScript。、
  • loader 可以是同步的,也可以是异步的。
  • loader 运行在Node.js中,并且能够执行任何可能的操作。
  • loader接收查询参数。用于对loader传递配置。
  • loader也能够使用options对象进行配置。
  • 除了使用package.json常见的main属性,还可以将普通的npm模块导出为loader,做法是在package.json里定义一个loader字段。
  • 插件(plugin)可以为loader带来更多特性。
  • loader能够产生额外的任意文件。

loader 通过(loader)预处理函数,为JavaScript生态系统提供了更多能力。用户现在可以更加灵活地引入细粒度逻辑,例如压缩,打包,语言翻译和其他更多。

解析loader

loader遵循标准的模块解析。多数情况下,loader将从模块路径(通常将模块路径认为是 npm install ,node_modules)解析。 loader模块需要导出为一个函数,并且使用Node.js兼容JavaScript编写。通常使用npm 进行管理,但是也可以将自定义loader作为应用程序中的文件。 按照约定,loader 通常被命名为 xxx-loader(例如 json-loader)。有关详细信息,请查看 如何编写 loader?。

六、插件 plugins

插件是 webpack 的支柱功能。webpack 自身也是构建于,你在 webpack 配置中用到的相同的插件系统之上!

插件目的在于解决 loader 无法实现的其他事。

1、剖析

webpack 插件是一个具有 apply 属性的 JavaScript 对象。apply 属性会被 webpack compiler 调用,并且 compiler 对象可在整个编译生命周期访问。

ConsoleLogOnBuildWebpackPlugin.js

const pluginName = 'ConsoleLogOnBuildWebpackPlugin';

class ConsoleLogOnBuildWebpackPlugin{
	apply(compiler){
		compiler.hooks.run.tap(pluginName,compilation=>{
			console.log("webpack 构建过程开始!");
		})
	}
}

compiler hook 的 tap 方法的第一个参数,应该是驼峰式命名的插件名称。建议为此使用一个常量,以便它可以在所有 hook 中复用。

2、用法

由于插件可以携带参数/选项,你必须在 webpack 配置中,向 plugins属性传入 new 实例。

根据你的 webpack 用法,这里有多种方式使用插件。

3、配置

webpack.config.js

const HtmlWebpackPlugin = require('html-webpack-plugin'); //通过npm 安装
const webpack = require('webpack');//访问内置插件
const path = require('path');

const config = {
	entry:'./path/to/my/entry/file.js',
	output:{
		filename:'my-first-webpack.bundle.js',
		path:path.resolve(__dirname,'dist')
	},
	module:{
		rules:[
			test:/\.(js|jsx)$/,
			use:'babel-loader'
		]
	},
	plugins:[
		new webpack.optimize.UglifyJsPlugin(),
		new HtmlWebpackPlugin({template:'./src/index.html'})
	]
};

module.exports = config;
Node API

即便使用 Node API,用户也应该在配置中传入 plugins 属性。compiler.apply 并不是推荐的使用方式。

some-node-script.js

const webpack = require('webpack');//访问webpack运行时(runtime)
const configuration = require('./webpack.config.js');

let compiler = webpack(configuration);
compiler.apply(new webpack.ProgressPlugin());

compiler.run(function(err,stats){
	//...
})

七、配置[configuration]

这是因为 webpack的配置文件,是导出一个对象的 JavaScript 文件。此对象,由 webpack根据对象定义的属性进行解析。

因为 webpack 配置是标准的 Node.js CommonJS 模块,你可以做到以下事情:

  • 通过require(...)导入其他文件
  • 通过require(...)使用npm 的工具函数
  • 对使用JavaScript控制流表达式,例如 ?:操作符
  • 对常用值使用常量或变量
  • 编写并执行函数来生成部分配置

虽然技术上可行,但应避免以下做法:

  • 在使用 webpack 命令行接口(CLI)(应该编写自己的命令行接口(CLI),或使用 --env)时,访问命令行接口(CLI)参数
  • 导出不确定的值(调用webpack 两次应该产生同样的输出文件)
  • 编写很长的配置(应该将配置拆分为多个文件)
基本配置

webpack.config.js

var path = require('path');

module.exports = {
	mode:'development',
	entry:'./foo.js',
	output:{
		path:path.resolve(__dirname,'dist'),
		filename:'foo.bundle.js'
	}
};

八、模块(modules)

在模块化编程中,开发者将程序分解成离散功能块(discrete chunks of functionality),并称之为模块。 每个模块具有比完整程序更小的接触面,使得校验、调试、测试轻而易举。 精心编写的模块提供了可靠的抽象和封装界限,使得应用程序中每个模块都具有条理清楚的设计和明确的目的。

Node.js从最一开始就支持模块化编程。然而,在 web,模块化的支持正缓慢到来。在 web 存在多种支持 JavaScript 模块化的工具,这些工具各有优势和限制。webpack基于从这些系统获得的经验教训,并将模块的概念应用于项目中的任何文件。

什么是webpack模块

对比Node.js模块,webpack模块能够以各种方式表达它们的依赖关系。几个例子如下

  • ES2015 import 语句
  • CommonJS require()语句
  • AMD definerequire语句
  • css/sass/less文件中的@import语句
  • 样式(url(...))或HTML文件(<img src=....>)中的图片链接(image url
支持的模块类型

webpack 通过 loader 可以支持各种语言和预处理器编写模块。 loader 描述了 webpack 如何处理 非 JavaScript(non-JavaScript) 模块,并且在 bundle 中引入这些依赖。 webpack 社区已经为各种流行语言和语言处理器构建了 loader,包括:

  • CoffeScript
  • TypeScript
  • ESNext(Babel)
  • Sass
  • Less
  • Stylus 总的来说,webpack 提供了可定制的、强大和丰富的 API,允许任何技术栈使用 webpack,保持了在你的开发、测试和生成流程中无侵入性(non-opinionated)。

九、模块解析[module resolution]

resolver 是一个库(library),用于帮助找到模块的绝对路径。一个模块可以作为另一个模块的依赖模块,然后被后者引用,如下:

import foo from 'path/to/module'
//或者
require('path/to/module')

所依赖的模块可以是来自应用程序代码或第三方的库(library)。resolver 帮助 webpack 找到 bundle 中需要引入的模块代码,这些代码在包含在每个 require/import 语句中。 当打包模块时,webpack 使用 enhanced-resolve 来解析文件路径

webpack 中的解析规则

使用enhanced-resolve,webpack 能够解析三种文件路径:

绝对路径

import "/home/me/file";

import "C:\\Users\\me\\file";

相对路径

import "../src/file1";
import "./file2";

在这种情况下,使用 import 或 require 的资源文件(resource file)所在的目录被认为是上下文目录(context directory)。在 import/require 中给定的相对路径,会添加此上下文路径(context path),以产生模块的绝对路径(absolute path)。

模块路径

import "module";
import "module/lib/file";

模块将在 resolve.modules 中指定的所有目录内搜索。 你可以替换初始模块路径,此替换路径通过使用 resolve.alias 配置选项来创建一个别名。 一旦根据上述规则解析路径后,解析器(resolver)将检查路径是否指向文件或目录。如果路径指向一个文件:

  • 如果路径具有文件扩展名,则被直接将文件打包。
  • 否则,将使用 [resolve.extensions] 选项作为文件扩展名来解析,此选项告诉解析器在解析中能够接受哪些扩展名(例如 .js, .jsx)。

如果路径指向一个文件夹,则采取以下步骤找到具有正确扩展名的正确文件:

  • 如果文件夹中包含 package.json 文件,则按照顺序查找 resolve.mainFields 配置选项中指定的字段。并且 package.json 中的第一个这样的字段确定文件路径。
  • 文件扩展名通过 resolve.extensions 选项采用类似的方法进行解析。

webpack 根据构建目标(build target)为这些选项提供了合理的默认配置。

解析Loader[Resolving Loaders

Loader 解析遵循与文件解析器指定的规则相同的规则。但是 resolveLoader 配置选项可以用来为 Loader 提供独立的解析规则。

缓存

每个文件系统访问都被缓存,以便更快触发对同一文件的多个并行或串行请求。在观察模式下,只有修改过的文件会从缓存中摘出。如果关闭观察模式,在每次编译前清理缓存。

十、依赖图[dependency graph]

17、webpack原理

18、前端监控

19、跨域和安全

20、性能优化

21、VirtualDom原理

22、Diff算法

23、MVVM双向绑定

24、Vuex原理

25、Redux原理

26、路由原理

27、VueRouter源码解析

28、ReactRouter源码解析