Vincent He's waking life

在发现我没有道德后
对方放弃了道德绑架


  • Home

  • Visited cities

  • Cheat sheet

[译]635000 个 npm 包中我应该用哪个

Posted on 2018-12-20 | In 前端 , tool chain , js

[英文原文] Which of the 635000 npm modules do I choose? - Corey Cleary

原创翻译,如有谬误,恳请指正

如果您曾在 Node 或 JavaScript 前端开发中投入过时间和精力,那么您就知道 npm 中有数以十万计的模块可供您选择

开发者不停的寻求帮助/抱怨:

“对模块的选择困难正在蚕食我们”

“X 模块和 Y 模块有什么区别?哪一个更好?”

“npm 很棒,但是这些模块可能在一年半载后失效,取决于模块维护者是否积极”

通常在提出这样的问题时,您会得到十个不同的答案。每个人都会给您推荐自己喜欢的模块,接下来就演变成争论哪一个是最好的。

选择 npm 模块时很容易面临纸上谈兵。选择太多,而新来者在鼓吹“快上车”,为您的项目选择合适的 npm 模块可能是有难度的。而且这些模块中有许多做类似(或相同)的事情,这也没有帮助。

与其浪费时间在 google 上搜索,在 npmjs.org 上搜索,或者浪费更多的时间不构建您的项目,还不如搞清楚什么时候该选择哪些模块。

精选清单

为了帮助解决这个问题,您将在下面找到针对最常见问题类型(即 web 框架、模板、身份认证等)的 npm 模块列表,以及何时使用这些模块。

这里有一些注意事项:您可能熟悉其中一些模块,甚至许多模块,但是有时候您面对的是您还没有接触到的技术栈(可能是身份验证或 Websocket 之类的东西),您需要知道有哪些备选模块可以完成这项工作。您可能有您认为更好的模块,或者可能有一个用例/需求没有包含在这里。我没有列出相同类别的 10 个不同模块,而是缩小了范围,这样您就可以避免分析瘫痪的陷阱。如果您认为自己的用例未被涵盖,请务必自行研究解决。本清单的目的在于让您能更快地启动和运行。

这些模块的选择依据如下:

  • 它们完成工作的能力如何
  • 社区规模(对于支持/故障排除很重要)
  • 积极维护

如果您发现自己仍然没有足够的信息做出决定,我建议使用slant.co和nodejs.libhunt.com来帮助进行比较。

注意:为了保持范围的合理性,这些模块都考虑到了服务器端。它们中的一些可以同时在客户机或服务器上使用,但我的原则是“服务器优先”。

HTTP requests (HTTP 请求)

  • Request:
    • 当您需要基于回调的 HTTP 请求时可选择它,例如从一个 REST 服务连接到另一个。
  • Axios
    • 当您需要基于 Promise的 HTTP 请求时可选择它
    • 注意:您可以使用request-promise,但是 axios 的依赖更少,并且基于原生 Promises

Web frameworks (Web 框架)

  • Express:
    • 如果您想为 API、网站或单页应用程序使用轻量级 web 框架,请使用它
    • 您不介意使用回调作为默认的异步处理方式
    • 使用该框架的模块生态极为繁荣
    • 您需要一个支持和故障排除的大型社区
  • Koa:
    • 当您想要一个比 Express 更简洁的框架时使用
    • Koa 更像是一个中间件层,它不提供模板或开箱即用的路由,因此更适合 API 开发
    • 要想支持开箱即用,您需要 async / await
  • Hapi
    • 如果您想要一个比 Express 或 Koa 更“自带电池”(译者注:原文”batteries”意为您不必重复造轮子,大多数您需要的功能都能通过(已有)库完成。您能导入并使用它们。)的框架,但又不像 Sails 那么多,那就使用它
  • Sails
    • 当您需要像 Rails 这样的东西时,请使用它,它具有几乎所有功能(但是根据您的应用程序可能不需要那么多)

Validation (前端验证)

  • Ajv
    • 在需要验证 JSON 时使用(比如来自 web 请求)
    • 您希望与应用程序的其他非 JS 部分共享这些验证规则(因为它是 JSON,所以您可以这样做)
  • Joi
    • 在需要验证输入时使用,并且喜欢链式调用的风格(译者注:代码见下方),而不是在 JSON 中定义验证规则
    • 您正在使用 Hapi(Hapi 自带 Joi)
1
2
3
4
const schema = joi.object().keys({
id: joi.string().guid().required(),
username: joi.string().alphanum().min(8).required()
});

Authentication (身份认证)

  • Passport:
    • 当您需要为您的网站或 API 使用身份验证中间件时使用
    • 您希望能够在多种身份验证类型(Oauth,Facebook 等)之间进行选择
    • 您需要管理会话

Asynchronous (异步)

  • Async (library):
    • 当您需要使用旧版本的 Node,而该版本的 Node 支持只支持回调而不支持 Promises 时
  • ES6 原生 promises (原生 JS, 非 npm):
    • 在使用大于 0.12 的 Node 版本时使用
    • 另一件需要考虑的事情是您的团队对 Promises 的接受程度。在 2018 年,大多数开发人员应该没问题了
  • async / await(原生 JS,非 npm)
    • 当您为了逃脱“回调地狱”却又误闯“Promise 地狱”
    • 您有很多来自 Promises 的.then 和.catch

