今年疫情原因,本来不是很想回家过年的,想着工作累了,在珠海(中山)做几天废人也不错。但是现在回想起来,虽然家里比较小也比较无聊,逢年过节还是应该回家看看。

阅读全文 »

有数据格式如下:

{
"id": "745",
"knownName": {
"en": "A. Michael Spence",
"se": "A. Michael Spence"
},
"familyName": {
// 结构同上,下同
// ..
},
"orgName": {
// orgName 当获奖者为组织时出现
// ..
},
"gender": "male",
"nobelPrizes": [
{
"awardYear": "2001",
// ...
"affiliations": [
{
"name": {
"en": "Stanford University",
// ...
},
"city": {
// ...
},
"country": {
// ...
},
// ...
}
]
}
]
}

想要实现:

  1. 查找名为 CERNaffiliation 的所在国家
  2. 查找获奖次数大于等于 5 次的 familyName
  3. 查找 University of California 的不同所在位置总数
  4. 查找至少一个诺贝尔奖授予组织而非个人的年份总数
阅读全文 »

上一篇博文 Integrate Renovate with GitLab 中介绍了为私有代码仓库与私有源提供依赖自动检测更新并发起 Merge Request 的方式。Renovate 可以自动通过 Release Notes 获取到版本之间的更新日志,并在 MR 中展示,这为执行合并的评审人提供了极大的便利。

接下来需要解决另一个问题:如何为分散在各处的私有依赖自动生成更新日志?

阅读全文 »

企业项目群中往往会有部分代码逻辑需要公用,将其抽离作为公共包发布到私有源的做法是比较优雅的解决方式。但是这么做的话后期需要面临一个问题:当一个公共依赖包的使用者数量逐渐庞大的时候,如何保证当此包发布新版本时,所有使用者都能尽可能快地得到更新?

传统的解决方案:

  1. 手工对所有项目逐个升级。这种办法相当繁琐,且容易产生遗漏,当项目数量足够庞大的时候,发布一次将会是相当痛苦的体验;
  2. 在依赖安装时指定版本为 latest。这种办法虽然能保证每次安装时都能得到最新版本,但是却有诸多弊端,如:
    1. 无法保证依赖的安全性,有可能一次更新不慎造成大面积的瘫痪;
    2. 对「依赖锁」不友好,如 yarn.lock 等。

因此,如何使这个过程变得优雅,是一个亟待解决的问题。

阅读全文 »

本文是一些 GitHub Actions 常用发布动作的总结。

强烈建议将所有 Publish actions 分开执行,不要集中到一个 Workflow 内。原因是如果其中一个动作因为某些原因失败了,GitHub 目前只能重启整个 Workflow,而如果 Workflow 内某个 Job 已经成功了,那么该 Job 下一次执行必然是失败(因为此类任务一般不能对同一个版本号执行两次,发布成功一次以后第二次尝试将会被拒绝发布),因此这一个提交的 Workflow 将永远不可能成功。

需要注意的是,以下所提到的 secrets.GITHUB_TOKEN 均是 GitHub Action 内置的 Access Token,无需自行创建。而其它 secrets 则需要在 项目主页 -> Settings -> Secrets 处创建。

阅读全文 »

应该 JetBrains 家的所有 IDE 都有这个配置。习惯了用 Markdown 写博客的人每次都要手动点一下 SoftWrap 挺烦的。后来发现了一个配置可以帮我省去这一步:

打开设置,找到:Editor > General > Soft Wraps,将 Soft-wrap files 选项勾上即可。IDE 默认已经填上了 *.md; *.txt; *.rst; *.adoc,因此不需要再做别的事情。

image

这样一来,每次只要打开以上格式的文件,编辑器就会自动开启 SoftWrap,一劳永逸。

这是一次关于本博客的 Debug 经历,过程非常曲折。关键词:Vue / SSR / 错配

不知道从哪篇博文开始,博客在直接从内页打开时,或者在内页刷新浏览器时,会报以下错误:

app.73b8bd4d.js:8
DOMException: Failed to execute 'appendChild' on 'Node':
This node type does not support this method.

该错误:

  1. 只会在 build 模式出现;
  2. 只会在发布上 GitHub Pages 后出现;
  3. 只会在某些博文中出现;
  4. 只会在直接从链接进入该博文,或者在该博文页面刷新时出现。

