npmrc
测试 nrm、npmrc 的优先级
实验
1. 没有设置 nrm。
默认设置 registry 为 https://registry.npmjs.org/
下载的所有包都是通过以上域名获取。
2. nrm use yarn。
设置 registry 为 https://registry.yarnpkg.com/。
看源码可知实际做的事情是
npm.commands.config(['set', 'registry', registry.registry], function (err, data) {
if (err) return exit(err);
console.log(' ');
var newR = npm.config.get('registry');
printMsg([
'', ' Registry has been set to: ' + newR, ''
]);
})
即
npm set registry 'https://registry.yarnpkg.com/'
效果为
cat ~/.npmrc
registry=https://registry.yarnpkg.com/
安装结果是从 registry.yarnpkg.com 里面下包。
3. 本地使用 npmrc。
当前项目操作
touch .npmrc
在 npmrc 里面填写,vim .npmrc
registry=https://registry.npm.taobao.org/
安装结果是从 registry.npm.taobao.org 里面下包。
4. 使用本地 npmrc + nrm。
有本地 npmrc 的时候,执行 nrm ls
输出的目录是 npmrc 上设置的目录。
5. 使用本地 npmrc + package-lock.json
这个分两种情况。
- 直接执行
npm i
将从 package-lock 中获取文件的下载地址。 - 如果执行的是
npm i <package>
将从 npmrc 中获取下载地址,并更新 package-lock。
6. npm i chai –registry https://registry.yarnpkg.com/
效果与只使用 .npmrc
一致。
总结
.npmrc
的配置文件与 package-lock.json
的配置文件优先级是比较高的。
其次才是 nrm 的配置项。
nrm
其实是设置了 global 的 npmrc。项目下的 npmrc 肯定优先级更高一些。
日常-极客时间
日常-Git 操作
最近想写一些自己的项目,然后在公司锁包 yarn.lock
,发现其 resolved
是内网的 npm,考虑到我还不太想把内网的域名发到 GitHub 上,那我就来批量修改一下吧。
首先直接动手用 git filter-branch --tree-filter "sed -i '' 's/first/second/g' filename"
,然后报错 sed: filename: No such file or directory
。这时候想到 commit 从头往后找,前面几个 commit 肯定没有这个文件。因为这个文件是最近几个 commit 才有的。然后想需要配合 find
来做这个操作。
find ./foldName -name 'xxx'
发现 find 也同样面临这个问题,find: ./foldName: No such file or directory
。这样的话只能是找到所有文件然后过滤掉,过滤用 grep
,即 find . -name 'yarn.lock' | grep -v 'node_modules'
。
整理可得:
$ git filter-branch -f --tree-filter "find . -name 'yarn.lock' | grep -v 'node_modules\|otherFolder' | xargs sed -i '' 's/first/second/g' filename""
桶排序
记一次学习桶排序 Algorithm in Javascript Bucket Sort
疑惑:
- 最大值怎么设置?
- 使用场景是啥?
通过各种渠道的搜索,发现是使用的人设置了一下最大值。
在这之间了解到一个叫稳定的概念。
稳定(stable、non-stable):稳定就是两个相等的数。。顺序不会变。
桶排序为啥会是稳定的呢?毕竟没有比较,没有比较就没有不稳定的情况。我理解的不稳定就是因为比较大小,会造成顺序切换,另外就是随机取一个值的时候,无法知道他比较后的位置(比如快排)。
对于不稳定的排序算法,只要举出一个实例,即可说明它的不稳定性;而对于稳定的排序算法,必须对算法进行分析从而得到稳定的特性。需要注意的是,排序算法是否为稳定的是由具体算法决定的,不稳定的算法在某种条件下可以变为稳定的算法,而稳定的算法在某种条件下也可以变为不稳定的算法。
毕竟稳定不稳定是可以相互切换的。
继续解答桶排的问题。
和算法的同事交流,桂波说:桶排可以设个初始化的桶数,遇到大的放不下的就再增加到那么多个。
桶排的简单理解:就比如说按年龄排序,1~10 岁放一起,11~20 放一起,21~30 放一起;放完第一波后,对 1~10 里面的再继续分为 1 放一起,2 放一起~
所以桶排是很占空间的。
解答:
- 最大值如果一开始已知就设置,若未知可先设置某个值,之后加桶
- 知道最大值的情况下,不限制空间。均匀分布的数字数组。
简单的代码实现
function bucketSort (arr) {
// 假设我们排序的范围为0-10 那么我们准备11个桶来放这些数字
let buckets = new Array(11).fill(0)
let newArr = []
// 装桶
arr.forEach(val => {
console.log('val', val)
buckets[val]++
})
console.log('arr', arr)
console.log('buckets', buckets)
buckets.forEach((val, index) => {
console.log('in val, index', val, index);
for (let i = 1; i <= val; i++) {
newArr.push(index)
}
})
return newArr
}
console.log(bucketSort([5, 3, 5, 2, 8]))
TODO: 使用场景可能需要补充或调整
to be continue…
References:
git 问题
git 操作。。。
merge 出错了怎么办之类的。。。
rebase 出错了解决。。。之类的。。。
push 多了 commit 怎么操作,怎么回退,怎么保存原有 commit,怎么 push,怎么备份(如果没有备份怎么办)。
letv
乐视 TV 用起来真是糟心,没有直播的东西,只能通过别的 APP 去看直播。
网上现在搜乐视的技术文章,清一色没有用的内容。
操作及注意事项:
-
PP 助手、360 助手、豌豆荚这些主流的在手机里面的 APP 可能都没法用,点不了,进入不了安装。
-
通过多乐市场去安装应用,这个应用还支持手机输入去查找应用。
-
在搜索框里面找到电视家3.0
-
目测 iOS 也有类似影院。
touchmove and scroll
Rem 自适应页面的布局配置
使用 Rem 适配屏幕
rem 是(font size of the root element),是根据网页的跟元素(html)来设置字体大小的。如下:
1
2
3
html {
font-size: 50px;
}
如果 html 的 fontSize 是固定的,则在不同尺寸的屏幕上可能要么不够放,要么布局上不符合我们的期待。因此我们希望 html 的 fontSize 跟随手机屏幕(即 window.innerWidth)的尺寸变化。
设置 viewport
1
<meta name="viewport" content="initial-scale=1, width=device-width, maximum-scale=1, user-scalable=no">
设置 Rem
1
2
3
4
5
6
7
8
9
10
11
12
var designCSSWidth = 375;
var baseFontSize = 50;
var w = window;
var d = document;
var html = d.documentElement;
function setRem() {
var width = w.innerWidth;
var size = baseFontSize * width / designCSSWidth;
html.style.fontSize = size + 'px';
}
setRem();
然后我们发现在部分机型在 WebView 内需要 load 之后才能获取正确 innerWidth,而一开始它只能获得有问题的 innerWidth,这会影响我们的布局。这个 WebView 下有问题,但是其浏览器是没有问题的。
1
2
var on = 'addEventListener';
w[on]('load', setRem, false);
只是如上设置发现,有问题的设备将会闪一下,毕竟 rem 突然变化了一下,简单的做法就是先 display none,好了再 display block。
但是设置 display none,会发现没有问题的设备白屏时间过长。这个不能忍。经测试只有安卓的设备会有问题,iOS 上没有看到问题,因此这些操作可以只在安卓生效。安卓一开始可以拿到一个错误的 innerWidth 然后 inneWidth 很大,通常大于 500,因此可以这么设定。
1
2
if (w.innerWidth > 500 && isAnd) {
}
这样设定后只有有问题的安卓机才会有过长的白屏时间。但我们不能只满足这一点,看是否也能让有问题的安卓机的白屏时间缩短。
首先我们想到用 setTimeout,然后简单测试了一下
1
2
3
4
var time = 100;
setTimeout(function() {
}, time);
经测试,这个 time 的时间可能是几十毫秒,也可能是一百多毫秒,总之这个时间不一定,所以完全可以多次 setTimeout 去解决渲染的问题。每秒 60 帧 1000 / 60。
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
var limit = 10;
var raf = function (cb) {
setTimeout(function () {
cb && cb();
}, 1000 / 60);
}
var isAnd = w.navigator.userAgent.match(/Android/) || true;
function setRemFallback() {
// 经测试不能保证第一次就拿到正确 innerWidth,所以设置一个延时(即次数限制)。
limit--;
if (limit && w.innerWidth > 500) {
raf && raf(setRemFallback)
} else {
setRem();
d.documentElement.style.display = 'block';
}
}
if (w.innerWidth > 500 && isAnd) {
d.documentElement.style.display = 'none';
/**
* 部分机型在 WebView 内需要 load 之后才能获取正确 innerWidth。判断标准为其大于 500 的时候。
* 先隐藏 HTML,拿到正确的 innerWidth 再显示。有问题的机器包括魅族 M1
*/
if (!raf) {
w[on]('load', setRemFallback, false);
} else {
raf(setRemFallback);
}
}
到这,其实也已经够用了,但是我们还可以精益求精。我们知道的,setTimeout 的刷新时间并不准确,并且性能也不好。有一个替代品 requestAnimationFrame。
简单说 requestAnimationFrame是浏览器用于定时循环操作的一个接口,类似于setTimeout,主要用途是按帧对网页进行重绘。
在这我们仅需要把 raf 这个方法换一下。另外 requestAnimationFrame 可能有兼容性问题,可考虑 webkitRequestAnimationFrame。
1
var raf = w.requestAnimationFrame || w.webkitRequestAnimationFrame;
最终结果为:
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
var designCSSWidth = 375;
var baseFontSize = 50;
var w = window;
var d = document;
var on = 'addEventListener';
var html = d.documentElement;
function setRem() {
var width = w.innerWidth;
var size = baseFontSize * width / designCSSWidth;
html.style.fontSize = size + 'px';
console.log('done rem', width);
}
var isAnd = w.navigator.userAgent.match(/Android/) || true;
var raf = w.requestAnimationFrame || w.webkitRequestAnimationFrame;
var limit = 10;
function setRemFallback() {
// 经测试不能保证第一次就拿到正确 innerWidth,所以设置一个延时(即次数限制)。
limit--;
if (limit && w.innerWidth > 500) {
raf && raf(setRemFallback)
} else {
setRem();
d.documentElement.style.display = 'block';
}
}
if (w.innerWidth > 500 && isAnd) {
d.documentElement.style.display = 'none';
/**
* 部分机型在 WebView 内需要 load 之后才能获取正确 innerWidth。判断标准为其大于 500 的时候。
* 先隐藏 HTML,拿到正确的 innerWidth 再显示。有问题的机器包括魅族 M1
*/
if (!raf) {
w[on]('load', setRemFallback, false);
} else {
raf(setRemFallback);
}
}
setRem();
w[on]('resize', setRem, false);
References:
- 移动端网页 rem响应式布局 最佳实践代码. https://github.com/jieyou/rem_layout
- CSS3动画那么强,requestAnimationFrame还有毛线用?. http://www.zhangxinxu.com/wordpress/2013/09/css3-animation-requestanimationframe-tween-%E5%8A%A8%E7%94%BB%E7%AE%97%E6%B3%95/
Webpack
Webpack 介绍
- Webpack 是什么?
- Webpack 能够解决什么问题?
- Webpack 的缺点问题?
- 迁移成本,如何配置 webpack config。
- Webpack 原理、设计理念(待续。。。)
- Webpack 优化(待续。。。)
- Webpack 插件开发(待续。。。)
介绍 Webpack 之前可以先了解一下前端工程化。
前端工程化
- 第一阶段:库/框架选型
- 第二阶段:简单构建优化
- 第三阶段:JS/CSS模块化开发
- 第四阶段:组件化开发与资源管理
前端工程化包含
- 开发规范
- 模块化开发
- 组件化开发
- 组件仓库
- 性能优化
- 项目部署
- 开发流程
- 开发工具
-
…
- 目录结构的制定
- 编码规范
- 前后端接口规范
- 文档规范
- 组件管理
- Git 分支管理
- Commit 描述规范
- 定期 CodeReview
- 视觉图标规范
- …
旧的任务运行工具处理方式:HTML、CSS 和 JavaScript 都是分离的。必须分别对每一项进行管理,并且还要确保所有东西正确地部署到生产环境。
|| || V
即
Web 开发中常用到的静态资源主要有 JavaScript、CSS、图片、Jade 等文件,Webpack 中将静态资源文件称之为模块。Webpack 是一个模块打包工具,其可以兼容多种 js 书写规范,且可以处理模块间的依赖关系,具有更强大的 js 模块化的功能。
Webpack 是什么:
Webpack 一个针对 JavaScript 代码的模块打包工具。—> 个针对所有前端代码的管理工具。
Webpack 为了解决文件依赖管理
。
Webpack 特性:
Webpack 具有 requireJs 和 browserify 的功能,但仍有很多自己的新特性:
- 对 CommonJS 、 AMD 、ES6的语法做了兼容
- 对 js、css、图片等资源文件都支持打包
- 串联式模块加载器以及插件机制,让其具有更好的灵活性和扩展性,例如提供对 CoffeeScript、ES6 的支持
- 有独立的配置文件 webpack.config.js
- 可以将代码切割成不同的 chunk,实现按需加载,降低了初始化时间
- 支持 SourceUrls 和 SourceMaps,易于调试
- 具有强大的 Plugin 接口,大多是内部插件,使用起来比较灵活
- webpack 使用异步 IO 并具有多级缓存。这使得 webpack 很快且在增量编译上更加快
Webpack 的两个最核心的设计哲学分别是:
一切皆模块 正如js文件可以是一个“模块(module)”一样,其他的(如 css、image 或 html)文件也可视作模块。因此,你可以 require(‘myJSfile.js’) 亦可以 require(‘myCSSfile.css’)。这意味着我们可以将事物(业务)分割成更小的易于管理的片段,从而达到重复利用等的目的。
按需加载 传统的模块打包工具(module bundlers)最终将所有的模块编译生成一个庞大的 bundle.js 文件。但是在真实的app里边,“bundle.js”文件可能有 10M 到 15M 之大可能会导致应用一直处于加载中状态。因此 Webpack 使用许多特性来分割代码然后生成多个“bundle”文件,而且异步加载部分代码以实现按需加载。
Webpack 能解决的问题:
- 模块化引用静态文件,统一管理静态文件(JS、CSS、IMAGES)
- 编译 ES6 代码、TypeScript 代码
- 异步加载、按需加载,提取公共代码(CommonsChunkPlugin)
- 压缩文件 + hash
- 自动编译 + 浏览器同步刷新(Webpack dev server、Hot Module Replacement、react-hot-loader)
- 支持使用全局变量 $、React,即不需要每个文件 import jquery
- 开发模式和生产模式
- 配置 publicPath,可修改代码中的文件指向 CDN 路径
- …
缺点
- 配置过多,过于复杂。
- 它使用 bundle 的解决思路在 http/2 的时代可能欠佳。
- 插件的开发较复杂,通常开发插件的时候得熟读源码。
- 官网的文档还不是很全。
- …
对比其他打包器
Feature | webpack/webpack | jrburke/requirejs | substack/node-browserify | jspm/jspm-cli | rollup/rollup | brunch/brunch |
---|---|---|---|---|---|---|
Additional chunks are loaded on demand | yes | yes | no | System.import | no | no |
AMD define |
yes | yes | deamdify | yes | rollup-plugin-amd | yes |
AMD require |
yes | yes | no | yes | no | yes |
AMD require loads on demand |
yes | with manual configuration | no | yes | no | no |
CommonJS exports |
yes | only wrapping in define |
yes | yes | commonjs-plugin | yes |
CommonJS require |
yes | only wrapping in define |
yes | yes | commonjs-plugin | yes |
CommonJS require.resolve |
yes | no | no | no | no | |
Concat in require require("./fi" + "le") |
yes | no♦ | no | no | no | |
Debugging support | SourceUrl, SourceMaps | not required | SourceMaps | SourceUrl, SourceMaps | SourceUrl, SourceMaps | SourceMaps |
Dependencies | 19MB / 127 packages | 11MB / 118 packages | 1.2MB / 1 package | 26MB / 131 packages | ?MB / 3 packages | |
ES2015 import /export |
yes (webpack 2) | no | no | yes | yes | yes, via es6 module transpiler |
Expressions in require (guided) require("./templates/" + template) |
yes (all files matching included) | no♦ | no | no | no | no |
Expressions in require (free) require(moduleName) |
with manual configuration | no♦ | no | no | no | |
Generate a single bundle | yes | yes♦ | yes | yes | yes | yes |
Indirect require var r = require; r("./file") |
yes | no♦ | no | no | no | |
Load each file separate | no | yes | no | yes | no | no |
Mangle path names | yes | no | partial | yes | not required (path names are not included in the bundle) | no |
Minimizing | uglify | uglify, closure compiler | uglifyify | yes | uglify-plugin | UglifyJS-brunch |
Multi pages build with common bundle | with manual configuration | yes | with manual configuration | with bundle arithmetic | no | no |
Multiple bundles | yes | with manual configuration | with manual configuration | yes | no | yes |
Node.js built-in libs require("path") |
yes | no | yes | yes | node-resolve-plugin | |
Other Node.js stuff | process, __dir/filename, global | - | process, __dir/filename, global | process, __dir/filename, global for cjs | global (commonjs-plugin) | |
Plugins | yes | yes | yes | yes | yes | yes |
Preprocessing | loaders, transforms | loaders | transforms | plugin translate | plugin transforms | compilers, optimizers |
Replacement for browser | web_modules , .web.js , package.json field, alias config option |
alias option | package.json field, alias option | package.json, alias option | no | |
Requirable files | file system | web | file system | through plugins | file system or through plugins | file system |
Runtime overhead | 243B + 20B per module + 4B per dependency | 14.7kB + 0B per module + (3B + X) per dependency | 415B + 25B per module + (6B + 2X) per dependency | 5.5kB for self-executing bundles, 38kB for full loader and polyfill, 0 plain modules, 293B CJS, 139B ES2015 System.register before gzip | none for ES2015 modules (other formats may have) | |
Watch mode | yes | not required | watchify | not needed in dev | rollup-watch | yes |
Webpack 配置
最简单的配置
webpack.config.js
1
2
3
4
5
6
7
8
9
var path = require('path');
module.exports = {
entry: './foo.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'foo.bundle.js'
}
};
详细配置可查看阮一峰老师的 github:https://github.com/ruanyf/webpack-demos
References
- Webpack 2 入门教程 https://llp0574.github.io/2016/11/29/getting-started-with-webpack2/
- Webpack 2 快速入门 https://github.com/dwqs/blog/issues/46
- webpack 入门及实践 https://www.w3ctech.com//topic/1557
- 前端工程——基础篇 https://github.com/fouber/blog/issues/10
- React 技术栈系列教程 http://www.ruanyifeng.com/blog/2016/09/react-technology-stack.html
LinkList JavaScript
LinkList JavaScript
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
/**
* 用 JavaScript 定义的一个链表结构。
* Definition for singly-linked list.
* function ListNode(val) {
* this.val = val;
* this.next = null;
* }
*/
/**
* @param {ListNode} l1
* @param {ListNode} l2
* @return {ListNode}
*/
function ListNode(val) {
this.val = val;
this.next = null;
}
/**
* 链表数据
* [2, 4, 3]
* [5, 6, 4]
*/
var l1 = new ListNode(2);
l1.next = new ListNode(4);
l1.next.next = new ListNode(3);
var l2 = new ListNode(5);
l2.next = new ListNode(6);
l2.next.next = new ListNode(4);