Database (数据库)

下面是数据库驱动程序、ORM 和查询生成器的组合。在使用 ORM 之前,我强烈建议您首先确保需要使用它。当您可以只使用原始 SQL 或查询生成器时,它们通常会添加另一层抽象,这层抽象不一定能够提供足够的回报。

  • mysql, node-postgres:
    • 当您不需要完整的 ORM,而是需要使用原始 SQL 查询数据库时使用(这些是驱动程序)
  • node-mongodb-native:
    • 当您不需要一个完整的 ORM,而是要直接查询 MongoDB 时使用
  • Mongoose:
    • 当您希望为 MongoDB 使用 ORM 时使用
  • Knex:
    • 当您不需要一个完整的 ORM 解决方案,而只是需要一些工具使编写查询代码更容易,可以使用它
    • Knex 是一个生成 SQL 的查询生成器
    • 您拥有 Postgres、MSSQL、MySQL、MariaDB、SQLite3、Oracle 或 Amazon Redshift 数据库
  • Objection.js:
    • 您希望 ORM 支持 Knex 支持的所有东西,不使用查询 DSL(因此您编写的代码更接近原始 SQL),具有基于 Promise 的 API 和良好的文档

Process management (进程管理)

这个网址提供了部分进程管理器的横向比较http://strong-pm.io/compare/。注意:它们还包括了 StrongLoop Process Manager,这是一个不错的工具,但是有点笨重。我建议您在决定使用 StrongLoop 之前先查看一下解决方案。

  • PM2:
    • 当您希望进程管理器在服务崩溃时处理重新启动,并允许您控制集群时使用
    • 注意:PM2 所依据的 AGPL 许可证存在一些潜在的违规行为。这里有一些讨论。我的看法是它最有可能被使用。但如果您有任何问题,请咨询您的法律部门,因为我不是律师。
  • forever:
    • 当您需要进程管理器来处理在服务崩溃时重新启动服务时使用
    • 您的部署规模较小(pm2 及其集群支持用于更大规模的部署)。如果您只有少量的服务/进程,那么您可能可以使用它
  • nodemon:
    • 当您希望监视应用程序中的任何代码更改时使用,并在本地开发时自动重启服务器
    • 非常适合用于开发!

Web Sockets

对于 Web Sockets,我只是推荐 primus,而不是列出一个列表。它支持所有主要的 Web Sockets 实现,并且维护者十分积极。如果您需要换成其他的库,您可以通过一行代码更改轻松地更换。

  • Primus:
    • 当您需要 Web Sockets 但又不想被束缚在特定的 Web Sockets 实现时使用

API documentation (API 文档)

  • Swagger-node:
    • 当您需要记录 REST API 并能够针对端点测试请求时使用

Utilities/misc (通用工具/杂项)

  • Lodash:
    • 当您需要 JS 实用程序库时使用
    • 您使用了大量的 OOP(面向对象编程)
  • Ramda:
    • 当您希望使用函数式的编程风格时,请使用
    • 您想要像 lodash 这样的东西,但是在函数式编程范式中
  • Moment:
    • 在需要解析、验证、操作和显示日期/时间时使用
  • UUID:
    • 当您需要随机的、唯一的、难以破解的 id 时使用
  • NVM:
    • 当您希望能够在环境中安装的多个 Node 版本之间切换时使用
  • Fs-extra:
    • 当您需要能够递归地使用mkdir、rm -rf和 Node 中缺少的其他文件系统级功能时,请使用
  • Nodemailer:
    • 当您需要从 Node 发送电子邮件时使用
  • Dotenv:
    • 当您需要将.env 文件中的环境变量加载到 process.env 时使用

CLI (命令行界面)

  • Commander:
    • 当您要构建一个 CLI 程序时使用,该程序将所有参数作为命令行上的标志
  • Inquirer:
    • 当您想要构建一个按顺序获取选项的“交互式”CLI 程序时使用(类似于运行 npm init 时的方式,它会询问您生成 package.json 文件的一系列问题)

Logging (日志)

  • Winston:
    • 当您需要一个日志库并需要不同的日志输出格式时使用
  • Bunyan:
    • 当您需要一个日志库,并以 JSON 作为唯一日志输出格式时使用
    • 您希望为不同的组件、请求或函数使用不同的日志记录器(也就是说,这些日志记录器可能以不同的方式解析事件)
  • Morgan:
    • 当您使用 Express 并且想要记录 HTTP 请求时使用
    • 注意:这将与 Winston 或 Bunyan 一起使用。由于它是中间件,它知道如何处理请求并记录它,但不处理 Winston 和 Bunyan 所做的日志输出的传输。

Templating (前端模板)

  • Pug (原 Jade):
    • 当您需要服务器端模板引擎时,请使用该引擎,该引擎易于阅读,并且支持开箱即用的子组件代码块
    • 您只需要输出 HTML
  • EJS:
    • 当您需要一个服务器端模板引擎,该引擎完全使用 JS,并且允许空格缩进(Pug 不允许)
    • 注意:不支持异步 JS 函数

