0%

原文链接 https://juejin.im/post/5d1ecb96f265da1b6d404433

什么是跨域

当一个资源从与该资源本身所在的服务器不同的域、协议、端口请求一个资源时,资源会发起一个跨域 HTTP 请求。

出于安全原因,浏览器做出了一些限制,跨站请求可以正常发起,但是返回结果被浏览器拦截了。

什么是同源策略

阅读全文 »

在移动互联网时代,信息安全越来越重要。前端方面也面临着越来越多的安全挑战,本文收集了网上各位大佬的分析总结,将持续整理总结常见的安全问题及其防御措施。

CSRF

CSRF 概念

CSRF(Cross-site request forgery)跨站请求伪造:攻击者诱导受害者进入第三方网站,在第三方网站中,向被攻击网站发送跨站请求。利用受害者在被攻击网站已经获取的注册凭证(cookies 等),绕过后台的用户验证,达到冒充用户对被攻击的网站执行某项操作的目的。

CSRF 攻击流程

阅读全文 »

原文链接:https://github.com/tcatche/tcatche.github.io/issues/22

柯里化

柯里化,是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数的技术。

柯里化,作为高阶函数的一种应用,是一个逐步接收参数的过程。

1
2
3
4
5
6
7
8
9
10
11
12
var add = (x, y) => x + y;

var curriedAdd = (x) => (y) => x + y;
var addOne = curriedAdd(1);

var addTen = curriedAdd(10);

addOne(5);
// 6

addTen(5);
// 15
阅读全文 »

先看 async / await 异步解决方案

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// sleep 函数,返回一个 Promise 对象
function sleep(ms) {
return new Promise((resolve, reject) => {
setTimeout(resolve, ms);
});
}

async function test() {
// 循环 100 次
for (let i = 0; i < 100; i++) {
// 等待 100ms 再返回
await sleep(100);
}
}

通过 babel 编译成 Generator 与 Promise

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
function _asyncToGenerator(fn) {
return function () {
var gen = fn.apply(this, arguments);
return new Promise(function (resolve, reject) {
function step(key, arg) {
try {
var info = gen[key](arg);
var value = info.value;
} catch (error) {
reject(error);
return;
}
if (info.done) {
resolve(value);
} else {
return Promise.resolve(value).then(
function (value) {
return step('next', value);
},
function (err) {
return step('throw', err);
}
);
}
}
return step('next');
});
};
}
function sleep(ms) {
return new Promise((resolve, reject) => {
setTimeout(resolve, ms);
});
}
let test = (function () {
var ref = _asyncToGenerator(function* () {
for (let i = 0; i < 100; i++) {
yield sleep(100);
}
});
return function test() {
return ref.apply(this, arguments);
};
})();

从上相关直观的看出来如何使用 GeneratorPromise 进行的异步解决方案。

阅读全文 »

原文链接:https://segmentfault.com/a/1190000014951691?utm_source=tag-newest

块级作用域的出现

通过 var 声明的变量存在变量提升的特性:

1
2
3
4
if (condition) {
var value = 1;
}
console.log(value);

初学者可能会觉得只有 conditiontrue 的时候,才会创建 value,如果 conditionfalse,结果应该是报错,然而因为变量提升的原因,代码相当于:

阅读全文 »

前面一至十一章,介绍了在 development 的模式下,整个完整了构建主流程。在了解构建流程的基础上,本章整理一些与 webpack 优化相关的知识点。

production 模式

我们参考 production 模式里,里面已经做了大部分的优化,如压缩,Scope Hoistingtree-shaking 等都给予了我们启发,接下来具体分析各个点。

