npmrc

2018-08-14 00:00:00 +0000

测试 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 肯定优先级更高一些。

日常-极客时间

2018-06-12 00:00:00 +0000

日常-Git 操作

2018-06-10 00:00:00 +0000

最近想写一些自己的项目,然后在公司锁包 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""

桶排序

2018-05-22 00:00:00 +0000

记一次学习桶排序 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 问题

2018-05-09 00:00:00 +0000

git 操作。。。

merge 出错了怎么办之类的。。。

rebase 出错了解决。。。之类的。。。

push 多了 commit 怎么操作,怎么回退,怎么保存原有 commit,怎么 push,怎么备份(如果没有备份怎么办)。

letv

2017-10-02 00:00:00 +0000

乐视 TV 用起来真是糟心,没有直播的东西,只能通过别的 APP 去看直播。

网上现在搜乐视的技术文章,清一色没有用的内容。

操作及注意事项:

  1. PP 助手、360 助手、豌豆荚这些主流的在手机里面的 APP 可能都没法用,点不了,进入不了安装。

  2. 通过多乐市场去安装应用,这个应用还支持手机输入去查找应用。

  3. 在搜索框里面找到电视家3.0

  4. 目测 iOS 也有类似影院。

touchmove and scroll

2017-09-27 00:00:00 +0000

Rem 自适应页面的布局配置

2017-09-24 00:00:00 +0000

使用 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。

window.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:

Webpack

2017-05-17 00:00:00 +0000

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 的功能,但仍有很多自己的新特性:

  1. 对 CommonJS 、 AMD 、ES6的语法做了兼容
  2. 对 js、css、图片等资源文件都支持打包
  3. 串联式模块加载器以及插件机制,让其具有更好的灵活性和扩展性,例如提供对 CoffeeScript、ES6 的支持
  4. 有独立的配置文件 webpack.config.js
  5. 可以将代码切割成不同的 chunk,实现按需加载,降低了初始化时间
  6. 支持 SourceUrls 和 SourceMaps,易于调试
  7. 具有强大的 Plugin 接口,大多是内部插件,使用起来比较灵活
  8. 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

LinkList JavaScript

2017-04-29 00:00:00 +0000

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);