Testing (测试)

  • Mocha:
    • 在需要编写和运行单元测试时使用
  • Chai:
    • 当您需要证明您的单元测试中的断言时,请使用
    • 注意:这将与 Mocha 一起使用
  • Chai-as-promised:
    • 当您希望在 promises 上证明您的断言时,而不是将断言放在 then 或 catch 中使用
  • Sinon:
    • 当您需要用于测试的 mock 库时使用

Tooling (开发工具)

  • ESdoc:
    • 当您想从您的代码中生成 API 文档,并且您正在使用最新的 JS 版本时,请使用
    • 默认情况下支持当前版本的 JS(支持 class),因此如果在代码中使用 prototypes,请使用 JSdoc
  • JSdoc:
    • 当您需要支持 ES6 的代码 API 文档生成器时使用
    • 支持classes 和 prototypes
  • ESlint:
    • 当您需要一个 linter 来自动查找(和修复)代码中的语法和代码格式问题时使用(译者注:可参考本人博文vscode + vetur + eslint + prettier 实现团队代码风格统一)

Debugging (调试)

现在,原生 Node 调试现在已经够用了,我的建议是直接使用它。几年前,引入一些 npm 模块是很有帮助的,而且您可能有一个特定的用例需要一个 npm 模块,但是现在已经有了足够的本地支持,如果您对调试没有任何太疯狂要求,请务必忽略掉额外的依赖项。

结论

挑选模块可能很难,但您只需要一些方法点来解决它。当您正在为如何抉择浪费时间,或者甚至不知道从哪里开始时,请使用本指南来帮助您。

一周网摘2018-12-w1

Posted on 2018-12-09 | In 杂

见微知著,Google Photos Web UI 完善之旅

Google 工程师撰文《Building the Google Photos Web UI》,里面详细介绍了 Google Photos for Web 是如何在几千上万张用户照片的体量下,做到自适应布局、高性能加载、60fps 流畅滚动,并提升页面速度的,干货不少值得一读!中文翻译:

zhuanlan.zhihu.com


为什么我们活得越来越像一只信息量过载的猪

智谷趋势

这篇文章本身也是信息过载/贩卖焦虑吧,有时候需要反省下自己到底想要什么


Parked cars covered by the season’s first snowfall in Moscow

Parked cars covered by the season’s first snowfall in Moscow

vscode + vetur + eslint + prettier 实现团队代码风格统一

Posted on 2018-12-07 | In 前端 , tool chain

vscode + vetur + eslint + prettier 实现团队代码风格统一

如果你也是 front-end coder,也采用 ES6、vue 单文件、css 预编译,希望实现团队代码格式/风格统一,可参考本文。

值得参考并执行的规范

  • 谷歌 HTML/CSS 规范
  • Airbnb CSS / Sass 指南
    • zh_CN
  • Airbnb JavaScript 风格指南
    • zh_CN
  • Eslint rules(强烈推荐)
  • 使用 ES6 进行开发的思考(via Baidu EFE)
  • Vue.js 风格指南

落地方案

  • IDE: vs code
    • ESLint // ide lint 报错/warning 要靠它
    • Prettier - Code formatter // 格式化 html/css/less/scss etc…
    • Vetur // 这里只用来语法提示,代码格式化交给 eslint(npm)
  • npm:
    • eslint
    • eslint-config-airbnb-base
    • eslint-config-prettier
    • eslint-plugin-import
    • eslint-plugin-vue
    • eslint-plugin-prettier
    • prettier
  • 关键配置文件(in git repo)
    • .vscode/setting.json // ESLint(ide 插件),vetur(ide 插件)配置在这里
    • .editorconfig // 字符集配置,缩进等配置
    • .eslintrc.js // eslint(npm)配置,ide eroor/warning 信息在这里配置
    • .eslintignore // eslint 排除文件,如一些库文件
    • .prettierrc.js // prettier 配置,如逗号分号规则
    • .prettierignore //prettier 排除文件

简单说下思路

  • eslint 优先级最高,装插件eslint-config-airbnb-base,eslint-config-prettier,eslint-plugin-vue,可以覆盖 prettier 的设置
  • eslint 主要负责 vue/js 的格式化
  • prettier 主要负责 html/css/less/scss… 的格式化
  • Vetur 也有格式化功能,直接 disable 掉,我们用更高级的
  • prettier 不支持 stylus,但是 Vetur 的依赖包括了stylusSupremacy,可以解决
  • 所有的配置都可以放在项目 repo 里,且优先级会高于 coder 本地的设置,保证团队所有成员提交的代码一致
  • 如果装了其他 format 插件,请在本项目中 disable 掉,我们不需要

附:配置文件

EditorConfig

1
2
3
4
5
6
7
8
9
10
11
12
13
root = true # 表明是最顶层的配置文件,发现设为true时,才会停止查找.editorconfig文件。

