JS库¶
链接: https://cloud.seatable.cn/dtable/external-links/59b453a8639945478de2/
husky¶
在 git commit 提交前,增加一个 pre-commit 的钩子,进行格式检测和单元测试
https://typicode.github.io/husky/get-started.html
npm install --save-dev husky
npx husky init
@babel/cli¶
babel 执行的命令行的 CLI
@babel/plugin-proposal-class-properties¶
Below is a class with four class properties which will be transformed. This https://babeljs.io/docs/en/babel-plugin-proposal-class-properties
@babel/plugin-proposal-export-default-from¶
Compile export default to ES2015 https://babeljs.io/docs/en/babel-plugin-proposal-export-default-from
@babel/plugin-proposal-export-namespace-from¶
Compile export namespace to ES2015 https://babeljs.io/docs/en/babel-plugin-proposal-export-namespace-from
@babel/plugin-proposal-object-rest-spread¶
Compile object rest and spread to ES5 https://babeljs.io/docs/en/babel-plugin-proposal-object-rest-spread
@babel/plugin-transform-member-expression-literals¶
Ensure that reserved words are quoted in property accesses https://babeljs.io/docs/en/babel-plugin-transform-member-expression-literals
@babel/plugin-transform-property-literals¶
Ensure that reserved words are quoted in object property keys https://babeljs.io/docs/en/babel-plugin-transform-property-literals
@babel/plugin-transform-runtime¶
Externalise references to helpers and builtins, automatically polyfilling your code without polluting globals https://babeljs.io/docs/en/babel-plugin-transform-runtime
@babel/preset-env¶
babel 预设编译后的JS代码的环境
@babel/preset-react¶
babel 编译 react 预设的库
@svgr/webpack¶
svg 文件loader https://www.npmjs.com/package/@svgr/webpack
@babel/core¶
babel 核心代码(编译es6) https://babeljs.io/docs/en/babel-core
@babel/node¶
babel-node 是一个 CLI,其工作方式与 Node.js CLI 完全相同,它的额外好处是在运行之前使用 Babel 预设和插件进行编译。 https://babeljs.io/docs/en/babel-node
@babel/plugin-transform-modules-commonjs¶
This plugin transforms ES2015 modules to CommonJS https://babeljs.io/docs/en/babel-plugin-transform-modules-commonjs
@babel/register¶
babel require hook https://www.npmjs.com/package/@babel/register
@babel/runtime¶
contains Babel modular runtime helpers and a version of regenerator-runtime https://babeljs.io/docs/en/babel-runtime
webpack-node-externals¶
babel-eslint¶
babel 代码规范检查 https://www.npmjs.com/package/eslint-plugin-babel
babel-jest¶
Babel jest plugin https://www.npmjs.com/package/babel-jest
babel-loader¶
This package allows transpiling JavaScript files using Babel and webpack. https://www.npmjs.com/package/babel-loader
babel-plugin-named-asset-import¶
babel 插件
babel-preset-react-app¶
This package includes the Babel preset used by Create React App. https://www.npmjs.com/package/babel-preset-react-app
case-sensitive-paths-webpack-plugin¶
这个 Webpack 插件强制所有必需模块的整个路径与磁盘上实际路径的确切大小写匹配。 使用此插件有助于缓解在 OSX 上工作的开发人员(不遵循严格的路径区分大小写)与其他开发人员或运行其他需要正确大小写路径的操作系统的构建框发生冲突的情况。 https://www.npmjs.com/package/case-sensitive-paths-webpack-plugin
css-loader¶
css 加载器
enzyme¶
Enzyme is a JavaScript Testing utility for React that makes it easier to test your React Components' output.
enzyme-adapter-react-¶
对 react 功能组件测试
Enzyme is a JavaScript Testing utility for React that makes it easier to test your React Components' output. You can also manipulate, traverse, and in some ways simulate runtime given the output.
eslint¶
代码格式检查
eslint-config-react-app¶
eslint 针对 react 的插件
eslint-loader¶
eslint 加载器
eslint-plugin-flowtype¶
ESLint 的流类型 linting 规则。
eslint-plugin-import¶
该插件旨在支持 ES6+ 导入/导出语法的 linting,并防止文件路径和导入名称拼写错误的问题
eslint-plugin-jsx-ay¶
用于 JSX 元素可访问性规则的静态 AST 检查器
eslint-plugin-react-hooks¶
This ESLint plugin enforces the Rules of Hooks. https://www.npmjs.com/package/eslint-plugin-react-hooks
html-webpack-plugin-beta¶
简化创建 HTML 文件以服务于打包的插件 https://www.npmjs.com/package/html-webpack-plugin
identity-obj-proxy¶
使用 ES6 代理的身份对象。 用于测试简单的 webpack 导入。 例如,您可以告诉 Jest 将此对象模拟为导入的 CSS 模块; 那么您在导入的样式对象上的所有 className 查找都将按原样返回。
jest-environment-jsdom-fourteen¶
jest 插件,可以在观察模式下,选择特定的单元测试执行,已经部署到个人项目中
jest-resolve¶
说明文档和 jest 在一个界面上
jest-watch-typeahead¶
Filter your tests by file name or test name
less¶
less 样式 The dynamic stylesheet language.
less-loader¶
less 加载器
mini-css-extract-plugin¶
css 按需加载(把CSS提取到不同的JS文件中)
optimize-css-assets-webpack-plugin¶
A Webpack plugin to optimize minimize CSS assets.
pnp-webpack-plugin¶
Webpack 的即插即用解析器
postcss-flexbugs-fixes¶
PostCSS plugin This project tries to fix all of flexbug's issues.
postcss-loader¶
postcss 加载器
postcss-normalize¶
PostCSS Normalize lets you use the parts of normalize.css or sanitize.css that you need from your browsers list.
postcss-preset-env¶
CSS 兼容不用版本早期的浏览器。
PostCSS Preset Env lets you convert modern CSS into something most browsers can understand, determining the polyfills you need based on your targeted browsers or runtime environments.
postcss-safe-parser¶
PostCSS 的容错 CSS 解析器,它将发现和修复语法错误,能够解析任何输入。
sass-loader¶
sass 加载器
style-loader¶
样式加载器
terser-webpack-plugin¶
This plugin uses terser to minify your JavaScript. 压缩JS https://www.npmjs.com/package/terser-webpack-plugin
webpack¶
webpack 打包工具
webpack-cli¶
webpack 命令行工具
webpack-dev-server¶
webpack 开发环境打包服务器
webpack-manifest-plugin¶
生成资源清单
module.exports = {
plugins: [
new ManifestPlugin()
]
}
workbox-webpack-plugin¶
https://developers.google.com/web/tools/workbox/modules/workbox-webpack-plugin
eslint-plugin-react¶
React specific linting rules for ESLint
file-loader¶
The file-loader resolves import/require() on a file into a url and emits the file into the output directory.
resolve-url-loader¶
这个 webpack 加载器允许你拥有一个分布式的 SCSS 文件集,以及与这些 SCSS 文件共存的资源。
webpack-bundle-tracker¶
将有关 webpack 编译过程的一些统计信息,记录到文件中。(tracker 追踪者)
和 webpack nodejs 存在兼容性问题。
This project is compatible with NodeJS versions 16 and up.
⚠️ Starting on version 17, NodeJS uses OpenSSL v3 which has compatibility issues with Webpack\@4.
This isn't an issue for Webpack\@5
however if you're using Node >= 17 and Webpack\@4, to properly use this package you must ensure to set the NODE_OPTIONS=--openssl-legacy-provider environment variable.
官方案例
var path = require('path');
var BundleTracker = require('webpack-bundle-tracker');
module.exports = {
context: __dirname,
entry: {
app: ['./app'],
},
output: {
path: path.resolve('./assets/bundles/'),
filename: '[name]-[hash].js',
publicPath: 'http://localhost:3000/assets/bundles/',
},
// 设置统计文件的存储路径和文件名
plugins: [
new BundleTracker({
path: path.join(__dirname, 'assets'),
filename: 'webpack-stats.json',
}),
],
};
实际项目使用,根据不同环境配置了不同的统计文件
new webpackBundleTracker({
filename: isEnvProduction ? './webpack-stats.pro.json' : './webpack-stats.dev.json',
publicPath: isEnvProduction ? '' : paths.publicUrlOrPath
}),
统计文件:webpack-stats.pro.json 提供了每一个资源文件的名称和路径,每一个 chunks 引用的资源(通常是 common + others)
{
"status": "done",
"assets": {
"static/css/app.58d2e6dd.css": {
"name": "static/css/app.58d2e6dd.css",
"path": "/build/frontend/static/css/app.58d2e6dd.css"
},
"static/css/commons.d6c420b4.css": {
"name": "static/css/commons.d6c420b4.css",
"path": "/build/frontend/static/css/commons.d6c420b4.css"
},
"static/css/draft.299cd106.css": {
"name": "static/css/draft.299cd106.css",
"path": "/build/frontend/static/css/draft.299cd106.css"
}
},
"chunks": {
"app": [
"static/js/runtime.e32c54a5.js",
"static/css/commons.d6c420b4.css",
"static/js/commons.e891325f.js",
"static/css/app.58d2e6dd.css",
"static/js/app.011a7734.js"
],
"draft": [
"static/js/runtime.e32c54a5.js",
"static/css/commons.d6c420b4.css",
"static/js/commons.e891325f.js",
"static/css/draft.299cd106.css",
"static/js/draft.e9f03bdc.js"
],
"wiki": [
"static/js/runtime.e32c54a5.js",
"static/css/commons.d6c420b4.css",
"static/js/commons.e891325f.js",
"static/css/wiki.30e6b692.css",
"static/js/wiki.41704f71.js"
],
"wiki2": [
"static/js/runtime.e32c54a5.js",
"static/css/commons.d6c420b4.css",
"static/js/commons.e891325f.js",
"static/css/wiki2.89e72cc3.css",
"static/js/wiki2.1aa50e13.js"
]
}
}
babel-register¶
The require hook will bind itself to node's require and automatically compile files on the fly.
clean-webpack-plugin¶
A webpack plugin to remove/clean your build folder(s).
webpack-merge¶
webpack-merge - Merge designed for Webpack
grunt¶
https://github.com/gruntjs/grunt
grunt 是 js 的任务运行器,可以自动化执行压缩,打包,测试等。实际项目使用不多,了解即可。
Why use a task runner? In one word: automation. The less work you have to do when performing repetitive tasks like minification, compilation, unit testing, linting, etc, the easier your job becomes. After you've configured it through a Gruntfile, a task runner can do most of that mundane work for you—and your team—with basically zero effort.
类似 webpack,这里需要配置一个 Gruntfile.js 文件,然后运行进行编译打包
module.exports = function(grunt) {
// 初始化配置
grunt.initConfig({
jshint: {
files: ['Gruntfile.js', 'src/**/*.js', 'test/**/*.js'],
options: {
globals: {
jQuery: true
}
}
},
watch: {
files: ['<%= jshint.files %>'],
tasks: ['jshint']
}
});
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.registerTask('default', ['jshint']);
};
gulp¶
gulp 是一个前端构建工具,支持自动化和工作流
A toolkit to automate & enhance your workflow
Leverage gulp and the flexibility of JavaScript to automate slow, repetitive workflows and compose them into efficient build pipelines.
配置文件:gulpfile.js
const { series } = require('gulp');
// The `clean` function is not exported so it can be considered a private task.
// It can still be used within the `series()` composition.
function clean(cb) {
// body omitted
cb();
}
// The `build` function is exported so it is public and can be run with the `gulp` command.
// It can also be used within the `series()` composition.
function build(cb) {
// body omitted
cb();
}
exports.build = build;
exports.default = series(clean, build);
video.js¶
视频播放器
这个库比较大,打包压缩后也有 1mb
watermark-dom¶
https://www.npmjs.com/package/watermark-dom
watermark.js是一个给B/S网站系统加水印的插件,确保系统保密性,安全性,降低数据泄密风险。
@typescript-eslint/eslint-plugin¶
An ESLint plugin which provides lint rules for TypeScript codebases. https://www.npmjs.com/package/@typescript-eslint/eslint-plugin
@typescript-eslint/parser¶
An ESLint parser which leverages TypeScript ESTree to allow for ESLint to lint TypeScript source code. https://www.npmjs.com/package/@typescript-eslint/parser
connect-multiparty¶
上传文件的中间件
csv¶
nodeJS 中数据类型和 csv 转换器
CSV for Node.js and the web
version¶
6.3.9
downloads¶
1,330,572
repository¶
github.com/adaltas/node-csv
homepage¶
csv.js.org
The csv project provides CSV generation, parsing, transformation and serialization for Node.js.
It has been tested and used by a large community over the years and should be considered reliable. It provides every option you would expect from an advanced CSV parser and stringifier.
This package exposes 4 packages:
-
csv-generate (GitHub), a flexible generator of CSV string and Javascript objects.
-
csv-parse (GitHub), a parser converting CSV text into arrays or objects.
-
csv-stringify (GitHub), a stringifier converting records into a CSV text.
-
stream-transform (GitHub), a transformation framework.
The full documentation for the current version is available here.
Usage¶
Installation command is npm install csv.
Each package is fully compatible with the Node.js stream 2 and 3 specifications. Also, a simple callback-based API is always provided for convenience.
Sample¶
This example uses the Stream API to create a processing pipeline.
// Import the package
import * as csv from '../lib/index.js';
// Run the pipeline
csv
// Generate 20 records
.generate({
delimiter: '|',
length: 20
})
// Transform CSV data into records
.pipe(csv.parse({
delimiter: '|'
}))
// Transform each value into uppercase
.pipe(csv.transform((record) => {
return record.map((value) => {
return value.toUpperCase();
});
}))
// Convert objects into a stream
.pipe(csv.stringify({
quoted: true
}))
// Print the CSV stream to stdout
.pipe(process.stdout);
Development¶
This parent project doesn't have tests itself but instead delegates the tests to its child projects.
Read the documentation of the child projects for additional information.
Related projects¶
-
Pavel Kolesnikov "ya-csv": http://github.com/koles/ya-csv
-
Chris Williams "node-csv": http://github.com/voodootikigod/node-csv
-
Mat Holt "PapaParse": https://github.com/mholt/PapaParse
date-format¶
nodeJS 日期对象转换成字符串
detect-character-encoding¶
Detect character encoding using ICU
etcd¶
分布式集群部署 etcd3
iconv-lite¶
字符串不同格式转码
version¶
0.6.3
downloads¶
74,008,351
repository¶
github.com/ashtuchkin/iconv-lite
homepage¶
github.com/ashtuchkin/iconv-lite
iconv-lite: Pure JS character encoding conversion¶
-
No need for native code compilation. Quick to install, works on Windows and in sandboxed environments like Cloud9.
-
Used in popular projects like Express.js (body_parser), Grunt, Nodemailer, Yeoman and others.
-
Faster than node-iconv (see below for performance comparison).
-
Intuitive encode/decode API, including Streaming support.
-
In-browser usage via browserify or webpack (~180kb gzip compressed with Buffer shim included).
-
Typescript type definition file included.
-
React Native is supported (need to install stream module to enable Streaming API).
-
License: MIT.
Usage¶
Basic API¶
var iconv = require('iconv-lite');
// Convert from an encoded buffer to a js string.
str = iconv.decode(Buffer.from([0x68, 0x65, 0x6c, 0x6c, 0x6f]), 'win1251');
// Convert from a js string to an encoded buffer.
buf = iconv.encode("Sample input string", 'win1251');
// Check if encoding is supported
iconv.encodingExists("us-ascii")
Streaming API ¶
// Decode stream (from binary data stream to js strings)
http.createServer(function(req, res) {
var converterStream = iconv.decodeStream('win1251');
req.pipe(converterStream);
converterStream.on('data', function(str) {
console.log(str); // Do something with decoded strings, chunk-by-chunk.
});
});
// Convert encoding streaming example
fs.createReadStream('file-in-win1251.txt')
.pipe(iconv.decodeStream('win1251'))
.pipe(iconv.encodeStream('ucs2'))
.pipe(fs.createWriteStream('file-in-ucs2.txt'));
// Sugar: all encode/decode streams have .collect(cb) method to accumulate data.
http.createServer(function(req, res) {
req.pipe(iconv.decodeStream('win1251')).collect(function(err, body) {
assert(typeof body == 'string');
console.log(body); // full request body string
});
});
Supported encodings¶
-
All node.js native encodings: utf8, ucs2 / utf16-le, ascii, binary, base64, hex.
-
Additional unicode encodings: utf16, utf16-be, utf-7, utf-7-imap, utf32, utf32-le, and utf32-be.
-
All widespread singlebyte encodings: Windows 125x family, ISO-8859 family, IBM/DOS codepages, Macintosh family, KOI8 family, all others supported by iconv library. Aliases like 'latin1', 'us-ascii' also supported.
-
All widespread multibyte encodings: CP932, CP936, CP949, CP950, GB2312, GBK, GB18030, Big5, Shift_JIS, EUC-JP.
See all supported encodings on wiki.
Encoding/decoding speed¶
Comparison with node-iconv module (1000x256kb, on MacBook Pro, Core i5/2.6 GHz, Node v0.12.0). Note: your results may vary, so please always check on your hardware.
BOM handling¶
-
Decoding: BOM is stripped by default, unless overridden by passing stripBOM: false in options (f.ex. iconv.decode(buf, enc, {stripBOM: false})). A callback might also be given as a stripBOM parameter - it'll be called if BOM character was actually found.
-
If you want to detect UTF-8 BOM when decoding other encodings, use node-autodetect-decoder-stream module.
-
Encoding: No BOM added, unless overridden by addBOM: true option.
UTF-16 Encodings¶
This library supports UTF-16LE, UTF-16BE and UTF-16 encodings. First two are straightforward, but UTF-16 is trying to be smart about endianness in the following ways:
-
Decoding: uses BOM and 'spaces heuristic' to determine input endianness. Default is UTF-16LE, but can be overridden with defaultEncoding: 'utf-16be' option. Strips BOM unless stripBOM: false.
-
Encoding: uses UTF-16LE and writes BOM by default. Use addBOM: false to override.
UTF-32 Encodings¶
This library supports UTF-32LE, UTF-32BE and UTF-32 encodings. Like the UTF-16 encoding above, UTF-32 defaults to UTF-32LE, but uses BOM and 'spaces heuristics' to determine input endianness.
-
The default of UTF-32LE can be overridden with the defaultEncoding: 'utf-32be' option. Strips BOM unless stripBOM: false.
-
Encoding: uses UTF-32LE and writes BOM by default. Use addBOM: false to override. (defaultEncoding: 'utf-32be' can also be used here to change encoding.)
Other notes¶
When decoding, be sure to supply a Buffer to decode() method, otherwise badthings usually happen.
Untranslatable characters are set to � or ?. No transliteration is currentlysupported.
Node versions 0.10.31 and 0.11.13 are buggy, don't use them (see #65, #77).
jsonwebtoken¶
服务端 JWT 登录验证
request¶
http 网络请求工具
socket.io¶
socket 服务端程序
uuid¶
生成 UUID
form-data¶
A library to create readable "multipart/form-data" streams. Can be used to submit forms and file uploads to other web applications.
https://www.npmjs.com/package/form-data
jest¶
单元测试工具
https://www.npmjs.com/package/jest
🃏 Delightful JavaScript Testing
-
👩🏻💻 Developer Ready : Complete and ready to set-up JavaScript testing solution. Works out of the box for any React project.
-
🏃🏽 Instant Feedback : Failed tests run first. Fast interactive mode can switch between running all tests or only test files related to changed files.
-
📸 Snapshot Testing : Jest can capture snapshots of React trees or other serializable values to simplify UI testing.
version¶
29.7.0
downloads¶
23,497,819
repository¶
github.com/jestjs/jest
homepage¶
jestjs.io/
supertest¶
HTTP assertions made easy via superagent. npmjs.com/package/supertest
chartjs¶
chartjs
version¶
0.3.24
downloads¶
10,662
repository¶
homepage¶
github.com/timer/chartjs#readme
Chart is a simple and functional charting library which currently supports bar charts. Implementations are done on-top of a HTML5 canvas element.
excalidraw¶
一个前端画图工具,效果不错,目前项目中使用
77K stars 周下载量 7万
https://docs.excalidraw.com/docs/@excalidraw/excalidraw/integration
https://www.npmjs.com/package/@excalidraw/excalidraw
https://github.com/excalidraw/excalidraw
import { Excalidraw } from "@excalidraw/excalidraw";
function App() {
return (
<>
<h1 style={{ textAlign: "center" }}>Excalidraw Example</h1>
<div style={{ height: "500px" }}>
<Excalidraw />
</div>
</>
);
}



