第15期 — 2019-08-11

在浏览器中阅读

周e信

Javascript

webpack-bundle-analyzer查看什么造成文件很大🔗

插件使用

const BundleAnalyzerPlugin = require('webpack-bundle-analyzer')
  .BundleAnalyzerPlugin;

module.exports = {
  plugins: [new BundleAnalyzerPlugin()]
};

webpack-contrib

Ryan Hefner

Allan Eagle

javascript位运算符妙用🔗

~ NOT(非)

~A = - (A+1)

//将indexOf转为boolean
!!~[].indexOf(1);

& AND(与)

(0 & 0) === 0     // 0 x 0 = 0
(0 & 1) === 0     // 0 x 1 = 0
(1 & 0) === 0     // 1 x 0 = 0
(1 & 1) === 1     // 1 x 1 = 1

去掉位元

(A & 0 = 0) — The bit is always turned off by a corresponding 0 bit.
(A & 1 = A) — The bit remains unchanged when paired with a

检查位元

const mask = 0b010000;
console.log((0b110010 & mask) === mask); //

判断奇偶

function isOdd(int) {
  return (int & 1) === 1; //相当于int % 2 == 0
}

function isEven(int) {
  return (int & 1) === 0;
}

console.log(isOdd(34)); // false
console.log(isOdd(-63)); // true
console.log(isEven(-12)); // true
console.log(isEven(199)); // false

| OR(或)

(0 | 0) === 0
(0 | 1) === 1
(1 | 0) === 1
(1 | 1) === 1

打开位元

(A | 0 = A)
(A | 1 = 1)
const mask = 0b10101010;

console.log(0b11010000 | mask); // 0b11111010

^ XOR (异或)

(0 ^ 0) === 0
(0 ^ 1) === 1
(1 ^ 0) === 1
(1 ^ 1) === 0

转换位元

(A ^ 0 = A) let A = 1 (A ^ 1 = 1) (A ^ 1 = 0)

<< (左移)

RGB 转 16 进制

function rgbToHex([red = 0, green = 0, blue = 0] = []) {
  return `#${((red << 16) | (green << 8) | blue).toString(16)}`;
}

>> (右移)

hex 转 RGB