[*]
charset = utf-8 # 编码格式,支持latin1、utf-8、utf-8-bom、utf-16be和utf-16le,不建议使用uft-8-bom。
indent_style = space # tab为hard-tabs,space为soft-tabs。
indent_size = 2 # 设置整数表示规定每级缩进的列数和soft-tabs的宽度(译注:空格数)。如果设定为tab,则会使用tab_width的值(如果已指定)。
end_of_line = lf # 定义换行符,支持lf、cr和crlf。
insert_final_newline = # 设为true表明使文件以一个空白行结尾,false反之。
trim_trailing_whitespace = true # 设为true表示会除去换行行首的任意空白字符,false反之。

[*.md]
insert_final_newline = false # 设为true表明使文件以一个空白行结尾,false反之。
trim_trailing_whitespace = false # 设为true表示会除去换行行首的任意空白字符,false反之。

.eslintrc.js

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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
/**
*
* 规则说明见 https://cn.eslint.org/docs/rules/
* eslint-plugin-import 规则见 https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/default.md
* eslint-plugin-vue 规则见 https://github.com/vuejs/eslint-plugin-vue
*
* "off" 或 0 - 关闭规则
* "warn" 或 1 - 开启规则,使用警告级别的错误:warn (不会导致程序退出)
* "error" 或 2 - 开启规则,使用错误级别的错误:error (当被触发的时候,程序会退出)
*
*/

module.exports = {
extends: [
// add more generic rulesets here, such as:
// 'eslint:recommended',
"airbnb-base", // airbnb lint规范
"plugin:vue/essential", // eslint-plugin-vue
"plugin:prettier/recommended" // eslint-config-prettier
],
// settings: {
// 'import/resolver': {
// webpack: {
// config: 'build/webpack.base.conf.js',
// },
// },
// },
// plugins: ['vue'],
rules: {
"prettier/prettier": 1,
"no-undef": 2, // 禁用未声明的变量,除非它们在 /*global */ 注释中被提到. e.g. /* global Stomp SockJS */ in .vue file's <scrpit>
"no-extend-native": 2, // 禁止扩展原生类型
"no-return-assign": 2, // 禁止在 return 语句中使用赋值语句
"import/order": 0, // Enforce a convention in module import order
"import/no-extraneous-dependencies": 0, // 禁止导入未在package.json的依赖项,devDependencies,optionalDependencies或peerDependencies中声明的外部模块。将使用最接近的父package.json。
"import/no-dynamic-require": 1, // CommonJS的require方法用于从不同文件导入模块。与ES6导入语法不同,可以为其提供将在运行时解析的表达式。虽然这有时是必要且有用的,但在大多数情况下并非如此。使用表达式(例如,连接路径和变量)作为参数使得工具更难以进行静态代码分析,或者在代码库中找到使用模块的位置。
"import/extensions": 0, // 某些文件解析算法允许您在导入源路径中省略文件扩展名。例如,节点解析器可以将./foo/bar解析为绝对路径/User/someone/foo/bar.js,因为默认情况下会自动解析.js扩展名。根据解析程序,您可以配置更多扩展程序以自动解决。
"import/no-unresolved": 0, // 确保导入的模块可以解析为本地文件系统上的模块,如标准Node require.resolve行为所定义。
"import/prefer-default-export": 1, // 当模块中只有一个导出时,更喜欢使用默认导出而不是命名导出。
"vue/no-async-in-computed-properties": 1, // 计算属性应该是同步的。其中的异步操作可能无法按预期工作,并可能导致意外行为,这就是您应该避免它们的原因。如果您需要异步计算属性,可能需要考虑使用其他插件[vue-async-computed]
"vue/no-side-effects-in-computed-properties": 1, // 在计算属性中引入副作用被认为是一种非常糟糕的做法。它使代码无法预测且难以理解。
"vue/no-reserved-keys": 1, // 此规则阻止使用保留名称以避免冲突和意外行为。
"vue/require-v-for-key": 2, // 当v-for写在自定义组件上时,它需要同时使用v-bind:key。在其他元素上,v-bind:key也最好写。
"vue/require-valid-default-prop": 1, // 此规则检查每个prop的默认值是否对给定类型有效。当使用函数未返回类型Array或Object的默认值时,它应报告错误。
"no-unused-vars": 1, // 禁止出现未使用过的变量
"generator-star-spacing": 0, // 强制 generator 函数中 * 号周围使用一致的空格
"no-plusplus": 0, // 禁用一元操作符 ++ 和 --
"func-names": 0, // 要求或禁止使用命名的 function 表达式
"no-console": 0, // no-console
radix: 0, // 强制在parseInt()使用基数参数
"no-control-regex": 0, // 禁止在正则表达式中使用控制字符
"no-continue": 0, // 禁用 continue 语句
"no-debugger": process.env.NODE_ENV === "production" ? 2 : 0,
"no-param-reassign": 1, // 禁止对 function 的参数进行重新赋值
"no-underscore-dangle": 1, // 禁止标识符中有悬空下划线"_"
"global-require": 1, // 要求 require() 出现在顶层模块作用域中
"no-var": 1, // 要求使用 let 或 const 而不是 var
"vars-on-top": 1, // 要求所有的 var 声明出现在它们所在的作用域顶部
"prefer-destructuring": 1, // 优先使用数组和对象解构
"no-useless-concat": 1, // 禁止不必要的字符串字面量或模板字面量的连接
"no-shadow": 1, // 禁止变量声明与外层作用域的变量同名
"guard-for-in": 1, // 要求 for-in 循环中有一个 if 语句,旨在防止使用for in循环而不过滤循环中的结果时可能出现的意外行为。
"no-restricted-syntax": 1, // 禁用特定的语法
"global-require": 1, // 要求 require() 出现在顶层模块作用域中
"consistent-return": 1, // 要求 return 语句要么总是指定返回的值,要么不指定
eqeqeq: 1, // 要求使用 === 和 !==
"no-unused-expressions": 1, // 禁止出现未使用过的表达式
camelcase: 1, // 强制使用骆驼拼写法命名约定
"block-scoped-var": 1, // 强制把变量的使用限制在其定义的作用域范围内,旨在减少绑定上下文之外的变量的使用,并从其他语言模拟传统的块范围。这是为了帮助语言新手避免变量提升的难题。
"no-redeclare": 1, // 禁止多次声明同一变量
"prefer-arrow-callback": 1, // 要求回调函数使用箭头函数
"array-callback-return": 1, // 强制数组方法的回调函数中有 return 语句,Array有几种过滤,映射和折叠的方法。如果我们忘记return在这些回调中写入语句,那可能是一个错误。
"default-case": 1, // 要求 switch 语句中有 default 分支
"no-loop-func": 1, // 禁止在循环中出现 function 声明和表达式
"no-fallthrough": 1, // 禁止 case 语句落空
"no-multi-assign": 1, // 禁止连续赋值
"no-lonely-if": 1, // 禁止 if 作为唯一的语句出现在 else 语句中.如果一个if陈述是该else块中唯一的陈述,那么使用一个else if表格通常会更清晰。
"no-irregular-whitespace": 1, // 禁止在字符串和注释之外不规则的空白
"prefer-const": 1, // 要求使用 const 声明那些声明后不再被修改的变量.如果一个变量从不重新分配,使用const声明更好。const 声明告诉读者,“这个变量永远不会被重新分配,”减少认知负荷并提高可维护性。
"no-use-before-define": 1, // 禁止在变量定义之前使用它们
"no-useless-escape": 1, // 禁用不必要的转义字符
"no-array-constructor": 1, // 禁用 Array 构造函数,由于单参数的缺陷以及Array全局可能被重新定义,所以通常不鼓励使用构造函数来构造新Array数组,而是倾向于使用数组文字符号。例外情况是Array构造函数用于通过给构造函数一个数字参数有意创建指定大小的稀疏数组。
"object-shorthand": 1, // 要求或禁止对象字面量中方法和属性使用简写语法
"no-prototype-builtins": 1, // 禁止直接调用 Object.prototypes 的内置属性.当假定对象将具有属性时,这可能导致错误Object.prototype。此规则可防止Object.prototype直接从对象调用方法。
"no-nested-ternary": 1, // 禁用嵌套的三元表达式.嵌套三元表达式会使代码更难理解。
"no-new-wrappers": 1, // 禁止对 String,Number 和 Boolean 使用 new 操作符.没有任何理由将这些基本包装用作构造函数
"prefer-promise-reject-errors": 1, // 要求使用 Error 对象作为 Promise 拒绝的原因
"no-labels": 1 // 禁用标签语句
}
};

