├── README.md
├── config
├── env.js
├── jest
│ ├── cssTransform.js
│ └── fileTransform.js
├── paths.js
├── polyfills.js
├── webpack.config.dev.js
├── webpack.config.prod.js
└── webpackDevServer.config.js
├── images
├── 1.png
├── 2.png
├── 3.png
├── 4.png
├── 5.png
└── 6.png
├── package-lock.json
├── package.json
├── public
├── favicon.ico
├── index.html
└── manifest.json
├── scripts
├── build.js
├── start.js
└── test.js
├── server
├── app.js
├── model
│ └── model.js
├── routes
│ ├── article.js
│ ├── message.js
│ ├── music.js
│ └── user.js
├── upload
│ ├── image-1519493311082.jpg
│ ├── image-1520226979355.jpg
│ ├── image-1520227864323.jpg
│ ├── image-1520229547392.jpg
│ ├── image-1520350000324.jpg
│ ├── music-1520226984271.mp3
│ ├── music-1520227879326.mp3
│ └── music-1520229552446.mp3
└── views
│ └── index.ejs
└── src
├── Global.scss
├── actions
└── actions.js
├── components
├── articleEditor
│ ├── articleEditor.js
│ └── articleEditor.scss
├── articlelist
│ ├── articlelist.js
│ └── articlelist.scss
├── articlepage
│ ├── articlepage.js
│ └── articlepage.scss
├── authRoute
│ └── authRoute.js
├── categorylist
│ ├── categoryList.scss
│ └── categorylist.js
├── editArticleList
│ ├── editArticleList.js
│ └── editArticleList.scss
├── editMessageList
│ ├── editMessageList.js
│ └── editMessageList.scss
├── editMusicList
│ ├── editMusicList.js
│ └── editMusicList.scss
├── editUserPage
│ ├── editUserPage.js
│ └── editUserPage.scss
├── messagelist
│ ├── messagelist.js
│ └── messagelist.scss
├── messagepost
│ ├── messagepost.js
│ └── messagepost.scss
├── musicPlayer
│ ├── musicPlayer.js
│ └── musicPlayer.scss
├── navlist
│ ├── navlist.js
│ └── navlist.scss
├── uploadMusic
│ ├── uploadMusic.js
│ └── uploadMusic.scss
└── userinfo
│ ├── userinfo.js
│ └── userinfo.scss
├── containers
├── admin
│ ├── admin.js
│ ├── admin.scss
│ └── subpage
│ │ ├── editArticle.js
│ │ ├── editMessage.js
│ │ ├── editMusic.js
│ │ ├── editUser.js
│ │ ├── postArticle.js
│ │ └── updateArticle.js
├── blog
│ ├── blog.js
│ ├── blog.scss
│ └── subpage
│ │ ├── article.js
│ │ └── blogindex.js
├── homepage
│ ├── homepage.js
│ └── homepage.scss
├── layout
│ ├── layout.js
│ └── layout.scss
├── message
│ ├── message.js
│ └── message.scss
├── music
│ ├── music.js
│ └── music.scss
├── register
│ ├── register.js
│ └── register.scss
└── signin
│ ├── signin.js
│ └── signin.scss
├── index.js
├── logo.svg
├── reducers
├── article.js
├── message.js
├── music.js
├── reducers.js
└── user.js
├── registerServiceWorker.js
└── static
├── font
├── demo.css
├── demo_fontclass.html
├── demo_symbol.html
├── demo_unicode.html
├── iconfont.css
├── iconfont.eot
├── iconfont.js
├── iconfont.svg
├── iconfont.ttf
└── iconfont.woff
├── images
├── avatar.jpg
├── blog-bg.png
└── wrap-bg.png
└── music
└── 山丘.mp3
/README.md:
--------------------------------------------------------------------------------
1 | 一款前后端分离,单页面的个人博客
2 | ====
3 | 所用技术栈
4 | ------
5 | 前端用React技术栈,React + Redux + React-Router,
6 | 前端后台管理界面antd,
7 | CSS预处理器用了Sass,
8 | 前后端数据传输用axios库,
9 | 后端用Node,express框架,数据库MongoDB。
10 |
11 | 简述
12 | ------
13 | 第一次从界面设计排版,到前后端编程,到部署上线都独立完成的一个项目(还在等域名备案。。。)
14 |
15 | 写这个博客,一是想给自己平常所学的东西有个应用发挥的地方。二是平常可以给自己的学习有个记录备忘的地方。
16 |
17 | 启动
18 | ------
19 | npm i
20 |
21 | 后端启动: node server/app.js
22 |
23 | 前端启动: npm start
24 |
25 | 界面展示
26 | ------
27 | 
28 | 
29 | 
30 | 
31 | 
32 | 
33 |
--------------------------------------------------------------------------------
/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.
31 | // https://github.com/motdotla/dotenv
32 | dotenvFiles.forEach(dotenvFile => {
33 | if (fs.existsSync(dotenvFile)) {
34 | require('dotenv').config({
35 | path: dotenvFile,
36 | });
37 | }
38 | });
39 |
40 | // We support resolving modules according to `NODE_PATH`.
41 | // This lets you use absolute paths in imports inside large monorepos:
42 | // https://github.com/facebookincubator/create-react-app/issues/253.
43 | // It works similar to `NODE_PATH` in Node itself:
44 | // https://nodejs.org/api/modules.html#modules_loading_from_the_global_folders
45 | // Note that unlike in Node, only *relative* paths from `NODE_PATH` are honored.
46 | // Otherwise, we risk importing Node.js core modules into an app instead of Webpack shims.
47 | // https://github.com/facebookincubator/create-react-app/issues/1023#issuecomment-265344421
48 | // We also resolve them to make sure all tools using them work consistently.
49 | const appDirectory = fs.realpathSync(process.cwd());
50 | process.env.NODE_PATH = (process.env.NODE_PATH || '')
51 | .split(path.delimiter)
52 | .filter(folder => folder && !path.isAbsolute(folder))
53 | .map(folder => path.resolve(appDirectory, folder))
54 | .join(path.delimiter);
55 |
56 | // Grab NODE_ENV and REACT_APP_* environment variables and prepare them to be
57 | // injected into the application via DefinePlugin in Webpack configuration.
58 | const REACT_APP = /^REACT_APP_/i;
59 |
60 | function getClientEnvironment(publicUrl) {
61 | const raw = Object.keys(process.env)
62 | .filter(key => REACT_APP.test(key))
63 | .reduce(
64 | (env, key) => {
65 | env[key] = process.env[key];
66 | return env;
67 | },
68 | {
69 | // Useful for determining whether we’re running in production mode.
70 | // Most importantly, it switches React into the correct mode.
71 | NODE_ENV: process.env.NODE_ENV || 'development',
72 | // Useful for resolving the correct path to static assets in `public`.
73 | // For example,
.
74 | // This should only be used as an escape hatch. Normally you would put
75 | // images into the `src` and `import` them in code to get their paths.
76 | PUBLIC_URL: publicUrl,
77 | }
78 | );
79 | // Stringify all values so we can feed into Webpack DefinePlugin
80 | const stringified = {
81 | 'process.env': Object.keys(raw).reduce((env, key) => {
82 | env[key] = JSON.stringify(raw[key]);
83 | return env;
84 | }, {}),
85 | };
86 |
87 | return { raw, stringified };
88 | }
89 |
90 | module.exports = getClientEnvironment;
91 |
--------------------------------------------------------------------------------
/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/tutorial-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/tutorial-webpack.html
7 |
8 | module.exports = {
9 | process(src, filename) {
10 | return `module.exports = ${JSON.stringify(path.basename(filename))};`;
11 | },
12 | };
13 |
--------------------------------------------------------------------------------
/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/facebookincubator/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(path, needsSlash) {
15 | const hasSlash = path.endsWith('/');
16 | if (hasSlash && !needsSlash) {
17 | return path.substr(path, path.length - 1);
18 | } else if (!hasSlash && needsSlash) {
19 | return `${path}/`;
20 | } else {
21 | return path;
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
9 |
10 |
24 |
25 |
26 |
27 |
IconFont 图标
28 |
29 |
30 | -
31 |
34 |
博客新闻
35 | #icon-bokexinwen
36 |
37 |
38 | -
39 |
42 |
登录 用户
43 | #icon-icon
44 |
45 |
46 | -
47 |
50 |
顺序播放
51 | #icon-shunxubofang
52 |
53 |
54 | -
55 |
58 |
首页
59 | #icon-home
60 |
61 |
62 | -
63 |
66 |
应用
67 | #icon-application
68 |
69 |
70 | -
71 |
74 |
单曲循环
75 | #icon-danquxunhuan
76 |
77 |
78 | -
79 |
82 |
留言评论
83 | #icon-liuyanpinglun
84 |
85 |
86 | -
87 |
90 |
随机播放_32
91 | #icon-suijibofang
92 |
93 |
94 | -
95 |
98 |
向左
99 | #icon-xiangzuo
100 |
101 |
102 | -
103 |
106 |
向右
107 | #icon-xiangyou
108 |
109 |
110 | -
111 |
114 |
管理
115 | #icon-guanli
116 |
117 |
118 | -
119 |
122 |
播放
123 | #icon-bofang
124 |
125 |
126 | -
127 |
130 |
暂停
131 | #icon-zanting
132 |
133 |
134 | -
135 |
138 |
个人简历
139 | #icon-gerenjianli
140 |
141 |
142 | -
143 |
146 |
音乐
147 | #icon-yinle
148 |
149 |
150 | -
151 |
154 |
音量-2
155 | #icon-yinliang2
156 |
157 |
158 | -
159 |
162 |
音量-1
163 | #icon-yinliang1
164 |
165 |
166 | -
167 |
170 |
音量-3
171 | #icon-yinliang3
172 |
173 |
174 |
175 |
176 |
177 |
symbol引用
178 |
179 |
180 |
这是一种全新的使用方式,应该说这才是未来的主流,也是平台目前推荐的用法。相关介绍可以参考这篇文章
181 | 这种用法其实是做了一个svg的集合,与另外两种相比具有如下特点:
182 |
183 | - 支持多色图标了,不再受单色限制。
184 | - 通过一些技巧,支持像字体那样,通过
font-size
,color
来调整样式。
185 | - 兼容性较差,支持 ie9+,及现代浏览器。
186 | - 浏览器渲染svg的性能一般,还不如png。
187 |
188 |
使用步骤如下:
189 |
第一步:引入项目下面生成的symbol代码:
190 |
191 |
第二步:加入通用css代码(引入一次就行):
192 |
<style type="text/css">
193 | .icon {
194 | width: 1em; height: 1em;
195 | vertical-align: -0.15em;
196 | fill: currentColor;
197 | overflow: hidden;
198 | }
199 | </style>
200 |
第三步:挑选相应图标并获取类名,应用于页面:
201 |
<svg class="icon" aria-hidden="true">
202 | <use xlink:href="#icon-xxx"></use>
203 | </svg>
204 |
205 |
206 |
207 |