sw-precache-webpack-plugin¶
SWPrecacheWebpackPlugin 是一个 webpack 插件,用于使用 service worker 缓存外部项目依赖项。 它将使用 sw-precache 生成一个 Service Worker 文件并将其添加到您的构建目录中。 https://www.npmjs.com/package/sw-precache-webpack-plugin
unified¶
AST 转换器
url-parse¶
Url 对象转换工具
vfile¶
解析序列化转换数据
@testing-library/user-event¶
以与用户相同的方式触发事件 https://www.npmjs.com/package/@testing-library/user-event
@reach/router¶
react-router 的增强版
resumablejs¶
大文件分块上传下载
chart.js¶
前端 canvas 绘图
classnames¶
组合 HTML 中的类名
周下载量 1000 万
const classNames = require('classnames');
classNames('foo', 'bar'); // => 'foo bar'
classNames('foo', { bar: true }); // => 'foo bar'
classNames({ 'foo-bar': true }); // => 'foo-bar'
classNames({ 'foo-bar': false }); // => ''
classNames({ foo: true }, { bar: true }); // => 'foo bar'
classNames({ foo: true, bar: true }); // => 'foo bar'
// lots of arguments of various types
classNames('foo', { bar: true, duck: false }, 'baz', { quux: true }); // => 'foo bar baz quux'
// other falsy values are just ignored
classNames(null, false, 'bar', undefined, 0, 1, { baz: null }, ''); // => 'bar 1'
copy-to-clipboard¶
复制内容到剪切板
https://www.npmjs.com/package/copy-to-clipboard
周下载量 500万
import copy from 'copy-to-clipboard';
copy('Text');
// Copy with options
copy('Text', {
debug: true,
message: 'Press #{key} to copy',
});
faker¶
模拟请求假数据
immutability-helper¶
react 中不可变元素复制的库
konva¶
canvas 在线图形编辑工具
MD5¶
生成字符串对应的 md5 加密结果
merge¶
合并对象(Object.assign)
moment¶
时间转换显示 时间处理
object-assign¶
兼容早期浏览器中的 Object.assign
prismjs¶
代码片段高亮
prop-types¶
类型验证(react)
resolve¶
实现节点 require.resolve() 算法,以便您可以异步和同步地代表文件 require.resolve() https://www.npmjs.com/package/resolve
semver¶
npm 的语义版本器 https://www.npmjs.com/package/semver
ts-pnp¶
https://www.npmjs.com/package/semver npm 的语义版本器
url-loader¶
loader for transforms files into base64 URIs. https://www.npmjs.com/package/url-loader
number-precision¶
小数精确计算
数字精确计算,大量使用有性能问题
https://www.npmjs.com/package/number-precision
周下载量 3W,星星 4K
import NP from 'number-precision'
NP.strip(0.09999999999999998); // = 0.1
NP.plus(0.1, 0.2); // = 0.3, not 0.30000000000000004
NP.plus(2.3, 2.4); // = 4.7, not 4.699999999999999
NP.minus(1.0, 0.9); // = 0.1, not 0.09999999999999998
NP.times(3, 0.3); // = 0.9, not 0.8999999999999999
NP.times(0.362, 100); // = 36.2, not 36.199999999999996
NP.divide(1.21, 1.1); // = 1.1, not 1.0999999999999999
NP.round(0.105, 2); // = 0.11, not 0.1
slugid¶
生成 UUID
socket.io-client¶
websocket 客户端
@testing-library/jest-dom¶
您想使用 jest 编写测试来断言有关 DOM 状态的各种事情。 作为该目标的一部分,您希望避免这样做时出现的所有重复模式。 检查一个元素的属性,它的文本内容,它的 css 类,你可以命名它。 https://www.npmjs.com/package/@testing-library/jest-dom
reselect¶
基于 redux 的选择器组件
shallowequal¶
浅比较两个对象是否相等
whatwg-fetch¶
window.fetch 的便携版
lodash¶
JS 工具库
version¶
4.17.21
downloads¶
52,325,095
repository¶
github.com/lodash/lodash
homepage¶
lodash.com/
The Lodash library exported as Node.js modules.
// Load the full build.
var _ = require('lodash');
// Load the core build.
var _ = require('lodash/core');
// Load the FP build for immutable auto-curried iteratee-first data-last methods.
var fp = require('lodash/fp');
// Load method categories.
var array = require('lodash/array');
var object = require('lodash/fp/object');
// Cherry-pick methods for smaller browserify/rollup/webpack bundles.
var at = require('lodash/at');
var curryN = require('lodash/fp/curryN');
See the package source for more details.
https://github.com/lodash/lodash/tree/4.17.21-npm
jszip¶
zip文件压缩编辑解压
A library for creating, reading and editing .zip files with JavaScript, with a lovely and simple API.
See https://stuk.github.io/jszip for all the documentation.
version¶
3.10.1
downloads¶
7,880,597
repository¶
github.com/Stuk/jszip
homepage¶
github.com/Stuk/jszip#readme
const zip = new JSZip();
zip.file("Hello.txt", "Hello World\n");
const img = zip.folder("images");
img.file("smile.gif", imgData, {base64: true});
zip.generateAsync({type:"blob"}).then(function(content) {
// see FileSaver.js
saveAs(content, "example.zip");
});
/*
Results in a zip containing
Hello.txt
images/
smile.gif
*/
camelcase¶
Convert a dash/dot/underscore/space separated string to camelCase or PascalCase: foo-bar → fooBar
https://www.npmjs.com/package/camelcase
dotenv¶
Dotenv is a zero-dependency module that loads environment variables from a .env file into process.env. Storing configuration in the environment separate from code is based on The Twelve-Factor App methodology. https://www.npmjs.com/package/dotenv
dotenv-expand¶
Dotenv-expand adds variable expansion on top of dotenv. If you find yourself needing to expand environment variables already existing on your machine, then dotenv-expand is your tool. https://www.npmjs.com/package/dotenv-expand
is-wsl¶
如果您需要解决 WSL 中未实现或有问题的功能,这会很有用。 支持 WSL 1 和 WSL 2。
https://www.npmjs.com/package/is-wsl
version¶
3.1.0
downloads¶
38,383,822
repository¶
github.com/sindresorhus/is-wsl
homepage¶
github.com/sindresorhus/is-wsl#readme
Check if the process is running inside Windows Subsystem for Linux (Bash on Windows)
Can be useful if you need to work around unimplemented or buggy features in WSL. Supports both WSL 1 and WSL 2.
import isWsl from 'is-wsl';
// When running inside Windows Subsystem for Linux
console.log(isWsl);
//=> true
axios¶
发送请求,是 promise 的封装
deep-copy¶
深拷贝引用类型变量
version¶
1.4.2
downloads¶
222,536
repository¶
github.com/simov/deep-copy
homepage¶
github.com/simov/deep-copy
var dcopy = require('deep-copy')
// deep copy object
var copy = dcopy({a: {b: [{c: 5}]}})
// deep copy array
var copy = dcopy([1, 2, {a: {b: 5}}])
dom-helpers¶
兼容 ie9 的 DOM 操作方法
glamor¶
css-in-js 直接在JS中写入css的样式
html2canvas¶
HTML 网页转换成截图
i18next¶
翻译
i18next-browser-languagedetector¶
翻译插件
i18next-xhr-backend¶
翻译(从后端获取数据)
is-hotkey¶
工具库,监听键盘事件,兼容不同操作系统
周下载量80万,广泛使用
https://www.npmjs.com/package/is-hotkey?activeTab=readme
import isHotkey from 'is-hotkey'
const isSaveHotkey = isHotkey('mod+s')
function onKeyDown(e) {
if (isSaveHotkey(e)) {
...
}
}
keymirror¶
创建键和值相等的对象
这个库是 10 年前写的,从 react 源码中拿出来的,https://www.npmjs.com/package/keymirror
周下载量 20 万,实际项目使用不多
lodash.throttle¶
lodash 的节流函数接口
promise¶
文件上传异步转换成同步操作
raf¶
动画效果
lerna.js¶
https://www.npmjs.com/package/lerna
主要功能:将多个依赖包完美的组合在一个引用中。Lerna is a tool that optimizes the workflow around managing multi-package repositories with git and npm.
实际项目中没有使用,了解即可
pdfjs 打印空白页的问题¶
项目中使用了 pdfjs 处理 PDF 文件预览和打印(火狐团队的第三方库)当 pdf 只有一张,谷歌浏览器打印会出现两章,第二页是空白的。
解决:page-break-after CSS 属性调整当前元素之后的分页符。把原来的 always 改成 auto 即可避免打印空白页。目前还没有测试到其他副作用。
.container {
page-break-after: 'auto';
}
https://developer.mozilla.org/zh-CN/docs/Web/CSS/page-break-after
https://developer.mozilla.org/en-US/docs/Web/CSS/page-break-inside
https://developer.mozilla.org/zh-CN/docs/Web/CSS/break-inside
debug¶
https://www.npmjs.com/package/debug
A tiny JavaScript debugging utility modelled after Node.js core's debugging technique. Works in Node.js and web browsers.
var debug = require('debug')('http');
var http = require('http');
var name = 'My App';
debug('booting %o', name);
http.createServer(function(req, res){
debug(req.method + ' ' + req.url);
res.end('hello\n');
}).listen(3000, function(){
debug('listening');
});
// fake worker of some kind
require('./worker');
jison¶
jison:An API for creating parsers in JavaScript,语法解析器
https://www.npmjs.com/package/jison
这个库6年前写的,最近4年没有更新,周下载量8万
jison 是一个语法解析器,可以直接把 '1+ 2 + 3' 这样的字符串解析转换成数学结果返回 6,具体语法类似 Bison
本地环境基本使用
1 全局安装 `npm install jison -g` 安装成功后,全局环境可以使用 jison 这个指令
2 获取解析规则 jison 格式的文件(这里可以从官方下载 `git://github.com/zaach/jison.git/examples`,或者自己写这个规则,例如脚本解析器的内容比较简答,公式解析器内容就比较复杂,具体涉及编译原理,暂时不展开)下面是部分 jison 文件
/* eslint-disable */
/* lexical grammar */
%lex
%%
\s+ {/* skip whitespace */}
and|AND {return '&';}
3 使用 jison 工具创建编译器 jison calculator.jison, 然后就在当前目录下面生成一个 `calculator.js` 的文件,对外会暴露一个 Parser 类
4 准备一个计算的字符串 `echo "1 + 2 + 3" > MichaelTest`,写入文件
5 使用解析器处理这个字符串,可以获取结果 node calculator.js MichaelTest
mockjs 模拟数据¶
可以用于前后端模拟数据进行调试
const Mock = require('mockjs');
const Random = Mock.Random;
const data = Mock.mock(
{
id: '',
title: Random.cparagraph(1, 5),
time: Random.datetime('yyyy-MM-dd'),
author: Random.cname(),
}
);
guppy¶
一个项目管理工具,可以可视化分析不同脚本运行情况
可视化查看第三方依赖的版本和更新情况
使用1K