.prettierrc

1
2
3
4
5
6
7
8
9
10
module.exports = {
printWidth: 80, //一行的字符数,如果超过会进行换行,默认为80
tabWidth: 2, //一个tab代表几个空格数,默认为80
useTabs: false, //是否使用tab进行缩进,默认为false,表示用空格进行缩减
singleQuote: true, //字符串是否使用单引号,默认为false,使用双引号
semi: true, //行位是否使用分号,默认为true
trailingComma: "es5", //是否使用尾逗号,有三个可选值"<none|es5|all>"
bracketSpacing: true //对象大括号直接是否有空格,默认为true,效果:{ foo: bar }
// parser: 'babylon', //代码的解析引擎,默认为babylon,与babel相同。
};

.vscode/setting.json

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
{
// 使用2个空格作为tab,并将对齐基准线设置为2个字符test
"editor.tabSize": 2,
// 保存文件时自动格式化,主要针对html/css/less/scss等eslint未覆盖的文件格式
// "editor.formatOnSave": true,
// 保存文件时按照eslint配置自动处理vue/js/jsx/ts/json文件格式
// "eslint.autoFixOnSave": true,
// 打开对vue的lint,并自动fix
"eslint.validate": [
"javascript",
"javascriptreact",
{
"language": "vue",
"autoFix": true
}
],
// 对于.vue文件,关闭prettier,交给eslint fix
"vetur.format.defaultFormatter.css": "none",
"vetur.format.defaultFormatter.html": "none",
"vetur.format.defaultFormatter.js": "none",
"vetur.format.defaultFormatter.less": "none",
"vetur.format.defaultFormatter.postcss": "none",
"vetur.format.defaultFormatter.scss": "none",
"vetur.format.defaultFormatter.stylus": "stylus-supremacy",
"vetur.format.defaultFormatter.ts": "none",

/* stylus 配置 start */
// 是否插入冒号
"stylusSupremacy.insertColons": false,
// 是否插入分号
"stylusSupremacy.insertSemicolons": false,
// 是否插入大括号
"stylusSupremacy.insertBraces": false,
// import之后是否换行
"stylusSupremacy.insertNewLineAroundImports": false,
// 两个选择器中是否换行
"stylusSupremacy.insertNewLineAroundBlocks": false
/* stylus 配置 end */
}


