├── .gitignore ├── .npmignore ├── .release-it.json ├── CHANGELOG.md ├── README.md ├── components ├── EgoistTag.vue ├── EgoistTags.vue ├── Footer.vue ├── Header.vue ├── LayoutWrapper.vue ├── List.vue └── Pagination.vue ├── example ├── .vuepress │ ├── config.js │ └── public │ │ └── sw.js ├── _archive │ └── how-to-code-split-libraries.md ├── _posts │ ├── 2015-10-anime-recommendations.md │ ├── 2015-10-anime-review.md │ ├── 2015-7-animes-review.md │ ├── 2016-1-anime-recommendations.md │ ├── 2016-4-anime-recommendations.md │ ├── 2016-7-anime-recommendations.md │ ├── 2016-front-end-primer.md │ ├── 5-12-memory.md │ ├── Hello-World.md │ ├── a-light-weight-localstorage-orm.md │ ├── all-things-last-long.md │ ├── best-thing-ever.md │ ├── bili.md │ ├── bundle-front-end-js-library.md │ ├── deploy-node-app.md │ ├── draw-chat-message-with-canvas.md │ ├── front-end-frameworks.md │ ├── fuuka-fate.md │ ├── git-memo.md │ ├── good-and-bad-anime.md │ ├── how-does-array-slice-call-arguments-work.md │ ├── how-does-nodejs-cli-program-work.md │ ├── how-to-learn-to-code.md │ ├── how-to-undo-with-git.md │ ├── kill-gulp-with-npm-scripts-and-nswatch.md │ ├── linus-and-i.md │ ├── log-in-with-your-teminal.md │ ├── my-rollup-plugin-postcss.md │ ├── neon-genesis-scaffolding-tool.md │ ├── new-timetable.md │ ├── node-js-module-style-guide.md │ ├── otaku-is-the-best.md │ ├── postgresql-simple-guide.md │ ├── revue-guide.md │ ├── short-hair.md │ ├── subaru-be-loyal-or-jerk.md │ ├── sublime-vscode-key-bindings.md │ ├── tesing-javascript-apps-using-jest.md │ ├── the-most-lightweight-es2015-setup.md │ ├── the-world-is-a-big-noise.md │ ├── this-is-how-it-started.md │ ├── tooling-free-you-from-jquery.md │ ├── true-how-to-learn-to-code.md │ ├── vue-jsx-full-guide.md │ ├── why-i-choose-tab-over-space.md │ ├── why-i-wont-marry.md │ ├── why-so-addicted-into-anime.md │ ├── write-better-code-with-eslint-and-prettier.md │ └── wtf-is-front-end-development.md ├── about.md ├── donate.md ├── girls.md └── index.md ├── index.js ├── layouts ├── 404.vue ├── Categories.vue ├── Category.vue ├── Layout.vue ├── Page.vue ├── Tag.vue └── Tags.vue ├── package.json ├── styles ├── highlight.styl ├── index.styl └── palette.styl └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | .temp 2 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | .idea 2 | __tests__ 3 | __mocks__ 4 | example 5 | -------------------------------------------------------------------------------- /.release-it.json: -------------------------------------------------------------------------------- 1 | { 2 | "src": { 3 | "tagName": "v%s", 4 | "commitMessage": "%s" 5 | }, 6 | "increment": "conventional:angular", 7 | "beforeChangelogCommand": "conventional-changelog -p angular -i CHANGELOG.md -s", 8 | "changelogCommand": "conventional-changelog -p angular | tail -n +3", 9 | "safeBump": false 10 | } 11 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | 2 | ## [1.5.1](https://github.com/ulivz/vuepress-theme-egoist/compare/v1.5.0...v1.5.1) (2018-12-23) 3 | 4 | 5 | 6 | 7 | # [1.5.0](https://github.com/ulivz/vuepress-theme-egoist/compare/v1.4.2...v1.5.0) (2018-12-18) 8 | 9 | 10 | ### Features 11 | 12 | * bump to latest vuepress 1.0.0-alpha.30 13 | 14 | 15 | ## [1.4.2](https://github.com/ulivz/vuepress-theme-egoist/compare/v1.4.1...v1.4.2) (2018-11-12) 16 | 17 | 18 | 19 | 20 | ## [1.4.1](https://github.com/ulivz/vuepress-theme-egoist/compare/v1.4.0...v1.4.1) (2018-10-29) 21 | 22 | 23 | 24 | 25 | # [1.4.0](https://github.com/ulivz/vuepress-theme-egoist/compare/v1.3.0...v1.4.0) (2018-10-07) 26 | 27 | 28 | ### Features 29 | 30 | * bump up to VuePress 1.0.0-alpha.8 ([ff75387](https://github.com/ulivz/vuepress-theme-egoist/commit/ff75387)) 31 | 32 | 33 | 34 | 35 | # [1.3.0](https://github.com/ulivz/vuepress-theme-egoist/compare/v1.2.3...v1.3.0) (2018-10-07) 36 | 37 | 38 | ### Features 39 | 40 | * bump up to VuePress 1.0.0-alpha.7 ([7bad4e4](https://github.com/ulivz/vuepress-theme-egoist/commit/7bad4e4)) 41 | 42 | 43 | 44 | 45 | ## [1.2.3](https://github.com/ulivz/vuepress-theme-egoist/compare/v1.2.2...v1.2.3) (2018-10-07) 46 | 47 | 48 | ### Bug Fixes 49 | 50 | * incorrect global component directory ([c85f9dc](https://github.com/ulivz/vuepress-theme-egoist/commit/c85f9dc)) 51 | 52 | 53 | 54 | 55 | ## [1.2.2](https://github.com/ulivz/vuepress-theme-egoist/compare/v1.2.1...v1.2.2) (2018-10-07) 56 | 57 | 58 | ### Bug Fixes 59 | 60 | * specify global compoennts directory since alpha.6 has removed it. ([9d6c672](https://github.com/ulivz/vuepress-theme-egoist/commit/9d6c672)) 61 | 62 | 63 | 64 | 65 | ## [1.2.1](https://github.com/ulivz/vuepress-theme-egoist/compare/v1.2.0...v1.2.1) (2018-10-07) 66 | 67 | 68 | 69 | 70 | # [1.2.0](https://github.com/ulivz/vuepress-theme-egoist/compare/v1.1.1...v1.2.0) (2018-10-07) 71 | 72 | 73 | ### Features 74 | 75 | * update to alpha.6 theme API ([0250373](https://github.com/ulivz/vuepress-theme-egoist/commit/0250373)) 76 | 77 | 78 | 79 | 80 | ## [1.1.1](https://github.com/ulivz/vuepress-theme-egoist/compare/v1.1.0...v1.1.1) (2018-09-26) 81 | 82 | 83 | ### Bug Fixes 84 | 85 | * add mising plugins ([ece464d](https://github.com/ulivz/vuepress-theme-egoist/commit/ece464d)) 86 | 87 | 88 | 89 | 90 | # [1.1.0](https://github.com/ulivz/vuepress-theme-egoist/compare/2095794...v1.1.0) (2018-09-26) 91 | 92 | 93 | ### Bug Fixes 94 | 95 | * missing $themeConfig.headerTitle ([2095794](https://github.com/ulivz/vuepress-theme-egoist/commit/2095794)) 96 | * missing pagination ([#1](https://github.com/ulivz/vuepress-theme-egoist/issues/1)) ([4c5d9ac](https://github.com/ulivz/vuepress-theme-egoist/commit/4c5d9ac)) 97 | 98 | 99 | ### Features 100 | 101 | * support tag ([0d4e46f](https://github.com/ulivz/vuepress-theme-egoist/commit/0d4e46f)) 102 | 103 | 104 | 105 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # vuepress-theme-egoist 2 | 3 | > A blog theme for [@EGOIST](https://github.com/egoist) and a mirror of [egoist/blog](https://github.com/egoist/blog), but powered by VuePress. 4 | 5 | > This is the world's first blog theme built with VuePress 1.x. 6 | 7 | ## Features 8 | 9 | - Original flavor of [EGOIST's blog](https://egoist.moe/) 10 | - [Tags](https://egoist.ulivz.com/tag/) 11 | - [Categories](https://egoist.ulivz.com/category/) 12 | - Pagination 13 | - Search 14 | 15 | This theme deeply integrated with: 16 | 17 | - [@vuepress/plugin-blog](https://vuepress.vuejs.org/plugin/official/plugin-blog.html) 18 | - [@vuepress/plugin-pagination](https://vuepress.vuejs.org/plugin/official/plugin-pagination.html) 19 | - [@vuepress/plugin-search](https://vuepress.vuejs.org/plugin/official/plugin-search.html) 20 | 21 | Check out the showcase [https://egoist.ulivz.com/](https://egoist.ulivz.com/) and [usage example](example). 22 | 23 | ## Contributing 24 | 25 | 1. Fork it! 26 | 2. Create your feature branch: `git checkout -b my-new-feature` 27 | 3. Commit your changes: `git commit -am 'Add some feature'` 28 | 4. Push to the branch: `git push origin my-new-feature` 29 | 5. Submit a pull request :D 30 | 31 | ## Author 32 | 33 | **vuepress-theme-egoist** © [ulivz](https://github.com/ULIVZ), Released under the [MIT](./LICENSE) License.
34 | Authored and maintained by ulivz with help from contributors ([list](https://github.com/ULIVZ/vuepress-theme-egoist/contributors)). 35 | 36 | > [github.com/ulivz](https://github.com/ulivz) · GitHub [@ulivz](https://github.com/ULIVZ) · Twitter [@_ulivz](https://twitter.com/_ulivz) 37 | 38 |
39 | 40 | 2018 © [ULIVZ](https://github.com/ULIVZ) 41 | -------------------------------------------------------------------------------- /components/EgoistTag.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | 13 | 38 | -------------------------------------------------------------------------------- /components/EgoistTags.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 16 | 17 | 25 | -------------------------------------------------------------------------------- /components/Footer.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 22 | 23 | 44 | -------------------------------------------------------------------------------- /components/Header.vue: -------------------------------------------------------------------------------- 1 | 18 | 19 | 28 | 29 | 102 | -------------------------------------------------------------------------------- /components/LayoutWrapper.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 17 | -------------------------------------------------------------------------------- /components/List.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 18 | 19 | 73 | -------------------------------------------------------------------------------- /components/Pagination.vue: -------------------------------------------------------------------------------- 1 | 24 | 25 | 57 | -------------------------------------------------------------------------------- /example/.vuepress/config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | title: '庶民样本', 3 | description: 'EGOIST 在这里写作', 4 | theme: require.resolve('../..'), 5 | googleAnalytics: 'UA-54857209-6', 6 | url: 'https://egoist.moe', 7 | feed: true, 8 | author: 'EGOIST', 9 | email: '0x142857@gmail.com', 10 | themeConfig: { 11 | headerTitle: 'e.z.', 12 | website: 'https://github.com/egoist', 13 | repo: 'egoist/blog', 14 | twitter: '_egoistlily', 15 | nav: [ 16 | { text: 'about', link: '/about.html' }, 17 | { text: 'girls', link: '/girls.html' }, 18 | { text: 'donate', link: '/donate.html' }, 19 | { text: 'tag', link: '/tag/' }, 20 | { text: 'category', link: '/category/' }, 21 | ] 22 | }, 23 | markdown: { 24 | // slugify: 'limax', 25 | highlightedLineBackground: '#ffe9ad', 26 | hideLanguage: true, 27 | plugins: [ 28 | 'markdown-it-footnote' 29 | ] 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /example/.vuepress/public/sw.js: -------------------------------------------------------------------------------- 1 | self.addEventListener('install', function(e) { 2 | self.skipWaiting(); 3 | }); 4 | 5 | self.addEventListener('activate', function(e) { 6 | self.registration.unregister() 7 | .then(function() { 8 | return self.clients.matchAll(); 9 | }) 10 | .then(function(clients) { 11 | clients.forEach(client => client.navigate(client.url)) 12 | }); 13 | }); -------------------------------------------------------------------------------- /example/_archive/how-to-code-split-libraries.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Library 的按需加载 3 | date: 2018-04-02 15:48:12 4 | tags: 5 | warning: 本文处于撰写阶段,还没有找到解决方案 😅 6 | --- 7 | 8 | 我在写一个[项目](https://github.com/egoist/docute/tree/dev),由于一些依赖较大,需要将其按需加载。webpack 自带了[按需加载](https://webpack.js.org/guides/lazy-loading/)的功能,不过似乎只适用于 App 的打包: 9 | 10 | ```js 11 | // 举个例子,这个项目的入口文件: 12 | // index.js 13 | export default arr => 14 | import('lodash/flatten').then(flatten => flatten.default(arr)) 15 | ``` 16 | 17 | 用以下的 `webpack.config.js` 打包的话: 18 | 19 | ```js 20 | module.exports = { 21 | entry: './index.js', 22 | devtool: false, 23 | mode: 'development', 24 | output: { 25 | path: __dirname + '/dist', 26 | libraryTarget: 'commonjs2' 27 | }, 28 | externals: { 29 | 'lodash/flatten': 'commonjs lodash/flatten' 30 | } 31 | } 32 | ``` 33 | 34 | 你会得到: 35 | 36 | ```js{11} 37 | // dist/main.js 38 | module.exports = 39 | // ...省略数百行 40 | /***/ "lodash/flatten": 41 | /*!*************************!*\ 42 | !*** external "lodash/flatten" ***! 43 | \*************************/ 44 | /*! no static exports found */ 45 | /***/ (function(module, exports) { 46 | 47 | module.exports = require("lodash/flatten"); 48 | 49 | /***/ }) 50 | 51 | /******/ }); 52 | ``` 53 | 54 | 如果你使用 webpack 然后引入打包后的 `dist/main.js` 的话就没有按需加载的效果了,因为 `import()` 被转换成了 `require()`, 55 | 56 | 如果我是要打包成 `umd` 格式,那就不用把 `lodash/flatten` 加到 `externals` 中,也就没这个问题。 57 | 58 | 现在我找到的疑似解决方案有: 59 | 60 | - 用 Rollup,不过很麻烦,只能用于 `es` `cjs` 格式的打包。 61 | - 用其他的方案,比如 SystemJS,不过不太熟 🤔 不知道行不行。 62 | 63 | *To be finished..* 64 | -------------------------------------------------------------------------------- /example/_posts/2015-10-anime-recommendations.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Recommended in October 2015 3 | date: 2015-10-13 11:29:50 4 | tags: 5 | - anime 6 | categories: 7 | - anime 8 | 9 | --- 10 | 11 | It’s time for EGOIST to take you to the new section. This year’s October new season is still in line with my taste. I will recommend some of the games I am chasing from Monday to Sunday. 12 | 13 | ## Monday 14 | 15 | I only recommend one, "One Punch Superman." I haven't seen the comics, but the punches are quite funny, and I have enough to watch the meat and sell it. 16 | 17 | ## Tuesday 18 | 19 | Boring days, no recommendations. 20 | 21 | ## Wednesday 22 | 23 | There is no doubt that there is a "about me being kidnapped to a noble female school as a sample of the public." Let me ignore it and look at the picture. 24 | 25 | ![anime](https://ooo.0o0.ooo/2015/10/12/561c7d0bceeb6.png) 26 | 27 | ## Thursday 28 | 29 | Still boring. 30 | 31 | ## Friday 32 | 33 | The work of the goddess of manga, "The Black Jack of Youth", I have seen less in medicine. This soundtrack and plot are very different in that era. 34 | 35 | ## Saturday 36 | 37 | "The new sister devil's contractor BURST" I saw the first issue, I saw that I was stoned, so I continued to chase. 38 | 39 | "Reloading weapons" is of course a cute woman, a little Loli. 40 | 41 | "I am a hero of the Lost Knights", I am a sister, and I like to dedicate myself to my sister. 42 | 43 | ## Sunday 44 | 45 | I didn't read the predecessor of "The false face of the rumored thing". I didn't feel that it was suitable for me when I looked at the painting style a little. But I like this period of cat ears. 46 | 47 | "The Ending Blazing Angels Phase 2", the characters are very interesting. Although the paintings and plots are seriously spit, the people are still very classic. Well, I just like Queen Cluru 233. 48 | 49 | "Immediate! Giants High School" is really crying me, and my first goddess Mikhasha. 50 | 51 | --- 52 | 53 | Specially attached to "Women's Drive", you don't have the light of the Holy Light. 54 | -------------------------------------------------------------------------------- /example/_posts/2015-10-anime-review.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 二〇一五年十月新番回顾 3 | date: 2016-01-11 12:12:34 4 | tags: 5 | - anime 6 | - review 7 | - animegirl 8 | --- 9 | 几个月前,也就是十月份的时候写了篇[二〇一五年十月新番推荐](/2015/10/13/anime-recommendations/),现在已经是一月份,在新老后宫交替的时节写回顾什么的,saikou! 10 | 11 | 首先是所有我看过的新番评分(只介绍我看完了的,可能有遗漏): 12 | 13 | *小于 5 烂番; 大于 8 神番* 14 | 15 | |名称|评分| 16 | |---|---| 17 | |传颂之物 虚伪的假面|7| 18 | |进击!巨人中学|7.5| 19 | |龙珠超|6.5| 20 | |一拳超人|7.8| 21 | |关于我被绑架到贵族女校当“庶民样本”的事|7| 22 | |重装武器|7.5| 23 | |学战都市|7.5| 24 | |终结的炽天使 第2期|6.5| 25 | |落第骑士英雄谭|7.5| 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 | ## 终结的炽天使 第2期 56 | 57 | 我喜欢的其实是筱娅。 58 | 59 | ## 落第骑士英雄谭 60 | 61 | 这是我喜欢的剧情类型。 62 | -------------------------------------------------------------------------------- /example/_posts/2015-7-animes-review.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Review of the new report in July 2015 3 | date: 2015-10-01 22:46:01 4 | tags: 5 | - anime 6 | categories: 7 | - anime 8 | --- 9 | 10 | The first day of the National Day is coming to an end, that is to say, the new fan in July this year has also become old. The days when the weekends were not updated were quite difficult. Write a review and pass the time. 11 | 12 | At the beginning of this season, what attracted me most was the ** "The boring world without the existence of the yellow section"**. In the introduction of the new fan before July, I probably ignored this anime directly. I thought it was boring and funny. Ignore it, although it is really funny, but it is very refreshing the lower limit of my exercise, opening the door to the new world for me, so it becomes my weekly chase. Whether it is the laughter of the teacher or the sister juice of Anna's predecessors, I am full of expectations for each episode. 13 | 14 | 15 | Let's talk about ** "Queen of the package" ** and ** "My wife is the president of the student" **, no doubt this is what I must chase every week, the reason is obvious, no revision is a gift from God. 16 | 17 | ** "The Spirit of the Restaurant" ** not in the last season ** I am a type of Meng female lord, this kind of black long arrogant attribute cold type is too much damage to me, can not stop. 18 | 19 | Look at the ** "dry little girl buried" ** Xiao buried completely because I saw a lot of people's praise, I couldn't make any effort on this kind of waste, but after I saw one or two episodes, I also bought potato chips cola two All three days have been completed. Now every Thursday night turns into my little night, never feels that the potato chips and cola are so enticing, is this a piece of music not a good thing? XD 20 | 21 | ** "Magic Girl Elia" ** and ** "Red Hair White Snow Ji" ** The first few episodes are quite interesting, and I can't catch up after watching. 22 | 23 | ** "Prison Academy" ** Nothing cute, but the flower room sister's health room play really made me die, this is not such a charming flower school sister can not imagine! We pursued for the welfare comics animation of flower school sister. 24 | 25 | ** "Dragon Ball Super" ** is also what I am looking forward to. After all, I like the Dragon Ball series very much. At the beginning, it is similar to God and God. There should be more exciting development in the back. 26 | 27 | For the big devil's ** "Charlotte" ** is naturally the sound of Tucao, in short, too many dragons and God's jumping story made me want a lot of desire to send a blade. The ending is also unable to vomit, although it is a happy end for the male owner, but it is too reluctant ending. In the early days of the day, the reversal of the film to save the world can be counted as rotten films. I am not talking about the "sinful crown" because it does not have too many dragon plots, disappearing characters and strange plot development. Besides, the sin crown on the soundtrack is enough for you to replay a hundred times. So Charlotte is undoubtedly another rotten film that the audience is willing to watch. 28 | 29 | --- 30 | 31 | The above is the review of the July New Fan. There is nothing to be interested in the October New Fan, except for the ** "One Punch Superman" ** and the ** "The Ending Blazing Angel" ** the second half. I think about the new fan in October last year. ** "Parasitic Beast"** and ** "Tokyo Ghoul"** I really blasted my October, will there be such a good October? 32 | 33 | No, maybe. 34 | 35 | --- 36 | 37 | Finally, this is a list of my follow-ups this season: 38 | 39 | - Gakuen Island ★★★ 40 | - The Spirit of the Restaurant ★★★★ 41 | - Prison Academy ★★★★ 42 | - Magical Girl Ilia ★★☆ 43 | - Charlotte ★★★★ 44 | - The boring world where the yellow piece does not exist ★★★★☆ 45 | - Liuhua's brave ★★★★ 46 | - Dragon Ball Super ★★★☆ 47 | - Out of the package queen ★★★★ 48 | - Red Hair White Snow Ji ★★★ 49 | - My wife is the student president ★★★★ 50 | - Dry matter little buried ★★★★ 51 | - Black Street ★★★ 52 | -------------------------------------------------------------------------------- /example/_posts/2016-1-anime-recommendations.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: New Fan recommended in January 2016 3 | date: 2016-01-30 18:54:29 4 | tags: 5 | - anime 6 | --- 7 | 8 | ## Monday 9 | 10 | ** The weakest and undefeated god-loading machine dragon ** is the story of the fallen knight and the school of war. 11 | 12 | ## Tuesday 13 | 14 | No! 15 | 16 | ## Wednesday 17 | 18 | **No color limit of the strange world ** Milk shake no money! 19 | 20 | ## Thursday 21 | 22 | not at all. 23 | 24 | ## Friday 25 | 26 | **Rough snack war ** Eating something is filthy! 27 | 28 | ## Saturday 29 | 30 | **Asian ** Are you sure you are not a Super Saiyan? I like the character of a man 233 31 | 32 | **Reloading weapons** Half a year, not enough. 33 | 34 | **GATE Fantasy Self-Defense Force ** I want to see the man with the harem brush dragon! 35 | 36 | ## Sunday 37 | 38 | **Dragon Ball Super** Reminiscing childhood. 39 | -------------------------------------------------------------------------------- /example/_posts/2016-4-anime-recommendations.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Recommended in April 2016 3 | subtitle: There is no fragrance in April, I still have a new fan 4 | date: 2016-04-10 17:18:27 5 | tags: 6 | - animes 7 | --- 8 | 9 | ## Monday 10 | 11 | ### Re: Different world life from scratch 12 | 13 | As the name suggests, this is the adventure of the "different world." In short, it is a "crossing class" plot. I don't know which force manipulates the male master from modern times to a time that is suspected of the Middle Ages. It seems that the male lord has also been given some power... 14 | 15 | ## Tuesday 16 | 17 | ### 100 Armed Wars 18 | 19 | This is a adaptation of a "fantasy" light novel. Humans rely on weapons called "Hundred Arms" to fight aliens, and the male-loving males enter the college to strengthen the stalks of the harem. 20 | 21 | 22 | ## Wednesday 23 | 24 | ### 双星之阴阳师 25 | 26 | The painting style is slightly curious, and the plot is very Chinese. Probably the story of the strongest "Yin and Yang" who was awakened by the female host after a major blow to decadence, and then I guess it should be a variety of battles with "dirty". 27 | 28 | ## Thursday 29 | 30 | No, study hard. 31 | 32 | ## Friday 33 | 34 | ### In the next transcript, what are you doing? 35 | 36 | In April, I was forced to play the strongest. After reading "Sakamoto," I made up for him to fight with "One Punch Superman". The picture is so beautiful. In short, Sakamoto is a perfect thing to do, "suspected aliens", and is loved by people in school at the age of "no matter men, women, young and old." Laughing. 37 | 38 | ### Online game wife can't be a girl 39 | 40 | I have only seen a little comics and the first episode of the TV version. It is probably a type of "fantasy" + "campus". It is also possible to develop into a "harem". Students who like "Sword Art Online" can look at it. 41 | 42 | ### Kabanely of Iron City 43 | 44 | The April funding was burning. OP is sung by Eimist and ED by Aimer, and the music is produced by Sawano Hiroyuki. This is destined that at least the music part of this piece will be as impressive as the "Sin Crown", and it is true in the performance of the first episode. There is even a BGM suspected of "hanging the Divine Comedy"! 45 | 46 | The plot is also going to the "God" route. "Zombie Besieged City" thinks about it. I feel that it is more creepy than the "Attacking Giant" and there is a possibility of being banned. Character design is also very good, the female owner seems to have the ability to be different from ordinary people, the feet look good, and the male owner is suspected to be the second middle school of high IQ. Both auditory and visual, the plot does not seem to be good, will it be God? 47 | 48 | In short, I am quite looking forward to the subsequent development. 49 | 50 | ## Saturday 51 | 52 | ### Reverse referee 53 | 54 | Cheng Bu Tang Long Yi (referred to as Jackie Chan) is a lawyer who rides a children's bicycle back and forth at home and in the court, and fights with a savage gangster and prosecutor, and has a wonderful story. 55 | 56 | ## Sunday 57 | 58 | ### Ninja Killer SE 59 | 60 | Another laugh in April is that it is different from the style of painting. This unique "PPT style" seems to save money but brings unexpected laughter. The plot is also obvious, and the dead will be resurrected by the former ninja. The man who was killed by the ninja was possessed by a mysterious ninja soul and began the road of destroying the "ninja". The only normal thing about this time is the painting of female characters. Both the shape and the amount of milk are very normal and beautiful. 61 | 62 | ![ninja se](https://o68eee1f9.qnssl.com/a15b4afegw1f397cnma1xj21gy13mgvd.jpeg) 63 | -------------------------------------------------------------------------------- /example/_posts/2016-7-anime-recommendations.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Recommended by New Fan in July 2016 3 | date: 2016-07-03 22:22:26 4 | tags: 5 | - animes 6 | --- 7 | 8 | There are about 12 new fans in the season I am chasing! It is not comparable to the first two seasons of this year (9, 8), but the previous data is actually a bit hydrated. Some of them are XDs that I started to look after I wrote the recommendation, so it may be more than that number. 9 | 10 | ## Monday 11 | 12 | ### Projectiles break 3 Future articles 13 | 14 | It is completely for the first season of the project. It is said that the new work is completely original. In short, it is still good to look at it with emotion. Maybe it is not bad. 15 | 16 | ### orange orange miracle 17 | 18 | Write to yourself ten years ago, in order not to let the past yourself make things that make you regret! Feeling is the door to the literary version of the destiny stone. 19 | 20 | ## Tuesday 21 | 22 | ### 灵能百百 23 | 24 | Another work of ONE teacher, looks like the twin brother of Saitama, and the animation is definitely good. Not much to say, get on the train! 25 | 26 | ### 魔装学园H×H 27 | 28 | The name of the same structure as the "Devil College DxD" can be seen at a glance, and the car is already open. 29 | 30 | ### Taboo Mantra 31 | 32 | The woman is like my Ai Lian, and the fighting scene is also very cool. 33 | 34 | ## Wednesday 35 | 36 | No, let's accompany your girlfriend. 37 | 38 | ## Thursday 39 | 40 | No, go to your girlfriend's chest. 41 | 42 | ## Friday 43 | 44 | ### Projectile Theory Break 3 Despair 45 | 46 | Same as before. 47 | 48 | ### 半田君传说 49 | 50 | Look at the introduction of the 坂本君 like July, but it is not the king, it is the dying king XD 51 | 52 | ### ReLIFE 53 | 54 | The Nite male lord eats APTX4869 and returns to the age of 17 to re-experience high school life and legally soak female high school students. 55 | 56 | ## Saturday 57 | 58 | ### 91Days 59 | 60 | This is a story about revenge (darkness. 61 | 62 | ### 食戟之灵 Season 2 63 | 64 | Does the drug king still know, I like Alice. 65 | 66 | ### Time Travel Girl 67 | 68 | I like time-traveling classes, such as the previous "girls who travel through time and space." 69 | 70 | ## Sunday 71 | 72 | ### 情热传说 the X 73 | 74 | Ufotable produced, of course, do not need money. 75 | 76 | ### DAYS 77 | 78 | The animation of the football class, I saw a set of episodes. I feel that the football-related characterization is not bad. I believe it will be a very burning story. 79 | 80 | ### Seven Great Crimes Season 2 81 | 82 | Only four episodes, Elizabeth powder as OVA! 83 | -------------------------------------------------------------------------------- /example/_posts/2016-front-end-primer.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Beginner's Guide to 2016 3 | subtitle: JavaScript is supposed to be easy and powerful, for all of us. 4 | date: 2016-02-06 15:10:05 5 | tags: 6 | - javascript 7 | - frontend 8 | --- 9 | 10 | At the beginning of the year at V2EX, I saw a lot of people posting questions about how to get started. Let me share my experience. 11 | 12 | Maybe you don't know who I am, but if you are interested in the front end, you can contact me to help you with the Review code and provide suggestions for improvement. This is my [GitHub] (https://github.com/egoist) address. 13 | 14 | I assume that the reader has only learned about simple HTML/CSS. 15 | 16 | ## HTML 17 | 18 | HTML doesn't have anything without CSS. It's equivalent to naming each area of ​​the page and then allowing you to do more. For example, the head navigation bar, you often give it a name called `header`. 19 | 20 | ## CSS 21 | 22 | CSS is an acronym for Cascading Style Sheets, a language used to define the presentation of your HTML. For example, let the text in your HTML display different fonts, and one element displays different heights. 23 | 24 | ## HTML+CSS 25 | 26 | Both HTML and CSS are languages ​​that are very grammatically loose, which makes them very easy to get started with, but once the amount of code gets bigger, it can be difficult to maintain. 27 | 28 | ### Template Engine 29 | 30 | Suppose you have two web pages, they share a single header, and then only the content part shows different content. You can only do two web pages in the existing knowledge background and copy the code of the navigation bar twice. . 31 | 32 | So with a template engine, such as [pug] (https://github.com/pugjs/pug), it allows you to reuse duplicate templates, reduce code size, and improve maintainability. 33 | 34 | ### CSS Processor 35 | 36 | Look at the following code: 37 | 38 | ```css 39 | .post { 40 | Font-size: 14px; 41 | -webkit-box-shadow: 0 0 1px #ccc; 42 | -moz-box-shadow: 0 0 1px #ccc; 43 | Box-shadow: 0 0 1px #ccc; 44 | } 45 | 46 | .post .post-content { 47 | Font-size: 16px; 48 | } 49 | 50 | .post .post-content .post-date { 51 | Color: #999; 52 | } 53 | ``` 54 | 55 | You will find the above `box-shadow` written three times to support the `box-shadow` attribute in different kernel browsers. 56 | 57 | Also, as the amount of code increases, long definitions like `.post .post-content .post-date` will get longer and longer. 58 | 59 | This is the code after the CSS processor: 60 | 61 | ```css 62 | .post { 63 | Font-size: 14px; 64 | Box-shadow: 0 0 1px #ccc; 65 | .content { 66 | Font-size: 16px; 67 | .date { 68 | Color: #999; 69 | } 70 | } 71 | } 72 | ``` 73 | 74 | Nested styles make the scope clearer, and you can use only standard CSS properties whenever possible and then let the CSS processor help you with other browsers. It is recommended to use [PostCSS] (https://github.com/postcss/postcss), which does not change your CSS code itself, but it abstracts your code into a JavaScript object that allows you to do whatever you want with the plugin. For example, implementing nested styles and automatically adding the prefix `-moz` `-webkit`. You can write your own plugins and it already has a lot of [off-the-shelf plugins] (https://github.com/postcss/postcss/blob/master/docs/plugins.md) for you to use. 75 | 76 | The thing to remember is that it just converts your custom CSS style** into a browser-compliant CSS. Why? Standard CSS is not good enough, such as the problem you just encountered. 77 | 78 | ## HTML+CSS Summary 79 | 80 | Now that you know what HTML/CSS can do when you use it together, you know that using the template engine and CSS processor can make you better write HTML/CSS. Keep in mind that "better" may only be more noticeable when the amount of code increases. 81 | 82 | So how do you implement these template engines and CSS processors? Many are using JavaScript. 83 | 84 | Recommended reading: [Learn to Code HTML & CSS] (http://learn.shayhowe.com/html-css/) As with its loose features, you need to use more to get a better grasp of usage. 85 | 86 | ## JavaScript 87 | 88 | JavaScript is a real language that is simple and powerful. (hereinafter referred to as JS) 89 | 90 | Just as HTML/CSS is a style rendering for web pages, JS (in the past) is used for web page interactions, such as a user clicking a button and popping up a box, which requires JS to complete. 91 | 92 | JS itself does not have the function of "listening user clicks". In the browser, modern browsers have built-in web page DOM API, which provides a set of JS interfaces, so that you can use JS calls to implement the functions. The functionality itself is based on a lower level C/C++ language. 93 | 94 | Therefore, a qualified front end needs to master the basics of JS, such as variables, arrays, functions, and the characteristics of almost all languages, and then the DOM API. The lack of this implementation of web page interaction is a piece of paper. 95 | 96 | Recommended reading: [MDN Web API] (https://developer.mozilla.org/zh-CN/docs/Web/API) is very comprehensive and requires a more gradual guideline for Google. 97 | 98 | As for learning the language of JS, I recommend three well-known ones. You don't need to look at it all. Pick one or two books and try to figure it out: 99 | 100 | - [JavaScript Definitive Guide] (https://book.douban.com/subject/10549733/) 101 | - [JavaScript Advanced Programming] (https://book.douban.com/subject/10546125/) 102 | - [The essence of JavaScript] (http://book.douban.com/subject/3590768/) 103 | 104 | 105 | ## Node.js 106 | 107 | As I said earlier, the past JS is the JS itself plus the browser's DOM API, so some people think of it: Can you replace the browser DOM API with the API of the user's operating system? This way JS looks more like a "real language" that can be run in the user's local environment and not just in the browser. 108 | 109 | Fortunately, the JavaScript runtime environment (v8) used by Google Chrome has evolved to convert JS code to machine code very quickly in recent years, so the pioneers of Node.js set up this organization, based on Chrome v8. The engine implements a cross-platform JavaScript runtime environment - now very popular Node.js. 110 | 111 | --- 112 | 113 | Is this feeling good? JavaScript developers' tools can also be developed in JavaScript! This is the premise of "easy and powerful" described in the subtitle. 114 | 115 | ### How to learn Node.js 116 | 117 | It's a big deal, if you know how to learn JavaScript before. It's nothing more than JS itself plus the API provided by Node.js. You can view the API directly by opening the Node.js website. 118 | 119 | Node.js is just a running environment, similar to the Java JVM, and the most important thing is the JavaScript itself. 120 | 121 | ## ES6 122 | 123 | It's very likely that you are now using the ES5 standard JavaScript syntax, and ES6 is the new language standard introduced in 2015 by TC39, the organization responsible for developing JavaScript language standards. 124 | 125 | **Why should I learn a new ES6 standard?** 126 | 127 | - you should not. Because ES6 and any new JS standards in the future are backwards compatible, meaning that any code you write now is also compliant with future versions of JS. 128 | - why not? Try it and don't get pregnant, and you will have a bright feeling. Any language is evolving, especially as the front end develops so fast. 129 | 130 | It’s almost the same, but you might wonder why you didn’t introduce how to learn some JS frameworks? Such as jQuery, Angular, React, Vue. 131 | 132 | OK, the next issue is an introduction to these frameworks, and some build tools and other related content will be introduced in the future. 133 | -------------------------------------------------------------------------------- /example/_posts/5-12-memory.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 5·12 What am I doing that day? 3 | date: 2017-05-12 20:44:40 4 | tags: 5 | --- 6 | 7 | For things that were a long time ago, such as what I am doing, what I am thinking, my memory is very vague, which is the inevitable result of the abuse of male special abilities. 8 | 9 | However, the day nine years ago was very special. At that time, I was still a second-year junior high school student, which was in the literal "Secondary" stage. At that time, I seemed to be in the middle of my life. I learned that I was the top four in my grades. At a certain event in the school, there were girls who confessed to me. This is what I don’t dare to think about now. She is not at all. Know me, just know that my grades are good to express my feelings. I was very surprised that day. I had lunch at noon and I ran to the top floor corridor alone. Looking at the distance from the railing, I could only feel the warmth of the sun shining on me. After that, I came to the conclusion that I like summer. After all, this allows me to enjoy such a pleasant time. At that time, I was a self-proclaimed "winner of life" with little but full content. 10 | 11 | But no matter how strange the behavior of human beings, there must be a reason. I am no exception. I found some clues along the memory. From the top of the building, I went back to the classroom and started to take a nap. Before I walked to my seat, I had to go through her seat. It turned out to be the case. I used to have this unrequited love in adolescence. I passed in front of her and was noticed to be happy all day. 12 | 13 | At that time, my favorite thing was the exam, because this is the only way to not judge the value of the students correctly. I have achieved some impressive results by relying on it. I liked to watch those who were judged as "no value". The expression of the classmates. At the beginning of the afternoon, it was a biology class. It was also a monthly test. I know that it should be high. After the exam went very smoothly, I swung the pen quickly and wanted to finish early and then leisurely watched the answer in the seat. I wanted to play something fresh, so I tried to stand up the bench and just sit on the back of the two bench legs. Then I created a movement similar to 噗 噗 or 咔哒, and even felt the vibration from the wall. "It must be that the nearby construction site is repairing the house, and the one that knocks down the bungalow in a slap in the face." I often see this kind of thing near my home. There is nothing wrong with this association. But I don't give me more time to think, even the desks, the ceiling fans that give us hard service, the glass that I have broken the ball, and the biological teacher who has no face to love! 14 | 15 | "Run! Zhu JJ!" 16 | 17 | This is a slightly echoed shout from the biology teacher. She is calling her son of one meter eight and seems to be sitting near me. And I don't know where the brain is on the foot, grab the test paper and run out! When I ran to the door, I couldn’t feel the turmoil in the classroom, because the whole building was shaking. If it wasn’t happening to me, it’s just a disaster film for entertainment. And write a film review - "Really make me feel like I want to vomit" and then recommend it to others to watch. Unfortunately, this is not the case. The first time I saw the corridor that was being squeezed, I went downstairs and looked back at the top floor. It’s hard to believe that I was still there to sing a few hours ago, and now I even have a sister. They didn't have time to look at it and rushed through the crowd. 18 | 19 | When I got to the playground, I felt that I should be safe. I took out the test paper and showed off my spirit to the students around me. At the same time, I also successfully concealed the embarrassment of panic. There are seven hundred people on the playground. It is probably the opportunity for a small number of teachers and students to gather together. The younger brothers and sisters of the third grade will not waste time on the playground. After passing through the mouth, I learned that the school asked us to rest on the playground and wait for our parents to pick up. 20 | 21 | At the time, I didn't have a mobile phone, and God knew how to contact my parents. 22 | 23 | I didn't have a mobile phone at the time, and of course I didn't have a computer. I didn't even have a QQ number. I know the earthquake, but I don’t know anything else. I think it’s not just my school earthquake, I still know. I was very tired. When I waited for 700 people to wait for 400 people, I remembered that I had a secret to pass the time and forgot to use it. So I invited a dead party to run to urinate, and made a pass when she passed by her side. I want to get some attention when I step on the bicycle, but I don’t know the effect. 24 | 25 | After repeating several similar behaviors, I seem to be more tired. I started to scream at these teachers in my heart. The rules for not doing shit should wait until the parents come to pick up. I also began to regret my behavior, probably before the behavior. Will be treated as a neuropathy. Then I felt that the fire in the sky had to be burned to the ground. The class teacher said, "Let's go, classmates, it's too late to go home and be careful." Thankfully, I also learned the good news of the specific notices such as the resumption time. 26 | 27 | I liked to observe everything around me at that time. I always felt that the weather was quite wrong. In my words, it was red in the sky, but it was very gloomy. There was also a demon wind. On the way home, I felt that everyone was very excited. I also No exception, I want to go home and watch TV all the way to know what happened. My family is actually the shop my parents opened. I lived in the store with my parents. When I got home, I saw that they dragged some things out and put them on the street. It seems that they are preventing something and then attracting me. It is an instant noodles and a box of mineral water. I have never seen these two things in the "pieces" at home. I am very happy. 28 | 29 | However, I never expected to spend the next week in instant noodles and more horrible things happened. 30 | -------------------------------------------------------------------------------- /example/_posts/Hello-World.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Hello World 3 | date: 2015-09-23 01:09:15 4 | categories: 5 | - Diary 6 | tags: 7 | - start 8 | --- 9 | As you can see, yet another Hello World post is written by me, I cannot even remember how much time I've spent in writing such silly posts. 10 | 11 | Another bad habit I had is I keep doing "Hello World" stuffs, that means I am afriad of those hard challenges. I'm pretending that I was busy by doing easy things, I can never be able to face the real me myself until I can make up my mind to skip those "do-it-happily" stuffs. No pains no gain is so easy to read, and so hard to perform. 12 | -------------------------------------------------------------------------------- /example/_posts/a-light-weight-localstorage-orm.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: A simple localStorage extension implementation 3 | date: 2015-09-30 12:56:03 4 | tags: 5 | - localStorage 6 | categories: 7 | - JavaScript 8 | --- 9 | 10 | I used to do something like `orm` of `localStorage`, which allows you to simply manipulate `localStorage` just like you would with a database. This library was created because it is intended to be a notebook and other applications that need to store notes locally and make it easy to query. 11 | 12 | You can simply preview it: 13 | 14 | ```javascript 15 | // localdb will automatically generate `_id`, `index` and `createdAt` for the newly inserted collcetion 16 | // and `updatedAt` 17 | // `_id` is an objectId similar to MongoDB 18 | Var User = new localdb('User', 'Array', true) 19 | 20 | Var users = [{ 21 |   Username: 'kevin', 22 |   Age: 16 23 | }, { 24 |   Username: 'joe', 25 |   Age: 19 26 | }, { 27 |   Username: 'zchan', 28 |   Age: 12 29 | }] 30 | 31 | Var opts = { 32 |   Sort: 1, 33 |   sortBy: 'age' 34 | } 35 | Var users_fetched = User.override(users, true).find(null, opts) 36 | 37 | Console.log(JSON.stringify(users_fetched, null, 2)) 38 | ``` 39 | 40 | This will output such a result in increments of `age`: 41 | 42 | ```json 43 | [ 44 |   { 45 |     "username": "zchan", 46 |     "age": 12, 47 |     "index": 2, 48 |     "_id": "560b780cfac748a940e57438", 49 |     "createdAt": "2015-09-30T05:50:04.156Z", 50 |     "updatedAt": "2015-09-30T05:50:04.156Z" 51 |   }, 52 |   { 53 |     "username": "kevin", 54 |     "age": 16, 55 |     "index": 0, 56 |     "_id": "560b780ca4833a2e978efcb2", 57 |     "createdAt": "2015-09-30T05:50:04.156Z", 58 |     "updatedAt": "2015-09-30T05:50:04.156Z" 59 |   }, 60 |   { 61 |     "username": "joe", 62 |     "age": 19, 63 |     "index": 1, 64 |     "_id": "560b780c1d6c1f81ca7bf2e9", 65 |     "createdAt": "2015-09-30T05:50:04.156Z", 66 |     "updatedAt": "2015-09-30T05:50:04.156Z" 67 |   } 68 | ] 69 | ``` 70 | 71 | If you want to query users whose `username` is `zchan`: 72 | 73 | ```javascript 74 | Var query = { 75 |   Username: 'zchan' 76 | } 77 | 78 | Var zchan = User.findOne(query) 79 | 80 | Console.log(JSON.stringify(zchan, null, 2)) 81 | ``` 82 | 83 | This queries and returns an object: 84 | 85 | ```json 86 | { 87 |   "username": "zchan", 88 |   "age": 12, 89 |   "index": 2, 90 |   "_id": "560b780cfac748a940e57438", 91 |   "createdAt": "2015-09-30T05:50:04.156Z", 92 |   "updatedAt": "2015-09-30T05:50:04.156Z" 93 | } 94 | ``` 95 | 96 | `.find` is similar to `.findOne` but does not limit the number and can be sorted, paged, etc. 97 | 98 | Even the `populate` feature of MongoDB is supported, but only one level of nesting can be queried for the time being: 99 | 100 | ```javascript 101 | // populate another class, eg: your Post have a Author field 102 | Const Post = new localdb('Post', 'Array') 103 | Const User = new localdb('User', 'Array') 104 | 105 | // you should have the Author's objectId to create an instance of that class 106 | Const author = User.extend('some_object_id') 107 | 108 | Post.add({ 109 |   Title: 'mt post title', 110 |   Author: author 111 | }) 112 | 113 | // then you can populate that field before .find or .findOne 114 | Post.populate('author').findOne() 115 | ``` 116 | 117 | --- 118 | 119 | For more detailed use, refer to this Vue and LocalDB [TodoMVC] (http://output.jsbin.com/titeve) demo and [API] (https://egoist.github.io/localdb/). 120 | -------------------------------------------------------------------------------- /example/_posts/all-things-last-long.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Everything is long 3 | date: 2015-06-12 16:24:51 4 | categories: 5 | - Diary 6 | --- 7 | Everything that is long will eventually come apart, separate from the mother, and be isolated from each other, but the process is slow and repeated. 8 | 9 | The first time I felt long, it was on a slope. The top-down glide kept me in sync with time. It was a long time for me and my childhood friends. It was like the summer of the year. The sun is generally indelible and seems to be going on all the time. 10 | 11 | The second long time, it is not very glorious, it is a long time under the desk. In the days after the roller skating, my courage didn't get any exercise. It wasn't a long-term thing to not go to the medical examination under the desk, but urinating is something that everyone can't do. In the end, I didn't hold back. I was brought back to my home by the teacher and my older sister in the upper grades. The urinary door became one of the laughing points that I was teased by my sister in the future. 12 | 13 | The third long time is that I am a little older, fifth grade. Several TV station sisters came to the school to find a small reporter for the sports meeting, so there was an interview that everyone could attend. And I also went. 14 | 15 | Maybe when I was a child, I was a child who thought I was very energetic. I was observing the interview situation of each of my classmates before, and now I know that I just thought that only I would do this. 16 | 17 | The classmate in front of me is also the best friend of my elementary school. His interview gave me a sentence that I thought was the most useful. "Children, when you talk later, you have to look at other people's eyes~". So, I seem to emphasize that I have a pair of "big bang" eyes, it is my turn, I just watched the TV station's sister. My sister seemed to know something. Even though I didn't pass it, I gave it a chance to let me write a sports report for her to see. For the first time, I felt the reward that sincerely brought me. As for the so-called long, but when I saw my sister's eyes have me, the time is still gentle. 18 | 19 | There are still a lot of long things. These three paragraphs of life may not be the most memorable, but they are first recalled. 20 | -------------------------------------------------------------------------------- /example/_posts/best-thing-ever.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: The first interesting thing in the world 3 | date: 2015-11-04 23:23:31 4 | tags: 5 | - thoughts 6 | categories: 7 | - thoughts 8 | --- 9 | Wang Xiaobo said that the pleasure of being deprived of thinking is a matter of falling, so watching the most interesting thing on this planet is in any case worth trying. 10 | 11 | The most interesting thing is not that the name is so bad. I didn't mean to look at the animation on the air. I didn't mean it at all. You can't admit it, but it's best not to refute it. Interesting things are not the same, but there is nothing new in the sun. My dad’s interesting thing when he was young is to watch Jin Yong’s martial arts novels. Wang Xiaobo thinks that having a book is the happiest and most interesting, but it can’t be Xiaohongshu, "The fun of being imprisoned" is worse than letting him die. 12 | 13 | Equally interesting is that things haven't changed unexpectedly, and what we find interesting is still the same essence. Now I am happy to watch animation. The interesting places are not experienced by people who don't see it, and even ambiguous. For example, my dad is, "Is it big to watch cartoons?" This is a complaint I recently received, I don't think so. 14 | 15 | Anything can be completely opposite. "Returning to the truth" can get a "naive" and "boring" response. It is difficult for you to explain to the opposite person some obvious but benevolent things. 16 | 17 | But the first fun in the world is irresistible. 18 | 19 | Just like being a person is naturally quite interesting, but some people think that it is also very interesting to be a cat to be a dog. In this case, I naturally would not argue with them. After all, there will be two species of reproductive isolation soon. There is no need for emotional exchanges. 20 | -------------------------------------------------------------------------------- /example/_posts/bili.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Bili: Swiss Army Knife Packing the JS Library" 3 | subtitle: Rollup-based packaging tool 4 | date: 2017-07-08 15:13:17 5 | tags: 6 | --- 7 | ## Preview 8 | 9 | ### Rollup 10 | 11 | [Rollup](https://github.com/rollup/rollup) is similar to the packaging tool like [Webpack] (https://webpack.js.org)/Browserify, but the packaged files are smaller, even if and Compared to Webpack 3. In addition to this, Rollup is mainly used to package libraries and has a very simple API interface. 12 | 13 | ### Swiss Army Knife 14 | 15 | A variety of uses, easy to carry and easy to operate, unexpectedly looks cool. 16 | 17 | ## 授业 18 | 19 | > Student A: I understand the truth, but EGOIST sensei[^sensei]! Why did you roll out the Rollup and sell it? This is not programming at all! 20 | 21 | It's true that this is not something that is difficult or in-depth. It is only used to solve a simple problem: simplify the packaging process and improve people's sense of value and belonging. 22 | 23 | > Student B: Oh? How did it do it, I want to know! Sensei sensei Tell me soon! 24 | 25 | Since this classmate asked me cutely, I will tell you in a simple and easy way! You can find Rollup's API eating method at [WIKI] (https://github.com/rollup/rollup/wiki/JavaScript-API). Simply put, it accepts a parameter, which determines how to find and manipulate you. Source code, such as: 26 | 27 | ```js 28 | Rollup.rollup({ 29 |   // Start with this file: 30 |   Entry: 'src/index.js', 31 |   // Customize how to convert code with a write plugin 32 |   Plugins: [] 33 | }) 34 | ``` 35 | 36 | Then it will return a Promise to send `bundle` to your hand, and you can decide how to generate the file: 37 | 38 | ```js 39 | Rollup.rollup(options) 40 |   .then(bundle => { 41 |     // I want to write to disk! 42 |     Bundle.write({ 43 |       // Wait, Rollup mother, written in commonjs format! 44 |       Format: 'cjs', 45 |       // Give the generated file a name! 46 |       Dest: 'bundle.js' 47 |     }) 48 |   }) 49 | ``` 50 | 51 | > Student C jumped up: EGOIST sensei! This looks so simple, there is no chance for you to play [Bili] (https://github.com/egoist/bili) QAQ 52 | 53 | It's really simple, but you can check out [Vue] (https://github.com/vuejs/vue/blob/dev/build/build.js) and [React](https://github.com/facebook/ The build script for react/blob/master/scripts/rollup/build.js) is incredibly long. 54 | 55 | The lower the level of the API, the simpler it seems, but in larger projects it will be used by experienced developers in more complex ways. People call this the **M attribute**, but this is already here. The scope of the lesson is beyond. 56 | 57 | In short, most projects have the need to generate multiple bundles, such as bundles of different formats, or bundles with different variables. You are bound to use Rollup ** simple APIs to solve these requirements multiple times. And pulling this out and putting it in a separate tool for reuse is what Bili does: 58 | 59 | ```bash 60 | Bili --format cjs,umd,es --compress umd 61 | ``` 62 | 63 | In order to use Bili's full functionality as much as possible directly with the command line, `format` accepts one or more format names separated by commas. Of course, arrays can be inconvenient on the command line. 64 | 65 | Let's take a look at using the original Rollup to write what it looks like: 66 | 67 | ```js 68 | Import { rollup } from 'rollup' 69 | 70 | Function build(format) { 71 |   Const plugins = [ 72 |     // ES2015 -> ES5 73 |     Require('rollup-plugin-buble')() 74 |   ] 75 | 76 |   Let compress = false 77 | 78 |   If (format.endsWith('Compress')) { 79 |     Format = format.replace(/Compress$/, '') 80 |     Compress = true 81 |   } 82 | 83 |   If (format === 'umd') { 84 |     // package the third party module 85 |     Plugins.push( 86 |       Require('rollup-plugin-node-resolve')(), 87 |       Require('rollup-plugin-commonjs')() 88 |     ) 89 |   } 90 | 91 |   If (compress) { 92 |     // compression 93 |     Plugins.push(require('rollup-plugin-uglifyjs')()) 94 |   } 95 | 96 |   Return rollup({ 97 |     Entry: 'src/index.js', 98 |     Plugins 99 |   }).then(bundle => bundle.write({ 100 |     Dest: `dist/index.${format}.js`, 101 |     Format 102 |   })) 103 | } 104 | 105 | Promise.all(['umd', 'cjs', 'es', 'umdCompress'].map(build)) 106 |   .then(() => console.log('done')) 107 |   .catch(err => console.error(err)) 108 | ``` 109 | 110 | It is the feeling of the above, Bili was recently awarded the honorary title of energy saving and emission reduction advocacy pioneer and keyboard life saver by China's super-university computer association, as well as the savior of human brain cells, keyboard player killer, Jean Zhengtai and Loli. These market names are easily packaged. 111 | 112 | [Bili is heavily used in my front-end library] (https://github.com/search?l=JSON&o=desc&q=bili+scripts+build&s=indexed&type=Code&utf8=%E2%9C%93), someone will ask What about CSS and pictures, fonts, etc. For CSS, I generally don't pack it and hand it to the user as it is. The fonts and pictures are generally used in CSS, and naturally the same. Of course, I haven't encountered the need for fonts and images for the time being. 113 | 114 | ## After class 115 | 116 | After school, students will be eager to go home, open the computer and found [Bili] (https://github.com/egoist/bili) [v0.17] (https://github.com/egoist/bili/releases/tag /v0.17.0) Several breaking changes, of course, are changes that can be made in a minute. 117 | 118 | Since then, everyone has lived a happy package life. 119 | 120 | [^sensei]: The meaning of the teacher (センセイ) in Japanese, when the female high school student speaks, can fully express the tension of the language. 121 | -------------------------------------------------------------------------------- /example/_posts/bundle-front-end-js-library.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Elegantly package front-end JavaScript libraries 3 | date: 2016-11-16 15:55:48 4 | tags: 5 | - javascript 6 | - bundle 7 | - bili 8 | --- 9 | 10 | Packaging JS libraries are not as complex as packaging Web apps, but they can be made simpler. 11 | 12 | ## Common Use Cases 13 | 14 | A JS library generally requires a CommonJS version, which does not package modules in node_modules. And a UMD version for direct use in the browser, it will package the modules in node_modules. 15 | 16 | Using [bili](https://github.com/universe-denpa/bili) everything will be simple and simple enough to require only one command: 17 | 18 | ```bash 19 | Bili --format cjs --format umd --module-name MyModule 20 | ``` 21 | 22 | This command means to package `./src/index.js` to the `./dist` directory and convert it to files in the `CommonJS` and `UMD` formats, where the module name in the `UMD` format is set to ` MyModule`, so that it can be referenced in the browser via the global variable `MyModule`. 23 | 24 | If you need a compressed UMD format file at the same time, you can get a `.min.js` and its `sourcemap` file by adding the `--compress` parameter. 25 | 26 | ## ES2015 27 | 28 | One of the goals of packaging is to compile ES next to ES5 using a converter like Babel. By default, bili uses [buble](https://buble.surge.sh/guide) to convert JavaScript code, which is much lighter than Babel. 29 | 30 | You can of course use babel to compile code in bili, which requires the bili configuration file `bili.config.js`: 31 | 32 | ```js 33 | Module.exports = { 34 |   jsCompiler: require('rollup-plugin-babel')({ 35 |     Presets: ['preset'] 36 |   }) 37 | } 38 | ``` 39 | 40 | Bili is based on [Rollup] (https://github.com/rollup/rollup), so the relevant Rollup plugin can be used to compile JS code. 41 | 42 | ## Buble 43 | 44 | As I said before, by default we use `buble`, you can change the buble configuration parameters in the configuration file: 45 | 46 | ```js 47 | Module.exports = { 48 |   Buble: { 49 |     objectAssign: 'objectAssign' 50 |   } 51 | } 52 | ``` 53 | 54 | It's worth mentioning that buble doesn't support `async/await` and can't convert `generator` to ES5 code, so we keep the generator code and use [async-to-gen] (https://github.com/leebyron /async-to-gen) Convert `async/await` to `generator`. If you use both, please consider browser compatibility, or replace it with babel to compile. 55 | 56 | ## Watch mode 57 | 58 | Compiling the code without the `watch` mode during development can be very painful. To open the bili watch mode, you can add the `--watch` parameter directly. 59 | 60 | ## More information 61 | 62 | Bili also has some built-in Rollup plugins. For more information, please refer to bili's [GitHub Wiki] (https://github.com/universe-denpa/bili/wiki) page. 63 | -------------------------------------------------------------------------------- /example/_posts/deploy-node-app.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: How to deploy a Node.js app 3 | subtitle: What do you tell me? 4 | date: 2016-03-23 15:37:20 5 | tags: 6 | - deploy 7 | - node.js 8 | - docker 9 | --- 10 | 11 | When you are familiar with Node.js, you are likely to write small things on your VPS, such as a personal API service or your website. The content shared in this article is relatively applicable regardless of the size of your app, because our principle is "run it forever and deploy it smartly". 12 | 13 | 14 | ## Uploading Code 15 | 16 | The first thing you need is to upload your app code locally to VPS, which we can't upload using the ftp method of the last century. When we develop git to synchronize the code of the local repository and the remote repository, you must have a feeling of trial and error. Similarly, we will also use git to operate here. 17 | 18 | The following can be replaced with the [pod](https://github.com/yyx990803/pod) tool, but you need to manage it with [PM2] (https://github.com/Unitech/pm2) process. And here is a relative general case. 19 | 20 | First we confirm: 21 | 22 | - `/var/repo` - this is the directory where git repo is stored on the VPS 23 | - `/var/www` - This is the VPS website directory 24 | 25 | ### Create an empty repo on the VPS 26 | 27 | ```bash 28 | $ mkdir -p /var/repo/app.git 29 | $ cd /var/repo/app.git 30 | $ git init --bare 31 | ``` 32 | 33 | Now you have a git repository with only version management and no app source files. 34 | 35 | ### Deployed hooks 36 | 37 | You need a hook `git hook`, which is to automatically copy the uploaded file to your website directory after each local git push. Here we use the git built-in `post-receive` hook: 38 | 39 | ```bash 40 | $ cd hooks 41 | # Write content to this file 42 | $ cat > post-receive 43 | # Enter, enter the following: 44 | ``` 45 | 46 | ```bash 47 | #!/bin/sh 48 | Git --work-tree=/var/www/domain.com --git-dir=/var/repo/app.git checkout -f 49 | Cd /var/www/domain.com 50 | Npm install 51 | # Here you can also add some build scripts, such as npm run build 52 | ``` 53 | 54 | Finally, press Ctrl+D to confirm the save. 55 | 56 | In order for you to have permission to execute this file, you need to: 57 | 58 | ```bash 59 | $ chmod +x post-receive 60 | ``` 61 | 62 | ### Local configuration 63 | 64 | Exit VPS: 65 | 66 | ```bash 67 | $ exit 68 | ``` 69 | 70 | Execute in your app directory: 71 | 72 | ```bash 73 | $ git remote add server ssh://user@yourdomain.com/var/repo/app.git 74 | ``` 75 | 76 | Wow, it’s done. Try posting your web app, simply submit it: 77 | 78 | ```bash 79 | $ git add -A 80 | $ git commit -m "deploy to server" 81 | $ git push server master 82 | ``` 83 | 84 | Then check `/var/www/domain.com` and your code is synced. 85 | 86 | ## Run your app forever 87 | 88 | You need to run your app persistently, as it is likely to crash during peak hours, and you also want your app to restart automatically after the system restarts. 89 | 90 | You can do this by referring to the [Ghost Deployment Guide] (http://support.ghost.org/deploying-ghost/#making-ghost-run-forever). Very complete, I won't go into details, but I recommend using Supervisor. 91 | 92 | You can also consider using [docker](https://nodejs.org/en/docs/guides/nodejs-docker-webapp/) this more modern (?) solution. 93 | 94 | ## Extended reading 95 | 96 | - [How to deploy your node app on Linux, 2016 edition] (https://certsimple.com/blog/deploy-node-on-linux) 97 | - [Running your Node & Express apps forever, no matter what, with Systemd and PM2] (https://www.terlici.com/2015/06/20/running-node-forever.html) 98 | - [Should servers have their timezone set to GMT/UTC?] (http://serverfault.com/questions/191331/should-servers-have-their-timezone-set-to-gmt-utc) 99 | - [Operating Node.js in Production] (https://blog.risingstack.com/operating-node-in-production/) 100 | - [How To Use HAProxy to Set Up HTTP Load Balancing on an Ubuntu VPS] (https://www.digitalocean.com/community/tutorials/how-to-use-haproxy-to-set-up-http-load- Balancing-on-an-ubuntu-vps) 101 | - [Node.js Security Tips] (https://blog.risingstack.com/node-js-security-tips/) 102 | -------------------------------------------------------------------------------- /example/_posts/draw-chat-message-with-canvas.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Draw a chat message with canvas 3 | subtitle: I will not learn canvas when I read it. 4 | date: 2017-09-15 21:58:02 5 | tags: 6 | - canvas 7 | - javascript 8 | --- 9 | 10 | I am not a person who is too motivated. I am tempted by most things, and I like to show off some of my own skills. 11 | 12 | I don't know much about canvas because I don't have a place to use it (after all, it's outside my comfort zone). Today I am interested in a long-awaited expression pack, such as one of them: 13 | 14 | sticker 15 | 16 | *[source: https://t.me/addstickers/MadeInBitinn](https://t.me/addstickers/MadeInBitinn)* 17 | 18 | So I want to use canvas to automatically generate one from the user input, although I have never used canvas. But based on the previous experience of [slogan] (https://egoist.moe/slogan/) I started. 19 | 20 | First I have to create a new canvas element I still remember, and then get its 2d context: 21 | 22 | ```js 23 | Const $canvas = document.getElementById('canvas') 24 | Const ctx = $canvas.getContext('2d') 25 | ``` 26 | 27 | Then start rendering, I am temporarily ignored for the left avatar, after all, I do not remember how to render the image, so start with other text, I need to render a username and the date on the right: 28 | 29 | ```js 30 | // Actually, I don’t remember how to render the text. 31 | // Google found out that it is ctx.fillText(text, x, y) 32 | ctx.fillText('EGOIST', 50, 10) 33 | // I reserve 50 width for the left avatar 34 | ``` 35 | 36 | Its effect is: 37 | 38 | ![p1](https://i.loli.net/2017/09/15/59bbe0f394e51.png) 39 | 40 | The user name in the original image seems to be blue bold unknown font, then I also search for APIs for color and fonts: 41 | 42 | ```js 43 | Ctx.font = 'bold 14px sans-serif' 44 | ctx.fillStyle = 'blue' 45 | ``` 46 | 47 | ![p2](https://i.loli.net/2017/09/15/59bbe259e6618.png) 48 | 49 | As I saw the `font` and `fillStyle` set before `fillText`, the reason is obvious. 50 | 51 | --- 52 | 53 | Next to render the date on the right, I need to know the width of the username, and I clearly remember that I can get it with `ctx.measureText`: 54 | 55 | ```js 56 | Const usernameWidth = ctx.measureText('EGOIST').width 57 | // Reset the font and color or it will be the same as the username 58 | Ctx.font = '14px sans-serif' 59 | ctx.fillStyle = '#666' 60 | // The `x` of the time is the width of the username + the width of the reserved avatar + the distance from the time to the username 61 | ctx.fillText('2017/7/7', usernameWidth + 50 + 10, 15) 62 | ``` 63 | 64 | ![p3](https://i.loli.net/2017/09/15/59bbe4404645e.png) 65 | 66 | --- 67 | 68 | Next is the body of the message, it may be multi-line and canvas can't automatically wrap, we need to manually identify it based on the newline `\n`: 69 | 70 | ```js 71 | Const content = `hello world 72 | Goodbye world` 73 | 74 | Content.split('\n').forEach((text, index) => { 75 |   ctx.fillText( 76 |     Text, 77 |     / / Reserve the width of the avatar 78 |     50, 79 |     // content distance from the top + approximate height of each line 80 |     30 + 15 * index 81 |   ) 82 | }) 83 | ``` 84 | 85 | ![p4](https://i.loli.net/2017/09/15/59bbe6a3a24df.png) 86 | 87 | --- 88 | 89 | In the end, only the avatar is left. I know I need an `input` element to get the image file, and then somehow let `ctx` render it: 90 | 91 | ```html 92 | 93 | ``` 94 | 95 | ```js 96 | document.getElementById('avatar').addEventListener('change', e => { 97 |   Draw(e.target.files[0]) 98 | }) 99 | 100 | // The following content is basically copied from StackOverflow 101 | Function draw(avatar) { 102 |   // draw an avatar 103 |   Const img = new Image() 104 |   Img.onload = () => { 105 |     // avatar actual width 40 106 |     // The remaining 10px is the margin to the right 107 |     ctx.drawImage(img, 0, 5, 40, 40) 108 |   } 109 |   Img.src = URL.createObjectURL(avatar) 110 | 111 |   // ... draw something else 112 | } 113 | ``` 114 | 115 | ![p5](https://i.loli.net/2017/09/15/59bbe9cc75c16.gif) 116 | 117 | --- 118 | 119 | The completed code can be found at: https://codepan.net/gist/6630c3910af4495ad06be5426db6c3f8 120 | The original version written in Vue can be found at: https://codepan.net/gist/a4d31a6dc1ac7517bd5d80dc62af1930 121 | Website: https://chat-meme.egoist.moe 122 | 123 | ##后日谈 124 | 125 | The code here may have problems with the way the height of the text is obtained, such as `content` the height of each line. I am the visually `15`. There will definitely be some deviation here. It seems that the height of each line can be approximated as approximately. Equal to `ctx.measureText('M').width`, but don't know if Chinese will be too much, there should be a better and more elegant solution. I am good at scratching, I don't want to ask questions here. 126 | 127 | The main purpose of writing this article is to show off my stupid way of writing code for future generations and let the readers gain confidence in the code, you may be much better than me. 128 | 129 | lol 130 | -------------------------------------------------------------------------------- /example/_posts/front-end-frameworks.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Front end frameworks overview 3 | subtitle: Do you really need frameworks? 4 | date: 2016-03-21 13:31:32 5 | tags: 6 | - frontend 7 | - javascript 8 | - js 9 | - bootstrap 10 | - jquery 11 | - vue 12 | - react 13 | - mvvm 14 | --- 15 | The front-end framework is a very popular word (Buzz word) in the near future. Let me introduce the mainstream framework and help you distinguish what is the real front-end framework. 16 | 17 | ## popular vocabulary 18 | 19 | When you talk about the front-end framework, you will hear some seemingly high-level words, such as `mvvm` `vdom` `view layer` `unidirection` and so on, and what these people call "framework": 20 | 21 | - Bootstrap 22 | - jQuery 23 | - BackBone 24 | - AngularJS 25 | - React 26 | - Vue 27 | 28 | ## Frame chaos 29 | 30 | ### Bootstrap 31 | 32 | Is Bootstrap a framework? Yes, even if it's just a collection of common CSS and jQuery plugin**, it's still a framework. But it's more of a collection of common code snippets than a framework that brings design patterns. 33 | 34 | Bootstrap brings you a grid system, which is a preset button, form, list, navigation, responsive style, etc. It is very useful when you are developing independently, because it saves time for "designing web pages". Moreover, the style of this preset is "not ugly", and naturally it is favored by many companies "pre-exploration". 35 | 36 | I prefer to refer to Bootstrap as a UI library, just like [purecss] (http://purecss.io/), [Foundation](foundation.zurb.com). Of course, the recently used UI library [weui] (https://github.com/weui/weui) used by the WeChat mobile terminal naturally belongs to this category. 37 | 38 | ### jQuery 39 | 40 | jQuery is a phenomenon that redefines the behavior of dom operations. 41 | 42 | In a sense, jQuery is a framework because it makes direct manipulation of dom for UI interaction a design pattern (laughs). This is a joke, jQuery can only be seen as a more abstract DOM API, to make up for the lack of the native DOM API, and to add a lot of commonly used helpers. 43 | 44 | The common web design patterns are MVC and MVVM, and another difference between them and jQuery is the processing of data. Code written in jQuery often uses dom to deal with data directly, and needs to "manually" update the page. On the other hand, MVC and MVVM usually store data on the model layer, and implement more efficient page rendering and updating through a certain binding mechanism. 45 | 46 | ### BackBone 47 | 48 | BackBone is often used with jQuery, MVC mode + a highly abstract DOM API that has conquered many developers. 49 | 50 | However, BackBone is often criticized as "not MVC" MVC, because it is difficult to reasonably use the code written in jQuery to generalize in MVC mode. In my opinion, this is because there is no standard View layer. Organize dom related code. 51 | 52 | ### Angular/Vue/React 53 | 54 | See http://cn.vuejs.org/guide/comparison.html for details. 55 | 56 | ## My choice 57 | 58 | In my opinion, Vue and React are more modern choices. The learning curve of Angular 2 looks so steep that it makes me daunting, and there are fans who can try it. 59 | 60 | The biggest difference between Vue and React is the community's activity and maturity. 61 | 62 | The React community seems to be active and mature, but the so-called best practice is endless. Sometimes [a thing] (http://sam.js.org/) can be used to show off and change the name. 63 | 64 | The Vue community seems to be more authoritarian, and the status quo is that all the chicory [small right] (http://evanyou.me/) is the leader. This is not bad, very good, there are many people who follow the right thing and there is nothing wrong with it. And now the community is booming, and Xiaoyou himself has started to develop Vue and related ecological components full time. 65 | 66 | ## How to learn a framework 67 | 68 | ### 基本 69 | 70 | First of all, familiar with this framework is the most basic, by reading some of the official guides and doing it yourself, such as trying Vue on [JSbin] (http://jsbin.com/). In this regard, Vue's [official tutorial] (http://cn.vuejs.org/guide/) is an industry model from the shallower to the deeper. 71 | 72 | ###生态 73 | 74 | A framework without ecology is not long-lived. One of the importance of ecology is to save developers time for repetitive work. So the next step is to have a broad understanding of the ecology. For example, if you use React as a dodomvc, you can check out [awesome-react] (https://github.com/enaqx/awesome-react), usually there will be some before. A guide written by people. 75 | 76 | ### Continuous learning 77 | 78 | I think that a good habit as a developer is to "try everything to solve as much as possible". Some things are clear to you once, and you don't have the experience you have solved yourself. It is difficult to bypass similar problems next time. 79 | 80 | "Self-solving" does not mean that you are a party, but that you can never go to Google~~ Baidu~~, can~~ Baidu~~ Never ask questions, can ask questions as much as possible, and describe them clearly. Can it be solved by Google? 81 | -------------------------------------------------------------------------------- /example/_posts/fuuka-fate.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: The past and present of the wind and summer 3 | date: 2017-02-11 19:59:29 4 | tags: 5 | - fuuka 6 | --- 7 | 8 | Feng Xia’s father was the representative of Japan who won the runner-up of the 100-meter runner-up in the World Athletics Championships. It is a legend. 9 | 10 | Yamato is a layman of the so-called athletics, and his physical strength may be the only thing he can do with his relationship. Going to the high school in Tokyo from the hometown of the country undoubtedly broadened the vision of Yamato. The first time I visited the new school, I realized the beauty of sports. A short-haired girl dressed in a unique umbilical dress with track and field athletes eagerly tried to see the girl suddenly rushed to accelerate around. The arc came to the crossbar, a sideways, oh wow, a great leap! 11 | 12 | Yamato looked at it, the girl's upper body gradually paralleled and crossed the crossbar. The parabola formed by the crossbar and the girl's eyes, chest and legs will make the Yamaha seem to have a real feeling in the stadium. 13 | 14 | If such a scene can't make Yamato fall in love with her at first sight, then what is the real meaning of these words at first sight. This girl like a breeze blows into the heart of Yamato and opens up the story of Yamato and the cool breeze. 15 | 16 | Telling the first sight of the parents in the summer, it is said that the windy summer has ended. Yes, the wind is dead in summer, and it’s dead. Yamato and the cool breeze have gone through a lot of things, and even finally because the breeze pregnancy both gave up academics and track and field and began to enter the society, maintaining a family, and the just-born autumn months and summers composed of a family of three. 17 | 18 | In the end, the daughter who made them make a big decision in life simply disappeared. Does it make sense, does it make sense, and where is the meaning? 19 | 20 | This is not just a dream involving the big and the cool breeze. Doesn't the wind and summer have it? Yes, the wind and the summer have grown up. At the age when Daiwa and the cool breeze first met, I also had what I wanted to do. Wind and summer do not like mobile phones, because using mobile phones to play games online to maintain virtual interpersonal relationships is not as real as the reality, Feng Xia likes to listen to songs, often wearing headphones standing on the school rooftop looking at the summer scenery. 21 | 22 | The wind and summer are extremely smart, and the lively and cheerful character makes it difficult for you to think of her quiet side. Listening to the song on the rooftop is enough to get the admiration of the cool breeze across the crossbar. 23 | 24 | Feng Xia’s boyfriend is a young man who is addicted to Twitter and is also her classmate. When he suddenly turned to the wind and summer class, there was a thing that was broken by the wind and summer as a metamorphosis of the sneak trousers. It's hard to imagine that the summer without a mobile phone will be with him, but what's the problem? 25 | 26 | The day of the wind and summer accident was originally the day when her dream began. The arrival of excellent makes Feng Xia find what he wants to do. It is not so much a kind of guidance as an encouragement. He likes to praise the sound of summer and summer, and sings songs to be pure and powerful, like an ethereal penetration. . The sound of the wind and summer is also very good, so I have a good name in front of the eight statues, so that everyone around me has committed snoring. If you say that you want to be a band, there is no problem with the sound of the wind and summer. It is better to say that it is too good to say that there is no problem. It is a waste of not making music. That's it, this day was originally the first time that Feng Xia and You's band debuted, but the wind and summer suffered a car accident on the road. 27 | 28 | During the competition, the summer was slow, and there was no way to contact the summer without using a mobile phone. The members of the band and the organizers pushed the position of the lead singer. The final result made everyone on the scene stunned. The original genius song like the wind summer is still owned by this band! 29 | 30 | But all this seems to have no meaning, there are some things that can't be avoided. After the game, I sat on the side of the road that I had traveled in the summer, and the mobile phone in my hand had already been turned off. The little child passing by the road looks very curious and asks: Big brother, are you waiting for someone?诶 If you have no power, please call your girlfriend. Excellent looks like usual, just holding the bench with both hands: Yes, but my girlfriend doesn't need a mobile phone. 31 | 32 | I am very self-blaming. Why didn’t I go to the competition with the wind summer? Why did the wind and summer die and I didn’t have the courage to renounce myself? The straight expression on my face tried to maintain the appearance of a normal person. 33 | 34 | However, the wind and summer did leave, and after that, I wanted to continue to realize the ideal of the summer. After many persuasion, the band members also came back again. After all, they were members of the summer and summer. After the wind and summer left a year, the second match came. 35 | 36 | That is, one night, I came to the vicinity of the competition venue, and the exit from the station was attracted by the songs from the crowd. Isn't this the summer and his favorite "star-falling town"? Through the crowd, I saw the girl who played the guitar singing, although it is not long hair, although it is similar, but this girl and the summer is still somewhat different, the wind summer can not play the guitar. If the summer is like an angel, and this girl is like an elf who appears in front of the good. 37 | 38 | Suddenly the chill felt that I realized the time. There was no one around me. Some girls were still playing. You try to ask: When do you want to play, although I also like to continue listening, but it is not safe for girls to go home so late. The girl listened to the unhappy look: Hey, who told you to be so fascinated, so how can I leave myself alone! When he was in a good mood, he was red, but fortunately someone came to solve the problem. Unfortunately, the attendant was the station manager, and he came up fiercely and asked: "What are you doing here, you have to spread it elsewhere!" When the girl sees this situation, she picks up the guitar bag and gives it to her: Run! 39 | 40 | After listening to the wind for a while, the girl called the best stop: now it should be no problem, take a rest on the steps. The girl's dress is very modern, and the guitar is very good. The black short jacket is a sexy but steady vest, and the short jeans are worn below. Some are unnatural and want to find some topics: Your song is really nice, I happen to be a band, come here to participate in the competition. The girl was a little surprised to hear that her band would also appear in the game, so she opened the joke and gave her a sing. Singing a piece of "star-falling town", the girl seemed to be very fascinated, and the two actually sat singing and singing the next morning! In the end, this girl who wants to be strong and the best agreement must decide the outcome in the game field: You call it excellent, it is really strange to not use the mobile phone, but it doesn’t matter, anyway, I will meet in the game in a few days. 41 | 42 | Excellent: Right, you haven't said what you are calling! 43 | Girl: Wind summer, Bijing wind summer. 44 | -------------------------------------------------------------------------------- /example/_posts/git-memo.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Git memo 3 | date: 2015-10-07 21:18:54 4 | tags: 5 | - git 6 | categories: 7 | - git 8 | --- 9 | 10 | Some common operational notes for Git. 11 | 12 | ## Starting 13 | 14 | After installing Git, configure your profile: 15 | 16 | ```bash 17 | #Configuring username 18 | Git config --global user.name "Your Real Name" 19 | # Configure email address 20 | Git config --global user.email you@email.address 21 | ``` 22 | 23 | Then generate an SSH key: 24 | 25 | ```bash 26 | Ssh-keygen -C 'your@email.address' -t rsa 27 | ``` 28 | 29 | **Initialize a project** 30 | 31 | ```bash 32 | # Initialize the git project 33 | Git init 34 | # Add a source called origin 35 | # Using ssh address 36 | Git remote add origin git@github.com:username/reponame.git 37 | # Login to https address using username/password 38 | Git remote add origin https://username@password:github.com/username/reponame.git 39 | ``` 40 | 41 | **Push to server** 42 | 43 | ```bash 44 | # Record all newly added and deleted files 45 | Git add -A 46 | # Update reason 47 | Git commit -m "message" 48 | # Push to the server side 49 | Git push origin master 50 | ``` 51 | 52 | **Update to local ** 53 | 54 | ```bash 55 | #源 + branch name 56 | Git pull origin master 57 | ``` 58 | 59 | **Clone project** 60 | 61 | Useful when downloading code: 62 | 63 | ```bash 64 | # clone to a folder named after this project name 65 | Git clone https://github.com/username/reponame.git 66 | # clone to your custom folder 67 | Git clone https://github.com/username/reponame.git name 68 | ``` 69 | 70 | *Keep Updating...* 71 | -------------------------------------------------------------------------------- /example/_posts/good-and-bad-anime.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 动漫与成见 3 | date: 2015-03-25 09:04:00 4 | categories: 5 | - Anime 6 | --- 7 | > 你知道动漫吗?也许你知道的动漫在你眼中代表着“幼稚”、“脱离现实”的东西,很可惜,你在以偏概全,或者你在用老一套的成见来看待自己不了解的世界。 8 | 觉得动漫是脱离现实的人也许忘了这和画画,和你听音乐,和你吃饭没什么不同,来源于生活进而表达生活,只是你的眼光太过狭隘。 9 | 撇开拉低智商的中国动漫不看,种类繁杂的日本动漫不管你是什么水平什么阶层什么年龄都能满足。 10 | 而有的人看了一部“喜羊羊与灰太狼”就叫苦不迭,誓死与动漫绝缘了。对此,我什么都不会说,只是摇头。 11 | 12 | 现在我这个年龄阶段的中国人基本是看动漫长大的,而比我更小的接触动漫还更多。小学四年级在我的学校就掀起了动漫热潮,那时候最火的的是四驱兄弟和火影忍者,我小学有三年都是报了学校航模兴趣班,原因就是老师会教组装四驱车,我从这些课上了解了马达、四驱和电池等等在那个时候对我来说堪称神奇的东西,小学前三年我在书法班度过,后三年在航模班。当然,后三年也是属于火影的,那个时候我们学校大门外就是卖各种火影周边的小商贩,而我们能承受的就是贴纸了,于是每每有休息时间大门那就会围上一群人,从铁栏里传递着各种另我羡慕的东西。而我的各种书的封面也被我贴上了这些琳琅满目的珍品。 13 | 14 | 动漫无意是我小时候珍贵的回忆之一。 15 | 16 | 而到了我现在这个年龄,中国大学生看动漫这件事似乎是被认为不成熟和“活在虚拟世界”以及“脱离现实”的。的确,中国的动漫不太适合学龄儿童观看,比如喜洋洋和灰太狼就完全可以加上一个降低中国儿童平均智商的罪名,而很多日本动漫的水平完全凌驾于这些批评者的智商之上,所以这再次印证了那句——“井底之蛙的批评者是活在精神世界最底层的人”。 17 | 18 | 很多人认为现实就是每天的日常生活。还有很多人认为看电影也算是活在虚拟世界,成天挂在嘴上的就是那句“你以为是电影啊……”,这些人活得太累,把现实看得太现实,我所知道的美国片确实和这些人想得差不多,“活在虚拟世界”,而有些欧洲片片中的女演员的一段床戏脱衣服居然可以脱得那么自然,自上而下脸上泛着红晕这感觉却又如此奔放,完全不会像美国片那样矫揉造作般的演技,这种比生活还生活的东西,你只能在电影中看到。 19 | 20 | 大多数人都是想和主流社会的想法趋于一致的,他们其实没有明辨是非的能力。比如对待同性恋,二战时期对待同性恋就是“烧死他们!烧死他们!”,在那个时候这句口号如同真理。而现在似乎社会恍然大悟般,虽然明着维护同性恋的权利,但是街上的路人们大多还是在偷着议论。一个社会的价值观都能发生如此大的转变可想这个社会到底有什么是对的什么是错的。电影「后会无期」里有句至理名言——小孩才看对错,成年人只看利弊。意思大概就是如果你不想装傻就给我认了吧,你只能这样。而有些人选择了装傻,他们就是王小波笔下的“沉默的大多数”中的一部分。他们被认为是弱势群体,因为他们不说话,谁知道他们已是另一个境界的人。 21 | 22 | 扯远了,再说说动漫。对于电影人们要求的是剧情和演技,而对于动漫自然也有剧情,不过演技则换成了画风和声优。画风自不必多说,个人见解不同,不过声优们绝对是公认的神一般的存在。在电影中你也看到过声嘶力竭,泪眼朦胧,不过绝对不会比声优们体现得更淋漓尽致。电影也有声优不过配音往往都是要按着演员的情绪状态来调整的,而动漫中的人物表情无疑比电影中看到的更夸张更解放天性,因此这样的配音也更为接近自然。而更大一部分则是日本声优的功劳,我昨天还分别看过一部动漫的国语版和日语版,国语配音显得极其平淡,而日语则抑扬顿挫感情充沛。 23 | 24 | 最后还是要告诉那些对动漫有成见的人,你看待一件事物是怎么的取决于你看到的是它的哪个部分,比如有人看 A 片纯粹为了手淫,而有些人则是为了学习经验来改善夫妻性生活质量,这个世界上除了科学没有对或错,有的只是固守的执念和狭隘的心胸。 25 | -------------------------------------------------------------------------------- /example/_posts/how-does-array-slice-call-arguments-work.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: '[].slice.call(arguments) 是如何工作的' 3 | date: 2015-12-13 22:39:30 4 | tags: 5 | - javascript 6 | categories: 7 | - javascript 8 | --- 9 | 首先 `.slice` 这个方法在不接受任何参数的时候会返回 `this` 本身,这是一个 `Array.prototype` 下的方法,因此 `this` 就是指向调用 `.slice` 方法的数组本身。 10 | 11 | `arguments` 是什么? `arguments` 是属于函数内部的变量,其值是函数参数列表,一个类数组对象: 12 | 13 | https://codepan.net/gist/edb0a855276de09d24ac0e5621957974 14 | 15 | 类数组对象可以像真正的数组对象一样操作,除了没有 length 属性,但这足以让 `.slice` 方法识别了。 16 | 17 | 你不可能用 `arguments.slice()` 这样的形式调用,因为 `arguments` 本身还是一个非数组对象,只是像数组。这个时候你想到了 `.call` 方法,这个方法让你可以自定义调用函数的内部 this 指向哪里,之前说过,默认是指向调用这个函数的对象。 18 | 19 | ```js 20 | Array.prototype.slice.call(arguments) 21 | // output: 22 | ['hello', 'world'] 23 | ``` 24 | 25 | 这样你就得到了一个真正的参数数组了,而 `.slice` 除了通过 `Array.prototype` 访问当然还可以通过对象直接量访问: 26 | 27 | ```js 28 | [].slice.call(arguments) 29 | ``` 30 | -------------------------------------------------------------------------------- /example/_posts/how-does-nodejs-cli-program-work.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Node.js 命令行程序是如何工作的 3 | subtitle: 命令行程序,也就是通过文本在终端中与程序进行交互 4 | date: 2017-10-18 17:15:45 5 | tags: 6 | - cli 7 | - node 8 | --- 9 | 你可能已经知道,在终端里可以调用不同的解释器来执行你的程序,比如: 10 | 11 | ```bash 12 | # 执行一段 shell 脚本 13 | sh ./foo.sh 14 | # 执行一段 node.js 代码 15 | node ./bar.js 16 | ``` 17 | 18 | 下一步你想做的可能是省略解释器,直接通过运行 `./foo.sh` 或者 `./bar.js` 来执行你的程序。想在命令行输入命令时省略解释器,你可以将它写入实际运行的程序中,比如 `./bar.js`: 19 | 20 | ```js 21 | #!/usr/bin/env node 22 | console.log('bar') 23 | ``` 24 | 25 | 这段程序第一行由两部分组成,即 **Shebang** 和 **解释器命令**。**Shebang** 就是开头的 `#!`,它告诉系统调用后面声明的解释器,而我们需要调用的解释器是 `node`,执行 `/usr/bin/env node` 可以寻找到系统 `$PATH` 里第一个出现的 `node` 命令。 26 | 27 | 这样你便可以通过执行 `./bar.js` 来执行这段程序了: 28 | 29 | ```bash 30 | ❯ chmod +x bar.js 31 | ❯ ./bar.js 32 | ``` 33 | 34 | 第一行的 `chmod +x bar.js` 是让系统允许将文件 `bar.js` 直接作为一段程序运行。现在你可以成功看到期望的输出: 35 | 36 | ![bar](https://i.loli.net/2017/10/18/59e724560f339.png) 37 | 38 | ## 命令行参数 39 | 40 | 在网页应用里,我们依靠 *URL* 来获得展现页面内容所需要的参数,比如依靠路径 `/user/egoist` 来获取数据并渲染用户 `egoist` 的页面。而命令行程序所依靠的便是命令行参数。 41 | 42 | 以刚才的 `bar.js` 为例,假设你需要将 `bar` 字符串重复 n 次输出,而 n 是用户决定的,你会这样做: 43 | 44 | ```js 45 | #!/usr/bin/env node 46 | const times = process.argv[2] || 1 47 | console.log('bar'.repeat(times)) 48 | ``` 49 | 50 | 然后在终端可以看到期望的结果: 51 | 52 | ![process.argv](https://ooo.0o0.ooo/2017/10/18/59e72774a1ce7.png) 53 | 54 | `process.argv` 是实际执行的命令参数列表(数组),比如运行 `./bar 4` 实际执行的是 `node ./bar 4`,第一个参数是解释器命令 `node`,第二个是被执行的程序路径。而我们这里只需要第三个参数。 55 | 56 | --- 57 | 58 | 正如浏览器里的 URL 有相应的各种路由解析库一样,将 `/user/egoist` 解析成 `{ username: 'egoist' }` 之类的,命令行参数当然也有,[minimist](https://github.com/substack/minimist) 便是 node.js 社区里应用最多的一个: 59 | 60 | ```js 61 | const minimist = require('minimist') 62 | 63 | // 大多数情况我们不需要关心 process.argv 的前两项 64 | const argv = minimist(process.argv.slice(2)) 65 | console.log(argv) 66 | ``` 67 | 68 | 使用不同的命令执行一下这段代码试试: 69 | 70 | ![minimist](https://i.loli.net/2017/10/18/59e72c19cea1f.png) 71 | 72 | 之后你便可以灵活地通过 `argv` 来判断如何输出用户期望的内容了。 73 | 74 | **命令行参数小贴士**: 75 | 76 | - 形如 `--foo` 的叫做 `switch`,也就是代表了一个布尔值 `foo: true`,后面不加任何值。 77 | - 一般用 `--no-foo` 来表示布尔值 `foo: false`。 78 | - 形如 `--name egoist` 的叫做 `flag`, 即后面要加值,比如字符串和数字。 79 | - 类似的写法是 `--name=egoist`,用 `=` 而不是空格来连接。 80 | - 只有一个连字符的一般用于其它 flag 的简写,比如用 `-f` 作为 `--foo` 的简写,使用这两个之中任何一个的效果相同。连字符后面一般是单个字符,而一个连字符加多个字符其实相当于合并了多个简写,比如 `-xFd` 相当于 `-x -F -d`。 81 | - 某些命令行参数解释器支持用英文小数点 `.` 连接的参数,比如: `--foo.bar baz`,解析之后对象 `foo` 的属性 `bar` 的值就是 `baz`。 82 | 83 | ## 命令行程序框架 84 | 85 | 类似 web 开发,你当然可以完全从头写你的命令行程序,自己实现一个命令行参数解释器,然后自行判断如何根据参数返回结果。 86 | 87 | 不过这有点浪费时间且本末倒置,如果你就是想学习那些方面的内容,你可以那样干,否则如果你只是想为你的一个奇思妙实现一个命令行工具,那就有点得不偿失,不如直接使用现成的框架来加速达成你原本的目标。 88 | 89 | ### 框架干了哪些事 90 | 91 | - 根据不同的命令[^1]调用不同的模块。 92 | - 自动生成帮助信息,比如执行 `git --help` 显示的内容。 93 | - 让整个程序更安全,比如指定 flag 哪些是必需的。 94 | - 自动命令补全。 95 | 96 | 在这里我就不过多介绍框架了,毕竟只要了解原理就能举一反三,不过我还是推荐几个常用的,节省读者的时间: 97 | 98 | - [Meow](https://github.com/sindresorhus/meow): 简单的基于 [minimist](https://github.com/substack/minimist) 的包装,没什么新功能。 99 | - [Commander.js](https://github.com/tj/commander.js): 功能齐全的框架,提供类似 git 的子命令系统,自动生成帮助信息等。 100 | - **[CAC](https://github.com/egoist/cac): 类似 Commander.js 但更轻巧、现代,支持插件。(我做的)** 101 | - [Yargs](http://yargs.js.org/): 功能强大的框架,但显得过于臃肿。 102 | 103 | 这里用 CAC 举个简单的例子,介绍一下如何使用: 104 | 105 | ```js 106 | // 假设把它放在 cli.js 里 107 | const cli = require('cac')() 108 | 109 | // 定义一个命令 110 | cli.command('hi', '打招呼', input => { 111 | console.log(`Hi ${input[0]}`) 112 | }) 113 | 114 | // 开始解析 process.argv 并执行相应命令 115 | cli.parse() 116 | ``` 117 | 118 | 执行 `./cli.js` 试试: 119 | 120 | ![cac](https://i.loli.net/2017/10/18/59e76be370455.png) 121 | 122 | 如你所见,这里只会在执行 `hi` 命令之后才会打招呼。 123 | 124 | 同时添加 `--help` flag 会打印出帮助信息: 125 | 126 | ![help](https://ooo.0o0.ooo/2017/10/18/59e76f8c2d27a.png) 127 | 128 | ## 配置 package.json 129 | 130 | 要想让你的程序的可执行文件全局可用,你需要将其加入到系统 `PATH` 中,而 npm 简化了这一步骤: 131 | 132 | ```json 133 | { 134 | "name": "my-cli", 135 | "bin": "./cli.js" 136 | } 137 | ``` 138 | 139 | 在本地测试时执行 `npm link` 或者 `npm i -g .` 系统便有了 `my-cli` 命令。 140 | 141 | 这里通过配置 [bin](https://docs.npmjs.com/files/package.json#bin) 让 npm 在安装程序的时候在 `{prefix}/bin` 目录创建一个[符号链接](https://zh.wikipedia.org/zh-hans/%E7%AC%A6%E5%8F%B7%E9%93%BE%E6%8E%A5)指向 `./cli.js` 的绝对路径。在不同的情况下这个 `prefix` 不同: 142 | 143 | - 全局安装的模块(即 `npm install -g`)的 `prefix` 是执行 `npm prefix -g` 得到的路径。 144 | - 否则将是当前目录里的 `./node_modules/.bin`。 145 | 146 | [^1]: 这里的命令指程序中的命令,比如 `git` 程序中有个命令叫 `log`,你可以通过执行 `git log` 使用。 -------------------------------------------------------------------------------- /example/_posts/how-to-learn-to-code.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 如何学写代码 3 | date: 2018-07-26 4 | compileTemplate: true 5 | tags: 6 | - how-to 7 | --- 8 | 9 | 10 | sit down and do work. 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /example/_posts/how-to-undo-with-git.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 如何在 Git 中使用撤消操作 3 | date: 2015-10-04 14:15:59 4 | tags: 5 | - git 6 | - udo 7 | categories: 8 | - git 9 | --- 10 | 11 | 版本控制系统的一个好处就是你可以轻易地撤销之前错误的操作。 12 | 13 | 当你用 `git commit` 提交了一个新的更改后 git 会将当时的文件内容暂时保存下来,之后你就可以用 git 随意回滚到任意一个版本。 14 | 15 | 这篇文章会介绍一些常见的可能用到撤销 `undo` 操作的情况。 16 | 17 | ## 撤销一个已发布的更新 18 | 19 | **情景**: 你已经用 `git push` 将代码提交到了 GitHub,然后你意识到这其中的一个 commit 有错误,于是你想撤销那个 commit。 20 | 21 | **操作**: `git revert ` 22 | 23 | **效果**: git 会新建一个新的 commit 来执行提供的 `` 对应 commit 的相反的更改,任何在该旧 commit 中删除的内容将会在新 commit 中添加进去,反之亦然。 24 | 25 | 这是 git 里最安全的撤消操作的办法,因为这不会影响你的提交历史。于是现在你可以提交新的 commit 去撤销之前错误的操作了。 26 | 27 | ## 修改上次 commit 的提交信息 28 | 29 | **情景**: 你在上次 commit 提交信息中打错了一个单词,比如你执行了 `git commit -m "fxied bug #42"` 然后你意识到应该是 `fixed bug #42`。 30 | 31 | **操作**: `git commit --amend` 或 `git commit --amend -m "Fixes bug #42"` 32 | 33 | **效果**: `git commit --amend` 结合最新的文件修改情况和上一次提交信息更新并替换上一次提交。没有新的文件更改就直接覆盖上次提交。 34 | 35 | ## 撤销本地修改 36 | 37 | **情景**: 你家的喵星人跑到你的键盘上装逼用双爪打字然后不知怎么还点了保存,然后编辑器还崩溃了,你还没有 commit 这只猫做的修改,你想撤销那个文件里被猫修改的内容。 38 | 39 | **操作**: `git checkout -- ` 40 | 41 | **效果**: `git checkout` 会将该文件的内容恢复到上一次 git commit 的状态。你可以提供一个分支名称或者直接提供要回到的 SHA。 42 | 43 | 请记住,这种方法作出的撤销是彻底的,这些内容不会被 commit 所以之后你并不能再用 git 恢复这些内容。 44 | 45 | ## 重置本地修改 46 | 47 | **情景**: 你在本地 commit 了一些内容(并没有 push),但是你搞错了,你想撤销最近这三个 commit,就像让它们从来不存在那样。 48 | 49 | **操作**: `git reset ` 或 `git reset --hard ` 50 | 51 | **效果**: `git reset` 会让你的 git 历史会退到你指定的 SHA 的状态。这些 commit 不存在了但是你硬盘上的这些文件还是维持在被修改了的状态,这是最安全的做法。但是有时你也想同时撤销硬盘上的修改,这时加上 `--hard` 就会很有用。 52 | 53 | ## 撤销本地修改之后重做 54 | 55 | **情景**: 你提交了一些 commit,然后执行 `git reset --hard` 来撤消这些 commit 并清除本地硬盘上的修改。但是最后你意识到你想要回这些 commit! 56 | 57 | **操作**: `git reflog` 和 `git reset` 或 `git checkout` 58 | 59 | **效果**: `git reflog` 是个修复项目提交历史的好方法。你可以找回几乎所有内容 —— 所有你 commit 过的内容 —— 用 reflog 就行。 60 | 61 | 你可能对 `git log` 很熟悉,这个操作会列出你的 git 提交历史。`git reflog` 很像它,但是列出的是 `HEAD` 修改的时间。 62 | 63 | 一些说明: 64 | 65 | - `HEAD` 修改。在切换分支时 `HEAD` 会被修改,用 commit 保存修改然后用 reset 撤消修改。但是在你 `git checkout -- ` 时并不会被修改,就像上面说过的那样,这些修改不会被 commit,所以 `git reflog` 也不能帮你找回这些内容。 66 | - `git reflog` 不是永远有用的。git 会定期清理那些无法追溯的内容。不要期望能用 `git reflog` 找回一个多月以前的内容。 67 | - 你的 `git reflog` 仅对你有用。你不能用 `git reflog` 来找回其他人 commit 的修改。 68 | 69 | ![reflog](https://cloud.githubusercontent.com/assets/2077/6953866/f6b9f054-d891-11e4-8c53-838eff9f40ae.png) 70 | 71 | 然后...接下来怎么做才能撤销之前的撤销?这取决你到你要干什么: 72 | 73 | - 如果你想回到一个特定的时间,用 `git reset --hard `。 74 | - 如果你想在不修改提交历史的情况下找回那些文件并作为新文件保存,用 `git checkout -- `。 75 | - 如果你想使其中一个 commit 回到你的项目历史中,用 `git cherry-pick `。 76 | 77 | ## 提交到了另一个分支 78 | 79 | **情景**: 你提交了一些 commits,然后意识到你当前是在 master 分支上,而你其实是想提交到一个 `feature` 分支上。 80 | 81 | **操作**: `git branch feature`, `git reset --hard origin/master`, 和 `git checkout feature` 82 | 83 | **效果**: 你可能常常使用 `git checkout -b ` 操作来检出一个新分支,这是一个很方便的创建新分支的操作,但是你并不想同时切换到那个分支上。现在使用 `git branch feature` 既可以创建一个 `feature` 新分支并且不会切换到那个分支,同时该分支会指向你当前分支最新的一个 commit。 84 | 85 | 下一步,用 `git reset --hard` 去恢复 `master` 分支到 `origin/master` 的状态。 86 | 87 | 最后,`git checkout` 到你的 `feature` 分支,你能看到所有的更改。 88 | 89 | ## 覆盖整个分支 90 | 91 | **情景**: 你基于 `master` 分支创建了 `feature` 分支,但是 `master` 分支远远落后 `origin/master` 的更改。现在 `master` 分支和 `origin/master` 同步了,你想马上同步到 `feature` 分支,还不是再次远远落后。 92 | 93 | **操作**: `git checkout feature` 和 `git rebase master` 94 | 95 | **效果**: 你可能知道用 `git reset` 然后重新 commit 来达到类似效果,不过那样会丢失 commit 历史。 96 | 97 | --- 98 | 99 | 本文乃原文常用部分译文: [How to undo (almost) anything with Git](https://github.com/blog/2019-how-to-undo-almost-anything-with-git) —— 作者: [jaw6](https://github.com/jaw6) 100 | -------------------------------------------------------------------------------- /example/_posts/kill-gulp-with-npm-scripts-and-nswatch.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 用 npm scripts 和 nswatch 替代 gulp 3 | subtitle: Long live gulp, I use npm script 4 | date: 2016-08-29 16:54:30 5 | tags: 6 | - gulp 7 | - npm 8 | --- 9 | 10 | ## 为什么用 npm scripts ? 11 | 12 | 首先我觉得 [Why I Left Gulp and Grunt for npm Scripts](https://medium.freecodecamp.com/why-i-left-gulp-and-grunt-for-npm-scripts-3d6853dd22b8#.8wsejnq0u) 里说的不用 gulp 的理由基本没有道理: 13 | 14 | 1. gulp 插件质量、数量和实时性 15 | 16 | 作者抱怨 gulp 插件的质量取决于插件作者,这可以理解,**但是 npm 的包同样取决于作者啊**。 17 | 18 | 作者抱怨 gulp 插件的数量不如 npm,**这不是废话吗**。 19 | 20 | 作者抱怨 gulp 插件不能及时更新,比如 babel 6 升级了 gulp-babel 并没有立刻升级。**又不是看直播,干嘛实时?** 21 | 22 | 2. debug 很痛苦,gulp crash 掉是因为某个插件吗还是因为版本问题 23 | 24 | 额,难道直接用 npm package 就没有这些问题吗。 25 | 26 | 3. 不连贯的文档,比如 gulp-eslint 和 eslint,eslint 的文档就是 gulp 插件的文档好得多 27 | 28 | 这不又是废话吗,写个插件还要把用的包的文档重新写一遍? 29 | 30 | --- 31 | 32 | 好了,原文挑剔 gulp 的理由全被扳倒了,但是其中支持 npm 的理由倒是挺有道理: 33 | 34 | 1. npm scripts 并不需要你很擅长命令行操作 35 | 36 | 你并不需要在 npm scripts 里用一些很高深的命令行,很多 unix 命令是需要花很长时间学习的。像类似 rm -rf 之类的命令很容易掌握,而且也有相应的 npm 包 [rimraf](https://github.com/isaacs/rimraf) 让你使用,且跨平台支持。 37 | 38 | 2. npm scripts 不够强大吗? 39 | 40 | ```JSON 41 | { 42 | "scripts": { 43 | "clean": "rimraf ./dist && mkdir dist", 44 | "prebuild": "npm run clean", 45 | "build": "cross-env NODE_ENV=production webpack" 46 | } 47 | } 48 | ``` 49 | 50 | npm scripts 甚至支持 `pre` `post` 这些 hook 让你在相应的一个 task 之前和之后调用。 51 | 52 | 你可以直接执行一个文件来完成相应的构建工作,这让你几乎能做任何 gulp 能做的事: 53 | 54 | ```JSON 55 | { 56 | "scripts": { 57 | "build": "node build.js" 58 | } 59 | } 60 | ``` 61 | 62 | 3. npm scripts 不是跨平台的 63 | 64 | 因为你可能会在 npm scripts 里用一些 unix 命令,解决方案有很多,比如用 npm 包替代这些命令。 65 | 66 | 4. 可维护性 67 | 68 | gulp tasks 也多了以后会变得很难维护,npm scripts 也是。解决方案是推荐写精简的 script,比如一个 script 只干一件事。或者很长很复杂的话你就需要专门放到一个 JS 文件里然后再在 npm scripts 里调用了。 69 | 70 | ## nswatch 71 | 72 | > https://github.com/egoist/nswatch 73 | 74 | 在 npm scripts 里只执行一个构建任务你可能不需要类似 `gulp.watch` 这样的功能,因为大部分构建工具都自带了 watch 功能,比如 `webpack --watch` 和 `rollup --watch`,但是排除这种情况在构建多个任务的时候就不方便了。 75 | 76 | 比如你要同时用一些 `.jade` `.css` `.js` 这些文件分别编译成 `.html` `.css` `.js` 文件,开发的时候怎么搞啊,怎么 watch 这些文件然后执行 rebuild 呢?好吧,你又想到了 `gulp` 😂 77 | 78 | 不过现在有 `nswatch` 了,为了解决类似的需求我今早洗澡之后写的。和 `gulp.watch` 类似,监听一些文件,不过这里是执行相应的 npm script。 79 | 80 | 你的 npm scripts: 81 | 82 | ```JSON 83 | { 84 | "scripts": { 85 | "build:js": "node scripts/build js", 86 | "build:html": "node script/build html", 87 | "build:css": "node scripts/build css" 88 | } 89 | } 90 | ``` 91 | 92 | 然后你可以在 `scripts/build.js` 里用你喜欢的 npm 包,比如 rollup, jade, postcss,来编译相应文件。 93 | 94 | 最后添加 `nswatch`: 95 | 96 | ```JSON 97 | { 98 | "scripts": { 99 | "watch": "nswatch src/*.js --script build:js & nswatch src/*.css --script build:css & nswatch src/*.jade --script build:html " 100 | } 101 | } 102 | ``` 103 | 104 | 由于有三个任务所以写得很长,你可以把它放进单独文件 `scripts/watch.js`: 105 | 106 | ```JavaScript 107 | const watch = require('nswatch') 108 | 109 | watch('./src/*.js', ['build:js']) 110 | watch('./src/*.jade', ['build:html']) 111 | watch('./src/*.css', ['build:css']) 112 | ``` 113 | 114 | 然后执行 `node scripts/watch` 一切都能运行了! 115 | 116 | 最后你可能还是需要把 `node scripts/watch` 写进 `package.json`,以后都用 `npm run watch` 来执行: 117 | 118 | ```JSON 119 | { 120 | "scripts": { 121 | "watch": "node scripts/watch" 122 | } 123 | } 124 | ``` -------------------------------------------------------------------------------- /example/_posts/linus-and-i.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 我和 Linus 的开源故事 3 | date: 2015-12-15 13:06:03 4 | categories: 5 | - tech 6 | --- 7 | 直播一下我刚刚在微信举行的给我没人用的开源项目举行的捐赠会: 8 | 9 | > 最近比较忙啊,有数个没人用的开源项目需要维护,别回我,往我微信转账就是了! 10 | 11 | > 已收到来自张先生的转账 10***0 元,特此感谢张先生,祝新年快乐阖家幸福! 12 | 13 | > 啊,继张先生之后,王小姐不甘寂寞,一波 10***1 元的转账一举超越张先生,成为捐款榜单首名!此时,掌声响起来,王小姐鲜红的裙子似乎和五星红旗合体了似的,显得格外鲜艳。 14 | 15 | > 突然,某路人途径捐赠现场,他说他叫音速索尼克,他是个忍者,忍者就是要为开源事业做贡献!话音刚落,索尼克拿出索尼开始玩 Fruit Ninja。 16 | 17 | > 捐赠现场突然人声鼎沸,原来是 Linus!Linux 的作者 Linus 到我的开源项目筹款捐赠会暨第一届两岸三地码农交流大会来露脸了! 18 | 我高兴的看着 Linus 生无可恋的脸,想不到他却说:talk is cheap show me your code。 19 | 我顿时失声,哑口,泪如泉涌。 20 | 我的 Code 不都在 GitHub 吗…… 21 | 22 | > 尽管我没拿出 Code 来,不过加了 Linus 的微信,把我的 GitHub 地址发了过去。Linus 还是很通情达理的,还是给我的筹款会捐赠了 10****0 日元,他说这是他昨天吃剩下的。 23 | -------------------------------------------------------------------------------- /example/_posts/log-in-with-your-teminal.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 在终端里使用第三方登录 3 | date: 2015-10-26 17:44:52 4 | tags: 5 | - terminal 6 | categories: 7 | - skills 8 | 9 | --- 10 | 11 | 显然你经常在网页和 APP 里使用第三方登录功能,比如用微博登录、用 QQ 登录、用 GitHub 登录,具体的方式是打开相关网页进行授权或者移动端可以利用应用内授权机制授权,那么在终端里如何操作第三方账号登录呢? 12 | 13 | 很显然,也只能通过打开授权网页的方式获取需要的 access token 来进行操作。 14 | 15 | ## 新建一个应用 16 | 17 | 常规步骤,稍后会用在这里获得的 `Client ID` 和 `Client Secret` 进行授权验证。 18 | 19 | 20 | ## 思路 21 | 22 | 这些操作需要你将 API 搭建在自己的服务器上并且拥有数据库读写功能。 23 | 24 | 你需要用户触发登录操作之后以 GET 的方式打开一个授权网页,比如 `/api/login`,请求时在 URL Query String 中传输一个随机生成的用户 Unique ID,形如 `/api/login?uid=$UID`,推荐使用 [open](https://www.npmjs.org/package/open) 这个库打开网址。 25 | 26 | 授权成功之后获得的 access token 和 UID 保存到数据库,在之前打开授权页面的同时 POST 请求 `/api/token`,在 body 中传输 UID 信息,设置一个较高的 timeout 让网页不会返回超时。 27 | 28 | 在授权过程中由于并未获取到 token 所以让 `/api/token` 返回一个 50X 错误,判断获取到 50X 错误后用 setInterval 持续请求这个地址直到返回 200 代码,这个时候 access token 已经被你写入数据库并在这个页面上以 json 的格式输出了,于是这样你得到了需要的 access token,命令行现在可以打印出登录成功的提示信息了。 -------------------------------------------------------------------------------- /example/_posts/my-rollup-plugin-postcss.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 我的 rollup-plugin-postcss 3 | date: 2018-02-27 14:28:14 4 | tags: 5 | - javascript 6 | - story 7 | --- 8 | 9 | [rollup-plugin-postcss](https://github.com/egoist/rollup-plugin-postcss) 是我两年前开源的一个项目,用于为 [Rollup](https://rollupjs.org/guide/en) 提供 [PostCSS](https://github.com/postcss/postcss) 支持。 10 | 11 | 这基本上是我刚开始工作的时候写的代码,所以见证了我一段心路历程。 12 | 13 | ## 2015 年 12 月 8 日 14 | 15 | 我[首次提交了代码](https://github.com/egoist/rollup-plugin-postcss/commit/ed445b067e0772aa39403db23bfb2bc4b6129aef#diff-04c6e90faac2675aa89e2176d2eec7d8),那个时候我的邮箱还是 `aprilorange.net@icloud.com`[^1],不过早已由于忘记密码且无法申诉而永久无法登录了。 16 | 17 | 当时的代码极为简单,仅仅是调用 `postcss` 转换 CSS 代码并提供 `plugins` 参数: 18 | 19 | ```js 20 | import postcss from 'postcss'; 21 | import styleInject from 'style-inject'; 22 | 23 | export default function (options = {}) { 24 | return { 25 | intro () { 26 | return styleInject.toString(); 27 | }, 28 | transform (code, id) { 29 | if (id.slice( -4 ) !== '.css') { 30 | return null; 31 | } 32 | code = postcss(options.plugins || []).process(code).css; 33 | code = `export default styleInject(${JSON.stringify(code)});` 34 | return { 35 | code, 36 | map: { mappings: '' } 37 | }; 38 | } 39 | }; 40 | }; 41 | ``` 42 | 43 | 之后就在当天,我向 PostCSS 项目提交 PR 请求在 README 上列出我的这个项目,而这个 PR 的序号也很溜: https://github.com/postcss/postcss/pull/666 44 | 45 | 发这个 Issue 的时候我刚下班,骑着自行车回家的途中发现收到了回复,我就停下车来,靠着自行车在成都万象城旁边傻站着摸着手机回复。 46 | 47 | PostCSS 的维护者告诉我应该使用异步的 API,我也就照做了,然后就发生了: 48 | 49 | ![lol](https://i.loli.net/2018/02/27/5a94fe69825e3.png) 50 | 51 | 其实我当时还不太懂 Promise,经他指出之后研究了一下才发现一个函数已经返回了 Promise 就不用再把它 wrap 进一个 Promise 了: 52 | 53 | ![promise](https://i.loli.net/2018/02/27/5a94fec490e73.png) 54 | 55 | 在这之后我也看到过其它人像我以前那样写,就感觉很好,因为我再也不会那么傻了。 56 | 57 | ## 2015 年 12 月 23 日 58 | 59 | 开源两周后,这个项目迎来了[第一个 Issue](https://github.com/egoist/rollup-plugin-postcss/issues/1),我当时是很激动的: 60 | 61 | ![issue 1](https://i.loli.net/2018/02/27/5a9500dcc43a7.png) 62 | 63 | 这个人可能在今天已经为读者们所熟知,也就是 [Preact](https://github.com/developit/preact) 的作者,我记得在当时 Preact 还只有几百个 stars? 64 | 65 | ## 2016 年 5 月 29 日 66 | 67 | 半年没更新这个项目了,难道是没人用吗,我也不知道因为我自己也不用。不过当时我似乎挺喜欢用 [AVA](https://github.com/avajs/ava) 写测试,因为 CLI 效果很炫而且默认就支持用 ES2015 写测试。 68 | 69 | 于是我就 commit 了一发[将 Mocha 替换成 AVA](https://github.com/egoist/rollup-plugin-postcss/commit/9698d66ca1f04a2308c94fe74d94d184f2891b96) 了。 70 | 71 | [^1]: 我的笔名叫四月橘林,所以当时英文名就叫 April Orange XD 72 | 73 | ## 2016 年 9 月 2 日 74 | 75 | 这天有人来了个 [PR](https://github.com/egoist/rollup-plugin-postcss/pull/5),尽管不知道 fix 了什么我还是合了吧? 76 | 77 | 之后又来了一些 contributors,慢慢地我就懒得管了,基本全都是他们在 fix bugs 或者添加新 features,逐渐地我自己也看不懂里面的代码了 😅 78 | 79 | ## 2018 年 1 月 10 日 80 | 81 | 过了一年多,我突然找回了责任心,想起了那句责任越大能力越大,打算重写一下这个项目。在此之前我折腾了很久的 webpack,于是就得到了一些重写的灵感,想让这个插件以 `loader` 的方式支持任何 CSS 预处理器,而且刚好 [Parcel](https://github.com/parcel-bundler/parcel) 突然流行了起来,我也就顺便让它无需配置便能编译 CSS/Sass/Less/Stylus。和每次重构之后的心情一样,我再次觉得这次的代码写得很完美了。 82 | 83 | ![current](https://i.loli.net/2018/02/27/5a9505707f0ea.png) 84 | 85 | ## 2018 年 2 月 27 日 86 | 87 | 今天,也就是我写这篇文章的日子,rollup-plugin-postcss 已被 [900](https://github.com/egoist/rollup-plugin-postcss/network/dependents) 多个项目使用,其中包括像 [microbundle](https://github.com/developit/microbundle) 和 [bili](https://github.com/egoist/bili) 这样基于 Rollup 的打包工具。 88 | 89 | 照目前的趋势来看,目前的代码还没有崩坏的迹象,在一段时间内可读性还能维持在较高范围。 90 | -------------------------------------------------------------------------------- /example/_posts/neon-genesis-scaffolding-tool.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 新世纪福音脚手架 3 | subtitle: she said, "it's futuristic." 4 | date: 2017-05-21 20:20:34 5 | tags: 6 | --- 7 | 好的作品不在于其形式,重要的是内容,我的很多音乐作品都是没有名字的,然而没有名字的东西无法商业流通,所以你才会看到我那些没有特殊意义、单纯靠滚键盘得到的名字。 —— [泽野弘之](http://music.163.com/#/artist?id=15290)曾经这样说过(其实并没有)。 8 | 9 | 这篇文章也是这个道理,想介绍一下我在半年前开始做的脚手架工具。给文章起标题也是一件很困难的事,最开始想到的是「史上最优雅的脚手架工具」、「来自未来的脚手架」,不过这些未免显得太标题党了,华而不实我自己都很尴尬。最近我刚好做了个[新世纪福音战士标题卡生成器](https://github.com/egoist/evangelion-card),于是就随机将几个关键词组合在一起 —— **新世纪福音脚手架**,意外地显得还不错。 10 | 11 | ![sao](https://ooo.0o0.ooo/2017/05/21/5921898822cae.png) 12 | 13 | **为了不让你对标题不明所以,简单地说明了它的来历,以下才是正文。** 14 | 15 | ## 脚手架 16 | 17 | 经常造轮子就会发现脚手架的重要性,这也是为什么 Yeoman 的发明者之一是 [@sindresorhus](https://github.com/sindresorhus) 的原因。后者已经在 npm 上发布了[超过 1000 个模块](https://www.npmjs.com/~sindresorhus),很难后有来者了。 18 | 19 | Yeoman 十分健壮,生态繁荣,然而要写[一个 generator 的复杂度](https://github.com/sindresorhus/generator-nm/blob/master/app/index.js)和写普通的代码几乎是差不多的,而我在能尽可能减少思考的时候就想减少思考,vue-cli 的思路很好地解决了我想减少思考的诉求,一个 generator 中间生成文件的过程有很多步骤是可以自动解决的。 20 | 21 | vue-cli 虽然名字里有 vue 属性,但是作为任意类型项目的脚手架工具都是可以的,尽管运行 `vue init react` 这样的命令会显得有些奇怪。这也是为什么我做了 [SAO](https://github.com/egoist/sao) 的原因,一个类似 vue-cli 的脚手架工具。在拥有 vue-cli 的功能的同时,它也能像 Yeoman 一样用 npm package 作为模板并支持测试。 22 | 23 | 举个例子,在运行 `sao vue` 的时候,如果 template-vue 这个 npm 模块没有全局安装,它会提示你安装,之后再使用模板根目录里的配置文件 `sao.js` 将同目录里的 `template/` 中的文件生成到 `process.cwd()` 即当前目录。如果不存在配置文件,那么只会当成一个普通的目录,简单地复制粘贴到当前目录。 24 | 25 | 📄 **template-vue/sao.js:** 26 | 27 | ```js 28 | module.exports = { 29 | // 从用户获取一些信息 30 | prompts: { 31 | pwa: { 32 | type: 'confirm', 33 | message: 'Add Progressive Web App support', 34 | default: true 35 | } 36 | }, 37 | // 如果要发布到 npm 38 | // .gitignore 会自动被 npm 更名为 .npmignore 39 | // 为了避免这种情况需要起个另外的名字 40 | // 然后在生成的时候改名为 .gitignore 41 | move: { 42 | gitignore: '.gitignore' 43 | }, 44 | // 只在用户确认了 pwa 选项的时候生成 pwa.js 45 | filters: { 46 | 'pwa.js': 'pwa' 47 | } 48 | } 49 | ``` 50 | 51 | 上面的这个配置文件满足了大部分脚手架的需求,即从用户获取信息 --> 根据此信息生成需要的文件。而且几乎与代码无关,这个配置文件完全是由**数据**组成的,只不过刚好是以 JS 对象的格式。 52 | 53 | ![preview](https://ooo.0o0.ooo/2017/05/21/59218de93485b.png) 54 | 55 | SAO 接收的第一个参数可以是: 56 | 57 | - 本地模板路径,比如 `./my-template` `/path/to/my-template`。 58 | - GitHub 项目缩略名,比如 `egoist/template-vue`。 59 | - npm 模块名(自动加上 `template-` 前缀),比如 `vue` 将会使用 npm 上的 `template-vue` 这个包。 60 | 61 | 而第二个参数是可选的,不存在时将会生成文件到工作区目录(当前目录),否则将会生成到指定的文件夹中。 62 | 63 | ## 测试脚手架 64 | 65 | 当脚手架变得复杂,你需要系统地测试以便让其在各种情况下都能生成正确的文件。对于一个脚手架,能从用户影响到它的变量只有 `prompts` 这个参数,也就是从用户获取的信息。而 SAO 的测试也主要是围绕这个来的,你可以模拟用户输入来检测生成结果。 66 | 67 | 📄 **template-vue/test.js:** 68 | 69 | ```js 70 | import test from 'ava' 71 | import sao from 'sao' 72 | 73 | test('generate pwa entry', async t => { 74 | const template = process.cwd() // 模板根目录 75 | const res = await sao.mockPrompt(template, { 76 | // 模拟的 prompts 数据 77 | // 默认使用 `prompts` 中的默认值 78 | // 在上面的 `sao.js` 中 `pwa` 默认为 `true` 79 | }) 80 | t.true(res.fileList.includes('pwa.js')) 81 | }) 82 | 83 | test('ignore pwa entry', async t => { 84 | const template = process.cwd() // 模板根目录 85 | const res = await sao.mockPrompt(template, { 86 | pwa: false 87 | }) 88 | t.false(res.fileList.includes('pwa.js')) 89 | }) 90 | ``` 91 | 92 | 这里的 `res.fileList` 是生成的文件列表,形如: 93 | 94 | ```js 95 | [ 96 | '.gitignore', 97 | 'pwa.js', 98 | 'src/index.js' 99 | ] 100 | ``` 101 | 102 | 以及 `res.files`,包含了生成文件的信息: 103 | 104 | ```js 105 | { 106 | '.gitignore': { 107 | contents: Buffer, 108 | stats: {}, // fs.Stats, 109 | path: '/absolute/path/to/this/file' 110 | }, 111 | // ... 112 | } 113 | ``` 114 | 115 | ## 最后 116 | 117 | 分享几个我自己经常使用的模板: 118 | 119 | - [template-nm](https://github.com/egoist/template-nm): 生成一个 npm 模块,我的所有模块都是用这个生成的。 120 | - [template-vue](https://github.com/egoist/template-vue): 生成一个*几乎*无需配置的 Vue 项目,基于 [Poi](https://poi.js.org)。 121 | - [awesome-sao](https://github.com/egoist/awesome-sao): 相关 SAO 资源。 122 | 123 | 关于更多 SAO 的使用方法和配置文件参数,可以访问 https://sao.js.org :P 虽然本文标题是来源于新世纪福音战士,但 SAO 显然是来源于 [Sword Art Online](https://zh.moegirl.org/zh-hans/%E5%88%80%E5%89%91%E7%A5%9E%E5%9F%9F) 的。 -------------------------------------------------------------------------------- /example/_posts/new-timetable.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 新的作息时间 3 | date: 2016-03-03 15:39:02 4 | tags: 5 | - life 6 | --- 7 | 是时候告别淫乱的日子,我打算开始一个健康规律的作息时间。 8 | 9 | ## 准备工作 10 | 11 | 睡觉时间: 晚上 10 点到次日凌晨 5 点。 12 | 学习时间: 早上 5 点 20 分到 6 点半。 13 | 洗澡时间: 早上 6 点半到 7 点。 14 | 早饭时间: 早上 7 点到 7 点 20 分。 15 | 16 | ## 热身 17 | 18 | 每天去 StackOverflow/SegmentFault 回答问题。 19 | 20 | 时间是早上 7 点半到 9 点以前。 21 | 22 | ## 日落 23 | 24 | 晚上 7 点半之前到家,8 点半到 9 点半跑步,之后随意嘿嘿嘿。 25 | 26 | ## 周末 27 | 28 | 周六是休息时间,不写代码不工作。 29 | 30 | 周日和工作日一样。 31 | -------------------------------------------------------------------------------- /example/_posts/node-js-module-style-guide.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Node.js 模块风格指南 3 | subtitle: 编写高质量、可复用的 Node.js 模块 4 | date: 2016-01-29 09:44:30 5 | tags: 6 | - node.js 7 | - javascript 8 | - sindresorhus 9 | 10 | --- 11 | JavaScript 代码一向的特点就是难以维护,保持一个良好的代码、组织风格有助于提升效率、重构代码、添加新功能、单元测试等等。 12 | 13 | 我总结了一下写了 200 个 NPM package 之后的一些个人经验和习惯。 14 | 15 | ## 初始化一个项目 16 | 17 | 不再使用 `npm init`。因为除了 `package.json` 还有一些额外的配置文件,比如 `circle.yml`、`.editorconfig`、`LICENSE` 、`README.md` 等等。 18 | 19 | 使用 [yeoman](http://yeoman.io)。如果你喜欢在代码中使用分号和用 travis 来测试,推荐 [sindresorhus](https://github.com/sindresorhus) 用的 [generator-nm](https://github.com/sindresorhus/generator-nm)。如果你不喜欢分号并且用 circle 来测试,推荐我用的 [generator-esnm](https://github.com/egoist/generator-esnm)。 20 | 21 | 想要定制你的 README.md ? [blah](https://github.com/IonicaBizau/blah) 可以为你定制生成 README.md 以及更多提升效率的功能。 22 | 23 | ## 注释 24 | 25 | 每一个具有单独意义的代码片段前都推荐写注释,就算再简单的代码你隔几天看也不可能一秒看出它在干什么,而有了注释就可以。对于复杂且意义重大的代码尽量写完整的 jsdoc 来说明。 26 | 27 | 另一个原因就是这样可以让你的代码显得更格式化,代码挤在一堆很傻且不美观。而且你也可以自动从你代码的 jsdoc 生成 api doc! 28 | 29 | ```js 30 | /** 31 | * Module dependencies 32 | */ 33 | const path = require('path') 34 | 35 | /** 36 | * Reverse array but not change itself 37 | * 38 | * @param {Array} names 39 | * @return {Array} 40 | */ 41 | function rev(names) { 42 | return names.concat().reverse() 43 | } 44 | ``` 45 | 46 | ## 编写可复用模块 47 | 48 | 对于一个项目中多次使用(>1)的代码,推荐放入单独的文件作为模块使用。 49 | 对于更为通用的代码尽量打包进一个单独的 npm module 来使用。 50 | 51 | ## 代码风格指南 52 | 53 | 对于分号的问题不作讨论,加不加都行。 54 | 55 | 对于异步代码,尽量不要使用 callback 而是改成 Promise,并且把 HTTP 请求封装进单独的模块,这样更方便配合 [co](https://github.com/tj/co) 来使用。 56 | 57 | ```js 58 | // fetchData.js 59 | // 老式回调风格 60 | const request = require('superagent') 61 | 62 | module.exports = function (callback) { 63 | request 64 | .get('xxx.json') 65 | .end((err, res) => { 66 | callback(res) 67 | }) 68 | } 69 | // app.js 70 | // 调用它 71 | const fetchData = require('./fetchData') 72 | 73 | module.exports = function () { 74 | fetchData(data => { 75 | console.log(data) 76 | }) 77 | } 78 | 79 | // fetchData.js 80 | // 无阻塞同步代码风格 81 | const fetch = require('node-fetch') 82 | 83 | module.exports = co.wrap(function* () { 84 | const data = yield fetch('xxx.json') 85 | .then(data => data.json()) 86 | return data 87 | }) 88 | // app.js 89 | // 调用它 90 | const fetchData = require('./fetchData') 91 | 92 | module.exports = co.wrap(function* () { 93 | const data = yield fetchData() 94 | console.log(data) 95 | }) 96 | ``` 97 | 98 | **还使用 co? 不是有 async/await 吗?** 99 | 100 | 在 async/await 没被 v8 引擎实现之前用 co 都还是第一选择,除非某些情况你使用了 babel 那你可以考虑使用 async/await。不过即使现在用 co 在将来 async/await api 被实现的时候也能轻松地迁移过去。 101 | 102 | > co is a stepping stone towards ES7 async/await -- TJ Holowaychuk 103 | 104 | 105 | ## ESLint 106 | 107 | 保持良好代码风格的方法之一就是 lint 你的代码,选择你习惯的代码风格,用编辑器实时 lint 或者添加一些 git hook 在 commit 的时候 lint 也可以。 108 | 109 | 我目前使用 [xo](https://github.com/sindresorhus/xo) 来检测代码,它默认无需配置但你可以根据你的喜好调整,基于 ESLint 。如果你喜欢这个风格也可以直接在 ESlint 中使用它的[配置文件](https://github.com/sindresorhus/eslint-config-xo)。 110 | 111 | ## 测试 112 | 113 | 写测试是很有趣的,当且仅当你用 [AVA](https://github.com/sindresorhus/ava) 的时候。 114 | 115 | ![ava](https://camo.githubusercontent.com/fc55513ee5cb412b2b0d1540032b602ed0142dbe/68747470733a2f2f63646e2e7261776769742e636f6d2f73696e647265736f726875732f6176612f666531636561316361336432633835313863306363333965633862653539326265616239303535382f6d656469612f6c6f676f2e737667) 116 | 117 | 我使用 AVA 的主要原因是: 118 | 119 | - 很快 120 | - 语法简洁 121 | - 内置 ES2015/2016 122 | - many more... 123 | 124 | ## Commit 风格 125 | 126 | 不使用没有意义的 Commit 信息,比如单纯只写个 `fix`、`update`、`change`。 127 | 128 | 尽量描述你干了什么事: 129 | 130 | ```bash 131 | git commit -m "fix tweak on ie9" 132 | git commit -m "release 0.0.1" 133 | git commit -m "refactor to use es2015" 134 | git commit -m "🔥" 135 | ``` 136 | 137 | 更好的做法是使用 [commitizen](https://github.com/commitizen/cz-cli) 来规范你的 commit message 格式。 138 | 139 | ![commitizen](https://github.com/commitizen/cz-cli/raw/master/meta/screenshots/add-commit.png) 140 | 141 | ## Semantic-Release 142 | 143 | 发布 NPM 模块是很让人困扰的一步,你需要手动 bump version,需要执行 `npm test` 来看是否有错,然后再手动执行 `npm publish`,这些步骤可以被规范且自动化。 144 | 145 | 使用 [semantic-release](https://github.com/semantic-release/semantic-release) 可以自动分析你的 commit message 然后根据这些推测你的代码改动来进行语义化的版本号升级并自动更新 changelog,[这些](https://github.com/egoist/tooling/releases) 就是自动生成的。 146 | 147 | ## 2016 148 | 149 | 200 more modules? Exciting! ✨ 150 | -------------------------------------------------------------------------------- /example/_posts/otaku-is-the-best.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 死宅什么的最好了 3 | date: 2016-06-23 16:02:49 4 | tags: 5 | - otaku 6 | categories: 7 | - anime 8 | --- 9 | 相比「死宅什么的最好了」这种论调,更常见的是「死宅什么的最恶心了」,真的是这样吗?那我们先来看看: 10 | 11 | ![1][1] 12 | 13 | 相信各位客官都看到了,这是何等变态的言论啊! 14 | 15 | 幸好似乎出现了主持正义的民众: 16 | 17 | ![2][2] 18 | 19 | [1]: https://o68eee1f9.qnssl.com/16-6-23/23095294.jpg 20 | [2]: https://o68eee1f9.qnssl.com/16-6-23/9021550.jpg 21 | 22 | 什么?我搞错了,是的,这是何等的无耻啊,这个死宅居然说自己是我女朋友的老公! 23 | 24 | --- 25 | 26 | 相信到这里各位拥有忍者动态视力的客官已经看清楚了,死宅什么的就是不分青红皂白自称是我女朋友的老公的那一类人,该杀! 27 | 28 | ## 剧情反转 29 | 30 | 我察觉到有些不对,表达对我女朋友的向往有什么不对吗,死宅的这种精神反而值得钦佩,明知道事实不会因为自己的意淫而得到任何改变。 31 | 32 | 这种精神除了刚出生的婴儿和精神病院的智障以外,上帝只给了死宅。 33 | 34 | 南无三,这是何等的珍贵啊! 35 | 36 | *开什么玩笑啊喂!*<(`^´)> 37 | -------------------------------------------------------------------------------- /example/_posts/postgresql-simple-guide.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: PostgreSQL 简明指南 3 | date: 2016-04-25 17:06:05 4 | tags: 5 | - postgresql 6 | - database 7 | --- 8 | 边学边记录,有错请指出。(Keep Updating...) 9 | 10 | ## 基础 11 | 12 | ### 安装 13 | 14 | `postgresql-contrib` 不是必需的,它提供一些额外的功能。 15 | 16 | ```bash 17 | $ sudo apt-get update 18 | $ sudo apt-get install postgresql postgresql-contrib 19 | ``` 20 | 21 | 安装完成后,它会自动在你的系统上新建一个叫 `postgres` 的用户,之后你需要切换过去来使用 `PostgreSQL`: 22 | 23 | ```bash 24 | $ sudo -i -u postgres 25 | ``` 26 | 27 | 进入交互模式: 28 | 29 | ```bash 30 | $ psql 31 | # 想退出则输入 `\q` 32 | ``` 33 | 34 | ### 初始化 35 | 36 | 用默认账户登录到默认数据库: 37 | 38 | ```bash 39 | $ sudo -u postgres psql template1 40 | ``` 41 | 42 | 修改默认账户的密码: 43 | 44 | ```sql 45 | $ postgres=# ALTER USER postgres with encrypted password 'xxxxxxx'; 46 | ``` 47 | 48 | 然后修改 `pg_hba.conf` 让其用 `md5` 方式加密: 49 | 50 | ```bash 51 | # 9.1 是版本号 52 | $ sudo vim /etc/postgresql/9.1/main/pg_hba.conf 53 | ``` 54 | 55 | 这样修改: local all postgres ~~peer~~ md5 56 | 57 | 重启数据库: 58 | 59 | ```bash 60 | $ sudo /etc/init.d/postgresql restart 61 | ``` 62 | 63 | ### 新建用户和数据库 64 | 65 | 在默认的 Linux 账户 `postgres` 下,你可以创建创建一个新的用户: 66 | 67 | ```sql 68 | $ postgres=# CREATE USER egoist WITH PASSWORD 'your_password'; 69 | ``` 70 | 71 | 下一步是创建一个数据库,并让指定用户据有读写权限: 72 | 73 | ```sql 74 | $ postgres=# CREATE DATABASE database_a; 75 | ``` 76 | 77 | 之后给予数据库 `database_a` 的权限到用户 `egoist`: 78 | 79 | ```sql 80 | $ postgres=# GRANT ALL PRIVILEGES ON DATABASE database_a to egoist; 81 | ``` 82 | 83 | ### 数据库相关查询 84 | 85 | #### 列出所有数据库 86 | 87 | ```bash 88 | # 当前用户 89 | # \l 或者 \list 90 | $ user=# \list 91 | 92 | # 非 psql 交互模式下 93 | $ psql -U username -l 94 | ``` 95 | 96 | ## 推荐阅读 97 | 98 | - [PostgreSQL Guide](http://postgresguide.com) 99 | -------------------------------------------------------------------------------- /example/_posts/revue-guide.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Revue 指南 3 | tags: 4 | - javascript 5 | - redux 6 | - revue 7 | - vue 8 | subtitle: 如何在 Vue 中使用 Redux 管理 State 9 | categories: [] 10 | date: 2015-12-18 17:10:00 11 | outdated: 由于多次更新以及不稳定性,本文中关于 Revue 的介绍已不再有效。 12 | --- 13 | 14 | ## 缘起小明 15 | 16 | 前几天小明找到我,说他想用 Vue 做一个小博客,自己写点东西,可是一来就遇到问题了,他发现组件之间的状态传递十分麻烦。父子组件还好点,在 Vue 里面可以用 `props` 执行函数或者 `this.$broadcast` `this.$dispatch` 来传递状态,可是两个完全没有联系的组件要共享状态十分困难啊。 17 | 18 | 他是这样说的,他在做编辑器的时候侧边栏和编辑框都想知道用户**是否已经保存**这个状态, 而这两个组件完全没办法通过上述的几个方法共享 state。 19 | 20 | 于是小明告诉我他绞尽脑汁想到的几个方法: 21 | 22 | - 把这个状态放到这两个组件共同的父组件中然后通过 `prop.sync` 来同步这两个组件的这个状态 23 | - 在这两个组件中都放置这个状态然后通过共同父组件的一个 prop 来在父组件中调用函数执行一个 `this.$dispatch` 通知子组件这个状态有改动,借此来同步各个组件中的这个状态。 24 | 25 | 以上方法都是可行的,但是一旦组件逻辑复杂起来这样的回调啊、绑定啊、同步啊都会乱套。 26 | 27 | ## 历史必然 28 | 29 | 于是出现了 Redux ! 30 | 31 | 当然,Redux 不是为 Vue 出现的。不过却成为了解决所有 JavaScript 应用中状态管理的一种方案。 32 | 33 | 我能做的关于 Redux 的介绍就是这样,了解更多请阅读官方[自述](https://github.com/rackt/redux)。 34 | 35 | ## Vue? 36 | 37 | 也许你现在知道了 Redux 最初是因为 React 这个 View Layer Framework 而生的,React 和 Vue 一样具有组件系统,需要状态管理。 38 | 39 | 那么就把 Redux 应用到 Vue 中来吧? 40 | 41 | 你可以这么做,也可以使用 Vue 官方的 Flux 实现 [Vuex](https://github.com/vuejs/vuex),它和 Redux 非常类似。几乎唯一的区别就是你需要在 action 里直接修改状态。这很好,因为 Vue 本身赞成的是 mutable state。而 Redux 中则是推荐不要修改状态而是返回一个新的状态,选择哪种看你习惯哪种。 42 | 43 | ## Revue 44 | 45 | Redux 在 React 中的应用是通过 [React-Redux](https://github.com/rackt/react-redux) 来绑定的,显得十分复杂。在 Vue 中绑定 Redux 却是十分的简单: 46 | 47 | ```javascript 48 | // 首先创建你的 reducers/actions/store 49 | // 然后引入 revue 和你的 store 50 | import Revue from 'revue' 51 | import store from './store' 52 | // 将 Revue 作为一个插件在 Vue 中初始化 53 | // 同时绑定这个 store 54 | Vue.use(Revue, { store }) 55 | ``` 56 | 57 | 这样就大功告成了,之后在每一个 Vue 实例被创建之后每个实例都会有 `this.$revue` 属性和 `this.$subscribe` 方法。现在就介绍这些该如何被使用: 58 | 59 | ```javascript 60 | new Vue({ 61 | data () { 62 | // this.$revue 实际上指向你创建的 redux store 对象 63 | // 所以 store 有的方法都可以通过 this.$revue 调用 64 | // 每一个 state 都需要一个初始状态 65 | // 然后像下面这样调用初始状态 66 | return { 67 | counter: this.$store.state.counter // 假设默认你设置的是 0 68 | } 69 | }, 70 | methods: { 71 | handleClick () { 72 | // 点击之后执行 increment 让 counter 自增 73 | this.$store.dispatch({type: 'INCERMENT'}) 74 | // 现在 store 里的 state 改变了! 75 | // this.$revue.getState().counter 的值现在为 1 76 | } 77 | }, 78 | ready () { 79 | // 你改变了 store 里的 state 可是它不会反映到你的实例中! 80 | // 你需要手动订阅这个 state 更新 81 | this.$subscribe('counter') 82 | // 我的 store 里没有 counter 这个状态,我给它起的名字是 count 怎么办? 83 | // 很简单 84 | this.$subscribe('count as counter') 85 | } 86 | }) 87 | ``` 88 | 89 | > 郑重提醒,本文开头提到的小明不是明哥,如有雷同,明哥不要打我。 90 | 91 | > 我个人是一般是使用 redux-actions 和 redux-saga 这套组合 92 | 93 | --- 94 | 95 | 相关链接: 96 | - [Redux](https://github.com/rackt/redux) 97 | - [Revue](https://github.com/egoist/revue) 98 | - [Vuex](https://github.com/vuejs/vuex) 99 | -------------------------------------------------------------------------------- /example/_posts/short-hair.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 短发女生 3 | date: 2018/06/14 4 | --- 5 | 6 | 短发女生**也**可以性感和可爱? **Get outta here**, 短发女生是最好的。 7 | 8 | 9 | ![fukka vector](https://i.loli.net/2018/06/14/5b222e81ba561.png) 10 | 11 | ![ena komiya](https://i.loli.net/2017/12/03/5a23dd8a0870c.jpg) 12 | 13 | ![isshiki iroha](https://i.loli.net/2018/06/14/5b222fd0ec541.png) 14 | 15 | 以上便是我最喜欢的三位女性角色,抱歉了蕾姆,虽然你也是短发。 16 | 17 | 不过在三次元,还是黑色比较适合这样的发型,有次进电梯,身前是一位黑色短发少女,只看背面就感觉非常帅气,真是兼具活力与魅力的发型。有种雾岛董香把头发染黑了的感觉,不过应该没有把前面一只眼睛遮住 😂 18 | 19 | 20 | ![touka](https://i.loli.net/2018/06/14/5b223ba70946e.gif) -------------------------------------------------------------------------------- /example/_posts/subaru-be-loyal-or-jerk.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 菜月昴前传 3 | subtitle: 是人渣、废柴抑或是英雄、天使之路? 4 | date: 2016-08-03 22:46:52 5 | tags: 6 | - anime 7 | - rezero 8 | - rem 9 | --- 10 | **从零开始的异世界生活** 的最虐心阶段已经过去了?我小说只看到了这以后的一点剧情,所以并不能确定,不过很难想象之后还会有剧情能比 15/17/18 集更触动我。 11 | 12 | 菜月昴说他会开始踏上成为蕾姆理想中的英雄之路,如果没有之前蕾姆的鼓励,那他说出这番话势必会再次被人口诛笔伐,史上最弱男主的确是事实。然而菜月昴的逆袭是剧情需要,Re:Zero 不可能一直这样 dark 下去,无限循环的死亡回归出现太多反而会引起不适。 13 | 14 | 按照一般向展开,男主应该是和女主一起秒天秒地秒空气之后拯救众人,幸福美满地回家,这样才有值得后代谈论的事。而 Re:Zero 并不是这样,女主从某一集开始就隐形了,于是后面变成男主为了救一个长时间不上大屏幕露脸的女主死了很多次,然后就是爱着男主的某个女仆为了不让男主死而让自己死了很多次。 15 | 16 | 简单替换一下,男主是菜月昴,女主是艾米莉亚,女仆是蕾姆。 17 | 18 | 他们之间的关系可以概括为: 19 | 20 | > 艾米莉亚从小混混手里救了菜月昴,菜月昴认定这是自己命中注定的另一半,开始大男子主义地施加各种保护,不管她需不需要。虽然之后的确是男主救了艾米莉亚,不过这也全靠他来到异世界获得的能力「死亡回归」,照这样来说真正救艾米莉亚的是沙提拉? 21 | 22 | > 菜月昴从森林魔兽手里救了蕾姆,然后蕾姆认定菜月昴是自己的英雄。蕾姆可以理解,毕竟我们看到了关于蕾姆小时候的回忆。菜月昴的确让蕾姆停止的时间重新开始流动了。只是对于菜月昴,他对艾米莉亚的爱有点空穴来风似的。 23 | 24 | 菜月昴的人物刻画很写实,这是这个异世界里唯一接近现实的东西了,去掉「异世界」这个设定简直可以直接给「欢迎来到 NHK」拍续集。 25 | 26 | Re:Zero 有一点很矛盾,就是「死亡回归」这个设定,这是菜月昴反复经受折磨的关键,也是菜月昴拯救艾米莉亚的关键,没有这个能力也许第一集就能完结了。所以菜月昴到底该痛恨这个诅咒还是接受并利用它,大概是主要剧情想要描述的东西之一。 27 | 28 | 最后有一点有意思的猜测是,一般各种套路中,两个都是单方面爱着自己所爱的人最终走在了一起。 29 | 30 | 不过不管后面如何发展,菜月昴到目前为止就像他自己说的那样差劲,而蕾姆只是不想看到曾经治愈了自己的人这样堕落下去。 31 | 32 | 对的,你是否也已经发现了: 33 | 34 | ![img](https://oidzj4vwh.qnssl.com/blog/57a1a6c6a86f0.jpg) -------------------------------------------------------------------------------- /example/_posts/sublime-vscode-key-bindings.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Sublime Text 和 VS Code 常用快捷键 3 | date: 2016-10-05 21:00:47 4 | tags: 5 | - sublime 6 | - vs code 7 | tip: 持续更新中。 8 | --- 9 | 为什么是 Sublime Text 和 VS Code 这样奇怪的组合一起说呢,因为目前为止我最喜欢这两个编辑器。当然 Atom 也非常好,如果启动速度更快的话也许我会用得更多。Sublime 的优点就是 UI 简单但不丑,也有些很不错的主题,这里面我最喜欢的就是 [Material Theme](https://github.com/equinusocio/material-theme)、[Partto Theme](https://github.com/samuelrafo/piatto) 以及 [Ayu Theme](https://github.com/dempfi/ayu),相比之下 VS Code 的主题没那么风骚,但显得非常 「Solid」也挺耐看,不能说有个性就是了。 10 | 11 | 不过不得不说, VS Code 作为编辑器的功能还是比 Sublime 强。 12 | 13 | ## 显示效果 14 | 15 | ### 重新打开刚刚关闭的标签页 16 | 17 | Command Shift T 18 | 19 | ### 粘贴时自动缩进 20 | 21 | **Sublime**: Command Shift V 22 | **VS Code**: 不支持,但可以在粘贴后用 Option Shift F 替代,[查看更多](http://stackoverflow.com/questions/34627181/how-does-one-paste-and-indent-in-visual-studio-code) 23 | 24 | ### 切换标签页 25 | 26 | Command Option ←/→ 27 | 28 | ### 分割编辑器 29 | 30 | 也就是把一个编辑器分成两个或多个块。 31 | 32 | **Sublime**: Command Option 1/2 33 | **VS Code**: Command \\ 34 | 35 | ### 显示 / 隐藏侧边栏 36 | 37 | **Sublime**: Command K B 38 | **VS Code**: Command B 39 | 40 | ## 选取内容 41 | 42 | ### 选取光标附近的内容 43 | 44 | 通常是一个单词,连按 d 会继续选取下一个相同的内容。 45 | 46 | Command D 47 | 48 | ### 往左 / 右选取一个字符 49 | 50 | 通常与上一步一起使用进行更精确的选取。 51 | 52 | Shift ←/→ 53 | 54 | ### 选取光标所在的行 55 | 56 | 同样,连按会继续选取下一行。 57 | 58 | **Sublime**: Command L 59 | **VS Code**: Command I 60 | 61 | ### 将光标移至选取的每一行末尾 62 | 63 | 通常与上一步一起操作,用于多行编辑。 64 | 65 | **Sublime**: Command Shift L 66 | **VS Code**: Control Option I 67 | 68 | ### 在多个位置显示光标 69 | 70 | **Sublime**: Command 点击 71 | **VS Code**: Option 点击 72 | 73 | ### 将光标移至行首 / 行尾 74 | 75 | Command ←/→ 76 | 77 | ### 从光标所在位置选取到行首 / 行尾的内容 78 | 79 | Command Shift ←/→ 80 | 81 | ## 查找内容 82 | 83 | ### 搜索项目中的文件 84 | 85 | Command P 86 | 87 | ### 跳到指定的一行 88 | 89 | Control G 90 | 91 | ### 跳到函数定义 92 | 93 | **Sublime**: Command R 94 | 95 | ## 移动内容 96 | 97 | ### 上下移动选取的内容 98 | 99 | Command Control ↑/↓ -------------------------------------------------------------------------------- /example/_posts/tesing-javascript-apps-using-jest.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 用 Jest 测试 JavaScript 应用 3 | date: 2017-11-26 15:05:04 4 | tags: 5 | - jest 6 | - javascript 7 | - test 8 | --- 9 | Jest 是 FaceBook 用来测试 JavaScript 应用的一套测试框架,这些应用当然也包括了 React 应用。它的优点之一是自带了对 React 的支持,同时也很容易支持其它框架。 10 | 11 | 从最简单的开始,我们可以看看如何用 Jest 测试纯 JS 项目。 12 | 13 | 假设你需要测试 `sum.js`: 14 | 15 | ```js 16 | export default (a, b) => a + b 17 | ``` 18 | 19 | 你只需要对应地新建一个 `sum.test.js`[^1]: 20 | 21 | ```js 22 | import sum from './sum' 23 | 24 | test('sum', () => { 25 | expect(sum(2, 3)).toBe(5) 26 | }) 27 | ``` 28 | 29 |
30 | 31 | 32 | 33 | 关于这里的 `expect` 语法 34 | 35 | 36 | 37 | 这里的 `expect` `toBe` 是 Jest 默认使用的断言语法,也就是用来比较 `值` 的 API,详见[相关文档](https://facebook.github.io/jest/docs/en/using-matchers.html#content)。 38 | 39 |
40 | 41 | 然后在终端运行 `jest` 命令的时候就会自动找到这个文件,执行这里面的测试: 42 | 43 | ![jest](https://i.loli.net/2017/11/26/5a1a6a9148ca3.png) 44 | 45 | 额,报错了,原来 Jest 默认只支持你所使用的 node.js 版本所支持的 JS 特性,例如 `import` `export` 就不支持,所以要么你的代码使用系统 node.js 兼容的语法写 (也就是使用 `require`),要么在这里使用 Babel 转义一下。 46 | 47 | 在 Jest 中使用 Babel 很简单,只需要安装 `babel-jest` 并新建一个 `.babelrc` 加入你想要的配置就行了,Jest 会自动使用 `babel-jest`。这里我们简单地使用 `babel-preset-env` 即可,对应的 `.babelrc` 是: 48 | 49 | ```json 50 | { 51 | "presets": ["env"] 52 | } 53 | ``` 54 | 55 | 然后重新运行 jest 测试便通过了: 56 | 57 | ![jest 2](https://i.loli.net/2017/11/26/5a1a6c085ba32.png) 58 | 59 | 对于 React 应用,基本和纯 JS 项目类似,不过你需要在 `.babelrc` 中配置对 `JSX` 的支持,在大多数时候你的项目本身就已经在使用 `.babelrc` 了,所以这一步甚至也省略掉了。 60 | 61 | ## 资源文件 62 | 63 | 当你要测试的代码引用了非 JS 文件时,Jest 就不知道如何使用这些文件了,例如你的 Webpack 项目中的一个文件: 64 | 65 | ```js 66 | import './style.css' 67 | ``` 68 | 69 | 正如你需要在 Webpack 中配置了 `css-loader` 一样,你也需告诉 Jest 如何处理 CSS 文件。 70 | 71 | 📝 **package.json:** 72 | 73 | ```json 74 | { 75 | "jest": { 76 | "transform": { 77 | "^.+\\.(js|jsx)$": "babel-jest", 78 | "^.+\\.css$": "/jest/css-transform.js" 79 | } 80 | } 81 | } 82 | ``` 83 | 84 |
85 | 86 | 87 | 88 | 关于 babel-jest 89 | 90 | 91 | 92 | 当你手动在 `package.json` 里设置了 `jest.transform` 时 `babel-jest` 不再会被自动使用了,我们需要在这里手动配置。 93 | 94 |
95 | 96 | 对应的 `./jest/css-transform.js` 97 | 98 | ```js 99 | // 大多数测试并不关心 CSS 文件里的内容 100 | // 所以这里我们直接返回一个空的对象 101 | module.exports = { 102 | process() { 103 | return 'module.exports = {};' 104 | }, 105 | getCacheKey() { 106 | // The output is always the same. 107 | return 'css-cache' 108 | } 109 | } 110 | ``` 111 | 112 | 类似地,你可以使用 `transform` 来设定如何处理其它类型的文件,比如 `.vue`[^2] `.svg` 文件。 113 | 114 | 115 | [^1]: Jest 默认使用 `[ '**/__tests__/**/*.js?(x)', '**/?(*.)(spec|test).js?(x)' ]` 这些测试文件,当然这是[可配置](https://facebook.github.io/jest/docs/en/configuration.html#testmatch-array-string)的。 116 | [^2]: `.vue` 的 `transform` 可以使用社区的 [jest-vue](https://github.com/eddyerburgh/vue-jest)。 117 | 118 | ## 浏览器 API 119 | 120 | 假设你要测试的是一个 Web 应用,依赖于一些浏览器 API 比如 `window` `document`,它在 Jest 中同样可以正常运行,因为 Jest 默认使用了 [js-dom](https://github.com/tmpvar/jsdom) 来模拟浏览器环境,不需要浏览器环境时可以通过使用命令行参数 `--env node` 或者[配置文件](http://facebook.github.io/jest/docs/en/configuration.html#testenvironment-string)来禁用。 121 | 122 | ## Snapshot 测试 123 | 124 | 当你期望某个值不会改变的时候,可以使用 snapshot 测试。简单地说,它就是记录这个值的状态到[本地自动生成的 snapshot 文件](https://github.com/facebook/jest/blob/master/examples/snapshot/__tests__/__snapshots__/link.react.test.js.snap)里,然后在下一次测试中用新的值来和其进行对比。这对 UI 之类的测试很有帮助: 125 | 126 | ```js 127 | import React from 'react' 128 | import Link from '../Link.react' 129 | import renderer from 'react-test-renderer' 130 | 131 | it('renders correctly', () => { 132 | const tree = renderer 133 | .create(Facebook) 134 | .toJSON() 135 | expect(tree).toMatchSnapshot() 136 | }) 137 | ``` 138 | 139 | 这确保了 `Facebook` 渲染出的内容不会出错。 140 | 141 | 当你更改了 `` 组件的逻辑,需要更新 snapshot 文件时,可以加上 `--updateSnapshot` 或者 `-u` 来更新。 142 | 143 | 类似的,Snapshot 测试不止于 UI 测试中,假设你写了个 Markdown 解析器,你可以用它来确保解析出的内容不会改变: 144 | 145 | ```js 146 | import renderMarkdown from './my-markdown-parser' 147 | 148 | test('render correctly', () => { 149 | const html = renderMarkdown('# markdown code') 150 | expect(html).toMatchSnapshot() 151 | }) 152 | ``` 153 | 154 | 查看[相关文档](https://facebook.github.io/jest/docs/en/snapshot-testing.html#content)。 155 | 156 | ## 异步代码测试 157 | 158 | https://facebook.github.io/jest/docs/en/asynchronous.html#content 159 | 160 | 我就懒得写了... 反正用 `Promise` 或者 `async/await` 就对了。 161 | -------------------------------------------------------------------------------- /example/_posts/the-most-lightweight-es2015-setup.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 最轻量的 ES2015 编译配置 3 | subtitle: Sometimes Babel, Sometimes Buble. 4 | date: 2017-04-28 21:11:32 5 | tags: 6 | - babel 7 | - buble 8 | --- 9 | ## 用 Buble 替换 Babel 10 | 11 | [Babel](http://babeljs.io/) 可以说是编译 ES2015+ 代码到 ES5 的首要选择,它的可扩展性很高,基于插件几乎能做任何事。 12 | 13 | 而 [Buble](https://buble.surge.sh/guide/) 则去掉了这种可扩展性,只会转换能够用 ES5 实现并保证性能的新特性,同时这样也让你免去配置的步骤。 14 | 15 | 对于下面这段代码,你可以通过编译结果看出它们设计上的不同: 16 | 17 | ```js 18 | class Foo { 19 | constructor() { 20 | this.pos = 0 21 | } 22 | 23 | say(word) { 24 | return `hello ${world}` 25 | } 26 | 27 | walk() { 28 | this.pos++ 29 | } 30 | } 31 | ``` 32 | 33 | Babel 的结果: 34 | 35 | ```js 36 | "use strict"; 37 | 38 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); 39 | 40 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 41 | 42 | var Foo = function () { 43 | function Foo() { 44 | _classCallCheck(this, Foo); 45 | 46 | this.pos = 0; 47 | } 48 | 49 | _createClass(Foo, [{ 50 | key: "say", 51 | value: function say(word) { 52 | return "hello " + world; 53 | } 54 | }, { 55 | key: "walk", 56 | value: function walk() { 57 | this.pos++; 58 | } 59 | }]); 60 | 61 | return Foo; 62 | }(); 63 | ``` 64 | 65 | Buble 的结果: 66 | 67 | ```js 68 | var Foo = function Foo() { 69 | this.pos = 0 70 | }; 71 | 72 | Foo.prototype.say = function say (word) { 73 | return ("hello " + world) 74 | }; 75 | 76 | Foo.prototype.walk = function walk () { 77 | this.pos++ 78 | }; 79 | ``` 80 | 81 | 总的来说 Buble 的结果可读性更强、更简洁,而且设计初衷就是为了不引入 `_createClass` 之类的 runtime。 82 | 83 | ## async/await 和 generator 函数 84 | 85 | Buble 暂时不支持编译 async/await 和 generator 函数,目前有以下几个工具作为替代: 86 | 87 | - [nodent](https://github.com/MatAtBread/nodent) (性能比 babel-plugin-tranform-async-to-generator 更好) 88 | - [async-to-gen](https://github.com/leebyron/async-to-gen) (不支持编译 generator) 89 | 90 | 我一般会将 Rollup、Buble 以及 async-to-gen 配合使用: 91 | 92 | ```js 93 | // rollup.config.js 94 | export default { 95 | plugins: [ 96 | require('rollup-plugin-async')(), 97 | require('rollup-plugin-buble')() 98 | ] 99 | } 100 | ``` 101 | 102 | 其实由于在开发 web app 的时候基本还是用 webpack 为主而且又是对 ES features 的需求不止于 ES2015,这个时候我一般还是选择用 Babel 编译。 103 | 104 | 而对于可复用的 library,不太需要 async/await 或者只是针对 Node.js 环境的时候,使用 Buble 还是很理想的。 -------------------------------------------------------------------------------- /example/_posts/the-world-is-a-big-noise.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 世界真喧扰 3 | date: 2017-05-04 13:57:06 4 | tags: 5 | --- 6 | 7 | 多说话让你有活着的实感,甚至还能调动你的神经,使你更为神采奕奕。 8 | 9 | 然而说出的不同的内容给自己和别人带来的影响也是不同的,比如有些人喜欢通过说话来贬低别人从而抬升自己,还有人希望用自己的一己之见混淆视听,这些都不是什么好的行径。 10 | 11 | 有些人说出的话其实是不经过大脑的,没有调查取证,没有任何思考的痕迹。前几日 Vue 娱乐圈又在知乎上[炸开了锅](https://www.zhihu.com/question/59039141),之所以称之为娱乐圈完全不是贬低 Vue,而是很多国人喜欢把 Vue 往自己身上贴,让其沾染上自己的逗逼气质。不然为何他们不去搅和一下 React 娱乐圈和 Angular 娱乐圈呢,因为它们的作者大概根本不会鸟这些人。尤小右的国人属性让这些人觉得自己也可能是「被选中的那一个」。这些人之中也产生了一些怪诞的想法: 12 | 13 | > @vayne: 尤是生意人,已经是个商人了,不必和他说技术 14 | 15 | 我哪天哪根筋不对也可能去黑一下尤小右,不过万万不会用这种勾当,完全是对自己接受的数十年教育成果的否定。尤小右去年在 GitHub 贡献的提交量约为 6000,而且几乎是流行的产生了很大价值的项目,不像我那些仅仅是用来改善心情的小玩具。所以在深思熟虑后我觉得技术这个方面应该没有什么问题。再说生意人,我想这个结论大概是七大罪之一的嫉妒吧,你写代码赚 star 可以但是靠它赚了这么多钱就不对了,不过是又一个前端框架,为什么你在 [patreon](https://www.patreon.com/evanyou) 上有如此多的支持者?靠这种半自愿的赞助就月入一万刀?我也是中国人啊,上帝一定是收了你一瓶 82 年的雪莉酒才这么照顾你的。这种心情我可以体会,以前高中的时候我是个学渣,每次看到学霸考高分的时候我也是同样的心情,那个学霸甚至比我还矮。 16 | 17 | 说到嫉妒这宗罪,真是人类迈不过去的一道坎,堪称世界性不可治愈型流行病。因为嫉妒很多人会犯一些颠覆常识、泯灭人性的错误。正如每次在足球比赛结束之后,你可能看到一方的球迷因为对方头牌犯的一个莫须有的错误而给他贴上猪狗不如的标签,而对方的球迷会因为自己的骄傲被如此对待,而故意挑起更大的冲突。对了,我说的就是皇马和巴萨,C罗和梅西。 18 | 19 | C罗曾经说过,「那些批评我的人都是嫉妒我长得帅、又有钱,球还踢的好」这句话其实不无道理。对于一个起点极高的人,你当然会抱怨世界的不公,抱怨这其中是否有什么蹊跷。躺在安稳的沙发上,对着奋力一次次轰门的C罗大放厥词。 20 | 21 | 然后在事情过后,将自己产生的痕迹消灭得干干净净,就像家畜那样掩埋掉自己排泄的场所。 -------------------------------------------------------------------------------- /example/_posts/this-is-how-it-started.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 拥有能够眺望的远方 3 | date: 2017-01-12 17:56:09 4 | --- 5 | 最近看了冬季新番「风夏」,本来只是普通地再一次被女主角打动而已,可是在无意看了评论区之后心情却变成另一个极端。 6 | 7 | > 风夏在漫画里死了。 8 | 9 | 虽然女主角死掉的漫画和动画都有,可是上了作品标题同时死了的还是非常令人难以相信,更何况是如此打动我的风夏。 10 | 11 | 于是第二天按耐不住好奇,彻夜看完了风夏的漫画(正在连载的部分)。就算知道风夏会死,我也没想到在第 37 话就说了再见,而且似乎「什么都还没有做」就离开了,甚至后来还出现了另一个叫风夏的。很多人诟病的是作者冷酷地对待自己作品里的角色和自己的读者,我也曾经这样觉得,因为一想到后面那么多的故事不是风夏和男主来一起经历那还有什么意义啊,我就忍不住想和男主一起哭。 12 | 13 | > 我总想的是: 如果是风夏在这里会怎样呢? 14 | 15 | 很残忍,令人难过。听说作者濑尾公治是小时候看了「哆啦A梦」之后便想成为一个漫画家。惊人地相似,我在看过濑尾的「涼風」「風夏」之后,虽说不至于做梦成为漫画家,可是也想画出令自己觉得残忍和难过的作品呢。 16 | 17 | --- 18 | 19 | 于是我今天开始学习画画了,正因如此对于代码和开源我可能一段时间内不会碰了。 20 | 21 | 那以后有机会画给你瞧瞧吧 :D -------------------------------------------------------------------------------- /example/_posts/tooling-free-you-from-jquery.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: tooling 让你从 jQuery 中解脱出来 3 | date: 2016-01-19 20:43:58 4 | subtitle: jQuery 只是个引子,泛指那些不用构建工具的 “显得很方便” 的开发方式 5 | tags: 6 | - tooling 7 | - webpack 8 | - jquery 9 | --- 10 | 11 | ## 起因 12 | 13 | 为什么我还需要用 jQuery?有时候我会有这样的疑惑。我觉得 jQuery 还存在于我某些小项目中的原因就是可以 “即插即用”。新建一个 `index.html`、复制一些代码、新建一个 `style` `script` 标签你就可以开始工作了,这种便利在某些时候非常好。 14 | 15 | 比如刚才,我想给自己做一个用于收取捐赠的网页(也许会有开源世界的同好喜欢我的项目也说不定呢),我在 “简单粗暴一个 html 搞定” 和 “Webpack + Vue 配合各种构建工具” 之间摇摆不定。 16 | 17 | 用过 Webpack 的都知道,也许配置和解决 bug 的时间会比写代码的时间更长,而且大部分情况配置文件都大同小异。那为什么不用**一个配置适用多个项目**?于是有了 [`tooling`](https://github.com/egoist/tooling),它其实就是用一个内置的 Webpack 配置来运行和编译指定的项目。 18 | 19 | ## tooling 带来了什么? 20 | 21 | 也许我的表达并不直观,简而言之,tooling 让你开发的便利程度趋近直接用一个 html 搞定。 22 | 23 | tooling 内置了 Vue 和 React 的依赖,这意味着你要开发这两种框架的网页几乎是 `no setup`,新建一个项目,不用 `npm init`,不用安装任何依赖,直接: 24 | 25 | **index.js** 26 | 27 | ```javascript 28 | import Vue from 'vue' 29 | import app from './app' 30 | 31 | new Vue({ 32 | el: 'body', 33 | components: {app} 34 | }) 35 | ``` 36 | 37 | **app.vue** 38 | 39 | ```vue 40 | 48 | 49 | 52 | ``` 53 | 54 | 然后运行 `tooling watch -e index` 就可以开着热加载模式进行开发了。 55 | 56 | 并不需要配置、对开发友好、ES6、PostCSS + PreCSS、享受 Vue 单文件组件的优势、React 的 JS everywhere 的畅快,这些带给你的远不止便利。 57 | 58 | ## Use Case 59 | 60 | 如果你实在不知道这玩意能在哪些地方用,那么我告诉你吧。 61 | 62 | - 你的开源项目的 gh-pages 主页 63 | - 你个人的一些小实验或者一个大项目的 prototype 64 | - 你的各种需要网页来展示的小发明。 65 | - many more... 66 | 67 | 看,[donate](https://github.com/egoist/donate) 就是一个例子,如果没用 tooling 的话这个 repo 里会多一堆配置文件,而现在我只需要 focus 这个项目本身。 68 | 69 | --- 70 | 71 | `tooling` 的 GitHub 主页: https://github.com/egoist/tooling -------------------------------------------------------------------------------- /example/_posts/true-how-to-learn-to-code.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 真・如何学写代码 3 | compileTemplate: true 4 | date: Fri Jul 27 2018 19:56:45 GMT+0800 (CST) 5 | --- 6 | 7 | 之前的一篇如何学写代码只有寥寥数字,但其实包含了大部分我想表达的内容: 8 | 9 | - 勤奋,你需要长时间坐在电脑上学习。(别忘了适当的休息和运动) 10 | - 自学能力,即使完整如九年义务教育都不能保证你顺利地成为一个合格的社会人,你的自学能力才能让你持续发展。如果你想去培训班,请参考[这里的讨论](https://www.zhihu.com/question/53567687),很不幸,国内没有靠谱的培训班。 11 | 12 | 实际上,写本文的理由是我有一个从事机械制图的朋友在寻求转行,自然平均工资比他高两倍以上的 IT 行业便入了他的法眼。 13 | 14 | sit down and do work 我觉得是适用于他的,毕竟机械制图也是需要对着电脑工作的行业。对于其它行业想转行的人士,只要能做到这点我觉得都有**开始**学写代码的能力。我是那种可以一个月不出一次门的人,所以对我来说很平常就是了。 15 | 16 | 以下是我给他这类人的建议: 17 | 18 | 编程挺难,明摆着的,不然工资也不会比其它部分行业高那么多。如果你想写好代码,就得多花时间。 19 | 20 | 首先学一个语言然后把它学好,比如 JavaScript 或者 Python,根据你的目的选择。 21 | 22 | 你至少得花半年以上的时间学习,然后再谈找工作,IT 公司比较重视项目经验,所以最好在这期间完成一些有意义的项目,要么是自己做,要么是实习。 23 | 24 | 一旦你走在正确的路上了你就会发现写代码很有趣,不过再有趣的工作让你重复半年也会有厌烦的时候。写代码就像造房子,你需要参与它的设计构思,这很有趣,但你也需要亲自添砖加瓦,搭脚手架,这些是重复的工作,自然不那么有趣。 25 | 26 | 除了编程语言,掌握适当的数据结构和算法知识也是必要的,不过不必太在意,有个了解就行了,大部分计算机工作都不会要你亲自实现一个 Hash Table 或者 Binary Search Tree。 -------------------------------------------------------------------------------- /example/_posts/vue-jsx-full-guide.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Vue JSX 使用指南 3 | subtitle: JSX 相关专利归 NoFaceBoooooooooook 所有 4 | date: 2017-09-21 12:19:14 5 | tags: 6 | - vue 7 | - jsx 8 | --- 9 | 10 | ## 什么是 JSX? 11 | 12 | 没怎么使用 React 或类似框架的同学可能不太了解 JSX,对此我不做赘述,简而言之这就是一种对 JavaScript 的补充,用来描述组件的 UI 部分,类似模板语言但它完整支持 JavaScript 本身的语言特性。 13 | 14 | 参考 FaceBook [关于 JSX 的介绍](https://facebook.github.io/react/docs/introducing-jsx.html)。 15 | 16 | ## 转换 JSX 17 | 18 | JSX 只是对 JavaScript 的补充并没有浏览器的支持,所以你需要用 [Babel](http://babeljs.io/) 搭配 [babel-preset-vue](https://github.com/vuejs/babel-preset-vue) 来获得完整的 Vue JSX 功能。 19 | 20 | ## 使用 JSX 21 | 22 | ### render 和 createElement 函数 23 | 24 | 你也许对 Vue 的 template (模板) 已经很熟悉了,如果你是用了 webpack + vue-loader 之类的组合,它其实是被转换成了 `render` 函数。 25 | 26 | 对于以下单文件组件: 27 | 28 | ```vue 29 | 32 | 33 | 42 | ``` 43 | 44 | 被 webpack + vue-loader 处理后是: 45 | 46 | ```js 47 | export default { 48 | data() { 49 | return { 50 | msg: 'hello' 51 | } 52 | }, 53 | render() { 54 | var _vm = this; 55 | var _h = _vm.$createElement; 56 | var _c = _vm._self._c || _h; 57 | return _c('div', [_vm._v(_vm._s(_vm.msg)), _c('div')]) 58 | } 59 | } 60 | ``` 61 | 62 | *[在线调试](https://jsx.egoist.moe/gist/8a264502933118ee7afe811139bb52f6)* 63 | 64 | 这里的 [createElement](https://vuejs.org/v2/guide/render-function.html#createElement-Arguments) 函数也经常被叫做 `h` 函数,它被用来创建一个 [vNode](https://github.com/vuejs/vue/blob/dev/src/core/vdom/vnode.js) (虚拟 DOM 节点)。你可以通过 `this.$createElement` 访问它但同时它也是 `render` 函数的第一个参数。 65 | 66 | 在使用 JSX 的时候,类似 template,不过只会转换 `render` 函数中的 JSX 表达式。 67 | 68 | 对于以下源代码: 69 | 70 | ```jsx 71 | export default { 72 | data() { 73 | return { 74 | msg: 'hello' 75 | } 76 | }, 77 | render() { 78 | return
{this.msg}
79 | } 80 | } 81 | ``` 82 | 83 | 它会被转换成: 84 | 85 | ```js 86 | export default { 87 | data() { 88 | return { 89 | msg: 'hello' 90 | }; 91 | }, 92 | render() { 93 | const h = arguments[0]; 94 | 95 | return h( 96 | 'div', 97 | null, 98 | [this.msg] 99 | ); 100 | } 101 | }; 102 | ``` 103 | 104 | *[在线调试](https://jsx.egoist.moe/gist/a2bda79dfa96053bc9bb5e743988796e)* 105 | 106 | ## Vue JSX 特性 107 | 108 | ### 和 React JSX 的不同 109 | 110 | Vue JSX 中 createElement 的第二个参数 `data` 与 React 中的有些不同,它是个嵌套的对象并且每个顶层的属性由不同的模块处理,提供不同的功能,比如 `class` (在 React 中是 `className`) 和 `on` 这两个属性: 111 | 112 | ```js 113 | createElement('div', { 114 | class: ['foo', 'bar'], 115 | on: { 116 | click: this.click 117 | }, 118 | ['foo'] 119 | }) 120 | ``` 121 | 122 | 对应的 JSX 是: 123 | 124 | ```jsx 125 |
foo
126 | ``` 127 | 128 | 对于这种嵌套对象,你可以在 JSX 中用 camelCase 或者 kebeb-case (连字符) 来表示,换句话说这里 JSX 中的 `onClick` 也可以写成 `on-click`,前者是为了让熟悉 React JSX 的同学更方便而加入的。 129 | 130 | 完整的属性列表请参考相关 [typing](https://github.com/vuejs/vue/blob/2deda3d4328eb7aea0adb0eaf01d68537ed0e0af/types/vnode.d.ts#L36-L60) 和 [README](https://github.com/vuejs/babel-plugin-transform-vue-jsx#difference-from-react-jsx)。 131 | 132 | ### v-model [插件页面](https://github.com/nickmessing/babel-plugin-jsx-v-model) 133 | 134 | 不久之前 Vue JSX 还不支持 `v-model` 因为这个转换比较复杂,感谢 [@nickmessing](https://github.com/nickmessing) 的 [babel-plugin-jsx-v-model](https://github.com/nickmessing/babel-plugin-jsx-v-model) 插件。 135 | 136 | 对于以下 template: 137 | 138 | ```html 139 | 140 | ``` 141 | 142 | 对应的 JSX 是: 143 | 144 | ```jsx 145 | 146 | ``` 147 | 148 | 编译后: 149 | 150 | ```js 151 | import _mergeJSXProps from "babel-helper-vue-jsx-merge-props"; 152 | 153 | var _this = this; 154 | 155 | h( 156 | "input", 157 | _mergeJSXProps([{ 158 | domProps: { 159 | "value": _this.username 160 | }, 161 | on: { 162 | "input": $event => { 163 | if ($event.target.composing) return; 164 | _this.username = $event.target.value; 165 | } 166 | } 167 | }, { 168 | directives: [{ 169 | name: "model", 170 | value: _this.username 171 | }] 172 | }]), 173 | [] 174 | ); 175 | ``` 176 | 177 | *[在线演示](https://jsx.egoist.moe/gist/7de4ca46ae8eb69dbd861e23c4603f64)* 178 | 179 | 其实在 JSX 里的 `v-model` 就是语法糖,你当然可以手动书写对应的逻辑。而这个 Babel 插件则简化了这一步骤。JSX 中的 `v-model` 拥有 template 中同样的功能。 180 | 181 | ### 事件修饰符 [插件页面](https://github.com/nickmessing/babel-plugin-jsx-event-modifiers) 182 | 183 | template 中的键盘事件修饰符在 JSX 中也有完整的支持。 184 | 185 | 对于以下 template: 186 | 187 | ```html 188 | 189 | 190 | ``` 191 | 192 | 对应的 JSX: 193 | 194 | ```jsx 195 | 196 | // 多个修饰符用 `-` 连字符连接 197 | Click 198 | ``` 199 | 200 | 转换之后的 JS: 201 | 202 | ```js 203 | 204 | var _this = this; 205 | 206 | h( 207 | "a", 208 | { 209 | on: { 210 | "click": $event => { 211 | $event.stopPropagation(); 212 | $event.preventDefault(); 213 | 214 | _this.doThat($event); 215 | } 216 | } 217 | }, 218 | ["Click"] 219 | ); 220 | ``` 221 | 222 | *[在线演示](https://jsx.egoist.moe/gist/8b99c95854d389df4772e4b677966403)* 223 | -------------------------------------------------------------------------------- /example/_posts/why-i-choose-tab-over-space.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 为什么我选择用 tab 而不是 space 来缩进 3 | date: 2016-01-17 22:33:44 4 | tags: 5 | - javascript 6 | - code 7 | - space 8 | - tab 9 | --- 10 | 圣战有很多种,诸如 Vim vs Emacs,Sublime vs Atom,OSX vs Windows,当然也有 Tab vs Space。 11 | 12 | 很久以前我听信了一个建议,“两个空格的缩进非常棒,你是前端更是如此了。” 13 | 14 | “为什么?” 我想问,但我并没有问,因为从网上搜索而来的理论中,“两个空格党” 这股力量不容小觑,我于是随波逐流,并且一直感觉不错,“两个空格” 似乎是对的,JS 嵌套多,空格少看起来不那么 “糟”。 15 | 16 | 但直到最近,我遭到了两次背叛。 17 | 18 | 第一次是我下班回来从 24 寸屏切换到家里的 14 寸笔记本,“天啊!两个空格几乎短到看不见了!” 我急忙切换到四个空格这才稍微好点,然而我不可能家里一个配置,公司一个配置,我第一次有了抛弃空格的念头。 19 | 20 | 第二次是我在某处 copy 了一段代码(没办法,我是面向 GitHub 编程的),“糟糕!他的代码是四个空格缩进!” 于是我还得 “帮他” 把代码缩进调整为两个空格。 21 | 22 | --- 23 | 24 | 分手理由充分了,我毫不犹豫地说了再见。 25 | 26 | 但是 tab 更好?当然。 27 | 28 | 理由之一是 tab 是非常适合 “有个性的人” 的,根据你的个性你可以调整 tab 的宽度,同样是 “一个 tab” 但你可以让它看起来像 “两个空格” 或者 “四个空格”,而不是生硬地调整 space 的数目,那样对你项目的协作者会非常糟,除非你们用同一个 size 的屏幕,同一个编程习惯。 29 | 30 | 其实还有非常多的理由,[Why tabs are clearly superior](http://lea.verou.me/2012/01/why-tabs-are-clearly-superior/) 会坚定你选择 tab 的决心。 31 | 32 | 总结一下就是: 33 | 34 | - Tab 占的体积更小。 35 | - Tab 的宽度可以因人而异,更个性化。 36 | - Tab 更利于多人协作。 37 | - Tab 不需要依靠某一个工具,所有编辑器都知道 “如何插入一个 tab” 38 | - Tab 更容易选中,还在为漏选一个 space 而烦恼? 39 | - Tab 现在在网页上不再难看,过去网页上一个 tab 显得非常宽,而现在 CSS3 的 `tab-size` 属性解决了这一痛点。 40 | 41 | > Use tab to indent, use space to align. 42 | > If you are using space, you are making alignment, not making indention. 43 | -------------------------------------------------------------------------------- /example/_posts/why-i-wont-marry.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 为什么我不会结婚 3 | date: 2016-04-02 19:27:34 4 | tags: 5 | --- 6 | - 有生理缺陷 7 | - 有心理缺陷 8 | - 没有值得喜欢的人 9 | -------------------------------------------------------------------------------- /example/_posts/why-so-addicted-into-anime.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 为什么动漫如此吸引我? 3 | date: 2015-07-10 09:08:51 4 | categories: 5 | - Anime 6 | tags: 7 | - anime 8 | --- 9 | 我想我第一部认真看的动漫应该是神奇宝贝,此外还有龙珠Z。但在那个时候,我其实不知道动漫到底是什么。我只是觉得这是日本卡通片而已,我并不知道大洋彼岸的岛国对动漫如此推崇,那里的动漫真是数以千计,各种脑残粉打扮得像动漫里的角色,当然那时我也并没体会到 hentai 的真正含义。 10 | 11 | 大概是从看浪客剑心开始我慢慢明白了动漫究竟是什么,我也开始学画漫画,我和我的小伙伴画了一部属于我们的漫画。这件事是真的很有趣,那个时候我大概 14 岁,我记得我是从网上找动漫资料学习画画,然后就被如此之多的动漫惊艳到了。 12 | 13 | 现在已经过了好几年了,我已经 24 岁,我那参军的兄弟依然亘古不变地从遥远的军营向我推荐动漫来看。我其实已经好几个月没碰动漫了,但现在我满血复活。不管我多少次停止看动漫这件事,我最终还是又开始看了,**为什么?我他妈到底怎么了?老大不小了看个屁的动漫啊?是不是该打住别去看那些半裸萌娘巨乳萝莉撕高达的东西了?动漫到底哪吸引你了?** 14 | 15 | 其实吧,我觉得原因也很简单。 16 | 17 | **第一,动漫的色彩效果真是很炫酷** 在动漫里有各种色彩搭配,亮色、鲜艳色、吸引眼球的颜色,甚至你可能并不知道鲜艳的颜色对保持健康略有裨益!就是说,丰富的颜色能让你心情变好。所以,看动漫从科学角度来说是对身体有好处的(这真的是我说的吗 233 18 | 19 | **另一个原因就是,我觉得,啊,对,萌妹子** 动漫里的女生都超可爱的是吧,娇小的外形、大大的眼睛、黑长直,卡哇伊卡哇伊卡哇伊 >3< 搞怪的妹子、萌系妹子、剑姬、肉魅以及我的我的最爱,“猫娘”。她们不只可爱还超性感,这是每个boy无法抵挡的。 20 | 21 | **但是!真正让我放不下动漫的原因是,里面的故事** 我看过的动漫各式各样的题材都有,情节各异。里面有些情节阐述的观念和想法是你闻所未闻、耳目一新的,比如说死亡笔记,一个男孩发现了一本日记然后发现自己能靠在日记上写上一个人的名字来杀死他。再比如CODE GEASS,讲的是几个拥有超自然能力的人进行的机甲战争,这些能力比如说读心术和强制控制他人行为。再比如黑之契约者,讲的是某个角色能靠割手腕然后把流出来的血洒在别人身上来杀人。 22 | 23 | 24 | 这些想法一个接着一个翻新,你永远想不到的想法就会出现在一部动漫中。我不知道是怎么回事,也许是美国人不善创新?所有故事都大同小异,乏味的故事靠着新的演员来骗钱,但是在日本,我去!你看了一集你就被吸引了,有些东西有人永远不会明白,除非他看了动漫。 25 | 26 | 最后作为一个作家,很感谢动漫带给我的灵感 :D 27 | 28 | --- 29 | 30 | 总感觉我翻译得怪怪的,还是去看原文吧: 31 | 32 | Just a Transilation from [WHY ANIME IS SO ADDICTING](https://medium.com/@dwarsement/why-anime-is-so-addicting-fcf6ef36b7c) 33 | -------------------------------------------------------------------------------- /example/_posts/write-better-code-with-eslint-and-prettier.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 用 ESLint 和 Prettier 写出高质量代码 3 | subtitle: 当然你的代码本身不能是无意义的 4 | date: 2017-12-11 21:37:05 5 | tags: 6 | - javascript 7 | - eslint 8 | - prettier 9 | --- 10 | 11 | [ESLint](https://github.com/eslint/eslint) 可以检测出你代码中潜在的问题,比如使用了某个变量却忘记了定义,而 [Prettier](https://github.com/prettier/prettier) 作为代码格式化工具,能够统一你或者你的团队的代码风格。 12 | 13 | 本文不会介绍这两种工具单独的使用方法,因为相关网络资料已经足够多了。这里我介绍一下怎么同时使用它们。 14 | 15 | ## 在 ESLint 中使用 eslint-plugin-prettier 16 | 17 | __为什么使用这种方法: 希望格式化结果完全符合 Prettier 的要求。__ 18 | 19 | 相关依赖: 20 | 21 | ```bash 22 | yarn add prettier eslint-config-prettier eslint-plugin-prettier --dev 23 | ``` 24 | 25 | `eslint-plugin-prettier` 的工作原理是,对比格式化前和用 Prettier 格式化后的代码,有不一致的地方就会报错,然后你可以手动运行 `eslint --fix` 来修复。 26 | 27 | 不过 Prettier 的格式化很可能和你使用的 ESLint 配置冲突,比如你的 ESLint 设定的不使用分号,而 Prettier 默认使用分号,这时候你需要配置 Prettier 让它不使用分号。反之如果你想使用 Prettier 的规则而不是 ESLint 的,为防止 ESLint 报错,你需要使用 `eslint-config-prettier` 来关闭所有可能引起冲突的规则。 28 | 29 | 总结一下我的配置如下 `package.json` (为了方便展示省略了不必要的部分): 30 | 31 | ```json {5-11} 32 | { 33 | "scripts": { 34 | "lint": "eslint *.js" 35 | }, 36 | "eslintConfig": { 37 | "extends": ["prettier"], 38 | "plugins": ["prettier"], 39 | "rules": { 40 | "prettier/prettier": "error" 41 | } 42 | }, 43 | "prettier": { 44 | "singleQuote": true, 45 | "semi": false 46 | } 47 | } 48 | ``` 49 | 50 | 上面高亮的 `eslintConfig` 可以简化为: 51 | 52 | ```json 53 | { 54 | "extends": ["plugin:prettier/recommended"] 55 | } 56 | ``` 57 | 58 | `eslint-plugin-prettier` 提供的 `recommended` 配置会自动添加 `eslint-config-prettier` 和 `eslint-plugin-prettier`,为你省去一些手动的配置。 59 | 60 | 你可以使用大多数编辑器里 ESLint 插件提供的 `autoFixOnSave` 选项来在保存时自动格式化。 61 | 62 | 63 | ## 使用 prettier-eslint-cli 64 | 65 | __为什么使用它: 希望格式化结果完全符合 ESLint 的要求。__ 66 | 67 | 相关依赖: 68 | 69 | ```bash 70 | yarn add prettier-eslint-cli --dev 71 | ``` 72 | 73 | 使用 ESLint 与 `eslint-plugin-prettier` 的结果是最终得到的代码是充分尊重 Prettier 的结果,而 `prettier-eslint-cli` 则是先执行 Prettier 然后再自动使用 `eslint --fix` 将与 ESLint 规则冲突的代码修正成 ESLint 想要的结果。这样其实引入 Prettier 不会影响你原有的设置。 74 | 75 | 总结一下我的配置如下 `package.json` (为了方便展示省略了不必要的部分): 76 | 77 | ```json 78 | { 79 | "scripts": { 80 | // ESLint 只负责检查代码质量 81 | "lint": "eslint *.js", 82 | // 用 Prettier 格式化代码并自动 `eslint --fix `以便下次执行 `npm run lint` 时不会报错 83 | "format": "prettier-eslint --write *.js" 84 | }, 85 | "eslintConfig": { 86 | "extends": "some-config" 87 | }, 88 | "prettier": { 89 | "singleQuote": true, 90 | "semi": false 91 | } 92 | } 93 | ``` 94 | 95 | 除了命令行的 `npm run format`,同时你也可以使用编辑器里的 Prettier 插件,并启用 `eslintIntegration` 来在编辑器里自动格式化代码。 96 | 97 | ## 在提交代码时格式化 98 | 99 | 安装需要的依赖: 100 | 101 | ```bash 102 | yarn add lint-staged husky@next --dev 103 | ``` 104 | 105 | [husky](https://github.com/typicode/husky) 被用来添加一些 git 钩子,这里我们需要一个用 `pre-commit` 在每次 `git commit` 操作时执行 `lint-staged` 命令。 106 | 107 | 而 [lint-staged](https://github.com/okonet/lint-staged) 可以对 git 暂存区文件(也就是你想要 commit 的文件)执行一些操作,比如这里我们想在代码被修改后将其格式化: 108 | 109 | ```json 110 | { 111 | "lint-staged": { 112 | "*.js": ["eslint --fix", "git add"] 113 | }, 114 | "husky": { 115 | "hooks": { 116 | "pre-commit": "lint-staged" 117 | } 118 | } 119 | } 120 | ``` 121 | 122 | ## 个人喜好 123 | 124 | 我个人倾向使用 eslint-plugin-prettier,因为 ESLint 一般是必需的,而使用 ESLint 插件的成本明显比使用一个新的命令行工具(即 prettier-eslint-cli)的成本低多了。 125 | -------------------------------------------------------------------------------- /example/_posts/wtf-is-front-end-development.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 什么是前端开发 3 | date: 2018-08-21 4 | published: false 5 | warning: 本文正在撰写中... 6 | --- 7 | 一个网页应用或者移动应用的开发通常分为两大块,后端和前端: 8 | 9 | - 后端: 处理数据,按需交给前端使用。 10 | - 前端: 从后端获取数据,然后以特定的界面 (UI) 来显示。 11 | 12 | 后端开发能使用的编程语言有很多,比如 Python、Go、Java、C# 等等。然而前端受制于环境,只能使用支持的语言来编写,比如 iOS 前端使用 Swift 或者 Obj-C,Java 前端使用 Java 或者 Kotlin,Web 前端使用 JavaScript。 13 | 14 | 如果只提「前端」,那通常指的是 Web 前端,本文也主要是*围绕 Web 前端进行讨论*。 15 | 16 | ## 前端开发的历史 17 | 18 | -------------------------------------------------------------------------------- /example/about.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 关于这个可爱的男孩子 3 | subtitle: 先定一个小目标,写出能用的代码就行了。 4 | --- 5 | 6 | ## 关于我 7 | 8 | 94 年生人,生无可恋脸,患有二次元禁断综合征。我会在这里写一些关于 Node.js、JavaScript、开源、足球、动漫、三次元相关的文章,如果你感兴趣可以订阅这个 [RSS](/atom.xml) 地址。 9 | 10 | ## 抓得到我吗 11 | 12 | - [GitHub](https://github.com/egoist) 13 | - [Twitter](https://twitter.com/_egoistlily) 14 | - [Telegram](https://t.me/egoistlily) 15 | - [微信](http://ww4.sinaimg.cn/large/a15b4afegw1f0nf2nlbzuj20n00ydtck) 16 | - [网易云音乐](http://music.163.com/#/user/home?id=12579252) 17 | - [AniList](https://anilist.co/user/egoistlily/) 18 | - 中国成都 19 | 20 | ## 赋湿一首 21 | 22 | 四百大妈,掺金坷垃。问斯大林,瞬间爆炸。 23 | 你麻痹的,抢劫王八。满喉精液,瞎卡啦卡啦。  24 | 25 | 身体健康,那才叫爽。哦内撒嘛,快po上网。 26 | 蓝蓝蓝路,山东蓝翔。视频删除,砸烂富土康。  27 | 28 | 加了特技,骑着摩的。非凡吔屎,爱疯垃圾。 29 | 超威蓝猫,全家萝莉。乖乖站好,到处丢东西。  30 | 31 | 断他魂结,发自真心。一本满足,用卫生巾。 32 | 控白控控,唱歌下棋。本気本気,倒悬打飞机。 33 | 34 | ## 兴♂趣 35 | 36 | 能一直写代码,一直踢足球,一直看动漫,一直单曲循环,就够了。 37 | 38 | 我的灵魂歌手: EGOIST/chelly、Aimer 39 | 我的灵魂球员: C罗 40 | 我的灵魂语言: JavaScript 41 | 42 | ## 装备 43 | 44 | - 电脑: MacBook Pro 840 (2015 early) 45 | - 手机: iPhone SE (主要) / 小米 5 (偶尔用) 46 | - 平板: iPad Pro 第二代 + Apple Pencil 第一代 47 | - 鼠标: Razer 地狱狂蛇 2014 (没在用) 48 | - 水杯: Lock&Lock LHC4125 49 | - 其它: Kindle (偶尔看) 50 | 51 | ## 前端开发 52 | 53 | ### Q: 为什么从事前端? 54 | 55 | 前端介于视觉和逻辑之间,可以同时创造包含着两种东西的产品。 56 | 57 | ### Q: 为什么没在牛逼的公司工作? 58 | 59 | 水平不够。 60 | 61 | ### Q: 我想学前端,给点建议? 62 | 63 | 建议找牛逼的人给建议。 64 | 65 | ### Q: 你为什么那么喜欢造轮子? 66 | 67 | Your work is going to fill a large part of your life, and the only way to be truly satisfied is to do what you believe is great work. And the only way to do great work is to love what you do. If you haven’t found it yet, keep looking. Don’t settle. As with all matters of the heart, you’ll know when you find it. 68 | 69 | -- Steve Jobs 70 | 71 | ### Q: 你为什么叫 EGOIST? 72 | 73 | [EGOIST/chelly](http://music.163.com/#/artist?id=19353) 74 | 75 | ## 三观 76 | 77 | 老师给我三观评价是「正正正」,你看看如何: 78 | 79 | - 那么可爱一定是男孩子 80 | - 看到二次元女孩子第一反应是 prpr 81 | - 天灭 ISIS 保平安 82 | 83 | 其次,我相信人最不能缺少的东西就是钱和梦想。不能缺少钱不是指为了钱夜以继日工作那样,唯利是图,而是指能够拥有足够维持自己梦想的钱,对的,真正重要的是梦想啊。没有梦想是件很可怕的事,它让你虚度光阴甚至让你对自己的存在产生疑问。 84 | -------------------------------------------------------------------------------- /example/donate.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 捐赠支持 3 | --- 4 | 5 | 文章基于 [署名-非商业性使用-禁止演绎 4.0 协议](https://creativecommons.org/licenses/by-nc-nd/4.0/deed.zh) 进行共享,[开源项目](https://github.com/egoist)都以 [MIT](https://egoist.mit-license.org/) 协议发布。 6 | 7 | 对你的支持,我会心怀感激且倍感荣幸地接受,并继续努力。 8 | 9 | ## 支付宝 10 | 11 | alipay 12 | 13 | ## 微信转账 14 | 15 | 16 | 17 | wechat 19 | -------------------------------------------------------------------------------- /example/girls.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 那些吸引我的女孩子们 3 | subtitle: 来自 EGOIST 的告白 4 | waifus: 5 | - name: 秋月风夏 6 | cv: Lynn 7 | - name: 战场原黑仪 8 | cv: 斋藤千和 9 | - name: CC 10 | cv: 由加奈 11 | - name: 蕾姆 12 | cv: 水濑祈 13 | - name: 三笠·阿克曼 14 | cv: 石川由依 15 | - name: 惣流·明日香·兰格雷 16 | cv: 宫村优子 17 | - name: 梦梦·贝莉雅·戴比路克 18 | cv: 丰崎爱生 19 | - name: 时崎狂三 20 | cv: 真田麻美 21 | - name: 董香 22 | cv: 雨宫天 23 | - name: 楪祈 24 | cv: 茅野爱衣 25 | - name: 阿尔托莉雅·潘德拉贡 26 | cv: 川澄綾子 27 | - name: 莫德雷德 28 | cv: 泽城美雪 29 | - name: 朝田诗乃 30 | cv: 泽城美雪 31 | - name: 小宮惠那 32 | cv: Lynn 33 | - name: 碧井风夏 34 | cv: 无 35 | - name: 牧濑红莉栖 36 | cv: 今井麻美 37 | - name: 雪之下雪乃 38 | cv: 早见沙织 39 | - name: 无名 40 | cv: 千本木彩花 41 | - name: 亚丝娜 42 | cv: 户松遥 43 | - name: 我妻由乃 44 | cv: 村田知沙 45 | - name: Zero Two 46 | cv: 户松遥 47 | - name: 梅 48 | cv: 市之濑加那 49 | - name: 安琪丽莎 50 | cv: 水树奈奈 51 | - name: 朝比奈凉风 52 | cv: 三桥加奈子 53 | - name: 艾米莉娅 54 | cv: 高桥李依 55 | - name: 贞德 (Fate) 56 | cv: 坂本真绫 57 | - name: 艾蕾欧诺拉·维尔塔利亚(艾莲) 58 | cv: 户松遥 59 | - name: 宫水三叶 60 | cv: 上白石萌音 61 | - name: 阿尔泰尔 62 | cv: 丰崎爱生 63 | - name: 赫萝 64 | cv: 小清水亚美 65 | - name: 生野艾米露 66 | cv: 雾之峰沙罗 67 | - name: 艾丝·华伦斯坦 68 | cv: 大西沙织 69 | - name: 冰无小雪 70 | cv: 早见沙织 71 | - name: 友利奈绪 72 | cv: 佐仓绫音 73 | - name: 椎名真白 74 | cv: 茅野爱衣 75 | - name: 加贺 76 | cv: 井口裕香 77 | - name: 赤城 78 | cv: 藤田咲 79 | - name: 霞之丘诗羽 80 | cv: 茅野爱衣 81 | - name: 更识楯无(更识刀奈) 82 | cv: 斋藤千和 83 | - name: 绚辻词 84 | cv: 名冢佳织 85 | - name: 常木耀 86 | cv: 佐仓绫音 87 | - name: 水野茜 88 | cv: 小原好美 89 | - name: 玛修·基列莱特 90 | cv: 高桥李依 91 | - name: 乌丸千岁 92 | cv: 千本木彩花 93 | - name: 森岛遥 94 | cv: 伊藤静 95 | - name: 绿川花 96 | cv: 花泽香菜 97 | - name: 希斯特利亚 98 | cv: 三上枝织 99 | - name: 西宫硝子 100 | cv: 早见沙织 101 | - name: 西宫结弦 102 | cv: 悠木碧 103 | - name: 夏川真涼 104 | cv: 田村由香里 105 | - name: 凉风青叶 106 | cv: 高田忧希 107 | - name: 山田妖精 108 | cv: 高桥未奈美 109 | - name: 和泉纱雾 110 | cv: 藤田茜 111 | - name: 千寿村正 112 | cv: 大西沙织 113 | - name: 樱宁宁 114 | cv: 朝日奈丸佳 115 | - name: 七咲逢 116 | cv: 由加奈 117 | - name: 加藤惠 118 | cv: 安野希世乃 119 | - name: 一色彩羽 120 | cv: 佐仓绫音 121 | - name: 惠惠 122 | cv: 高桥李依 123 | - name: 輝夜月 124 | cv: 不详 125 | --- 126 | 127 | ## 当前 128 | 129 | 我喜欢小宮惠那的性格,平时是那么灵动、活泼,委屈时的无助却又让人看得心疼。 130 | 131 | 132 | 133 | 134 | ![ena](https://i.loli.net/2017/12/03/5a23dd8a0870c.jpg) 135 | 136 | ## 历史 137 | 138 | 按照声优出现次数排名: 139 | 140 |
141 |
    142 |
  • 143 | {{ waifu.name }} {{ waifu.cv }} 144 |
  • 145 |
146 |
147 | 148 | -------------------------------------------------------------------------------- /example/index.md: -------------------------------------------------------------------------------- 1 |
2 | egoist 3 | . 4 | lily 5 |
6 | 7 | 59 | 60 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | 3 | module.exports = { 4 | name: 'vuepress-theme-egoist', 5 | plugins: [ 6 | '@vuepress/blog', 7 | '@vuepress/pagination', 8 | [ 9 | '@vuepress/search', { 10 | searchMaxSuggestions: 10 11 | }], 12 | [ 13 | '@vuepress/register-components', { 14 | componentsDir: [ 15 | path.resolve(__dirname, 'components') 16 | ] 17 | }] 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /layouts/404.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 32 | 33 | 49 | -------------------------------------------------------------------------------- /layouts/Categories.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | -------------------------------------------------------------------------------- /layouts/Category.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | -------------------------------------------------------------------------------- /layouts/Layout.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 30 | -------------------------------------------------------------------------------- /layouts/Page.vue: -------------------------------------------------------------------------------- 1 | 25 | 26 | 63 | 64 | 127 | 128 | 179 | 180 | 261 | -------------------------------------------------------------------------------- /layouts/Tag.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | -------------------------------------------------------------------------------- /layouts/Tags.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vuepress-theme-egoist", 3 | "version": "1.5.1", 4 | "description": "A blog theme for @EGOIST and a mirror of egoist/blog, but powered by VuePress.", 5 | "main": "index.js", 6 | "scripts": { 7 | "release": "release-it", 8 | "dev": "vuepress dev example --temp example/.temp", 9 | "build": "vuepress build example --temp example/.temp" 10 | }, 11 | "files": [ 12 | "components", 13 | "layouts", 14 | "styles", 15 | "index.js" 16 | ], 17 | "repository": { 18 | "type": "git", 19 | "url": "git+https://github.com/ulivz/vuepress-theme-egoist.git" 20 | }, 21 | "keywords": [ 22 | "documentation", 23 | "vue", 24 | "vuepress", 25 | "generator" 26 | ], 27 | "dependencies": { 28 | "@vuepress/plugin-blog": "^1.0.0-alpha.30", 29 | "@vuepress/plugin-pagination": "^1.0.0-alpha.30", 30 | "@vuepress/plugin-search": "^1.0.0-alpha.30", 31 | "@vuepress/plugin-medium-zoom": "^1.0.0-alpha.30" 32 | }, 33 | "devDependencies": { 34 | "release-it": "v7.4.8", 35 | "conventional-changelog-cli": "^2.0.1", 36 | "vuepress": "^1.0.0-alpha.30", 37 | "limax": "^1.6.0", 38 | "markdown-it-footnote": "^3.0.1", 39 | "medium-zoom": "^0.4.0", 40 | "scifi": "^0.1.4", 41 | "v-tippy": "^2.0.0", 42 | "vue-feather-icons": "^4.7.0" 43 | }, 44 | "peerDependencies": { 45 | "vuepress": "^1.0.0-alpha.30" 46 | }, 47 | "author": "ULIVZ ", 48 | "license": "MIT", 49 | "bugs": { 50 | "url": "https://github.com/vuejs/vuepress/issues" 51 | }, 52 | "homepage": "https://github.com/vuejs/vuepress/packages/@vuepress/theme-blog-example#readme" 53 | } 54 | -------------------------------------------------------------------------------- /styles/highlight.styl: -------------------------------------------------------------------------------- 1 | /* http://prismjs.com/download.html?themes=prism&languages=markup+css+clike+javascript+bash+c+cpp+coffeescript+diff+docker+git+go+http+ini+jade+json+less+livescript+makefile+markdown+nginx+python+jsx+rust+sass+scss+sql+stylus+swift+typescript+yaml */ 2 | /** 3 | * prism.js default theme for JavaScript, CSS and HTML 4 | * Based on dabblet (http://dabblet.com) 5 | * @author Lea Verou 6 | */ 7 | 8 | .token.comment, 9 | .token.prolog, 10 | .token.doctype, 11 | .token.cdata { 12 | color: slategray; 13 | } 14 | 15 | .token.punctuation { 16 | color: #999; 17 | } 18 | 19 | .namespace { 20 | opacity: .7; 21 | } 22 | 23 | .token.property, 24 | .token.tag, 25 | .token.boolean, 26 | .token.number, 27 | .token.constant, 28 | .token.symbol, 29 | .token.deleted { 30 | color: #905; 31 | } 32 | 33 | .token.selector, 34 | .token.attr-name, 35 | .token.string, 36 | .token.char, 37 | .token.builtin, 38 | .token.inserted { 39 | color: #690; 40 | } 41 | 42 | .token.operator, 43 | .token.entity, 44 | .token.url, 45 | .language-css .token.string, 46 | .style .token.string { 47 | color: #a67f59; 48 | } 49 | 50 | .token.atrule, 51 | .token.attr-value, 52 | .token.keyword { 53 | color: #07a; 54 | } 55 | 56 | .token.function, 57 | .token.class-name { 58 | color: #DD4A68; 59 | } 60 | 61 | .token.regex, 62 | .token.important, 63 | .token.variable { 64 | color: #e90; 65 | } 66 | 67 | .token.important, 68 | .token.bold { 69 | font-weight: bold; 70 | } 71 | .token.italic { 72 | font-style: italic; 73 | } 74 | 75 | .token.entity { 76 | cursor: help; 77 | } 78 | -------------------------------------------------------------------------------- /styles/index.styl: -------------------------------------------------------------------------------- 1 | * 2 | box-sizing: border-box 3 | 4 | body 5 | margin: 0 6 | font: 300 1em/1.8 PingFang SC,Lantinghei SC,-apple-system,Microsoft Yahei,Hiragino Sans GB,Microsoft Sans Serif,WenQuanYi Micro Hei,sans 7 | background-color: #fdf6e3 8 | 9 | a 10 | font-weight 300 11 | text-decoration none 12 | color: #b58900 13 | cursor: crosshair 14 | &:hover 15 | background: #eee8d5 16 | 17 | .main 18 | padding: 40px 70px 19 | 20 | .cv 21 | font-size 12px 22 | border 1px solid #ccc 23 | padding 0 3px 24 | margin-left 10px 25 | 26 | // override nprogress 27 | $spinnerColor = #ff69b4 28 | 29 | #nprogress .bar 30 | background: $spinnerColor 31 | 32 | #nprogress .peg 33 | box-shadow: 0 0 10px $spinnerColor, 0 0 5px $spinnerColor 34 | 35 | 36 | @import './highlight.styl' 37 | 38 | @media screen and (max-width: 768px) 39 | .main 40 | padding: 20px 10px 41 | .hide-on-mobile 42 | display: none !important 43 | -------------------------------------------------------------------------------- /styles/palette.styl: -------------------------------------------------------------------------------- 1 | $accentColor = #b58900 2 | $textColor = #586e75 3 | $borderColor = #eaecef 4 | $codeBgColor = #282c34 5 | $arrowBgColor = #ccc --------------------------------------------------------------------------------