function hexToRgb(hex) {
  hex = hex.replace(/^#?([0-9a-f]{6})$/i, '$1');
  hex = Number(`0x${hex}`);

  return [
    (hex >> 16) & 0xff, // red
    (hex >> 8) & 0xff, // green
    hex & 0xff // blue
  ];
}

>>>(补零右移)

基于位元的配置

const LIST_FRACTION = 0x1; // (001)
const LIST_UNIQUE = 0x2; // (010)
const LIST_SORTED = 0x4; // (100)

// 打开配置
const LIST_ALL = LIST_FRACTION | LIST_UNIQUE | LIST_SORTED; // (111)

// 关闭配置
const LIST_DEFAULT = LIST_ALL ^ LIST_UNIQUE; // (101)

//判断配置
(flag & LIST_UNIQUE) === LIST_UNIQUE; //(存在)
(flag & LIST_UNIQUE) !== LIST_UNIQUE; //(不存在)

貌似 javscript 不需要这些 C 风格的。

Glad Chinda 摘译 Ka

globalThis 提议-访问全局对象的标准方式🔗

globalThis提供了一个标准的方式去获取不同环境下的全局对象。

对于 nodejs 里,module 里的变量不是全局变量。需要通过 global

事实上,在不同的 JavaScript 环境中拿到全局对象是需要不同的语句的。在 Web 中,可以通过 window、self 或者 frames 取到全局对象,但是在 Web Workers 中只有 self 可以。在 Node.js 中,它们都无法获取,必须使用 global。在松散模式下,可以在函数中返回 this 来获取全局对象,但是在严格模式下 this 会返回 undefined 。

Dr. Axel Rauschmayer 摘译 Ka

Intl.NumberFormat 新特性🔗

提议

现在支持 BigInt

const formatter = new Intl.NumberFormat('fr');
formatter.format(12345678901234567890n);
// → '12 345 678 901 234 567 890'
formatter.formatToParts(123456n);
// → [
// →   { type: 'integer', value: '123' },
// →   { type: 'group', value: ' ' },
// →   { type: 'integer', value: '456' }
// → ]

支持计量单位

const formatter = new Intl.NumberFormat('en', {
  style: 'unit',
  unit: 'kilobyte'
});
formatter.format(1.234);
// → '1.234 kB'
formatter.format(123.4);
// → '123.4 kB'

常用方法

const formatter = new Intl.NumberFormat('en');
formatter.format(987654.321);
// → '987,654.321'
formatter.formatToParts(987654.321);
// → [
// →   { type: 'integer', value: '987' },
// →   { type: 'group', value: ',' },
// →   { type: 'integer', value: '654' },
// →   { type: 'decimal', value: '.' },
// →   { type: 'fraction', value: '321' }
// → ]

码农们需要的

1024

// Test compact notation.
const formatter = new Intl.NumberFormat('en', {
  notation: 'compact'
});
formatter.format(1234.56);
// → '1.2K'
formatter.format(123456);
// → '123K'
formatter.format(123456789);
// → '123M'

兆每秒(科学范式)

const formatter = new Intl.NumberFormat('en', {
  style: 'unit',
  unit: 'meter-per-second',
  notation: 'scientific'
});
formatter.format(299792458);
// → '2.998E8 m/s'

百分比

const formatter = new Intl.NumberFormat('en', {
  style: 'unit',
  unit: 'percent',
  signDisplay: 'always'
});
formatter.format(-12.34);
// → '-12.34%'
formatter.format(12.34);
// → '+12.34%'
formatter.format(0);
// → '+0%'
formatter.format(-0);
// → '-0%'

金额

const formatter = new Intl.NumberFormat('en', {
  style: 'currency',
  currency: 'USD',
  signDisplay: 'exceptZero',
  currencySign: 'accounting'
});
formatter.format(-12.34);
// → '($12.34)'
formatter.format(12.34);
// → '+$12.34'
formatter.format(0);
// → '$0.00'
formatter.format(-0);
// → '($0.00)'

Mathias Bynens and Shane F. Carr (V8) 摘译 Ka

FileSaver-浏览器直接保存文件🔗

基于浏览器TransformStream的实现StreamSaver

var FileSaver = require('file-saver');
//保存Blob
var blob = new Blob(["Hello, world!"], {type: "text/plain;charset=utf-8"});
FileSaver.saveAs(blob, "hello world.txt");

// 保存链接
FileSaver.saveAs("https://httpbin.org/image", "image.jpg");

//保存canvas
var canvas = document.getElementById("my-canvas");
canvas.toBlob(function(blob) {
    saveAs(blob, "pretty image.png");
});

Eli Grey 编辑 Ka

Node.js

开源我的世界克隆版🔗

技术栈为ThreeJS, ReactJS, GraphQL, and NodeJS.

Ian Huang

Ka

monitr - 出自雅虎的nodejs监控包🔗

安装使用

npm install monitr

var monitor = require('monitr');
monitor.start();
monitor.stop();

运行方式

会创建独立的线程监控使用此包的node进程的状态,通过本地域socket发送json格式统计信息.

 { status:
     { pid: <pid of the node process>,
       ts: <current time stamp>,
       cluster: <process group id>,
       reqstotal: <total requests processed by this node process server>,
       utcstart: <when the process was started>,
       events: <number of new reports being processed since last stats reporting>,,
       cpu: <cpu usage>,
       mem: <memory usage>,
       cpuperreq: <cpu usage per request>,
       oreqs: <current open requests count>,
       sys_cpu: <system cpu load>,
       oconns: <current open connections count>,
       user_cpu: <user cpu load>,
       rps: <requests per second>,
       kbs_out: <kbs of data transferred since last stats reporting>,
       elapsed: <time elapsed since last event>,
       kb_trans: <total kbs of data transferred>,
       jiffyperreq: <cpu usage in terms of ticks per request>,
       gc: {
           scavenge: { count: <number>, elapsed_ms: <number>, max_ms: <number> },
           marksweep: { count: <number>, elapsed_ms: <number>, max_ms: <number> }
       }
    }
 }

Yahoo 编辑 Ka

frontless-同构服务端渲染实时框架🔗

整合了 FeathersJS(基于 express 的 websocket 实时协议) , RiotJS(自定义标签 mvp 框架) | Turbolinks(移动端触摸导航加速) | ExpressJS。

服务端推送更新的例子

组件代码

<my-component>
  <div>{state.value}</div>
  <script>
    export default () => ({
      id: "message",
      state: {
        value: ''
      }
    })
  </script>
</my-component>

api 代码

app.use('myservice', {
  async create(data) {
    return app.setState('message', {
      value: 'Hello!'
    });
  }
});

触发状态修改的代码

client.service('myservice').create({});

Anton Nesterov 编辑 Ka

alpaca-免手续费炒美股api🔗

alpaca(羊驼)是用来炒美股的0手续费的api。其提供实时股票数据,和交易api。

公司背景

尚不支持非美籍账户

编辑 Ka

Apollo Client已支持React Hooks🔗

安装

npm install @apollo/react-hooks

简洁的代码 - 使用useQuery查询

const LAST_LAUNCH = gql`
  query lastLaunch {
    launch {
      id
      timestamp
    }
  }
`;

export function LastLaunch() {
  const { loading, data } = useQuery(LAST_LAUNCH);
  return (
    <div>
      <h1>Last Launch</h1>
      {loading ? <p>Loading</p> : <p>Timestamp: {data.launch.timestamp}</p>}
    </div>
  );
}

使用useMutation修改

function Message() {
  const [saveMessage, { loading }] = useMutation(SAVE_MESSAGE);
  const [deleteMessage] = useMutation(DELETE_MESSAGE);
  const { data } = useQuery(GET_MESSAGE);

  return (
    <div>
      <p>
        {loading
          ? 'Loading ...'
          : `Message: ${data && data.message ? data.message.content : ''}`}
      </p>
      <p>
        <button onClick={() => saveMessage()}>Save</button>
        <button onClick={() => deleteMessage()}>Delete</button>
      </p>
    </div>
  );
}

改进对typescript的支持

减少包大小(减少一半)

使用useLazyQuery支持延迟查询

改进的文档

Hugh Willson 摘译 Ka

前端

react-flippy创建翻面卡🔗
import Flippy, { FrontSide, BackSide } from 'react-flippy';
// ... component class
render() {
	// .. return
  <Flippy
    flipOnHover={false} // default false
    flipOnClick={true} // default false
    flipDirection="horizontal" // horizontal or vertical
    ref={(r) => this.flippy = r} // to use toggle method like this.flippy.toggle()
    // if you pass isFlipped prop component will be controlled component.
    // and other props, which will go to div
    style={{ width: '200px', height: '200px' }} /// these are optional style, it is not necessary
  >
    <FrontSide
      style={{
        backgroundColor: '#41669d',
      }}
    >
      RICK
    </FrontSide>
    <BackSide
      style={{ backgroundColor: '#175852'}}>
      ROCKS
    </BackSide>
  </Flippy>
}

Berkay Aydın

开发者需要注意的firefox-68新特性🔗

支持Css Scroll Snapping特性

支持::marker

开发者工具-打印样式按钮

错误的样式依然会在样式表里显示以便觉察

Rachel Andrew 摘译 Ka

投稿

riot.js-简单小巧自定义标签风格的框架🔗
  • 体积小
  • 覆盖安卓,IOS,非常适合 H5
  • 自定义标签风格
  • 简单易用
  • 支持 slot

使用示例

<!DOCTYPE html>
<html>
  <head>
    <title>Riot Example: Timer</title>
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <link rel="stylesheet" href="style.css" />
  </head>

  <body>
    <timer></timer>

    <!-- riot tags -->
    <script src="timer.riot" type="riot"></script>

    <!-- scripts we need -->
    <script src="https://cdn.jsdelivr.net/npm/riot@4/riot+compiler.min.js"></script>

    <!-- mount this app -->
    <script>
      riot.compile().then(() => {
        riot.mount('timer', { start: 0 });
      });
    </script>
  </body>
</html>

编辑 Ka

Pierre Poupin

Edern Clemente

css动画讲解🔗

时序动画

线性和贝塞尔曲线

几种常见贝塞尔曲线

  • linear: 匀速,适合属性变化(颜色,透明度)。
  • ease: 快加速,慢减速。
  • ease-in: 慢加速到指定速度,无减速。适合元素出屏。
  • ease-out: 无加速直接到指定速度,满减速。适合入屏。
  • ease-in-out: 慢加速,慢减速。

Transitions

由元素的状态改变触发 例如:

.glowAndGrow {
  height: 100px;
  transition: background-color 0.5s, height 1s;
}
.glowAndGrow:hover {
  background-color: gold;
  height: 200px;
}
<div class="glowAndGrow">This box glows and grows on hover</div>

Animations

由keyframes组成动画

Mohammed Ibrahim

ES标准提议-脚本中以模块引入样式🔗
import styles from "styles.css";
document.adoptedStyleSheets = [...document.adoptedStyleSheets, styles];

参见此讨论

Dan Clark 编辑 Ka

Python

取余与取模的区别🔗
# 取余
> 5 rem -3
2
# 取模
> 5 mod -3
-1

简言之取余(remainder)相当于

Math.trunc(5 / -3);

取模(modulo)相当于

Math.floor(5 / -3);

在 javascript 里,%运算符是取余

在 python 里,%运算符是取模

Dr. Axel Rauschmayer 摘译 Ka

其他

宁愿打官司也不想改网站-美国比萨店请求最高法关闭关于残疾人可访问性的起诉🔗

如今美国ADA相关的诉讼正是律师大赚的时候。

美国最大披萨外卖商Domino却特立独行,要求最高法关闭针对其网站不达标ADA的诉讼。

其解释说:

  • 其网站的特性(Pizza Tracker)很难转换为文字
  • 改进将花费巨大(比打官司都贵?)
  • 目前标准也不明确,不知道怎么算达标

Nick Statt, @nickstatt

广告

扫描二维码关注微信公众号
本期阅读量