heycqing / blog Goto Github PK
View Code? Open in Web Editor NEW🐝 之前使用云服务器做的博客,现在打算迁移到Github上来,省事省力,操作简单
Home Page: https://heycqing.github.io/blog/archives
🐝 之前使用云服务器做的博客,现在打算迁移到Github上来,省事省力,操作简单
Home Page: https://heycqing.github.io/blog/archives
同步读取入口文件,然后通过 babylon
解析js文件,再通过 babel-traverse
来操作js的语法树,再交给 babel-core
转码成现在浏览器可以跑起来的代码,
其中通过一个数组来保存已经构建好父文件和子文件的依赖关系,
[ './message.js' ]
[ './name.js' ]
[]
然后不断去遍历这个存有依赖关系的数组,得出另外一个数组,这个数组包含文件的索引id,文件名,它的依赖文件,还有通过 babel-core
转码出来的代码。
queue: [ { id: 0,
filename: './example/entry.js',
dependencies: [ './message.js' ],
code:
'"use strict";\n\nvar _message = require("./message.js");\n\nvar _message2 = _interopRequireDefault(_message);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nconsole.log(_message2.default);',
mapping: { './message.js': 1 } },
{ id: 1,
filename: 'example/message.js',
dependencies: [ './name.js' ],
code:
'"use strict";\n\nObject.defineProperty(exports, "__esModule", {\n value: true\n});\n\nvar _name = require("./name.js");\n\nexports.default = "hello " + _name.name + "!";',
mapping: { './name.js': 2 } },
{ id: 2,
filename: 'example/name.js',
dependencies: [],
code:
'"use strict";\n\nObject.defineProperty(exports, "__esModule", {\n value: true\n});\nvar name = exports.name = \'world\';',
mapping: {} } ]
最关键的是,通过遍历生成的 queue 数组
,把 其中的 code 属性值
放进 CommomJs 模块规范的代码打包函数里。
function (require, module, exports) {
// 写的代码,即上面的 queue 数组对象中的不同对象的code属性的值
})
最后一步就是,让浏览器读取到第4步打包好的代码,这里没有引入其他插件,是通过内部的代码块实现的。
例子是下面的:
(function(modules) {
function require(id) {
const [fn, mapping] = modules[id];
function localRequire(name) {
return require(mapping[name]);
}
const module = { exports : {} };
fn(localRequire, module, module.exports);
return module.exports;
}
require(0);
})({0: [function(){console.log('hhhhh')}]})
真实的代码如下:
(function(modules) {
function require(id) {
const [fn, mapping] = modules[id];
function localRequire(name) {
return require(mapping[name]);
}
const module = { exports : {} };
fn(localRequire, module, module.exports);
return module.exports;
}
require(0);
})({0: [
function (require, module, exports) {
"use strict";
var _message = require("./message.js");
var _message2 = _interopRequireDefault(_message);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
console.log(_message2.default);
},
{"./message.js":1},
],1: [
function (require, module, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _name = require("./name.js");
exports.default = "hello " + _name.name + "!";
},
{"./name.js":2},
],2: [
function (require, module, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var name = exports.name = 'world';
},
{},
],})
通过babel解析代码成ES5代码,通过构建文件依赖关系,使用 commomJs 模块化打包文件,使用浏览器能理解的代码实现引入打包文件。
场景 : 当你反复修改当前URL的内容时,URL链接没有更变,你会发现浏览还是会渲染以前的内容,或许需要等待几分钟的时间才会刷新页面,但是你又不想等待,这时候怎么办?
解决:可以在当前的URL后面加上随机数。
假如当前URL为:http://www.123.com
,
随便加上随机数:http://www.123.com?123123123
基本原理:由于http是无状态的,浏览器不会记录当前访问的链接是不是之前的链接,这时候浏
览器会默认认为这是一条不同的URL,这种情况很多时候是和 get请求能缓存 挂
钩,典型的例子就是:同一条URL的get请求的key-value键值对没有变化,这时候IE
浏览器将不会重复发起请求,一样的解决方法。
其他解决方法:可以从HTTP缓存角度入手,更改请求首部的过期时间等等
③ 可以重启浏览器看看是否已经生效
🚀 如果你本地开发使用的是 switchHost 或者 频繁切换host文件 可以食用这份方案
半年博客没有更新的原因...😷
然后也借此机会,把一些分享的东西都整合一下吧。
平时有写一些文章,也有一些dome和一些问题的记录,也有自己拍了一些vlog,
文章主要分散在 github 的博客,微信公众号,掘金,简书等平台上,
就是你现在看到的Issues,
有一些是放置在 wusiqing.com上
平时也会自己去拍摄一些小视频,做一些剪辑,然后发布,视频主要还是在 vue 手机视频平台, 微信公众号,bilibili上,主要也是一些自己除技术以外的个人爱好方面。
然后看到一些好玩的东西也会分享出来,当然也会带着自己的一些看法在里面,em...也就是想分享一下
推荐一款关于有效提高前端开发效率的 Chrome 插件, PageLiner 一款Chrome参考线插件。
缘由是,在开发一个文字对齐小需求时,想去用一下参考线校对一下两元素是不是对齐,[参考线出自PS😂😂],临睡前本来想着自己可以做一个简单的类似于photoshop参考线功能的chrome小插件,然后带着想法入睡了。
第二天醒来,先搜索有没有相关类似功能的插件,😤还让我真找到了,这款 PageLiner 的插件,想法破灭了。
PageLiner 是一款能在Chrome标签页里实现参考线的功能,当然在开发者工具中也能实现。
GitHub地址: https://github.com/Crease29/pageliner
上面的 readme.md
文档会有一个插件的操作说明
大概长这个样子:
它的作者把它放到了 chrome 的应用商店上 PageLiner for chrome / 需翻墙
如果翻墙不了的,可以到我的百度网盘上取:
链接:https://pan.baidu.com/s/1EnP6FAf9IuFp4jOlI9wogw 密码:27zm
按道理来说,直接修改了 /etc/host
配置就可以了,
可以通过 ping 相对应的 hostname 就知道是否生效.
(深度好文)[https://www.cnblogs.com/hustskyking/p/hosts-modify.html]
(参考链接)[https://blog.csdn.net/weixin_42681866/article/details/93458795]
(清除浏览器dns缓存)[http://cnzhx.net/blog/how-to-flush-dns-cache-in-linux-windows-mac/]
实现以下的效果:
常用的元信息:
<title>标题名</title>
<meta name='description' content="描述摘要">
标题:浏览器会解析到 <title>
标签会自动获取web页面的标题
描述:描述摘要,很奇怪的是即使你在 <meta name='description' content=".......">
标签上写了这样的格式,浏览器在分享时都不会抓取
缩略图:浏览器在分享时会自动抓取第一张图片。 [这和在旧版本的微信页面中分享是只能抓取第一张大于等于 300 * 300的图片]
测试页面: wx_share.html
测试结果:
结论:只能获取到标题和缩略图,但是不能获取到描述摘要。
专属社交账号分享的元信息:
<meta property="og:type" content="website" />
<meta property="og:title" content="页面标题">
<meta property="og:description" content="描述信息">
<meta property="og:image" content="完整的图片链接路径">
<meta property="og:url" content="URL路径">
添加了以上的元信息之后,web页面在分享出去的时候,浏览器就可以完整抓取到标题,描述摘要,缩略图;
测试页面: wx_share_2.html
测试结果:
结论:可以获取到完整的标题,描述摘要,缩略图。
理论上网页在微信中打开并分享情况应该是和普通浏览器是一样的,因为微信内置的浏览器就是基于X5内核的QQ浏览器,但是微信团队2017年在微信开发文档中说明了不允许开发者自定义分享链接,要基于微信的JSSDK接口开发。
很早之前,开发者是可以在页面通过隐藏300*300的图片让微信来获取缩略图,同时也可以获取到描述信息和标题,但是现在已经失效。
在微信客户端打开同样的网页【 wx_share_2.html】,然后分享给朋友,是如下图一样的:
这和在普通浏览器中打开网页并分享给朋友是完全不一样的。
鉴于这种情况,前端想单独赋予网页能在微信端开发并分享的能力是没有的,可以通过配合后端来联调微信的 JSSDK分享接口
来实现。
模块是一个可划分,对内封装起来,对外界可提供相关接口的代码块
模块化是模块之间有依赖关系的
- 为什么需要模块化?
- 模块化是什么样的?
- 如何使用模块化?
直接定义依赖 - 1999
命名空间模式 - 2002
命名空间为代码组织提供了某种排序
// file app.js
var app = {};
// file greeting.js
app.helloInLang = {
en: 'Hello world!',
es: '¡Hola mundo!',
ru: 'Привет мир!'
};
// file hello.js
app.writeHello = function (lang) {
document.write(app.helloInLang[lang]);
};
模块模式 - 2003
使用闭包封装了代码和数据,并且提供方法让外界访问到它
var greeting = (function () {
var module = {};
var helloInLang = {
en: 'Hello world!',
es: '¡Hola mundo!',
ru: 'Привет мир!'
};
module.getHello = function (lang) {
return helloInLang[lang];
};
module.writeHello = function (lang) {
document.write(module.getHello(lang))
};
return module;
}());
到了这里,不过都是完成了 隔离 的目标,但是依赖关系呢?
模块定义依赖关系 - 2006
注释定义依赖关系 - 2006
外部定义依赖关系 - 2007
在代码外部使用对象或者数组来定义依赖关系,常见的是配置文件;
// file deps.json
{
"files": {
"main.js": ["sayHello.js"],
"sayHello.js": ["helloInLang.js"],
"helloInLang.js": []
}
}
// file helloInLang.js
var helloInLang = {
en: 'Hello world!',
es: '¡Hola mundo!',
ru: 'Привет мир!'
};
// file sayHello.js
function sayHello(lang) {
return helloInLang[lang];
}
// file main.js
console.log(sayHello('en'));
沙盒模式 - 2009
使用一个顶级的对象来代替window的全局作用域,或者说直接是用一个构造函数来代替全局变量。每次都通过 new 一个沙盒对象来构建 文件之间的互相依赖关系。
// file sandbox.js
function Sandbox(callback) {
var modules = [];
for (var i in Sandbox.modules) {
modules.push(i);
}
for (var i = 0; i < modules.length; i++) {
this[modules[i]] = Sandbox.modules[modules[i]]();
}
callback(this);
}
// file greeting.js
Sandbox.modules = Sandbox.modules || {};
Sandbox.modules.greeting = function () {
var helloInLang = {
en: 'Hello world!',
es: '¡Hola mundo!',
ru: 'Привет мир!'
};
return {
sayHello: function (lang) {
return helloInLang[lang];
}
};
};
// file app.js
new Sandbox(function(box) {
document.write(box.greeting.sayHello('es'));
});
到了这里,以上的所有依赖关系都得自己去处理构建的,然后再自己调用
依赖注入 - 2009
使用依赖注入的设计模式,可以直接调用其它文件,而不再需要自己创建
CommonJs Modules - 2009
commonJs是在 由于nodeJS 没有适当的模块规范来统一代码分发问题 的情况下诞生的,前身是 serverJS, 由 Mozilla 工程师Kevin Dangoor发起,社区人员一起开发的成果。所以,它是一种规范。
它是一种模块化的规范,主要是应用在除客户端js以外的Js应用中,包括服务端nodeJs和桌面应用,它是如何工作? --> 在发送给 js 引擎之前,会把一组组的使用commonJs模块规范的js文件打包,
会被把js代码放到被这样的形式函数中。
(function (exports, require, module, __filename, __dirname) {
// ...
// Your code injects here!
// ...
});
是我们非常熟悉的两个关键字: module 、require
使用CommonJs规范的模块都是同步加载的,即第一个模块加载完再会轮到第二个加载
// file greeting.js
var helloInLang = {
en: 'Hello world!',
es: '¡Hola mundo!',
ru: 'Привет мир!'
};
var sayHello = function (lang) {
return helloInLang[lang];
}
module.exports.sayHello = sayHello;
// file hello.js
var sayHello = require('./lib/greeting').sayHello;
var phrase = sayHello('en');
console.log(phrase);
ADM (Asynchronous Module Definition) - 2009
有了同步加载,当然会有异步加载规范,在 CommonJs 全面开启规范工作的同时,有另外一种声音 --- 讨论异步加载模块规范的可能性,讨论的动机即:这(异步加载模块)将有助于加快Web应用程序的加载速度,而无需进行任何预先打包。
另一名来自Mozilla的工程师James Burke(开发requireJs)提出ADM的基本**: 模块加载不应该是同步的,更应该是使用浏览器功能来并行加载js脚本文件(也就是使用浏览器自带的功能来实现异步加载)。所以,异步加载模块规范也诞生了。
// file lib/greeting.js
define(function() {
var helloInLang = {
en: 'Hello world!',
es: '¡Hola mundo!',
ru: 'Привет мир!'
};
return {
sayHello: function (lang) {
return helloInLang[lang];
}
};
});
// file hello.js
define(['./lib/greeting'], function(greeting) {
var phrase = greeting.sayHello('en');
document.write(phrase);
});
这感觉是,两种不同的**在对抗,但是由于 nodeJS 的蓬勃发展,npm社区的活跃,支持 CommonJS 的开发人员远大于支持 ADM 的开发人员
UMD (Universal Module Definition)- 2011
UMD (通用模块定义),它的出现很好的兼顾了主张同步模块加载的 commomJs 和 主张异步模块加载的 ADM ,可以在服务器环境和浏览器环境都分别支持 commonJS 和 ADM 。
主要**是,通过判断当前的环境是支持commonJS 还是支持 ADM 来使用不同的参数达到目的。
(function(define) {
define(function () {
var helloInLang = {
en: 'Hello world!',
es: '¡Hola mundo!',
ru: 'Привет мир!'
};
return {
sayHello: function (lang) {
return helloInLang[lang];
}
};
});
}(
typeof module === 'object' && module.exports && typeof define !== 'function' ?
function (factory) { module.exports = factory(); } :
define
));
这段代码使用立即执行函数来判断当前的规范环境,如果是支持commomJs 环境的,则使用函数 function (factory) { module.exports = factory(); }
,否则则使用 define
例如在CommonJS环境使用
为什么会这样做?
因为当时的支持CommomJs的环境不支持ADM,支持ADMd的环境也不支持CommonJs,两者冲突较大,让整个js生态环境没有得到一个统一的模块规范,呈现一团糟的状态。然后 UMD 的出现,兼顾了2者,得到了众多开发者的拥簇。
Labeled Modules - 2012
标签模块,主要**是提出可传递模块,(看着代码,是不是感觉有点眼熟,形式类似于c语言的 go to 关键字)。
使用标签来代替模块的引入关系,
这个时候 ES6 已经研发2年了。
```js
// file greeting.js
var helloInLang = {
en: 'Hello world!',
es: '¡Hola mundo!',
ru: 'Привет мир!'
};
exports: var greeting = {
sayHello: function (lang) {
return helloInLang[lang];
}
};
// file hello.js
require: './lib/greeting';
var phrase = greeting.sayHello('es');
document.write(phrase);
```
YModules - 2013
基于 Yandex 上研发的一个模块化系统,主要是解决CommonJS和ADM没有解决的问题,但是入手的门槛高,有要求。
反正我没看懂...
ES6 模块规范 - 2015
ES6规范准备了5年,
看了代码你可能有点疑惑,这不是ES6规范的代码?
是的,ES6的一个版本即 ES 6.1 版本在2015年6月发布,正式名称是:《ECMAScript 2015 标准》(简称 ES2015),随后的2016年6月发布小幅修订的《ECMAScript 2016 标准》(简称 ES2016),因为差异过小,都统称 ES6 .
ES6 既是一个历史名词,也是一个泛指,含义是 5.1 版以后的 JavaScript 的下一代标准,涵盖了 ES2015、ES2016、ES2017 等等,而 ES2015 则是正式名称,特指该年发布的正式版本的语言标准。
-- 引用阮一峰老师的话
es6 的模块规范,完全取代了CommonJs 和 ADM 两者,即可以在服务端支持 js 模块化,又可以在客户端支持 js 模块化。不再需要使用 UMD 的兼顾两者了。
// file lib/greeting.js
const helloInLang = {
en: 'Hello world!',
es: '¡Hola mundo!',
ru: 'Привет мир!'
};
export const greeting = {
sayHello: function (lang) {
return helloInLang[lang];
}
};
// file hello.js
import { greeting } from "./lib/greeting";
const phrase = greeting.sayHello("en");
document.write(phrase);
done!
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.