81 changed files with 1009 additions and 1619 deletions
@ -1,16 +0,0 @@
@@ -1,16 +0,0 @@
|
||||
# http://editorconfig.org |
||||
root = true |
||||
|
||||
[*] |
||||
indent_style = space |
||||
indent_size = 2 |
||||
end_of_line = lf |
||||
charset = utf-8 |
||||
trim_trailing_whitespace = true |
||||
insert_final_newline = true |
||||
|
||||
[*.md] |
||||
trim_trailing_whitespace = false |
||||
|
||||
[Makefile] |
||||
indent_style = tab |
@ -1,5 +0,0 @@
@@ -1,5 +0,0 @@
|
||||
BROWSER=none |
||||
ESLINT=1 |
||||
REACT_EDITOR=code |
||||
PORT=50001 |
||||
SOCKET_SERVER=none |
@ -1,7 +0,0 @@
@@ -1,7 +0,0 @@
|
||||
**/*.md |
||||
**/*.svg |
||||
**/*.ejs |
||||
**/*.html |
||||
package.json |
||||
.umi |
||||
.umi-production |
@ -1,11 +0,0 @@
@@ -1,11 +0,0 @@
|
||||
{ |
||||
"singleQuote": true, |
||||
"trailingComma": "all", |
||||
"printWidth": 100, |
||||
"overrides": [ |
||||
{ |
||||
"files": ".prettierrc", |
||||
"options": { "parser": "json" } |
||||
} |
||||
] |
||||
} |
@ -1,30 +0,0 @@
@@ -1,30 +0,0 @@
|
||||
import { IConfig } from 'umi-types'; // ref: https://umijs.org/config/
|
||||
|
||||
const config: IConfig = { |
||||
treeShaking: true, |
||||
ssr: true, |
||||
hash: process.env.NODE_ENV === 'production', |
||||
plugins: [ |
||||
// ref: https://umijs.org/plugin/umi-plugin-react.html
|
||||
[ |
||||
'umi-plugin-react', |
||||
{ |
||||
antd: true, |
||||
dva: true, |
||||
dynamicImport: false, |
||||
title: 'blotter_page', |
||||
dll: true, |
||||
routes: { |
||||
exclude: [ |
||||
/models\//, |
||||
/services\//, |
||||
/model\.(t|j)sx?$/, |
||||
/service\.(t|j)sx?$/, |
||||
/components\//, |
||||
], |
||||
}, |
||||
}, |
||||
], |
||||
], |
||||
}; |
||||
export default config; |
@ -1,21 +0,0 @@
@@ -1,21 +0,0 @@
|
||||
MIT License |
||||
|
||||
Copyright (c) 2019 OhYee |
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy |
||||
of this software and associated documentation files (the "Software"), to deal |
||||
in the Software without restriction, including without limitation the rights |
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||
copies of the Software, and to permit persons to whom the Software is |
||||
furnished to do so, subject to the following conditions: |
||||
|
||||
The above copyright notice and this permission notice shall be included in all |
||||
copies or substantial portions of the Software. |
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
||||
SOFTWARE. |
@ -1,10 +0,0 @@
@@ -1,10 +0,0 @@
|
||||
# Blotter page |
||||
|
||||
Web page for [blotter](https://github.com/OhYee/blotter) |
||||
|
||||
## Start |
||||
|
||||
```bash |
||||
yarn |
||||
yarn start |
||||
``` |
@ -0,0 +1,108 @@
@@ -0,0 +1,108 @@
|
||||
.main_content { |
||||
margin: 20px; |
||||
} |
||||
|
||||
.dimmed::before { |
||||
content: ' '; |
||||
position: fixed; |
||||
top: 0; |
||||
right: 0; |
||||
bottom: 0; |
||||
left: 0; |
||||
z-index: 1; |
||||
background: rgba(0, 0, 0, 0); |
||||
animation: dimmed-change 0.5s 1 alternate; |
||||
animation-iteration-count: 1; |
||||
animation-fill-mode: forwards; |
||||
} |
||||
|
||||
@keyframes dimmed-change { |
||||
100% { |
||||
background: rgba(0, 0, 0, 0.5); |
||||
} |
||||
} |
||||
|
||||
.sider { |
||||
.avatar { |
||||
margin: 20px 0; |
||||
-webkit-transition: 0.4s; |
||||
-webkit-transition: -webkit-transform 0.4s ease-out; |
||||
transition: transform 0.4s ease-out; |
||||
-moz-transition: -moz-transform 0.4s ease-out; |
||||
} |
||||
.avatar:hover { |
||||
transform: rotateZ(360deg); |
||||
-webkit-transform: rotateZ(360deg); |
||||
-moz-transform: rotateZ(360deg); |
||||
} |
||||
|
||||
.divider { |
||||
:global(.ant-divider-inner-text) { |
||||
padding: 5px 0; |
||||
} |
||||
} |
||||
} |
||||
|
||||
html, |
||||
body, |
||||
#root { |
||||
height: 100%; |
||||
} |
||||
|
||||
body { |
||||
margin: 0; |
||||
} |
||||
|
||||
:global(.shadow) { |
||||
-moz-box-shadow: 2px 2px 2px #ccc; |
||||
-webkit-box-shadow: 2px 2px 2px #ccc; |
||||
box-shadow: 2px 2px 2px 2px #ccc; |
||||
} |
||||
|
||||
:global(.right5), |
||||
:global(.right10), |
||||
:global(.right20) { |
||||
display: inline; |
||||
&::after { |
||||
content: ' '; |
||||
display: inline-block; |
||||
} |
||||
} |
||||
:global(.right5)::after { |
||||
margin-right: 5px; |
||||
} |
||||
:global(.right10)::after { |
||||
margin-right: 10px; |
||||
} |
||||
:global(.right20)::after { |
||||
margin-right: 20px; |
||||
} |
||||
|
||||
blockquote { |
||||
padding: 0.5em 1em; |
||||
color: #6a737d; |
||||
border-left: 0.25em solid #dfe2e5; |
||||
margin: 20px 0; |
||||
} |
||||
code { |
||||
padding: 0.2em 0.4em; |
||||
margin: 0 0.5em; |
||||
font-size: 85%; |
||||
background-color: rgba(27, 31, 35, 0.05); |
||||
border-radius: 3px; |
||||
font-family: Cascadia Code, Source Code Variable, SFMono-Regular, Consolas, Liberation Mono, Menlo, |
||||
monospace; |
||||
} |
||||
|
||||
:global(.ant-comment-content) { |
||||
:global(.ant-form-item-label) > label { |
||||
color: rgba(0, 0, 0, 0.65); |
||||
} |
||||
} |
||||
|
||||
.footer { |
||||
text-align: center; |
||||
line-height: 1em; |
||||
// border-top: #aaa 1px solid; |
||||
padding-top: 15px; |
||||
} |
@ -1,5 +1,4 @@
@@ -1,5 +1,4 @@
|
||||
import React, { ComponentProps, Ref } from 'react'; |
||||
import router from 'umi/router'; |
||||
|
||||
import PostList from '@/components/post_list'; |
||||
|
@ -1,20 +0,0 @@
@@ -1,20 +0,0 @@
|
||||
import { requestAsync } from './../src/utils/request'; |
||||
import { Request, Response } from 'express'; |
||||
|
||||
export default { |
||||
'GET /api/avatar': async (req: Request, res: Response) => { |
||||
var email = req.query['email']; |
||||
|
||||
var data: any = await requestAsync('get', 'https://api.github.com/search/users', { |
||||
q: `${email} in:email`, |
||||
}); |
||||
var avatar = ''; |
||||
if (data['items'] && data['items'].length > 0) { |
||||
avatar = data['items'][0]['avatar_url']; |
||||
} else { |
||||
avatar = `https://secure.gravatar.com/avatar/null`; |
||||
} |
||||
res.send(avatar); |
||||
res.end(); |
||||
}, |
||||
}; |
@ -1,61 +0,0 @@
@@ -1,61 +0,0 @@
|
||||
import { Request, Response } from 'express'; |
||||
|
||||
const comments: { [key: string]: Blotter.Comment[] } = { |
||||
'/post/wsl2_systemd': [ |
||||
{ |
||||
id: 1, |
||||
email: 'oyohyee@oyohyee.com', |
||||
avatar: 'https://secure.gravatar.com/avatar/d57072b4a47209833738ecda534634da', |
||||
time: '2018-01-11 15:32:12', |
||||
content: '第一条回复', |
||||
children: [ |
||||
{ |
||||
id: 2, |
||||
email: 'oyohyee@oyohyee.com', |
||||
avatar: 'https://secure.gravatar.com/avatar/d57072b4a47209833738ecda534634da', |
||||
time: '2019-01-11 15:32:12', |
||||
content: '回复回复', |
||||
children: [ |
||||
{ |
||||
id: 3, |
||||
email: 'oyohyee@oyohyee.com', |
||||
avatar: 'https://secure.gravatar.com/avatar/d57072b4a47209833738ecda534634da', |
||||
time: '2019-09-11 15:32:12', |
||||
content: '???', |
||||
children: [], |
||||
}, |
||||
], |
||||
}, |
||||
{ |
||||
id: 4, |
||||
email: 'oyohyee@oyohyee.com', |
||||
avatar: 'https://secure.gravatar.com/avatar/d57072b4a47209833738ecda534634da', |
||||
time: '2019-05-11 15:32:12', |
||||
content: '回复回复', |
||||
children: [], |
||||
}, |
||||
], |
||||
}, |
||||
{ |
||||
id: 5, |
||||
email: 'oyohyee@oyohyee.com', |
||||
avatar: 'https://secure.gravatar.com/avatar/d57072b4a47209833738ecda534634da', |
||||
time: '2018-01-11 15:32:12', |
||||
content: '第二条回复', |
||||
children: [], |
||||
}, |
||||
], |
||||
}; |
||||
|
||||
export default { |
||||
'GET /api/comment': (req: Request, res: Response) => { |
||||
var url = req.query['url']; |
||||
var comment = comments[url]; |
||||
if (comment) { |
||||
res.send(comment); |
||||
} else { |
||||
res.status(404); |
||||
} |
||||
res.end(); |
||||
}, |
||||
}; |
@ -1,104 +0,0 @@
@@ -1,104 +0,0 @@
|
||||
export default { |
||||
'GET /api/friends': <Blotter.Friend[]>[ |
||||
{ |
||||
image: 'https://taifua.com/wp-content/uploads/2019/09/default.jpg', |
||||
link: 'https://taifua.com/', |
||||
name: '太傅亭', |
||||
description: '面朝大海,春暖花开', |
||||
posts: [ |
||||
{ |
||||
title: '腾讯课堂NEXT学院产品组实习总结', |
||||
link: 'https://taifua.com/csig-next-trainee.html', |
||||
}, |
||||
{ title: 'C / C++程序编译全过程', link: 'https://taifua.com/compile.html' }, |
||||
], |
||||
}, |
||||
{ |
||||
image: 'https://www.oyohyee.com/static/img/logo.svg', |
||||
link: 'https://www.oyohyee.com/', |
||||
name: "OhYee's Blog", |
||||
description: '', |
||||
posts: [ |
||||
{ |
||||
title: 'WSL2(Arch Linux)使用systemd', |
||||
link: 'http://127.0.0.1:8000/post/wsl2_systemd', |
||||
}, |
||||
{ title: 'Arch Linux的使用', link: 'http://127.0.0.1:8000/post//' }, |
||||
], |
||||
}, |
||||
{ |
||||
image: 'https://taifua.com/wp-content/uploads/2019/09/default.jpg', |
||||
link: 'https://taifua.com/', |
||||
name: '太傅亭', |
||||
description: '面朝大海,春暖花开', |
||||
posts: [ |
||||
{ |
||||
title: '腾讯课堂NEXT学院产品组实习总结', |
||||
link: 'https://taifua.com/csig-next-trainee.html', |
||||
}, |
||||
{ title: 'C / C++程序编译全过程', link: 'https://taifua.com/compile.html' }, |
||||
], |
||||
}, |
||||
{ |
||||
image: 'https://www.oyohyee.com/static/img/logo.svg', |
||||
link: 'https://www.oyohyee.com/', |
||||
name: "OhYee's Blog", |
||||
description: '', |
||||
posts: [], |
||||
}, |
||||
{ |
||||
image: 'https://gw.alipayobjects.com/zos/rmsportal/KDpgvguMpGfqaHPjicRK.svg', |
||||
link: 'https://ant.design/', |
||||
name: 'Ant Design', |
||||
description: '', |
||||
posts: [], |
||||
}, |
||||
{ |
||||
image: 'https://www.oyohyee.com/static/img/logo.svg', |
||||
link: 'https://www.oyohyee.com/', |
||||
name: "OhYee's Blog", |
||||
description: '', |
||||
posts: [], |
||||
}, |
||||
{ |
||||
image: 'https://taifua.com/wp-content/uploads/2019/09/default.jpg', |
||||
link: 'https://taifua.com/', |
||||
name: '太傅亭', |
||||
description: '面朝大海,春暖花开', |
||||
posts: [ |
||||
{ |
||||
title: '腾讯课堂NEXT学院产品组实习总结', |
||||
link: 'https://taifua.com/csig-next-trainee.html', |
||||
}, |
||||
{ title: 'C / C++程序编译全过程', link: 'https://taifua.com/compile.html' }, |
||||
], |
||||
}, |
||||
{ |
||||
image: 'https://www.oyohyee.com/static/img/logo.svg', |
||||
link: 'https://www.oyohyee.com/', |
||||
name: "OhYee's Blog", |
||||
description: '', |
||||
posts: [], |
||||
}, |
||||
{ |
||||
image: 'https://taifua.com/wp-content/uploads/2019/09/default.jpg', |
||||
link: 'https://taifua.com/', |
||||
name: '太傅亭', |
||||
description: '面朝大海,春暖花开', |
||||
posts: [ |
||||
{ |
||||
title: '腾讯课堂NEXT学院产品组实习总结', |
||||
link: 'https://taifua.com/csig-next-trainee.html', |
||||
}, |
||||
{ title: 'C / C++程序编译全过程1111111111111111111111111111111111', link: 'https://taifua.com/compile.html' }, |
||||
], |
||||
}, |
||||
{ |
||||
image: 'https://www.oyohyee.com/static/img/logo.svg', |
||||
link: 'https://www.oyohyee.com/', |
||||
name: "OhYee's Blog", |
||||
description: '', |
||||
posts: [], |
||||
}, |
||||
], |
||||
}; |
@ -1,81 +0,0 @@
@@ -1,81 +0,0 @@
|
||||
export default { |
||||
// 支持值为 Object 和 Array
|
||||
'POST /api/index/post': { |
||||
posts: [ |
||||
{ |
||||
title: '这是一篇测试文章', |
||||
abstract: '这篇文章主要用于测试文章卡片', |
||||
url: '/', |
||||
view: 100, |
||||
publish_time: '2019-01-01 15:32:21', |
||||
edit_time: '2019-01-01 15:32:21', |
||||
tags: [{ name: '测试', id: 'test', icon: '', color: '' }], |
||||
head_image: '', |
||||
}, |
||||
{ |
||||
title: 'WSL2(Arch Linux)使用systemd', |
||||
abstract: '在WSL2中以pid 1运行systemd', |
||||
view: 383, |
||||
url: 'wsl2_systemd', |
||||
publish_time: '2019-09-11 14:39:39', |
||||
edit_time: '2019-09-11 14:39:39', |
||||
tags: [ |
||||
{ id: 'wsl', name: 'WSL', icon: '', color: '' }, |
||||
{ |
||||
id: 'arch', |
||||
name: 'Arch', |
||||
icon: 'https://www.oyohyee.com/static/img/tags/arch.png', |
||||
color: 'blue', |
||||
}, |
||||
], |
||||
head_image: '', |
||||
}, |
||||
{ |
||||
title: 'Arch Linux的使用', |
||||
abstract: '如何安装Arch Linux', |
||||
url: '/', |
||||
view: 100, |
||||
publish_time: '2019-01-01 15:32:21', |
||||
edit_time: '2019-01-02 15:32:21', |
||||
tags: [ |
||||
{ name: '测试', id: 'test', icon: '', color: '' }, |
||||
{ |
||||
name: 'Arch Linux', |
||||
id: 'arch', |
||||
icon: 'https://www.oyohyee.com/static/img/tags/arch.png', |
||||
color: 'blue', |
||||
}, |
||||
], |
||||
head_image: 'https://www.oyohyee.com/static/img/posts/onenote.jpg', |
||||
}, |
||||
{ |
||||
title: |
||||
'Arch Linux的使用长标题长标题长标题长标题长标题长标题长标题长标题长标题长标题长标题长标题长标题长标题长标题长标题长标题长标题长标题长标题长标题长标题长标题长标题长标题长标题长标题长标题长标题长标题长标题长标题长标题长标题长标题长标题长标题长标题长标题长标题', |
||||
abstract: |
||||
'如何安装Arch Linux长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容长内容', |
||||
url: '/', |
||||
view: 100, |
||||
publish_time: '2019-01-01 15:32:21', |
||||
edit_time: '2019-01-02 15:32:21', |
||||
tags: [ |
||||
{ name: '测试', id: 'test', icon: '', color: '' }, |
||||
{ |
||||
name: '微软', |
||||
id: 'Mircosoft', |
||||
icon: 'https://www.oyohyee.com/static/img/tags/mircosoft.png', |
||||
color: 'red', |
||||
}, |
||||
], |
||||
head_image: '', |
||||
}, |
||||
], |
||||
} as { posts: Blotter.PostCard[] }, |
||||
'GET /api/site': <Blotter.Site>{ |
||||
view: 1536631, |
||||
beian: '豫ICP备17000379号', |
||||
friends: [ |
||||
{ name: 'ACBlackTea', link: 'http://blog.csdn.net/acblacktea' }, |
||||
{ name: 'Wilbert', link: 'http://blog.csdn.net/snow_me' }, |
||||
], |
||||
}, |
||||
}; |
@ -1,37 +0,0 @@
@@ -1,37 +0,0 @@
|
||||
export default { |
||||
// 支持值为 Object 和 Array
|
||||
'POST /api/menu': <ResponseMenu>{ |
||||
menu_list: [ |
||||
{ |
||||
name: '首页', |
||||
icon: 'home', |
||||
link: '/', |
||||
}, |
||||
{ |
||||
name: '归档', |
||||
icon: 'container', |
||||
link: '/archive', |
||||
}, |
||||
{ |
||||
name: '标签', |
||||
icon: 'tag', |
||||
link: '/tag', |
||||
}, |
||||
{ |
||||
name: '评论区', |
||||
icon: 'message', |
||||
link: '/comment', |
||||
}, |
||||
{ |
||||
name: '关于', |
||||
icon: 'idcard', |
||||
link: '/about', |
||||
}, |
||||
{ |
||||
name: '后台', |
||||
icon: 'setting', |
||||
link: '/setting', |
||||
}, |
||||
], |
||||
}, |
||||
}; |
@ -1,59 +0,0 @@
@@ -1,59 +0,0 @@
|
||||
import { Request, Response } from 'express'; |
||||
|
||||
const posts: { [key: string]: Blotter.Post } = { |
||||
wsl2_systemd: { |
||||
title: 'WSL2(Arch Linux)使用systemd', |
||||
abstract: '在WSL2中以pid 1运行systemd', |
||||
view: 383, |
||||
url: 'wsl2_systemd', |
||||
publish_time: '2019-09-11 14:39:39', |
||||
edit_time: '2019-09-11 14:39:39', |
||||
tags: [ |
||||
{ id: 'wsl', name: 'WSL', icon: '', color: '' }, |
||||
{ |
||||
id: 'arch', |
||||
name: 'Arch', |
||||
icon: 'https://www.oyohyee.com/static/img/tags/arch.png', |
||||
color: 'blue', |
||||
}, |
||||
], |
||||
head_image: '', |
||||
content: `<h1 id="wsl2arch-linuxsystemd">WSL2(Arch Linux)使用systemd</h1>
|
||||
<h2 id="heading">概述</h2> |
||||
<p>WSL本身是由Windows负责运行的,因此使用<code>tree</code>可以看到根进程不是systemd,而这将导致无法启动服务的守护进程(deamon),如nginx、docker、mysql等</p> |
||||
<p>按道理上包括ip转发、原生systemd慢慢都会实现,但是现阶段只能采用第三方方案实现。</p> |
||||
<p>一个比较好的解决方案是使用<a href="https://github.com/arkane-systems/genie">arkane-systems/genie</a>项目 <br> |
||||
大概原理是在一个单独的命名空间跑systemd,从而实现能够正常执行systemctl指令并启动服务</p> |
||||
<h2 id="heading1">安装步骤</h2> |
||||
<h3 id="-net">安装运行 .NET</h3> |
||||
<p>首先需要安装<code>.NET Core runtime</code>,这个可以直接<code>yay dotnet</code>,找到带runtime的安装即可 |
||||
安装完成后检查下是否其安装目录,如果不在默认位置需要手动写一下环境变量,如<code>export DOTNET_ROOT=/opt/dotnet</code></p> |
||||
<h3 id="heading2">安装相应的编译环境</h3> |
||||
<p>需要python、python-markdown、python-six、python-packaging、python-setuptool、python-attrs等依赖包 |
||||
而且按照测试来看似乎无法自动安装,因此最好先使用yay安装上他们(这些模块使用pip安装貌似也不行)</p> |
||||
<p>另外还需要安装 <code>make</code></p> |
||||
<h3 id="genie">安装genie</h3> |
||||
<p>使用 <code>yay -S genie-systemd</code> 下载 <code>genie</code> 源码并安装,如果中间出现缺少某个环境的话,退回到上一步安装即可</p> |
||||
<h2 id="heading3">使用</h2> |
||||
<p><code>genie</code> 有三个指令:</p> |
||||
<p><code>genie -i</code> 启动systemd进程 |
||||
<code>genie -s</code> 启动systemd进程,并进入该环境终端 |
||||
<code>genie -c <command></code> 启动systemd进程,并执行相应的指令</p> |
||||
<p>比如要运行docker,使用<code>genie -s</code>进入到环境后,执行<code>sudo systemctl start docker</code>即可 |
||||
而且在这里执行<code>pstree</code>,可以看到根进程已经变成了<code>systemd</code> |
||||
执行完成后退出这个命名空间后,<code>systemd</code>不会关闭</p>`,
|
||||
}, |
||||
}; |
||||
|
||||
export default { |
||||
'GET /api/post': (req: Request, res: Response) => { |
||||
var url = req.query['url']; |
||||
var post = posts[url]; |
||||
if (post) { |
||||
res.send(post); |
||||
} else { |
||||
res.status(404); |
||||
} |
||||
res.end(); |
||||
}, |
||||
}; |
@ -0,0 +1,2 @@
@@ -0,0 +1,2 @@
|
||||
/// <reference types="next" />
|
||||
/// <reference types="next/types/global" />
|
@ -0,0 +1,75 @@
@@ -0,0 +1,75 @@
|
||||
const withTypescript = require('@zeit/next-typescript'); |
||||
const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin'); |
||||
const withLess = require('@zeit/next-less'); |
||||
const withSass = require('@zeit/next-sass'); |
||||
const withCss = require('@zeit/next-css'); |
||||
const withPlugins = require('next-compose-plugins'); |
||||
const path = require('path'); |
||||
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin'); |
||||
const withTM = require('next-transpile-modules'); |
||||
const cssLoaderGetLocalIdent = require('css-loader/lib/getLocalIdent.js'); |
||||
|
||||
// with ant design
|
||||
// https://juejin.im/post/5cc74b925188252e741cce09
|
||||
withAntd = (nextConfig = {}) => { |
||||
return Object.assign({}, nextConfig, { |
||||
lessLoaderOptions: { |
||||
javascriptEnabled: true, |
||||
}, |
||||
cssModules: true, |
||||
cssLoaderOptions: { |
||||
camelCase: true, |
||||
localIdentName: '[local]___[hash:base64:5]', |
||||
getLocalIdent: (context, localIdentName, localName, options) => { |
||||
let hz = context.resourcePath.replace(context.rootContext, ''); |
||||
if (/node_modules/.test(hz)) { |
||||
return localName; |
||||
} else { |
||||
return cssLoaderGetLocalIdent(context, localIdentName, localName, options); |
||||
} |
||||
}, |
||||
}, |
||||
webpack(config, options) { |
||||
if (config.externals) { |
||||
const includes = [/antd/]; |
||||
config.externals = config.externals.map(external => { |
||||
if (typeof external !== 'function') return external; |
||||
return (ctx, req, cb) => { |
||||
return includes.find(include => |
||||
req.startsWith('.') ? include.test(path.resolve(ctx, req)) : include.test(req), |
||||
) |
||||
? cb() |
||||
: external(ctx, req, cb); |
||||
}; |
||||
}); |
||||
} |
||||
|
||||
return typeof nextConfig.webpack === 'function' |
||||
? nextConfig.webpack(config, options) |
||||
: config; |
||||
}, |
||||
}); |
||||
}; |
||||
|
||||
module.exports = withPlugins([withAntd, withTM, withLess, withCss, withSass], { |
||||
serverRuntimeConfig: { |
||||
//这里的配置项只能在服务端获取到,在浏览器端是获取不到的
|
||||
}, |
||||
publicRuntimeConfig: { |
||||
//这里的配置既可以服务端获取到,也可以在浏览器端获取到
|
||||
}, |
||||
webpack: (config, options) => { |
||||
// TODO: Remove after next.js update
|
||||
// https://github.com/zeit/next.js/issues/7779
|
||||
config.resolve.alias['@'] = path.resolve(__dirname, '.'); |
||||
|
||||
// TypeScript check
|
||||
// config.plugins.push(
|
||||
// new ForkTsCheckerWebpackPlugin({
|
||||
// tsconfig: './tsconfig.json',
|
||||
// }),
|
||||
// );
|
||||
|
||||
return config; |
||||
}, |
||||
}); |
@ -1,65 +1,35 @@
@@ -1,65 +1,35 @@
|
||||
{ |
||||
"private": true, |
||||
"scripts": { |
||||
"start": "umi dev", |
||||
"build": "umi build", |
||||
"test": "umi test", |
||||
"server": "cross-env NODE_ENV=development COMPRESS=none concurrently \"umi dev\" \"nodemon server.js\"", |
||||
"lint:es": "eslint --ext .js src mock tests", |
||||
"lint:ts": "tslint \"src/**/*.ts\" \"src/**/*.tsx\"", |
||||
"precommit": "lint-staged" |
||||
"dev": "next -p 50002", |
||||
"build": "next build", |
||||
"start": "next start -p 50002" |
||||
}, |
||||
"dependencies": { |
||||
"@types/express": "^4.17.1", |
||||
"@types/mongodb": "^3.3.14", |
||||
"@types/react-responsive": "^8.0.2", |
||||
"antd": "^3.26.7", |
||||
"@material-ui/core": "^4.9.2", |
||||
"@types/antd": "^1.0.0", |
||||
"@types/node": "^13.7.0", |
||||
"@types/react": "^16.9.19", |
||||
"@zeit/next-css": "^1.0.1", |
||||
"@zeit/next-less": "^1.0.1", |
||||
"@zeit/next-sass": "^1.0.1", |
||||
"@zeit/next-typescript": "^1.1.1", |
||||
"antd": "^3.26.9", |
||||
"axios": "^0.19.2", |
||||
"dva": "^2.4.1", |
||||
"mongodb": "^3.5.2", |
||||
"nodemon": "^2.0.2", |
||||
"babel-plugin-import": "^1.13.0", |
||||
"css": "^2.2.4", |
||||
"fork-ts-checker-webpack-plugin": "^4.0.3", |
||||
"less": "^3.10.3", |
||||
"next": "^9.2.1", |
||||
"next-compose-plugins": "^2.2.0", |
||||
"next-transpile-modules": "^3.0.2", |
||||
"null-loader": "^3.0.0", |
||||
"react": "^16.12.0", |
||||
"react-dom": "^16.8.6", |
||||
"react-dom": "^16.12.0", |
||||
"react-responsive": "^8.0.3", |
||||
"umi-request": "^1.2.18", |
||||
"umi-server": "^1.2.2" |
||||
}, |
||||
"devDependencies": { |
||||
"@types/jest": "^25.1.0", |
||||
"@types/react": "^16.9.19", |
||||
"@types/react-dom": "^16.9.5", |
||||
"@types/react-test-renderer": "^16.0.3", |
||||
"babel-eslint": "^10.0.3", |
||||
"babel-plugin-import": "^1.13.0", |
||||
"concurrently": "^5.1.0", |
||||
"cross-env": "^7.0.0", |
||||
"eslint": "^6.5.1", |
||||
"eslint-config-umi": "^1.4.0", |
||||
"eslint-plugin-flowtype": "^4.3.0", |
||||
"eslint-plugin-import": "^2.14.0", |
||||
"eslint-plugin-jsx-a11y": "^6.2.3", |
||||
"eslint-plugin-react": "^7.11.1", |
||||
"husky": "^4.2.1", |
||||
"lint-staged": "^10.0.4", |
||||
"react-test-renderer": "^16.12.0", |
||||
"tslint": "^6.0.0", |
||||
"tslint-eslint-rules": "^5.4.0", |
||||
"tslint-react": "^4.2.0", |
||||
"umi": "^2.13.3", |
||||
"umi-plugin-react": "^1.15.2", |
||||
"umi-types": "^0.5.12" |
||||
}, |
||||
"lint-staged": { |
||||
"*.{ts,tsx}": [ |
||||
"tslint --fix", |
||||
"git add" |
||||
], |
||||
"*.{js,jsx}": [ |
||||
"eslint --fix", |
||||
"git add" |
||||
] |
||||
}, |
||||
"engines": { |
||||
"node": ">=8.0.0" |
||||
"react-router": "^5.1.2", |
||||
"sass": "^1.25.0", |
||||
"tsconfig-paths-webpack-plugin": "^3.2.0", |
||||
"typescript": "^3.7.5" |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,49 @@
@@ -0,0 +1,49 @@
|
||||
import React from 'react'; |
||||
import App from 'next/app'; |
||||
|
||||
import BasicLayout from '@/components/layout'; |
||||
const Layout = BasicLayout as any; |
||||
|
||||
export default class MyApp extends App { |
||||
constructor(props: any) { |
||||
super(props); |
||||
console.log('APP', props); |
||||
} |
||||
static pageProps = { |
||||
layoutProps: {}, |
||||
componentProps: {}, |
||||
}; |
||||
static async getInitialProps({ Component, router, ctx }) { |
||||
const isServer = !!ctx.req; |
||||
try { |
||||
var layoutPromise = {}; |
||||
var componentPromise = {}; |
||||
|
||||
console.log(Layout.getInitialProps); |
||||
if (isServer && Layout.getInitialProps) { |
||||
layoutPromise = Layout.getInitialProps(ctx); |
||||
} |
||||
if (Component.getInitialProps) { |
||||
componentPromise = Component.getInitialProps(ctx); |
||||
} |
||||
if (isServer) { |
||||
MyApp.pageProps.layoutProps = await layoutPromise; |
||||
} |
||||
MyApp.pageProps.componentProps = await componentPromise; |
||||
} catch (e) { |
||||
console.log(e); |
||||
} |
||||
|
||||
return { pageProps: MyApp.pageProps }; |
||||
} |
||||
|
||||
render() { |
||||
const { Component, pageProps } = this.props; |
||||
|
||||
return ( |
||||
<Layout {...pageProps.layoutProps}> |
||||
<Component {...pageProps.layoutProps} {...pageProps.componentProps} /> |
||||
</Layout> |
||||
); |
||||
} |
||||
} |
@ -0,0 +1,34 @@
@@ -0,0 +1,34 @@
|
||||
import React, { ComponentProps } from 'react'; |
||||
|
||||
import Head from 'next/head'; |
||||
|
||||
import { Card } from 'antd'; |
||||
|
||||
import Container from '@/components/container'; |
||||
|
||||
import { GlobalProps } from '@/utils/global'; |
||||
|
||||
interface AboutPageProps extends GlobalProps, ComponentProps<'base'> {} |
||||
interface AboutPageState {} |
||||
|
||||
export class AboutPage extends React.Component<AboutPageProps, AboutPageState> { |
||||
static defaultProps = {}; |
||||
|
||||
constructor(props: any) { |
||||
super(props); |
||||
this.state = {}; |
||||
} |
||||
|
||||
render() { |
||||
return ( |
||||
<Container> |
||||
<Head> |
||||
<title>{`关于我|${this.props.blog_name}`}</title> |
||||
</Head> |
||||
<Card></Card> |
||||
</Container> |
||||
); |
||||
} |
||||
} |
||||
|
||||
export default AboutPage; |