后记

  • 代码格式化相关的文章已经汗牛充栋,关键点不在于各种圣战,而在于团队风格统一
  • vue 格式文件格式化比较特殊,template/script/style 部分由不同的插件来完成
  • 通过统一 IDE/插件/配置文件实现:
    • 自动格式化前端开发常见文件,实现团队代码风格统一
    • 杜绝因格式问题导致的提交冲突
    • 统一配置,团队共享,实现同步
  • 搞清楚各种 linter/formater/IDE 插件/npm 插件的分工/优先级很重要
  • ts 解决方案/git commit lint/eslint webpack loader 应该是更好也是更严格的方案,目前暂未涉及,将会是以后努力的方向

欢迎拍砖,欢迎交流

本文完

七牛把用户当猴耍呢,一生黑

Posted on 2018-12-06 | In power user of everything

七牛云速度还是可以的,也算厚道,一直免费给你一个二级域名用,10G/月的免费流量对于我也够用。

但是最近估计有人用图层上传了不和谐的东西(这些毒瘤也该死),导致七牛云收回了二级域名使用权,之前上传到图层的文件都报错“no such domain”。

那好吧,我看看怎么挽回,一看就傻眼了:

  • 想继续用七牛云
    • 可以,先绑自己域名
  • OK,我绑还不行吗?
    • 域名要备案
  • 备 NMB 案,老子不用了,批量下载
    • 没有批量下载 GUI
  • 我写脚本下载
    • 原来送的二级域名收回了,所有图片都没办法访问了。但是有 shell 工具可以批量下载
  • 那我试试 shell
    • 原来送的二级域名收回了,没办法获取下载地址

意思是七牛收回二级域名了,不仅外网无法访问你的资源,你自己也没有办法在后台操作了,如果你之前没备份,就瓜起了

不说了,七牛一生黑

  • 有补救办法吗?
    • 备(NMB)案

好在天无绝人之路,曲线救国的方法

  1. 重新创建一个测试 bucket(会分配一个新的测试域名,有限期 30 天)
  2. batchcopy 原 bucket 到新的 bucket
  3. qdownload 新 bucket

要用到的工具:qshell

这个命令行工具 api 据我观察最近已经和两个月前不兼容了(黑点 2)

目前主要关注batchcopy和qdownload

鉴于 api 经常变就不贴命令了,自己看文档吧。

删 bucket,走人

macOs 下设置Capslock切换输入法

Posted on 2018-12-05 | In power user of everything

如果你有以下需求,不妨一试:

  • 使用搜狗输入法(为了词库)
  • 外接键盘,想实现内置/外置键盘的 cmd 和 opt 位置一致
  • 想用 Capslock 一键切换中/英

预防杠精:

系统自带拼音输入法/搜狗输入法都可以设置 caps 切换中英,为何折腾?

答:很多场景,例如各种登录的 pwd input 获得焦点时,系统会自动把输入法切换为自带的英语输入法,这时你是不知情的,你不得不用 ctrl + space 切换回中文输入法。这个过程需要确认,有种反复插拔 usb 的感觉。

你把默认的英文输入法删除了不就好了?

答:首先删不掉,10.14 之前有方法可以 hack,但不推荐,有坑,而且不安全。

实现方法

下载Karabiner,安装之,重启系统

Karabiner是一个 mac 下修改键盘映射的工具

关闭搜狗的中英切换快捷键

此步骤在于避免误操作,从此以后只有两种输入法:英文/中文,互相的状态也单一,纯粹

设置切换输入法的快捷键为 command+control+option+shift+p

我知道默认的快捷键是ctrl+space,设成这个几乎不会用到的快捷键,可以省出ctrl+space,设置成更常用的功能

利用 Karabiner 将Capslock映射为command+control+option+shift+p

配置文件地址在 ~/.config/karabiner/karabiner.json,这里只贴出关键配置

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
"complex_modifications": {
"parameters": {
"basic.simultaneous_threshold_milliseconds": 50,
"basic.to_delayed_action_delay_milliseconds": 500,
"basic.to_if_alone_timeout_milliseconds": 1000,
"basic.to_if_held_down_threshold_milliseconds": 500
},
"rules": [
{
"manipulators": [
{
"description": "Change caps_lock to command+control+option+shift+p.",
"from": {
"key_code": "caps_lock",
"modifiers": {
"optional": ["any"]
}
},
"to": [
{
"key_code": "p",
"modifiers": [
"left_command",
"left_control",
"left_option",
"left_shift"
]
}
],
"type": "basic"
}
]
}
]
}

交换 cmd/opt

保证外接键盘的键位和内置键盘一样,不然会疯掉

后记