production 模式启用的插件

  • FlagDependencyUsagePlugin
    • 触发时机:compilation.hooks.optimizeDependencies
    • 功能:标记模块导出中被使用的导出,存在 module.usedExports 里。用于 Tree shaking
    • 对应配置项:optimization.usedExports:true
  • FlagIncludedChunksPlugin
    • 触发时机:compilation.hooks.optimizeChunkId
    • 功能:给每个 chunk 添加了 ids,用于判断避免加载不必要的 chunk
  • ModuleConcatenationPlugin
    • 触发时机:compilation.hooks.optimizeChunkModules
    • 功能:使用 esm 语法可以作用域提升(Scope Hoisting)或预编译所有模块到一个闭包中,提升代码在浏览器中的执行速度
    • 对应配置项:optimization.concatenateModules:true
  • NoEmitOnErrorsPlugin
    • 触发时机:compiler.hooks.shouldEmitcompilation.hooks.shouldRecord
    • 功能:如果在 compilation 编译时有 error,则不执行 Record 相关的钩子,并且抛错和不编译资源
  • OccurrenceOrderModuleIdsPluginOccurrenceOrderChunkIdsPlugin
    • 注意不是文档写的 OccurrenceOrderPlugin,这个没用
    • 触发时机:compilation.hooks.optimizeModuleOrdercompilation.hooks.optimizeChunkOrder
    • 功能:根据模块初始调用次数或者总调用次数排序(配置),这样在后面分配 ID 的时候常被调用 ID 就靠前,除此之外,还可以让 id 为路径,hash 等。
    • 对应配置项:optimization.occurrenceOrderoptimization.chunkIdsoptimization.moduleIds
  • SideEffectsFlagPlugin
    • 触发时机:normalModuleFactory.hooks.modulecompilation.hooks.optimizeDependencies
    • 功能:
      • normalModuleFactory.hooks.module 钩子里读取 package.json 里的 sideEffects 字段和读取 module.rule 里的 sideEffects 赋给 module.factoryMeta(纯的 ES2015 模块);
      • compilation.hooks.optimizeDependencies 钩子里根据 sideEffects 配置,删除未用到的 export 导出
    • 对应配置项:optimization.sideEffects:true(默认)
  • TerserPlugin
    • 触发时机:template.hooks.hashForChunkcompilation.hooks.optimizeChunkAssets
    • 功能:
      • template.hooks.hashForChunk 钩子即在 chunks 生成 hash 阶段会把压缩相关的信息也打入到里面
      • compilation.hooks.optimizeChunkAssets 钩子触发资源压缩事件
    • 对应配置项:
      • optimization.minimize 是否开启压缩
      • optimization.minimizer 定制 Terser,默认开启多进程压缩和缓存
阅读全文 »

前面分析了 webpack 的普通主流程构建,另外,通过设置 watch 模式,webpack 可以监听文件变化,当它们修改后会重新编译。文档

webpack-dev-serverwebpack-dev-middlewareWatch 模式默认开启。

接下来设置 cli 命令加上 --watch 之后 对 watch 模式下的主流程进行分析(mode = development)。

初次构建

资源构建

阅读全文 »

前言及总流程概览 里的 demo 为例, 前十一张章分析了打包过程,现在来分析它打包后的文件。

demo

1
2
3
4
5
//src/a.js
import { add } from 'Src/b';
import('./c.js').then((m) => m.sub(2, 1));
const a = 1;
add(3, 2 + a);
1
2
3
4
5
6
7
8
//src/b.js
import { mul } from '@fe_korey/test-loader?number=20!Src/e';
export function add(a, b) {
return a + b + mul(10, 5);
}
export function addddd(a, b) {
return a + b * b;
}
1
2
3
4
5
6
//src/c.js
import { mul } from 'Src/d';
import('./b.js').then((m) => m.add(200, 100)); //require.ensure() 是 webpack 特有的,已经被 import() 取代。
export function sub(a, b) {
return a - b + mul(100, 50);
}
阅读全文 »

资源写入文件

回到 seal。执行:

1
this.summarizeDependencies();

得到 this.fileDependencies, this.contextDependencies, this.missingDependencies 后,触发了一系列处理资源,优化资源的钩子之后,回到 Compiler.jscompile 里的 compilation.seal 回调。

执行:

阅读全文 »