该错误带来的影响,会导致页面上的所有 JavaScript 功能全部失效,具体来说是与 Vue.js 相关的功能。如:导航链接(因为使用了 Vue-Router),评论框,一些依赖于 Vue.js 的 VuePress 插件,等等。

screenshot

阅读全文 »

如果公司有专业运维,项目的部署上线过程一般来说开发者都不会接触到。但是很不幸,我所在的团队没有独立的运维团队,所以一切都得靠自己(与同事)。

以下都只是工作中逐步优化得到的经验总结,并且只以 Node.js 程序部署为例。

阅读全文 »

package.json

Change webpack related devDependencies versions:

  1. webpack to ^4
  2. webpack-dev-server to ^3
  3. Add webpack-cli
  4. Replace extract-text-webpack-plugin with mini-css-extract-plugin
  5. Replace uglifyjs-webpack-plugin with terser-webpack-plugin
{
"devDependencies": {
"mini-css-extract-plugin": "^1",
"terser-webpack-plugin": "^4",
"webpack": "^4",
"webpack-cli": "^3",
"webpack-dev-server": "^3"
}
}

webpack.base.conf.js

Add mode option.

// ...

module.exports = {
mode: process.env.NODE_ENV === 'production' ? 'production' : 'development',
context: path.resolve(__dirname, '../'),
// ...
}

webpack.prod.conf.js

  1. Add performance and optimization option
  2. Replace ExtractTextPlugin with MiniCssExtractPlugin
  3. Remove UglifyJsPlugin and all webpack.optimize.CommonsChunkPlugin
// ...
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const TerserPlugin = require('terser-webpack-plugin');
// ...
const webpackConfig = merge(baseWebpackConfig, {
// ...
performance: {
hints: false
},
optimization: {
runtimeChunk: {
name: 'manifest'
},
minimizer: [
new TerserPlugin(),
new OptimizeCSSPlugin({
cssProcessorOptions: config.build.productionSourceMap
? { safe: true, map: { inline: false } }
: { safe: true }
}),
],
splitChunks: {
chunks: 'async',
minSize: 30000,
minChunks: 1,
maxAsyncRequests: 5,
maxInitialRequests: 3,
name: false,
cacheGroups: {
vendors: {
test: /[\\/]node_modules[\\/]/,
name: 'vendor',
chunks: 'initial',
priority: -10
}
}
}
},
// ...
plugins: [
// new UglifyJsPlugin({
// uglifyOptions: {
// compress: {
// warnings: false
// }
// },
// sourceMap: config.build.productionSourceMap,
// parallel: true
// }),
// new ExtractTextPlugin({
// filename: utils.assetsPath('css/[name].[contenthash].css'),
// // Setting the following option to `false` will not extract CSS from codesplit chunks.
// // Their CSS will instead be inserted dynamically with style-loader when the codesplit chunk has been loaded by webpack.
// // It's currently set to `true` because we are seeing that sourcemaps are included in the codesplit bundle as well when it's `false`,
// // increasing file size: https://github.com/vuejs-templates/webpack/issues/1110
// allChunks: true,
// }),
new MiniCssExtractPlugin({
filename: utils.assetsPath('css/[name].css'),
chunkFilename: utils.assetsPath('css/[name].[contenthash].css')
}),
// split vendor js into its own file
// new webpack.optimize.CommonsChunkPlugin({
// name: 'vendor',
// minChunks (module) {
// // any required modules inside node_modules are extracted to vendor
// return (
// module.resource &&
// /\.js$/.test(module.resource) &&
// module.resource.indexOf(
// path.join(__dirname, '../node_modules')
// ) === 0
// )
// }
// }),
// extract webpack runtime and module manifest to its own file in order to
// prevent vendor hash from being updated whenever app bundle is updated
// new webpack.optimize.CommonsChunkPlugin({
// name: 'manifest',
// minChunks: Infinity
// }),
// This instance extracts shared chunks from code splitted chunks and bundles them
// in a separate chunk, similar to the vendor chunk
// see: https://webpack.js.org/plugins/commons-chunk-plugin/#extra-async-commons-chunk
// new webpack.optimize.CommonsChunkPlugin({
// name: 'app',
// async: 'vendor-async',
// children: true,
// minChunks: 3
// }),
],
// ...
})

That’s it, enjoy. 🎉

0%