按照以上设置,可以实现不用考虑内置/外置键盘,只需要 caps 就能在中/英之间切换,就算 pwd input 自动切换成英文输入法了,只要发现了点一下 caps 就好,不用再反复确认到底是输入法切换了还是中英状态切换了
设置开机启动什么的不赘述了

缺点

大小写指示灯再也不会亮了

本文完。

一周网摘2018-11-w5

Posted on 2018-11-30 | In 杂

每个 JavaScript 工程师都应懂的 33 个概念 @leonardomso

这个项目是为了帮助开发者掌握 JavaScript 概念而创立的。它不是必备,但在未来学习(JavaScript)中,可以作为一篇指南。

本篇文章是参照 @leonardomso 创立,英文版项目地址在这里。 由于原版资源都要翻墙,所以本人创立一个中文版,附上关于这些概念在国内的一些文章和视频。 若有觉得更好的文章或者视频,可以贡献出来,觉得有误的,请联系我删除。


Science Fiction Interfaces(汤不热好像要科学上网)

![](/pic/sinaimg/006tNbRwgy1fxlac0gfjyj30zk0k0gp2.jpg)

一些科幻作品里出现的电脑操作 UI 界面


ScriptOJ

![](/pic/sinaimg/006tNbRwgy1fxlaf9lu74j31350u01kx.jpg)

ScriptOJ 是首个 Web 前端开发评测系统
从大量实战代码、面试题目中总结出精华题库和相应的测试
帮助你提升、锻炼 Web 开发技能,简单直接地获取第一手 Web 前端实战经验。


HTML5 声音引擎 Howler.js

Howler.js 支持很多声音格式以兼容各种浏览器。MP3, MPEG, OPUS, OGG, OGA, WAV, AAC, CAF, M4A, MP4, WEBA, WEBM, DOLBY, FLAC.


macOS Mojave 上的 launchrocket 凉了

“That’s really unfortunate. That probably means this prefpane is effectively dead.”

官宣

不过有替代方案

1
brew services list

and then

1
brew services start xxx(your service)

每月电影2018-10

Posted on 2018-11-19 | In movies

动物世界 (2018)

动物世界

豆瓣评分: 7.3/10
个人评分: 7.5/10

漫画改编,完成度和工业化程度在大陆电影中可称翘楚。如果主演不是李易峰和周冬雨可能还有加分

不足之处在于导演炫技痕迹明显且无必要


奇迹

奇迹

豆瓣评分: 8.8/10
个人评分: 8.5/10

是枝裕和为新干线拍的命题作文

小朋友的视角与世界已经太久没有体会了,温暖,纯粹


无人知晓

无人知晓

豆瓣评分: 9.1/10
个人评分: 8.8/10

【西巢鸭弃婴事件】改编,人类的不负责任/不作为是一种极端的恶,人性之下是兽性


网络谜踪 Searching (2018)

网络谜踪

豆瓣评分: 8.5/10
个人评分: 8.5/10

据了解应该不是第一部以电脑屏幕为呈现场景的电影,但却是我看的第一部。至少形式上很震撼

教科书般的本格派推理,真相导演其实早就预埋在正品之中

韩国周杰伦跑了一万年龙套终于接了部好电影


需避坑:

  • 七月与安生 (2016),除了狗血还是狗血
  • 蚁人2:黄蜂女现身 Ant-Man and the Wasp (2018),格局小得可怕

一周网摘2018-09-w2

Posted on 2018-09-08 | In 杂

nginxconfig.io

![](/pic/20180910/nginxconfig.io.jpg)

比较懒不想写 Nginx 配置?可以去 nginxconfig.io 在线生成一套,有前端(MVVM)、PHP 后端、Node.js、单页应用、WordPress 等多个预置模板,一般需求稍微改改就够了。