Storybook¶
帮助一个 UI 组件库用于演示如何使用的工具。最新版本是 8,项目中使用的版本是 7。
可能官方文档和现在的配置不一样 https://storybook.js.org/docs/get-started/react-vite
下面是项目的配置(7)
安装¶
"@storybook/addon-actions": "7.6.17",
"@storybook/addon-docs": "7.6.17",
"@storybook/addon-essentials": "7.6.17",
"@storybook/addon-interactions": "7.6.17",
"@storybook/addon-knobs": "7.0.2",
"@storybook/addon-links": "7.6.17",
"@storybook/addon-onboarding": "1.0.11",
"@storybook/blocks": "7.6.17",
"@storybook/preset-create-react-app": "7.6.17",
"@storybook/react": "7.6.17",
"@storybook/react-webpack5": "7.6.17",
"@storybook/test": "7.6.17",
配置¶
.storybook/main.js
module.exports = {
stories: ['../stories/**/*.stories.js'],
staticDirs: ['../public'],
// 插件
addons: [
'@storybook/addon-actions',
'@storybook/addon-links',
'@storybook/addon-knobs',
{
name: '@storybook/addon-docs',
options: {
configureJSX: true,
}
}
],
framework: {
name: "@storybook/react-webpack5",
options: {
builder: {
useSWC: true,
},
},
}
};
.storybook/preview.js
import React from 'react';
import { Title, Subtitle, Description, Primary, Controls, Stories } from '@storybook/blocks';
/** @type { import('@storybook/react').Preview } */
const preview = {
parameters: {
actions: { argTypesRegex: "^on[A-Z].*" },
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/i,
},
},
options: {
storySort: {
method: '',
order: [],
locales: '',
}
},
docs: {
page: () => (
<>
<Title />
<Subtitle />
<Description />
<Primary />
<Controls />
</>
),
}
},
};
export default preview;
开启服务¶
"storybook": "storybook dev -p 6006",
"build-storybook": "storybook build -c .storybook -o docs",
使用 UI 组件¶
stories/components/cell-editor/text-editor.stories.js
import React from 'react';
import { action } from '@storybook/addon-actions';
import TextEditor from '../../../src/TextEditor';
const meta = {
title: 'Editors/text-editor',
component: TextEditor,
tags: ['autodocs'],
decorators: [
(Story, context) => {
return (
<div>
{context.parameters.title && <h1>{context.parameters.title}</h1>}
{context.parameters.subTitle && <p className='storybook-sub'>{context.parameters.subTitle}</p>}
<Story />
</div>
);
}
],
parameters: {
title: '',
subTitle: '',
}
};
export default meta;
export const Demo1 = {
args: {
isReadOnly: false,
value: value,
column: column,
onCommit: (updated) => { action('onCommit')(updated); },
},
parameters: {
subTitle: ''
}
};
printjs¶
https://printjs.crabbly.com/#documentation
https://github.com/crabbly/Print.js?tab=readme-ov-file
exif-js¶
https://www.npmjs.com/package/exif-js
从图片中提取 exif 信息(拍摄时间、拍摄位置等)
dotenv¶
https://www.npmjs.com/package/dotenv
Dotenv is a zero-dependency module that loads environment variables from a .env file into process.env.
可以把环境变量从 .env 文件中读出来,然后在代码中判断不同的环境,执行不同的逻辑。
S3_BUCKET="YOURS3BUCKET"
SECRET_KEY="YOURSECRETKEYGOESHERE"
在项目代码中
require('dotenv').config()
console.log(process.env)
GreaseMonkey¶
GreaseMonkey 油脂猴子,简称“油猴”,是一个浏览器插件,可以执行 JS 脚本。它们可以实现诸如自动化操作、改善用户界面、绕过限制等多种功能。
百度链接:https://baike.baidu.com/item/Greasemonkey/10727057
教程链接:
https://blog.csdn.net/qq_21561501/article/details/102696669
https://blog.csdn.net/jayandchuxu/article/details/79113755
https://blog.csdn.net/wujiayu31415/article/details/136191014
https://zhuanlan.zhihu.com/p/667584378
不同浏览器插件名称不一样,例如 Chrome ViolentMonkey 暴力猴
一个开源的用户脚本管理器,支持很多浏览器
Violentmonkey provides userscripts support for browsers. It works on browsers with WebExtensions support. It supports most scripts for Greasemonkey and Tampermonkey. Features: - Update automatically according to the meta data. - Scripts will be executed in order as shown in the list. - GM functions are supported. - Support import from and export to a zip file. - Sync to Dropbox, OneDrive, Google Drive and WebDAV!
这里提供了很多网站的功能(下载视频,复制粘贴等)例如 https://greasyfork.org/en/scripts/438182-seatable-custom-style-online
antd-mobile¶
阿里出品的移动端 UI 组件库
https://www.npmjs.com/package/antd-mobile
https://github.com/ant-design/ant-design-mobile
周下载量 2万,国内使用广泛
主要组件和案例(待完善)
<ActionSheet />
<Button />
个人案例演示:https://michael18811380328.github.io/react-demos/antd/
个人案例源码:https://github.com/Michael18811380328/react-demos/blob/master/src/routes/29-antd.jsx
注意版本升级后的 css 自定义:https://stackoverflow.com/questions/74529378/antd-5-module-not-found-error-cant-resolve-antd-dist-antd-less/74529656#74529656
autoprefixer¶
自动增加 css 前缀,兼容不同版本浏览器
fs-extra¶
fs 的高级版本
https://www.npmjs.com/package/fs-extra
express¶
中间层服务器
express-rate-limit¶
请求次数限制
response-time¶
HTTP 响应时间 nodejs 和 express 联合使用
rimraf¶
The UNIX command rm -rf for node. https://www.npmjs.com/package/rimraf
sharp¶
https://www.npmjs.com/package/sharp
nodejs 中图片工具库,可以生成图片(批量生成随机图片),或者图片格式转换等等
除了调整图像大小外,还可以进行旋转、提取、合成和伽玛校正等操作。
// 下面是批量生成随机图片的案例
// npm install sharp
const sharp = require('sharp');
const fs = require('fs');
const path = require('path');
const util = require('util');
const mkdir = util.promisify(fs.mkdir);
const writeFile = util.promisify(fs.writeFile);
const IMAGE_WIDTH = 800; // 图片宽度
const IMAGE_HEIGHT = 600; // 图片高度
const IMAGE_COUNT = 1000; // 图片数量
const OUTPUT_DIR = 'random_images'; // 输出目录
async function createRandomImage(filename) {
const red = Math.floor(Math.random() * 256);
const green = Math.floor(Math.random() * 256);
const blue = Math.floor(Math.random() * 256);
const image = await sharp({
create: {
width: IMAGE_WIDTH,
height: IMAGE_HEIGHT,
channels: 4,
background: { r: red, g: green, b: blue, alpha: 255 }
}
});
await image.toFile(filename);
}
async function main() {
try {
await mkdir(OUTPUT_DIR, { recursive: true });
for (let i = 0; i < IMAGE_COUNT; i++) {
const filename = path.join(OUTPUT_DIR, `${i}.png`);
await createRandomImage(filename);
}
} catch (error) {
console.error(error);
}
}
main();
转换图片
const semiTransparentRedPng = await sharp({
create: {
width: 48,
height: 48,
channels: 4,
background: { r: 255, g: 0, b: 0, alpha: 0.5 }
}
})
.png()
.toBuffer();
cheerio¶
一个为服务器特别定制的,快速、灵活、实施的jQuery核心实现.
https://www.npmjs.com/package/cheerio
https://github.com/cheeriojs/cheerio
https://github.com/cheeriojs/cheerio/wiki/Chinese-README
28K stars 周下载量900万,看起来还是很火,已经发布 1.0 版本,很多项目使用
把HTML告诉你的服务器
const cheerio = require('cheerio');
const $ = cheerio.load('<h2 class="title">Hello world</h2>');
$('h2.title').text('Hello there!');
$('h2').addClass('welcome');
$.html();
//=> <html><head></head><body><h2 class="title welcome">Hello there!</h2></body></html>
jquery 比较重,cheerio实现了核心jQuery的子集。
cheerio会从jQuery库中删除所有DOM矛盾和浏览器的尴尬部分,展示她真正华丽的API。
中文教程:https://www.cheeriojs.cn/docs/intro
目前实际项目不会使用,看起来这个主要用于服务器向客户端返回内容使用,或者服务器转换 HTML 使用。
image-size¶
nodejs 模块,获取任何图片的尺寸
const sizeOf = require("image-size")
const dimensions = sizeOf("images/funny-cats.png")
console.log(dimensions.width, dimensions.height)
tesseract¶
Tesseract 是一款由 Google 开发的开源 OCR(光学字符识别)库。它可以识别图片中的文字,并将其转换为可编辑的文本格式。
如果您想要使用 Tesseract 识别图片并将输出重定向到另一个文件,您可以使用命令行界面来执行这个操作。基本的命令行示例,它演示了如何使用 Tesseract 识别图片并将结果保存到文本文件中:
tesseract input.png output -l eng --oem 3 --psm 3 && echo "OCR Completed."
tesseract 1.png output -l chi_sim --psm 6 && cat ./output.txt
在这个命令中:
-
input.png 是需要进行 OCR 处理的图片文件。
-
output 是输出文本文件的文件名,不需要带有 .txt 扩展名,Tesseract 会自动添加。
-
-l eng 指定使用英文训练数据。
-
--oem 3 启用老式布局分析模式(LSTM-only)。OEM:OCR Engine Mode:引擎模式,取值 0123。 0:3.x以前的识别引擎 1:神经网络LSTM的识别引擎 2:混合模式,传统+LSTM 3:默认,那种支持就用那种
-
--psm 3 设置页面分割模式,这里设置为只有文本。PSM:Page Segmentation Mode,对每页文档进行结构化分析,默认的PSM的选项参数位PSM_AUTO=3
参考:https://cloud.tencent.com/developer/article/2205370
如果您想将输出重定向到一个文件
tesseract input.png output -l eng --oem 3 --psm 3 > newfile.txt && echo "OCR Completed."
在这两个示例中,输出都会被重定向到指定的文件,而不是打印到控制台。如果您想同时将输出保存到文件并在控制台上查看,可以使用 tee 命令。
tesseract input.png output -l eng --oem 3 --psm 3 | tee output.txt && echo "OCR Completed."
请确保您的系统上安装了 Tesseract-OCR,并且可以通过命令行访问 tesseract 命令。
1、brew install
2、下载中文识别包 brew install tesseract-lang
其他参考:
https://blog.csdn.net/s_ongfei/article/details/136500069
https://blog.csdn.net/qq_39522120/article/details/135503159
本地测试可以这样弄,然后写一个 bash 脚本循环
tesseract input.png output -l chi_sim --psm 3
使用 Tesseract 进行前端 ORM¶
嵌入 React 应用中
"tesseract.js": "^5.1.0",
import { createWorker } from 'tesseract.js';
const URLS = [
'https://cloud.seatable.cn/seafhttp/files/628ad059-0a07-4dc4-a675-7ae2a1f15d81/image-1720508732396.png',
];
export default function Contact() {
(async () => {
const worker = await createWorker('chi_sim');
for (let i = 0; i < URLS.length; i++) {
const URL = URLS[i];
const ret = await worker.recognize(URL);
console.log(i);
console.log(ret.data.text.replace(/[\s]/ig, ''));
}
await worker.terminate();
})();
return (
<div id="contact"></div>
);
}
nodejs 脚本
import { createWorker } from 'tesseract.js';
const URLS = [
'https://cloud.seatable.cn/seafhttp/files/628ad059-0a07-4dc4-a675-7ae2a1f15d81/image-1720508732396.png',
];
(async () => {
const worker = await createWorker('chi_sim');
for (let i = 0; i < URLS.length; i++) {
const URL = URLS[i];
const ret = await worker.recognize(URL);
console.log(i);
console.log(ret.data.text.replace(/[\s]/ig, ''));
}
await worker.terminate();
})();
nodejs 批量 OCR 结果
const fs = require('fs');
const { exec } = require('child_process');
// 批量 ORM 图片文件(默认图片,识别效率不太高)
var runNodes = async function(files, father_path) {
for (let i = 0; i < files.length; i++) {
const URL = father_path + '/' + files[i];
const command = `tesseract ${URL} output -l chi_sim --oem 3 --psm 3 && cat output.txt > ${i}.md`
await exec(command, (error, stdout, stderr) => {
if (error) {
console.error(`执行的错误: ${error}`);
return;
}
console.log(`stdout: ${stdout}`);
if (stderr) {
console.error(`stderr: ${stderr}`);
}
});
}
}
const path = './images';
// check path valid (user input path may not valid)
if (!fs.existsSync(path)) {
console.log(`${path} is invalid`);
return;
}
var files = fs.readdirSync(path);
runNodes(files, path);
python 脚本
import pytesseract
from pathlib import Path
from PIL import Image
def ocr(filename):
pth = Path(filename)
image = Image.open(filename)
# 图片二值化
image = image.convert('L')
# 可以定义阈值
threshold = 200
table = []
for i in range(256):
if i < threshold:
table.append(0)
else:
table.append(1)
# 识别图片
curdir = pth.parent
tessdata_dir_config = f'--tessdata-dir "{curdir}"'
content = pytesseract.image_to_string(
image, lang='chi_sim', config=tessdata_dir_config,) # 使用简体中文解析图片
print(content)
ocr('/root/dev/gotoolkits/figures/python-ocr-02.png')
问题和不足¶
如果识别清晰的截图,准确率能到 100%
如果截图中有其他的画笔颜色,或者图形比较多,那么准确率不太高,这种还需要手动处理
@antv/g2¶
链接¶
项目介绍¶
数据驱动的高交互可视化图形语法 AntV - G2
G2 是一套基于可视化编码的图形语法,以数据驱动,具有高度的易用性和扩展性,用户无需关注各种繁琐的实现细节,一条语句即可构建出各种各样的可交互的统计图表。
同时,G2 也是 AntV 最重要的组成,始于《The Grammar of Graphics》一书描述的视觉编码语法系统(这也是 G2 项目命名的由来)。
星标¶
12K
Fusion Design¶
项目介绍¶
一套企业级中后台UI的解决方案,致力于解决设计师与前端在工作协同、产品体验一致性、开发效率方面的问题
你可以通过一站式协作平台灵活地定制自己的 DesignSystem,生成设计物料与代码分片到设计师的工具端 FusionCool 及开发者的工具端 Iceworks,同时保证代码和视觉稿之间的一致性
Fusion Design 是一种旨在提升设计与开发之间 UI 构建效率的工作方式。通过建设基于 DPL 模式的,设计、前端之间的标准协议与工作流,来快速构建符合业务诉求的 DPL,提升 DPL 的构建效率和应用效率,帮助业务快速实现 UI 构建。
| npm 链接 | github 链接 | github 星标 | 使用建议 |
|---|---|---|---|
| https://fusion.design/pc/?themeid=4 | https://github.com/alibaba-fusion/next | 4.6K | 一般 |
使用案例¶
https://fusion.design/pc/doc/design/%E8%AE%BE%E8%AE%A1%E6%A6%82%E8%A7%88/11?themeid=2
痛点¶
适合alibaba内部使用,不适合小团队使用,有一定学习成本。在浏览器端进行编辑工作流等,和传统 APP 使用流畅度有区别。
zepto¶
zepto.js 是 jquery 在移动端的库,实际上 jquery 基本不使用了,zepto 也没有必要使用了,下面供参考:
zepto 源码注释 还是2013年的
使用 zeptojs 内嵌到 android webview 影响正常滚动时
https://github.com/madrobby/zepto/blob/master/src/touch.js 去掉 61 行,其实就是使用原生的滚动
babel¶
把ES6转换成ES5必备的工具
babel-plugin-rawest¶
- React 的 DOM 直出方案。
babel-plugin-macros¶
- 前端文件写 node 逻辑。
babel-plugin-dynamic-import-node¶
有些场景下会需要禁用 import() 语法。
babel-plugin-react-require¶
- 自动为 jsx 语法加 react 引用。
babel-plugin-react-remove-prop-types¶
- 删除 prop-types,生产环境用。
docz¶
文档
emotion¶
css modules¶
webrtc¶
移动端调用摄像头扫码
统计信息:字数 4653 阅读10分钟
基本技术和概念
webrtc¶
WebRTC (Web Real-Time Communications) 是一项实时通讯技术,它允许网络应用或者站点,在不借助中间媒介的情况下,建立浏览器之间点对点(Peer-to-Peer)的连接,实现视频流和(或)音频流或者其他任意数据的传输。WebRTC包含的这些标准使用户在无需安装任何插件或者第三方的软件的情况下,创建点对点(Peer-to-Peer)的数据分享和电话会议成为可能。
扫码:使用 webRTC 技术,通过浏览器打开移动端的摄像头,进行扫码,并将扫码结果返回到 JS 中。
视频通话:使用 web-socket 技术和 webRTC 技术,实现视频通话。
本文档使用第一种功能,前端在移动端实现扫码功能。
webrtc-adapter¶
第三方库 webrtc-adapter 是一个垫片,用于处理浏览器 webRTC 兼容性。
WebRTC adapter https://www.npmjs.com/package/webrtc-adapter
只需要引入这个库,不需要其他的操作,No further action is required.
import adapter from 'webrtc-adapter';
ZXing¶
ZXing(“斑马线”)是1D/2D条形码图像处理库: https://github.com/zxing-js/library,官方案例是 TS 的
案例见两个 html,qr-camera.html 可以完整使用, bar-image.html 缺少图片
React 具体实现¶
import React from 'react';
import 'webrtc-adapter';
import { BrowserMultiFormatReader } from '@zxing/library';
import { Modal } from 'antd-mobile';
export default class Camera extends React.Component {
constructor(props) {
super(props);
this.codeReader = new BrowserMultiFormatReader();
}
componentDidMount() {
this.initCamera();
}
initCamera = () => {
this.codeReader.listVideoInputDevices().then((videoInputDevices) => {
// 这里使用默认的摄像头 undefined
this.codeReader.decodeFromVideoDevice(undefined, 'video', (result, err) => {
// 给扫描对象增加动画效果
if (!this.scanRef.style.animation) {
this.scanRef.style.animation = 'scanCode 3s linear infinite';
}
// 有结果后,把扫码的结果通过回调函数返回
if (result) {
this.props.changeInputValue(result.text);
}
});
}).catch(() => {
console.log('Failed to turn on camera');
});
}
onCloseCamera = () => {
this.codeReader.reset();
}
render() {
return(
<Modal
onClose={this.props.onClose}
transparent
visible={true}
className="mobile-custom-camera"
>
<div className="custom-scan-container">
{/* 上面显示当前的视频效果,并进行扫码 */}
<video
id="video"
width="300"
height="200"
></video>
{/* 下面是一个用于扫码的动画效果,一个线上下移动 */}
<div className="custom-camera-line" ref={ref => this.scanRef = ref}></div>
</div>
</Modal>
);
}
}
对应的 CSS
.camera-auto-fill-value {
position: absolute;
top: 9px;
right: 6px;
cursor: pointer;
color: #999;
background: #fff;
display: flex;
justify-content: center;
width: 24px;
height: 24px;
}
.mobile-custom-camera {
width: 310px;
}
.mobile-custom-camera .am-modal-content {
padding-top: 0;
width: 310px;
}
.mobile-custom-camera .am-modal-content .am-modal-body {
padding: 0;
line-height: 1;
height: 210px;
overflow: hidden;
}
.mobile-custom-camera .custom-scan-container {
height: 210px;
width: 310px;
background: linear-gradient(#ddd, #ddd) left top,
linear-gradient(#ddd, #ddd) left top,
linear-gradient(#ddd, #ddd) right top,
linear-gradient(#ddd, #ddd) right top,
linear-gradient(#ddd, #ddd) right bottom,
linear-gradient(#ddd, #ddd) right bottom,
linear-gradient(#ddd, #ddd) left bottom,
linear-gradient(#ddd, #ddd) left bottom;
background-color: rgba(0,0,0,.4);
background-repeat: no-repeat;
background-size: 5px 50px, 50px 5px;
}
.mobile-custom-camera .custom-scan-container>video {
background: #fff;
margin-top: 5px;
object-fit: fill;
}
/* 这是动画线段的样式 */
.mobile-custom-camera .custom-camera-line {
position: absolute;
width: 80%;
left: 10%;
border: 1px solid #ddd;
top: -2px;
}
@keyframes scanCode {
from {
top: 0;
}
to {
top: 200px;
}
}
参考链接¶
Vue 移动端实现调用相机扫描二维码 https://blog.csdn.net/weixin_41856395/article/details/120597131
WebRTC 从实战到未来 https://juejin.cn/post/7151932832041058340
官方案例¶
qr-camera.html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="author" content="ZXing for JS">
<title>官方案例 |ZXing TypeScript | Decoding from camera stream</title>
<!-- 引入线上样式库 -->
<link rel="stylesheet" rel="preload" as="style" onload="this.rel='stylesheet';this.onload=null" href="https://fonts.googleapis.com/css?family=Roboto:300,300italic,700,700italic">
<link rel="stylesheet" rel="preload" as="style" onload="this.rel='stylesheet';this.onload=null" href="https://unpkg.com/normalize.css@8.0.0/normalize.css">
<link rel="stylesheet" rel="preload" as="style" onload="this.rel='stylesheet';this.onload=null" href="https://unpkg.com/milligram@1.3.0/dist/milligram.min.css">
</head>
<body>
<main class="wrapper" style="padding-top:2em">
<section class="container" id="demo-content">
<h1 class="title">Scan QR Code from Video Camera</h1>
<p>This example shows how to scan a QR code with ZXing javascript library from the device video camera. If more
than one video input devices are available (for example front and back camera) the example shows how to read
them and use a select to change the input device.</p>
<p>此示例显示如何使用ZXing javascript库从设备摄像机扫描二维码。如果有多个视频输入设备可用(例如前置和后置摄像头),该示例将显示如何读取它们并使用选择来更改输入设备。</p>
<!-- 点击按钮,开始或者重置 -->
<div>
<a class="button" id="startButton">Start</a>
<a class="button" id="resetButton">Reset</a>
</div>
<!-- 这里显示视频 -->
<div>
<video id="video" width="300" height="200" style="border: 1px solid gray"></video>
</div>
<!-- 更改视频来源,如果有多个摄像头 -->
<div id="sourceSelectPanel" style="display:none">
<label for="sourceSelect">Change video source 更改视频源</label>
<select id="sourceSelect" style="max-width:400px">
</select>
</div>
<div style="display: table">
<label for="decoding-style"> Decoding Style 解码样式</label>
<select id="decoding-style" size="1">
<option value="once">Decode once 解码一次</option>
<option value="continuously">Decode continuously 连续解码</option>
</select>
</div>
<label>Result:</label>
<pre>
<code id="result"></code>
</pre>
<p>See the <a href="https://github.com/zxing-js/library/tree/master/docs/examples/qr-camera/">source code</a> for
this example.</p>
</section>
<footer class="footer">
<section class="container">
<p>ZXing TypeScript Demo.</p>
</section>
</footer>
</main>
<script type="text/javascript" src="https://unpkg.com/@zxing/library@latest"></script>
<script type="text/javascript">
// 解码一次
function decodeOnce(codeReader, selectedDeviceId) {
codeReader.decodeFromInputVideoDevice(selectedDeviceId, 'video').then((result) => {
console.log(result)
// 捕获到视频中的二维码,解析后返回字符串,例如微信个人名片:https://u.wechat.com/EG_lz_oLmz6PHpvOemd5XMw
document.getElementById('result').textContent = result.text
}).catch((err) => {
console.error(err)
document.getElementById('result').textContent = err
})
}
// 连续解码
function decodeContinuously(codeReader, selectedDeviceId) {
codeReader.decodeFromInputVideoDeviceContinuously(selectedDeviceId, 'video', (result, err) => {
if (result) {
// properly decoded qr code 正确解码的二维码
console.log('Found QR code!', result)
document.getElementById('result').textContent = result.text
}
if (err) {
// As long as this error belongs into one of the following categories
// the code reader is going to continue as excepted. Any other error
// will stop the decoding loop.
//
// Excepted Exceptions:
// - NotFoundException
// - ChecksumException
// - FormatException
if (err instanceof ZXing.NotFoundException) {
console.log('No QR code found.')
}
if (err instanceof ZXing.ChecksumException) {
console.log('A code was found, but it\'s read value was not valid.')
}
if (err instanceof ZXing.FormatException) {
console.log('A code was found, but it was in a invalid format.')
}
}
})
}
window.addEventListener('load', function () {
// 设置变量保存选中摄像头
let selectedDeviceId;
// 初始化对象
const codeReader = new ZXing.BrowserQRCodeReader()
console.log('ZXing code reader initialized')
// 先获取输入设备的信息
codeReader.getVideoInputDevices()
.then((videoInputDevices) => {
// 获取当前设备的摄像头个数 videoInputDevices
const sourceSelect = document.getElementById('sourceSelect')
// 默认第一个是选中的设别ID
selectedDeviceId = videoInputDevices[0].deviceId
// 如果有多个摄像头
if (videoInputDevices.length >= 1) {
videoInputDevices.forEach((element) => {
const sourceOption = document.createElement('option')
sourceOption.text = element.label
sourceOption.value = element.deviceId
sourceSelect.appendChild(sourceOption)
})
sourceSelect.onchange = () => {
selectedDeviceId = sourceSelect.value;
};
const sourceSelectPanel = document.getElementById('sourceSelectPanel')
sourceSelectPanel.style.display = 'block'
}
// 点击开始按钮的回调函数
document.getElementById('startButton').addEventListener('click', () => {
// 获取渲染的次数,然后执行对应的函数
const decodingStyle = document.getElementById('decoding-style').value;
if (decodingStyle == "once") {
decodeOnce(codeReader, selectedDeviceId);
} else {
decodeContinuously(codeReader, selectedDeviceId);
}
console.log(`Started decode from camera with id ${selectedDeviceId}`)
})
// 点击重置按钮的回调函数
document.getElementById('resetButton').addEventListener('click', () => {
// 重置对象
codeReader.reset()
document.getElementById('result').textContent = '';
console.log('Reset.')
})
})
.catch((err) => {
// 本地使用 http-server 测试时,使用 http 协议,移动端报错 Can't enumerate devices, method not supported. 无法枚举设备,不支持方法。
// https://stackoverflow.com/questions/63833315/zebra-crossing-javascript-not-detecting-devices
// It turns out, the script requires a browser SSL connection. Not just on the JS, but the enveloping page as well.
// 解决方法
// 首先使用以下命令生成一个证书 ** 对 key.pem 和 cert.pem,它将有效期约10年(准确地说是3650天)
// openssl req -newkey rsa:2048 -new -nodes -x509 -days 3650 -keyout key.pem -out cert.pem
// # 然后便可以起服务了 下面两个命令都可以,后者会自动打开默认浏览器运行页面
// http-server -S
// http-server -S -C cert.pem -o
// 本机直接使用 http-server 即可启动服务
alert(err)
})
})
</script>
</body>
</html>
bar-image.html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="author" content="ZXing for JS">
<title>ZXing TypeScript | Decoding Barcode from images</title>
<link rel="stylesheet" rel="preload" as="style" onload="this.rel='stylesheet';this.onload=null"
href="https://fonts.googleapis.com/css?family=Roboto:300,300italic,700,700italic">
<link rel="stylesheet" rel="preload" as="style" onload="this.rel='stylesheet';this.onload=null"
href="https://unpkg.com/normalize.css@8.0.0/normalize.css">
<link rel="stylesheet" rel="preload" as="style" onload="this.rel='stylesheet';this.onload=null"
href="https://unpkg.com/milligram@1.3.0/dist/milligram.min.css">
</head>
<body>
<main class="wrapper" style="padding-top:2em">
<section class="container" id="demo-content">
<h1 class="title">Scan barcode from <code><img></code></h1>
<p>
<a class="button-small button-outline" href="../../index.html">HOME 🏡</a>
</p>
<p>
These examples show how to scan a barcode with ZXing javascript library from an image. The examples decode from
the
<code>src</code> in
<code>img</code> tag, however is also possible to decode directly from an url without an
<code>img</code> tag.
</p>
<div id="code-128">
<h2 class="title">Scan barcode from Code 128</h2>
<div>
<a class="button decodeButton">Decode</a>
</div>
<div>
<img class="img" src="../../resources/blackbox/code128-1/1.png" style="border: 1px solid gray" />
</div>
<label>Result:</label>
<blockquote>
<p class="result"></p>
</blockquote>
</div>
<br />
<br />
<div id="ean-13">
<h2 class="title">Scan barcode from EAN-13</h2>
<div>
<a class="button decodeButton">Decode</a>
</div>
<div>
<img class="img" src="../../resources/blackbox/ean13-1/1.png" style="border: 1px solid gray" />
</div>
<label>Result:</label>
<blockquote>
<p class="result"></p>
</blockquote>
</div>
<br />
<br />
<div id="itf">
<h2 class="title">Scan barcode from ITF</h2>
<div>
<a class="button decodeButton">Decode</a>
</div>
<div>
<img class="img" src="../../resources/blackbox/itf/1.png" style="border: 1px solid gray" />
</div>
<label>Result:</label>
<blockquote>
<p class="result"></p>
</blockquote>
</div>
<p>
See the
<a href="https://github.com/zxing-js/library/tree/master/docs/examples/barcode-image/">source code</a>
for these examples.
</p>
</section>
<footer class="footer">
<section class="container">
<p>ZXing TypeScript Demo. Licensed under the <a target="_blank"
href="https://github.com/zxing-js/library#license" title="MIT">MIT</a>.</p>
</section>
</footer>
</main>
<script type="text/javascript" src="https://unpkg.com/@zxing/library@latest"></script>
<script type="text/javascript">
window.addEventListener('load', () => {
const codeReader = new ZXing.BrowserBarcodeReader();
console.log('ZXing code reader initialized');
const decodeFun = (e) => {
const parent = e.target.parentNode.parentNode;
const img = parent.getElementsByClassName('img')[0].cloneNode(true);
const resultEl = parent.getElementsByClassName('result')[0];
codeReader.decodeFromImage(img)
.then(result => {
console.log(result);
resultEl.textContent = result.text;
})
.catch(err => {
console.error(err);
resultEl.textContent = err;
});
console.log(`Started decode for image from ${img.src}`)
};
for (const element of document.getElementsByClassName('decodeButton')) {
element.addEventListener('click', decodeFun, false);
}
})
</script>
</body>
</html>
jsdoc¶
根据 js 代码自动写文档
An API documentation generator for JavaScript.
https://jsdoc.app/about-getting-started.html
https://github.com/photonstorm/phaser3-docs/blob/master/package.json
可以根据需求生成 md 或者 HTML 格式的文档等
"build": "./node_modules/.bin/jsdoc *.js",
"gen": "node --max_old_space_size=8192 node_modules/jsdoc/jsdoc.js -c jsdoc.conf.json -R ../phaser/README.md",
"json": "jsdoc -c jsdoc.data.json"
在源代码中增加注释(函数注释和类注释)
/**
* check the param is an array
* @param {array} arr - input parameter
* @returns boolean
*/
const isArray = (arr) => {
return Array.isArray(arr);
};
export { isArray };
import isArray from './utils';
/** This is a description of the foo function. */
function foo() {
}
/**
* Represents a book.
* @constructor
*/
function Article(title, author) {
console.log(isArray(title));
return title + author;
}
/**
* Represents a book.
* @constructor
* @param {string} title - The title of the book.
* @param {string} author - The author of the book.
*/
class Book {
constructor(props) {
this.title = props.title;
this.author = props.author;
}
/**
* say hi to someone
* @param {string} name - The user name.
*/
sayHi(name) {
console.log('Hi ' + name);
}
}
具体配置文件
{
"tags": {
"allowUnknownTags": true
},
"source": {
"include": [
"../phaser/src/",
"../phaser/plugins/fbinstant"
],
"exclude": [
"../phaser/src/phaser-arcade-physics.js",
"../phaser/src/phaser-core.js",
"../phaser/src/physics/matter-js/poly-decomp/",
"../phaser/src/physics/matter-js/lib",
"../phaser/src/polyfills",
"../phaser/src/phaser-ie9.js"
],
"includePattern": ".+\\.js?$",
"excludePattern": "(^|\\/|\\\\)_"
},
"plugins": [
"jsdoc-plugins/typedef",
"jsdoc-plugins/this"
],
"opts": {
"debug": false,
"destination": "./json/phaser.json",
"encoding": "utf8",
"outputSourceFiles": false,
"outputSourcePath": true,
"recurse": true,
"private": false,
"lenient": true,
"sourceType": "script",
"template": "node_modules/jsdoc-json"
}
}