# 2019.09.19 今天是每日时报陪你的第 247 天
[文章] 作者对 React 16.8.6 代码做一个详细的核心源码解析。通过两个部分来完成这个解析:第一是加上这份代码的中文注释,第二是配套相应的文章:https://github.com/KieSun/react-interpretation (opens new window)
[类库] 使用 joi 工具来验证数据模型是否符合预期:https://github.com/hapijs/joi (opens new window)
[类库] 在使用 Webpack 构建出用于发布到线上的代码时,都会有压缩代码这一流程。最常见的 JavaScript 代码压缩工具是 UglifyJS,并且 Webpack 也内置了它,但在构建用于线上的代码时构建一直卡在一个时间点迟迟没有反应,其实卡住的这个时候就是在进行代码压缩,所以 ParallelUglifyPlugin 能帮我们解决这个问题:https://github.com/gdborton/webpack-parallel-uglify-plugin (opens new window)
[工具] Prepack 由 Facebook 开源,它采用较为激进的方法:在保持运行结果一致的情况下,改变源代码的运行逻辑,输出性能更高的 JavaScript 代码。 实际上 Prepack 就是一个部分求值器,编译代码时提前将计算结果放到编译后的代码中,而不是在代码运行时才去求值:https://prepack.io (opens new window)
# 示例 - joi
const Joi = require("@hapi/joi");
const schema = Joi.object({
username: Joi.string()
.alphanum()
.min(3)
.max(30)
.required(),
password: Joi.string().pattern(/^[a-zA-Z0-9]{3,30}$/),
repeat_password: Joi.ref("password"),
access_token: [Joi.string(), Joi.number()],
birth_year: Joi.number()
.integer()
.min(1900)
.max(2013),
email: Joi.string().email({
minDomainSegments: 2,
tlds: { allow: ["com", "net"] }
})
})
.with("username", "birth_year")
.xor("password", "access_token")
.with("password", "repeat_password");
schema.validate({ username: "abc", birth_year: 1994 });
// -> { value: { username: 'abc', birth_year: 1994 } }
schema.validate({});
// -> { value: {}, error: '"username" is required' }
// Also -
try {
const value = await schema.validateAsync({
username: "abc",
birth_year: 1994
});
} catch (err) {}
# 示例 - webpack-parallel-uglify-plugin
import ParallelUglifyPlugin from "webpack-parallel-uglify-plugin";
module.exports = {
plugins: [
new ParallelUglifyPlugin({
// Optional regex, or array of regex to match file against. Only matching files get minified.
// Defaults to /.js$/, any file ending in .js.
test,
include, // Optional regex, or array of regex to include in minification. Only matching files get minified.
exclude, // Optional regex, or array of regex to exclude from minification. Matching files are not minified.
cacheDir, // Optional absolute path to use as a cache. If not provided, caching will not be used.
workerCount, // Optional int. Number of workers to run uglify. Defaults to num of cpus - 1 or asset count (whichever is smaller)
sourceMap, // Optional Boolean. This slows down the compilation. Defaults to false.
uglifyJS: {
// These pass straight through to uglify-js@3.
// Cannot be used with uglifyES.
// Defaults to {} if not neither uglifyJS or uglifyES are provided.
// You should use this option if you need to ensure es5 support. uglify-js will produce an error message
// if it comes across any es6 code that it can't parse.
},
uglifyES: {
// These pass straight through to uglify-es.
// Cannot be used with uglifyJS.
// uglify-es is a version of uglify that understands newer es6 syntax. You should use this option if the
// files that you're minifying do not need to run in older browsers/versions of node.
}
})
]
};