├── .github
├── ISSUE_TEMPLATE
│ └── bug_report.md
└── PULL_REQUEST_TEMPLATE.md
├── .gitignore
├── .prettierrc.json
├── .travis.yml
├── CHANGELOG.md
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── README_ZH.md
├── babel.config.js
├── config
├── env.js
├── jest
│ ├── cssTransform.js
│ └── fileTransform.js
├── paths.js
├── webpack.config.dev.js
├── webpack.config.prod.js
└── webpackDevServer.config.js
├── images.d.ts
├── package.json
├── public
├── favicon.ico
├── index.html
└── manifest.json
├── scripts
├── build.js
├── start.js
└── test.js
├── src
├── Routers.tsx
├── apis
│ ├── about.service.ts
│ ├── article.service.ts
│ ├── cv.service.ts
│ ├── home.service.ts
│ ├── index.service.ts
│ ├── layouts.service.ts
│ └── music.service.ts
├── assets
│ ├── fonts
│ │ ├── DankMono-Italic.woff2
│ │ └── Ubuntu-Regular.woff2
│ ├── images
│ │ ├── kyotoanimation.png
│ │ ├── normal.cur
│ │ ├── stripes_grey.png
│ │ ├── yancey-official-blog-cat-scroll.png
│ │ ├── yancey-official-blog-logo.png
│ │ └── yancey-official-blog-svg-icons.svg
│ └── styles
│ │ ├── _functions.scss
│ │ ├── _mixins.scss
│ │ ├── _variables.scss
│ │ └── global.scss
├── baseUrl.ts
├── components
│ ├── CV
│ │ ├── Card.module.scss
│ │ └── Card.tsx
│ ├── Common
│ │ ├── AutoBackToTop
│ │ │ └── AutoBackToTop.tsx
│ │ ├── ErrorMonitor
│ │ │ └── ErrorMonitor.tsx
│ │ ├── Footer
│ │ │ ├── Footer.module.scss
│ │ │ └── Footer.tsx
│ │ ├── Header
│ │ │ ├── Header.module.scss
│ │ │ └── Header.tsx
│ │ ├── Loading
│ │ │ └── Loading.tsx
│ │ └── Title
│ │ │ └── Title.tsx
│ ├── HoC
│ │ └── withPersistentData.tsx
│ ├── Music
│ │ ├── Card.module.scss
│ │ └── Card.tsx
│ ├── Post
│ │ ├── Like
│ │ │ ├── Like.scss
│ │ │ └── Like.tsx
│ │ ├── LinkCard
│ │ │ ├── LinkCard.module.scss
│ │ │ └── LinkCard.tsx
│ │ ├── PostSummary
│ │ │ ├── PostSummary.module.scss
│ │ │ └── PostSummary.tsx
│ │ ├── Search
│ │ │ ├── Search.module.scss
│ │ │ └── Search.tsx
│ │ └── Tag
│ │ │ ├── Tag.module.scss
│ │ │ └── Tag.tsx
│ ├── Skeletons
│ │ ├── BlogDetailSkeleton
│ │ │ ├── Skeletons.module.scss
│ │ │ └── Skeletons.tsx
│ │ ├── BlogSummarySkeleton
│ │ │ ├── Skeletons.module.scss
│ │ │ └── Skeletons.tsx
│ │ ├── FeaturedRecordSkeleton
│ │ │ └── Skeletons.tsx
│ │ ├── LinkCardSkeleton
│ │ │ ├── Skeletons.module.scss
│ │ │ └── Skeletons.tsx
│ │ ├── LiveTourSkeleton
│ │ │ └── Skeletons.tsx
│ │ └── YanceyMusicSkeleton
│ │ │ └── Skeletons.tsx
│ └── Widget
│ │ ├── Bubble
│ │ └── Bubble.jsx
│ │ ├── Player
│ │ ├── Player.tsx
│ │ └── player.scss
│ │ └── ScrollToTop
│ │ ├── ScrollToTop.module.scss
│ │ └── ScrollToTop.tsx
├── constants
│ ├── constants.ts
│ └── routePath.ts
├── containers
│ ├── About
│ │ ├── About.scss
│ │ └── About.tsx
│ ├── Apps
│ │ ├── Apps.module.scss
│ │ └── Apps.tsx
│ ├── Archive
│ │ ├── Archive.module.scss
│ │ └── Archive.tsx
│ ├── Blog
│ │ ├── Blog.module.scss
│ │ └── Blog.tsx
│ ├── BlogDetail
│ │ ├── BlogDetail.scss
│ │ └── BlogDetail.tsx
│ ├── CV
│ │ ├── CV.module.scss
│ │ └── CV.tsx
│ ├── Home
│ │ ├── Home.module.scss
│ │ └── Home.tsx
│ ├── Legal
│ │ ├── Legal.module.scss
│ │ └── Legal.tsx
│ ├── Music
│ │ ├── FeaturedRecords.tsx
│ │ ├── LiveTours.tsx
│ │ ├── Music.module.scss
│ │ ├── Music.tsx
│ │ ├── MusicNotes.tsx
│ │ └── YanceyMusic.tsx
│ └── NotFound
│ │ ├── NotFound.module.scss
│ │ └── NotFound.tsx
├── history.ts
├── index.tsx
├── layouts
│ └── Layouts.tsx
├── react-app-env.d.ts
├── registerServiceWorker.ts
├── stores
│ ├── aboutStore.ts
│ ├── articleStore.ts
│ ├── cvStore.ts
│ ├── homeStore.ts
│ ├── index.ts
│ ├── layoutsStore.ts
│ └── musicStore.ts
├── test
│ └── tools.spec.ts
├── tools
│ ├── axios.ts
│ └── tools.ts
└── types
│ ├── about.ts
│ ├── apps.ts
│ ├── article.ts
│ ├── common.ts
│ ├── cv.ts
│ ├── home.ts
│ ├── layout.ts
│ ├── music.ts
│ ├── presistent.ts
│ └── widget.ts
├── tsconfig.json
├── tsconfig.prod.json
├── tsconfig.test.json
├── tslint.json
└── yarn.lock
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Describe the bug**
11 | A clear and concise description of what the bug is.
12 |
13 | **To Reproduce**
14 | Steps to reproduce the behavior:
15 | 1. Go to '...'
16 | 2. Click on '....'
17 | 3. Scroll down to '....'
18 | 4. See error
19 |
20 | **Expected behavior**
21 | A clear and concise description of what you expected to happen.
22 |
23 | **Screenshots**
24 | If applicable, add screenshots to help explain your problem.
25 |
26 | **Desktop (please complete the following information):**
27 | - OS: [e.g. iOS]
28 | - Browser [e.g. chrome, safari]
29 | - Version [e.g. 22]
30 |
31 | **Smartphone (please complete the following information):**
32 | - Device: [e.g. iPhone6]
33 | - OS: [e.g. iOS8.1]
34 | - Browser [e.g. stock browser, safari]
35 | - Version [e.g. 22]
36 |
37 | **Additional context**
38 | Add any other context about the problem here.
39 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | **Before submitting a pull request,** please make sure the following is done:
2 |
3 | 1. Fork the repository and create your branch from master.
4 |
5 | 2. Run yarn in the repository root.
6 |
7 | 3. If you've fixed a bug or added code that should be tested, add tests!
8 |
9 | 4. Ensure the test suite passes (yarn test). Tip: yarn test --watch TestName is helpful in development.
10 |
11 | 5. Run yarn test-prod to test in the production environment. It supports the same options as yarn test.
12 |
13 | 6. If you need a debugger, run yarn debug-test --watch TestName, open chrome://inspect, and press "Inspect".
14 |
15 | 7. Format your code with prettier (yarn prettier).
16 |
17 | 8. Make sure your code lints (yarn lint). Tip: yarn linc to only check changed files.
18 |
19 | 9. Run the Flow typechecks (yarn flow).
20 |
21 | 10. If you haven't already, complete the CLA.
22 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # dependencies
2 | node_modules
3 | build
4 | dist
5 |
6 | # testing
7 | /coverage
8 |
9 | # misc
10 | .DS_Store
11 | .env.local
12 | .env.development.local
13 | .env.test.local
14 | .env.production.local
15 |
16 | npm-debug.log*
17 | yarn-debug.log*
18 | yarn-error.log*
19 |
20 | # IDE
21 | .idea
22 |
--------------------------------------------------------------------------------
/.prettierrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "singleQuote": true,
3 | "jsxSingleQuote": true,
4 | "semi": true,
5 | "bracketSpacing": true,
6 | "trailingComma": "all",
7 | "proseWrap": "preserve"
8 | }
9 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | sudo: true
3 | node_js:
4 | - '8'
5 | cache:
6 | directories:
7 | - node_modules
8 | jobs:
9 | include:
10 | - stage: test
11 | if: (branch = master) AND (NOT (type IN (pull_request)))
12 | script:
13 | - yarn install
14 | - yarn test
15 | - yarn build
16 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | ## 2.3.1 (2019-05-13)
2 |
3 | Support skeleton for blog summary component and try a new lazyload component.
4 |
5 | ## 2.3.0 (2019-05-12)
6 |
7 | Add Canvas Bubble for Home Page.
8 |
9 | ## 2.2.0 (2019-05-08)
10 |
11 | Use React.lazy() replace react-loadable.
12 |
13 | ## 2.1.0 (2019-04-03)
14 |
15 | Add skeleton for blog detail page.
16 |
17 | ## 2.0.0 (2019-01-14)
18 |
19 | Refactor with TypeScript.
20 |
21 | ## 1.1.0 (2018-12-30)
22 |
23 | Remove dependencies on jQuery and optimize performance.
24 |
25 | ## 1.0.0 (2018-10-14)
26 |
27 | First Blood.
28 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Code of Conduct
2 |
3 | Yancey Inc. has adopted a Code of Conduct that we expect project participants to adhere to. Please [read the full text](https://code.fb.com/codeofconduct/) so that you can understand what actions will and will not be tolerated.
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing to BLOG_FE
2 |
3 | Want to contribute to BLOG_FE? There are a few things you need to know.
4 |
5 | We wrote a [contribution guide](https://reactjs.org/contributing/how-to-contribute.html) to help you get started.
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Yancey Inc.
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # [Blog FE for PC](https://www.yanceyleo.com/)
2 |
3 | [](https://app.codacy.com/app/YanceyOfficial/BLOG_FE?utm_source=github.com&utm_medium=referral&utm_content=Yancey-Blog/BLOG_FE&utm_campaign=Badge_Grade_Dashboard)
4 | [](https://opensource.org/licenses/MIT)
5 | [](https://github.com/Yancey-Blog/BLOG_FE)
6 | [](https://github.com/Yancey-Blog/BLOG_FE)
7 | [](https://github.com/Yancey-Blog/BLOG_FE/pulls)
8 | [](https://travis-ci.org/Yancey-Blog/BLOG_FE)
9 |
10 | English | [中国語](https://github.com/Yancey-Blog/BLOG_FE/blob/master/README_ZH.md)
11 |
12 | ## Introduction
13 |
14 | This is the second blog website I wrote, The first version was released in March 2018 which wrote by Django and Bootstrap. With the booming of SPA, I decided to write a react version and add some new features. After about two months of design and coding, the second version was released.
15 |
16 | Mainwhile, I also wrote a [CMS](https://github.com/Yancey-Blog/BLOG_CMS/) to manage and operate the data. You can click the link to fork.
17 |
18 | Now, I am writing the [mobile side pages](https://github.com/Yancey-Blog/BLOG_WAP/), coming soon~
19 |
20 | ## Technology Stack
21 |
22 | - BLOG_FE_FOR_PC: react + react-router-4 + mobx + TypeScript;
23 | - CMS: react + react-router-4 + mobx + Google reCAPTCHA + Ant Design;
24 | - BE Express + Mongo + JWT + Ali OSS + Google reCAPTCHA
25 |
26 | I alse used CSS Module、Webp、SVG Sprite and so on...
27 |
28 | ## Page
29 |
30 | ### Home Page
31 |
32 | 
33 | 
34 |
35 | The home page contains five parts:
36 |
37 | - Background
38 | - Motto
39 | - Announcement
40 | - The Latest 3 Projects
41 | - The Latest 10 Articles
42 |
43 | #### Background
44 |
45 | The first time you visited my website, you will see the latest background, meanwhile, the id of this background will saved in localStorge. You can switch background by clicking the `left arrow` or `right arrow`. So, when open the website again, you will see the current background usless clear cache or I delete/hide the background in CMS.
46 |
47 | #### Motto
48 |
49 | My motto.
50 |
51 | #### Announcement
52 |
53 | I always publish new information in the component.
54 |
55 | #### The Latest 3 Projects
56 |
57 | Display the latest 3 open source projects of mine, click on any one to jump to the corresponding GitHub page
58 |
59 | #### The Latest 10 Articles
60 |
61 | Display the latest 10 articles summary, which is include release date, title, PV, likes, tag, summary and so on, click one to jump to the article detail page.
62 |
63 | ### Blog Page
64 |
65 | 
66 |
67 | The left part is a pageable summary list; The right part includes two parts: `tags list` and `top 7 most viewed`
68 |
69 | In addition, you can see a search button in the rightmost position of `header` component. Yep,a lovely Hatsune Miku will appear.
70 |
71 | 
72 |
73 | ### Blog Detail Page
74 |
75 | 
76 |
77 | - Collect people views counts.
78 |
79 | - Display the article cover, title, publish date(show the lastest update date when you are moving in the text.)
80 |
81 | - The right part is menu
82 |
83 | - In the maim body
84 |
85 | - Click on the picture to zoom in
86 | - Click the header of code to zoom in
87 | - Like
88 | - Comment
89 | - Previous article and Next article
90 | - Share to Twitter
91 |
92 | ### Archive Page
93 |
94 | 
95 |
96 | - Click on the circle to show the current month's articles.
97 |
98 | - Click on the `Fold` to hide all articles.
99 |
100 | - Click on the `Unfold` to show all articles.
101 |
102 | ### Music Page
103 |
104 | 
105 |
106 | 
107 |
108 | - The Lives image
109 | - Music notes
110 | - Featured reecords
111 | - My works
112 |
113 | ### Apps Page
114 |
115 | 
116 |
117 | Todos:
118 |
119 | - Blog for Android
120 | - Blog for iOS
121 | - Blog for Mac
122 |
123 | ### CV Page
124 |
125 | - My basic information
126 | - Work experience
127 | - Program experience
128 |
129 | ### About Page
130 |
131 | 
132 |
133 | Display the development history of the blog.
134 |
135 | ## Change Logs
136 |
137 | - 2018-10-14 First blood.
138 | - 2018-12-30 Remove dependencies on jQuery and optimize performance.
139 | - 2019-01-14 Refactor with TypeScript.
140 | - 2019-04-03 Add skeleton for blog detail page.
141 | - 2019-05-08 Use React.lazy() replace react-loadable.
142 | - 2019-05-12 Add Canvas Bubble for Home Page.
143 | - 2019-05-13 Support skeleton for blog summary component and try a new lazyload component.
144 |
145 | ## TODO
146 |
147 | - SSR
148 | - Optimize performance
149 | - Fragment page
150 | - RSS
151 |
152 | ## License
153 |
154 | BLOG FE is [MIT licensed](https://opensource.org/licenses/MIT).
155 |
--------------------------------------------------------------------------------
/README_ZH.md:
--------------------------------------------------------------------------------
1 | # [Blog FE for PC](https://wwww.yanceyleo.com/)
2 |
3 | [](https://app.codacy.com/app/YanceyOfficial/BLOG_FE?utm_source=github.com&utm_medium=referral&utm_content=Yancey-Blog/BLOG_FE&utm_campaign=Badge_Grade_Dashboard)
4 | [](https://opensource.org/licenses/MIT)
5 | [](https://github.com/Yancey-Blog/BLOG_FE)
6 | [](https://github.com/Yancey-Blog/BLOG_FE)
7 | [](https://github.com/Yancey-Blog/BLOG_FE/pulls)
8 |
9 | 中文 | [English](https://github.com/Yancey-Blog/BLOG_FE/blob/master/README.md)
10 |
11 | ## Introduction
12 |
13 | 这是我写的第二个博客网站。第一个是在今年(2018 年)3 月份完成的,用的 Bootstrap + Django. 至于为什么写第二版,无非是看到别人的博客太好看了 😂。
14 |
15 | 2.0 的数据还在迁移中...因此下面的图各种 demo1 demo2...
16 |
17 | 2.0 版本是一个前后端分离的项目,这次除了前端和后端,还专门写了一个[后台管理系统](https://github.com/Yancey-Blog/BLOG_CMS/blob/master/README.md)。其中:
18 |
19 | - 前端主要技术栈是 react + react-router-4 + mobx;
20 | - 管理后台用的是 react + react-router-4 + mobx + Google reCAPTCHA + Ant Design;
21 | - 后端则是 Express + Mongo + JWT + Ali OSS + Google reCAPTCHA + request promise.
22 |
23 | 全端用到了 Airbnb 的 eslint,前端还用到了 CSS Module、Webp、SVG Sprite 等等一些好玩的技术,下面具体介绍
24 | 一下整个前端。
25 |
26 | 因为刚毕业不久,工作时间也不多,感觉做的项目还稍显稚嫩,因此决定开源出来接受大佬们的意见。
27 |
28 | ## Detail
29 |
30 | ### Global Component
31 |
32 | 全局无非就是标配的 header、footer、滚动进度指示条、当然还有一个音乐播放器的组件。
33 |
34 | 此外,我还后端写了一个`glonalConfig`的接口,暂时只想到一个功能,就是控制前端的`filter: grayscale(100%);`属性,用在一些哀悼日时,后台会开启这个按钮。
35 |
36 | ### Home Page
37 |
38 | 
39 | 
40 |
41 | 主页分为 5 个部分:
42 |
43 | - Background
44 | - Motto
45 | - Announcement
46 | - The Latest 3 Projects
47 | - The Latest 10 Articles
48 |
49 | #### Background
50 |
51 | 先说背景图,后台存有多张背景图,因此通过左右按钮可以切换背景图。并且当前那张背景图的 id 会存储到 localStorage,因此只要不清掉 localStorage,下次打开还是当前那张背景图。
52 |
53 | 当然如果 localStorage 没有相关 id 或者这张图片被我在后台删除了,将会返回最新发布的图片。
54 |
55 | 其实后台我还设置了图片的显隐按钮,当某张图片的 id 在 localStorage,但被我在后台隐藏了,同样将会返回最新发布的图片。
56 |
57 | #### Motto
58 |
59 | Motto 部分对应上面第一张图这个部分。
60 |
61 | 死は生の対極としてではなく、その一部として存在している
62 |
63 | 同样是请求后端接口,取得最新的那条 Motto
64 |
65 | _ps: 上面那句话来自「ノルウェイの森」(《挪威的森林》)_
66 |
67 | #### Announcement
68 |
69 | 和 Motto 部分同理,用途是发布一些最新消息。
70 |
71 | #### The Latest 3 Projects
72 |
73 | 这个是用来展示我最新的三个开源项目,url 会连接到相应的 GitHub.
74 |
75 | #### The Latest 10 Articles
76 |
77 | 整个博客的核心部分之一,在首页会显示最新 10 篇文章的摘要模块,上面显示发布时间、title、PV 量、点赞量、Tags、summary、show more,点击图片、标题或者 show more 都可以进入到文章细节页。
78 |
79 | ### Blog Page
80 |
81 | 
82 |
83 | 左边是最新的十篇 summary, 而下面是后端分页的分页器;右边上面是文章的标签集合,下面是 7 篇最高 PV 的文章(设计大家都懂,知乎的设计)。
84 |
85 | 此外,其实在 header 的右上角还有一个*搜索*按钮,点进去是这个样子:
86 |
87 | 
88 |
89 | 没错,可爱的初音ミク, 通过在搜索框输入,模糊匹配文章名。当然这里没有第一版好,第一版用了 whoosh + jieba 搜索引擎,效果理论上要比这版好一些。
90 |
91 | ### Blog Detail Page
92 |
93 | 
94 |
95 | 关于 Blog Detail 页面其实有很多地方,一张图放不下:
96 |
97 | - 从上面来看是 header cover、标题、发布时间(鼠标移入显示最后修改时间)、tags 等;
98 | - 正文部分的图片可以点击放大,形成一个手动轮播图的效果;
99 | - code 部分用了 highlight.js
100 | - 其中点击 code 的头部,也就是仿 Mac 按钮那个部分,代码块也会全屏放大
101 | - 右边是 toc
102 | - 下面还有点赞、Twitter(这个地方恐怕要做 SSR,因为 Twitter Card 必须要拿到实际的 meta 信息,如果是 JS 生成的,比如用了 react-helmet,是不会被识别出来的)
103 | - 然后就是用了 LiveRe 的评论插件。
104 | - 最后还有人见人恨的复制文本附带版权信息:
105 |
106 | 不知道大家看到一个小细节没,打开Chrome开发者工具,选择查看元素,将鼠标移动到html页面,发现浏览器自动给栅格标上了虚线,看下图。
107 |
108 | Article Name: Grid
109 | Article URL: https://blog.yanceyleo.com/p/5bc202a26b48dfee0a0dcedf
110 | License: Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0)
111 |
112 | **后期确实要把这个页面做成 SSR,除了 Twitter Card 的问题,因为现在正文用的 dangerouslySetInnerHTML,这一块也没法做懒加载。**
113 |
114 | ### Archive Page
115 |
116 | 
117 |
118 | 这个部分显示归档,话说毕竟好久不写后端了,写聚合分组 SQL 那一块的时候确实花了些时间。
119 |
120 | 点击大一点儿的圆圈会显示/隐藏某个月的文章归档信息,默认展示最新一个月的归档信息,右边的按钮控制展示全部和关闭全部,其实原理就是用了 checkbox.
121 |
122 | ### Music Page
123 |
124 | 我的业余爱好是做音乐,因此 Blog 也不会少了 Music 模块。
125 |
126 | 
127 |
128 | 
129 |
130 | 第一张图的左上角是我看过的 Live 的轮播图片,当然图片肯定都是在拍照时间拍的;
131 |
132 | 右边是 Music Notes,实际上就是`articles?tag=Music`,然后取最新的四篇,当然数据还没迁移过来,随便找了篇文章加上了 Music 的 tag;
133 |
134 | 第二张图上面是一些我喜欢的唱片,关于购买地址,没有任何商业用途,一般链接来自日亚抑或 cdjapan;
135 |
136 | 下面则是我的一些小作品了,链接指向 SoundCloud(需 fq)
137 |
138 | ### Apps Page
139 |
140 | 
141 |
142 | 现在还没去做,后期会计划写 Wap 版(1.0 是用的响应式,这次想把 Wap 单独抽离出来);用 NR 写 iOS 和 Andriod;用 Electron 写个 Mac 版,毕竟用着 Nav Bar 的 MBP, 还是想在这个地方做点儿好玩的事情出来。
143 |
144 | ### CV Page
145 |
146 | 这里就不放图了,简历分三部分,都是从后端取出来的:
147 |
148 | - 基本信息
149 | - 工作经历
150 | - 项目经历
151 |
152 | ### About
153 |
154 | 
155 |
156 | About 页面也是从后端取出来的,用来记录 Blog 发展的大事记(估计就是 Bug 修改历程 噗 x)。
157 |
158 | ## License
159 |
160 | BLOG FE is [MIT licensed](https://opensource.org/licenses/MIT).
161 |
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: ['@babel/preset-env', '@babel/preset-react']
3 | };
4 |
--------------------------------------------------------------------------------
/config/env.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const fs = require('fs');
4 | const path = require('path');
5 | const paths = require('./paths');
6 |
7 | // Make sure that including paths.js after env.js will read .env variables.
8 | delete require.cache[require.resolve('./paths')];
9 |
10 | const NODE_ENV = process.env.NODE_ENV;
11 | if (!NODE_ENV) {
12 | throw new Error(
13 | 'The NODE_ENV environment variable is required but was not specified.'
14 | );
15 | }
16 |
17 | // https://github.com/bkeepers/dotenv#what-other-env-files-can-i-use
18 | var dotenvFiles = [
19 | `${paths.dotenv}.${NODE_ENV}.local`,
20 | `${paths.dotenv}.${NODE_ENV}`,
21 | // Don't include `.env.local` for `test` environment
22 | // since normally you expect tests to produce the same
23 | // results for everyone
24 | NODE_ENV !== 'test' && `${paths.dotenv}.local`,
25 | paths.dotenv,
26 | ].filter(Boolean);
27 |
28 | // Load environment variables from .env* files. Suppress warnings using silent
29 | // if this file is missing. dotenv will never modify any environment variables
30 | // that have already been set. Variable expansion is supported in .env files.
31 | // https://github.com/motdotla/dotenv
32 | // https://github.com/motdotla/dotenv-expand
33 | dotenvFiles.forEach(dotenvFile => {
34 | if (fs.existsSync(dotenvFile)) {
35 | require('dotenv-expand')(
36 | require('dotenv').config({
37 | path: dotenvFile,
38 | })
39 | );
40 | }
41 | });
42 |
43 | // We support resolving modules according to `NODE_PATH`.
44 | // This lets you use absolute paths in imports inside large monorepos:
45 | // https://github.com/facebook/create-react-app/issues/253.
46 | // It works similar to `NODE_PATH` in Node itself:
47 | // https://nodejs.org/api/modules.html#modules_loading_from_the_global_folders
48 | // Note that unlike in Node, only *relative* paths from `NODE_PATH` are honored.
49 | // Otherwise, we risk importing Node.js core modules into an app instead of Webpack shims.
50 | // https://github.com/facebook/create-react-app/issues/1023#issuecomment-265344421
51 | // We also resolve them to make sure all tools using them work consistently.
52 | const appDirectory = fs.realpathSync(process.cwd());
53 | process.env.NODE_PATH = (process.env.NODE_PATH || '')
54 | .split(path.delimiter)
55 | .filter(folder => folder && !path.isAbsolute(folder))
56 | .map(folder => path.resolve(appDirectory, folder))
57 | .join(path.delimiter);
58 |
59 | // Grab NODE_ENV and REACT_APP_* environment variables and prepare them to be
60 | // injected into the application via DefinePlugin in Webpack configuration.
61 | const REACT_APP = /^REACT_APP_/i;
62 |
63 | function getClientEnvironment(publicUrl) {
64 | const raw = Object.keys(process.env)
65 | .filter(key => REACT_APP.test(key))
66 | .reduce(
67 | (env, key) => {
68 | env[key] = process.env[key];
69 | return env;
70 | },
71 | {
72 | // Useful for determining whether we’re running in production mode.
73 | // Most importantly, it switches React into the correct mode.
74 | NODE_ENV: process.env.NODE_ENV || 'development',
75 | // Useful for resolving the correct path to static assets in `public`.
76 | // For example,
.
77 | // This should only be used as an escape hatch. Normally you would put
78 | // images into the `src` and `import` them in code to get their paths.
79 | PUBLIC_URL: publicUrl,
80 | }
81 | );
82 | // Stringify all values so we can feed into Webpack DefinePlugin
83 | const stringified = {
84 | 'process.env': Object.keys(raw).reduce((env, key) => {
85 | env[key] = JSON.stringify(raw[key]);
86 | return env;
87 | }, {}),
88 | };
89 |
90 | return { raw, stringified };
91 | }
92 |
93 | module.exports = getClientEnvironment;
94 |
--------------------------------------------------------------------------------
/config/jest/cssTransform.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | // This is a custom Jest transformer turning style imports into empty objects.
4 | // http://facebook.github.io/jest/docs/en/webpack.html
5 |
6 | module.exports = {
7 | process() {
8 | return 'module.exports = {};';
9 | },
10 | getCacheKey() {
11 | // The output is always the same.
12 | return 'cssTransform';
13 | },
14 | };
15 |
--------------------------------------------------------------------------------
/config/jest/fileTransform.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | const path = require('path');
4 |
5 | // This is a custom Jest transformer turning file imports into filenames.
6 | // http://facebook.github.io/jest/docs/en/webpack.html
7 |
8 | module.exports = {
9 | process(src, filename) {
10 | const assetFilename = JSON.stringify(path.basename(filename));
11 |
12 | if (filename.match(/\.svg$/)) {
13 | return `module.exports = {
14 | __esModule: true,
15 | default: ${assetFilename},
16 | ReactComponent: (props) => ({
17 | $$typeof: Symbol.for('react.element'),
18 | type: 'svg',
19 | ref: null,
20 | key: null,
21 | props: Object.assign({}, props, {
22 | children: ${assetFilename}
23 | })
24 | }),
25 | };`;
26 | }
27 |
28 | return `module.exports = ${assetFilename};`;
29 | },
30 | };
31 |
--------------------------------------------------------------------------------
/config/paths.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const path = require('path');
4 | const fs = require('fs');
5 | const url = require('url');
6 |
7 | // Make sure any symlinks in the project folder are resolved:
8 | // https://github.com/facebook/create-react-app/issues/637
9 | const appDirectory = fs.realpathSync(process.cwd());
10 | const resolveApp = relativePath => path.resolve(appDirectory, relativePath);
11 |
12 | const envPublicUrl = process.env.PUBLIC_URL;
13 |
14 | function ensureSlash(inputPath, needsSlash) {
15 | const hasSlash = inputPath.endsWith('/');
16 | if (hasSlash && !needsSlash) {
17 | return inputPath.substr(0, inputPath.length - 1);
18 | } else if (!hasSlash && needsSlash) {
19 | return `${inputPath}/`;
20 | } else {
21 | return inputPath;
22 | }
23 | }
24 |
25 | const getPublicUrl = appPackageJson =>
26 | envPublicUrl || require(appPackageJson).homepage;
27 |
28 | // We use `PUBLIC_URL` environment variable or "homepage" field to infer
29 | // "public path" at which the app is served.
30 | // Webpack needs to know it to put the right
61 |