口红色号名称 - RGB 颜色值

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
{
"brands": [{
"name": "圣罗兰",
"series": [{
"name": "莹亮纯魅唇膏",
"lipsticks": [{
"color": "#D62352",
"id": "49",
"name": "撩骚"
}, {
"color": "#DC4B41",
"id": "14",
"name": "一见倾心"
}, {
"color": "#B22146",
"id": "05",
"name": "浮生若梦"
}, {
"color": "#A25356",
"id": "08",
"name": "纯真梦幻"
},
...
}, {
"name": "香奈儿可可小姐",
"series": [{
"name": "唇膏水亮",
"lipsticks": [{
"id": "69",
"color": "#F17365",
"name": "传情"
},
...

“老婆你看我还是很疼你的”


精辟

这就好像说寺庙门口阮老师在给穷人施粥,这时候一个(伪)美食家走了过来,拿起勺子在桶里搅来搅去,然后从桶底捞出了一根头发,接着就大声的向大家喊到:
快来看,这个人做的粥有问题,何止是有问题,简直是完全错误的。
阮老师让很多人从饿肚子到吃饱饭,但它可能确实就是清粥白饭,偶尔也有点瑕疵。
但那些高喊着大家要吃燕窝鲍鱼的人,你们倒是能长年累月的拿出来分给大家啊。
结果这些人只是说着风凉话,看着热闹,最后还一哄而上砸了人家的摊子。
你说你们是不是有病

via 如何看待文章《面试官:阮一峰版的快速排序完全是错的》? - 王德福的回答 - 知乎


visualgo.net

![](/pic/20180910/visualgo.jpg)

推荐一个算法可视化项目,常见的算法基本都找的到,并且每一步都会动态演示出来,不过有点美中不足的是连伪代码都顺手翻译了(看到“做…while”这种组合挺懵逼的……不习惯的话可以切英文版),初学算法的话可以看一看。

微信对我来说只是IM+支付工具,仅此而已

Posted on 2018-09-03 | In power user of everything

前言

曾几何时,每次点亮手机屏幕,微信的图标上面必然会有未读提醒,强迫症的你点进去以后却发现是某公众号的日经广告推送。关掉公众号信息提醒吧,又看不到文章;不关吧过了几分钟又弹出来一篇“震惊”。

是时候作出改变了。

微信的平台化

还记得微信刚刚诞生时,“免费发短信”是其唯一卖点。那时的我,支付使用支付宝,阅读主要靠 RSS,微信的出现似乎对于我来说没什么影响。

后来的微信逐渐往平台发展:

  • 摇一摇(陌生人社交)
  • 朋友圈(Facebook of China)
  • 公众号(干掉博客)
  • 小程序(appstore in 微信)

平台化的微信极大的降低了互联网小白用户的使用门槛:记不住网站域名?-没关系,直接找认证过的公众号;不会用浏览器收藏夹?-微信自带“收藏功能”;不会分享链接?二维码在每篇 post 底部都有。

微信让那些曾经对于电脑和智能手机望而却步的大爷大妈每天刷得不亦乐乎,成为收割“国民总时间”的利器。

灾难

平台化的微信对我来说是个灾难。

我从来不喜欢在微信看文章,因为经常在你看文章的过程中,有好友消息来了,你不得不退出去回消息,再重新回到文章。这个“退出文章-回消息-重新寻找文章入口-返回阅读进度”的体验实在是太糟糕了。尽管微信最近的版本加入了文章悬浮球的功能,但也仅是聊胜于无。

自媒体概念的兴起已经从事实上杀死了独立 blogger。现在某个领域的内容创作者如果想发声,不大会注册域名,搭建独立博客。更好的选择是直接开个公众号,不管是运维还是推广成本都比搭建博客低太多。

从最近微信公众号改版加入信息瀑布流的举动来开,微信的公众号有点想接替 rss 的意思。但是且不谈互联网中立,单是公众号信息流无法分类,无法显示未读,仅有一个残废的置顶功能,它还远远不能满足我的需求。

微信阅读:曲线救国?

微信阅读可以直接把公众号作为文集加入书架,并可以整理分类,也可以显示更新,曾经有段时间我尝试使用它来阅读所有的微信公众号文章。但是微信阅读还是无法显示未读条数,且没有信息流。当你想集中阅读的时候,切换文章/切换文集/切换分类的操作还是让你想死。

重回 rss

还好 rss 还没死透。rsshub 等渠道还是可以订阅到所有的微信公号文章,甚至还有全文输出的 feed 可以在微信删帖前缓存文章内容。关于如何使用 rss 订阅公众号有时间再写篇文章。

上帝的归上帝,凯撒的归凯撒。

无论是屏幕尺寸的局限,还是多任务系统的羸弱,都注定了手机成不了生产工具。

现在我的微信仍保留的功能:

  • 朋友圈(熟人社交还是绕不过去)
  • 小程序(即用即搜,用完即走)
  • 支付(说句题外话,支付宝 vs 微信支付这件事上我却比较看好微信,毕竟支付宝能做的事微信都能做,微信能做的事支付宝却未必)

除了一些会员类和银行提醒类的公众号,再没关注任何其他公众号。

(全文完)

每月电影2018-09

Posted on 2018-08-09 | In movies

走到尽头 끝까지 간다 (2014)

豆瓣评分: 7.8/10
个人评分: 8.5/10

“这部电影没有设置正面人物和反面人物的对比。出场的所有警察几乎都是某种意义上的“坏警察”。但是这些坏警察都有自己的道德底线,他们贪钱但也能干,他们从罪犯那里捞钱,但不利用职务之便欺负平民,他们绝不杀人。这是“冷硬派”侦探故事的典型设定。更符合真实的复杂人性,而杜绝了脸谱化的说教味道。这是韩国主流电影的又一个致胜之处。题材的广泛和自由的表达。他们永远把叙述故事放到第一位,而非警世和教育。韩国电影之所以产生好故事,一个重要原因就是从不避讳所谓的“阴暗面”。你不去触及,那些暗面仍然存在,而你真的写了一群坏警察,也不会有人认为所有韩国警察都作恶多端。成年人看电影,尤其对主流故事片,看的就是虚幻的故事,进入情境,投射感情,抽离回现实,这就是全部。”

<i class="fa fa-angle-left" aria-label="Previous page"></i>12345<i class="fa fa-angle-right" aria-label="Next page"></i>

41 posts
10 categories
46 tags
GitHub E-Mail Twitter Douban Zhihu
© 2014 — 2025 Vincent He