init rf-blog project
init rf-blog db config init rf-blog vue config init rf-blog node config create dev-admin\dev-client
Showing
60 changed files
with
603 additions
and
0 deletions
rf-blog/.babelrc
0 → 100644
1 | +{ | ||
2 | + "presets": [ | ||
3 | + "es2015", | ||
4 | + [ | ||
5 | + "env", | ||
6 | + { | ||
7 | + "modules": false, | ||
8 | + "targets": { | ||
9 | + "browsers": ["> 1%", "last 2 versions", "not ie <= 8"] | ||
10 | + } | ||
11 | + } | ||
12 | + ], | ||
13 | + "stage-2" | ||
14 | + ], | ||
15 | + "plugins": ["transform-runtime"], | ||
16 | + "env": { | ||
17 | + "test": { | ||
18 | + "presets": ["env", "stage-2"] | ||
19 | + } | ||
20 | + } | ||
21 | +} |
rf-blog/LICENSE
0 → 100644
1 | +MIT License | ||
2 | + | ||
3 | +Copyright (c) 2021 rf | ||
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. |
rf-blog/build/build.js
0 → 100644
1 | +"use strict"; | ||
2 | + | ||
3 | +process.env.NODE_ENV = "production"; | ||
4 | +const path = require("path"); | ||
5 | +const webpack = require("webpack"); | ||
6 | +const config = require("./webpack.prod.conf"); | ||
7 | +const compiler = webpack(config); | ||
8 | +// 以包的形式包装rm -rf命令,删除文件夹 | ||
9 | +const rm = require("rimraf"); | ||
10 | +// 美化node控制台进度 | ||
11 | +const ora = require("ora"); | ||
12 | +const spinner = ora({ | ||
13 | + text: "building for production loading...", | ||
14 | + color: "yellow", | ||
15 | + spinner: { interval: 80, frames: ["-", "+", "-"] }, | ||
16 | +}); | ||
17 | +// 开启loading动画 | ||
18 | +spinner.start(); | ||
19 | +// 美化控制台输出 | ||
20 | +const chalk = require("chalk"); | ||
21 | +const isAdmin = process.env.NODE_ENV_TYPE === "admin"; | ||
22 | +// 打包前先删除之前可能已打包过的文件 | ||
23 | +const rmFile = path.resolve( | ||
24 | + __dirname, | ||
25 | + `../puclic/${isAdmin ? "admin" : "client"}` | ||
26 | +); | ||
27 | + | ||
28 | +rm(rmFile, (rmErr) => { | ||
29 | + if (rmErr) throw rmErr; | ||
30 | + compiler.run((err, stats) => { | ||
31 | + spinner.stop(); | ||
32 | + if (err) { | ||
33 | + throw err; | ||
34 | + } | ||
35 | + if (stats.hasErrors()) { | ||
36 | + console.log(chalk.redBright("Build failed with errors.\n")); | ||
37 | + process.exit(1); | ||
38 | + } | ||
39 | + process.stdout.write( | ||
40 | + stats.toString({ | ||
41 | + colors: true, | ||
42 | + modules: false, | ||
43 | + children: false, | ||
44 | + chunks: false, | ||
45 | + chunkModules: false, | ||
46 | + }) + "\n\n" | ||
47 | + ); | ||
48 | + console.log(chalk.greenBright("Build completed with success.\n")); | ||
49 | + | ||
50 | + compiler.close((closeErr) => { | ||
51 | + if (closeErr) { | ||
52 | + console.log( | ||
53 | + chalk.redBright( | ||
54 | + `compiler close failed with message ${closeErr.message}` | ||
55 | + ) | ||
56 | + ); | ||
57 | + } | ||
58 | + }); | ||
59 | + }); | ||
60 | +}); |
rf-blog/build/config.js
0 → 100644
1 | +module.exports = { | ||
2 | + admin: { | ||
3 | + dev: { | ||
4 | + env: "development", | ||
5 | + publicPath: "/", | ||
6 | + host: "localhost", | ||
7 | + port: "8090", | ||
8 | + assetsSubDirectory: "static", | ||
9 | + devtoolType: "eval-cheap-module-source-map", | ||
10 | + proxyTable: { | ||
11 | + "/admin_api": { | ||
12 | + target: "http://localhost:3000/admin_api/", | ||
13 | + changeOrigin: true, | ||
14 | + pathRewrite: { | ||
15 | + "^/admin_api": "/", | ||
16 | + }, | ||
17 | + }, | ||
18 | + }, | ||
19 | + }, | ||
20 | + build: { | ||
21 | + env: "production", | ||
22 | + publicPath: "./", // html引用资源路径 | ||
23 | + assetsPath: "static", // 静态资源目录 | ||
24 | + assetsSubDirectory: "static", // html资源存放目录 | ||
25 | + devtoolType: "source-map", // 代码位置信息 | ||
26 | + }, | ||
27 | + }, | ||
28 | + | ||
29 | + client: { | ||
30 | + dev: { | ||
31 | + env: "development", | ||
32 | + publicPath: "/", | ||
33 | + host: "localhost", | ||
34 | + port: "8080", | ||
35 | + assetsSubDirectory: "static", | ||
36 | + devtoolType: "eval-cheap-module-source-map", | ||
37 | + proxyTable: { | ||
38 | + "/client_api": { | ||
39 | + target: "http://localhost:3000/client_api/", | ||
40 | + changeOrigin: true, | ||
41 | + pathRewrite: { | ||
42 | + "^/client_api": "/", | ||
43 | + }, | ||
44 | + }, | ||
45 | + }, | ||
46 | + }, | ||
47 | + build: { | ||
48 | + env: "production", | ||
49 | + publicPath: "./", | ||
50 | + assetsPath: "static", | ||
51 | + assetsSubDirectory: "static", | ||
52 | + devtoolType: "source-map", | ||
53 | + }, | ||
54 | + }, | ||
55 | +}; |
rf-blog/build/webpack.base.conf.js
0 → 100644
1 | +"use strict"; | ||
2 | +const path = require("path"); | ||
3 | +const VueLoaderPlugin = require("vue-loader/lib/plugin"); | ||
4 | +// 以link标签形式,抽离出css | ||
5 | +const MiniCssExtractPlugin = require("mini-css-extract-plugin"); | ||
6 | + | ||
7 | +const isAdmin = process.env.NODE_ENV_TYPE === "admin"; | ||
8 | +const isProd = process.env.NODE_ENV === "prod"; | ||
9 | +const prodConf = isAdmin | ||
10 | + ? require("./config").admin.build | ||
11 | + : require("./config").client.build; | ||
12 | +// 拼接路径 | ||
13 | +const resolve = (dir) => { | ||
14 | + return path.join(__dirname, "..", dir); | ||
15 | +}; | ||
16 | +// 资源路径 | ||
17 | +const assetsPath = (dir) => { | ||
18 | + return path.posix.join(prodConf.assetsPath, dir); | ||
19 | +}; | ||
20 | + | ||
21 | +module.exports = { | ||
22 | + entry: { | ||
23 | + app: [ | ||
24 | + isAdmin | ||
25 | + ? resolve("code/admin/src/main.js") | ||
26 | + : resolve("code/client/src/main.js"), | ||
27 | + "babel-polyfill", | ||
28 | + ], | ||
29 | + }, | ||
30 | + // 配置模块如何被解析 | ||
31 | + resolve: { | ||
32 | + //自动解析文件扩展名(补全文件后缀)(从左->右) | ||
33 | + extensions: [".js", ".vue", ".json"], | ||
34 | + // 配置别名映射 | ||
35 | + alias: { | ||
36 | + vue$: "vue/dist/vue.esm.js", | ||
37 | + src: isAdmin ? resolve("code/admin/src") : resolve("code/client/src"), | ||
38 | + components: isAdmin | ||
39 | + ? resolve("code/admin/src/components") | ||
40 | + : resolve("code/client/src/components"), | ||
41 | + style: isAdmin | ||
42 | + ? resolve("code/admin/src/styles") | ||
43 | + : resolve("code/client/src/style"), | ||
44 | + views: isAdmin | ||
45 | + ? resolve("code/admin/src/views") | ||
46 | + : resolve("code/client/src/views"), | ||
47 | + store: isAdmin | ||
48 | + ? resolve("code/admin/src/store") | ||
49 | + : resolve("code/client/src/store"), | ||
50 | + api: isAdmin | ||
51 | + ? resolve("code/admin/src/api") | ||
52 | + : resolve("code/client/src/api"), | ||
53 | + utils: isAdmin | ||
54 | + ? resolve("code/admin/src/utils") | ||
55 | + : resolve("code/client/src/utils"), | ||
56 | + }, | ||
57 | + }, | ||
58 | + plugins: [ | ||
59 | + // 引用vue-loader时必须确保引入该plugin | ||
60 | + new VueLoaderPlugin(), | ||
61 | + new MiniCssExtractPlugin({ | ||
62 | + filename: assetsPath("css/[name].[chunkhash].css"), | ||
63 | + chunkFilename: assetsPath("css/[name].[chunkhash].css"), | ||
64 | + }), | ||
65 | + ], | ||
66 | + module: { | ||
67 | + rules: [ | ||
68 | + { | ||
69 | + test: /\.js$/, | ||
70 | + loader: "babel-loader", | ||
71 | + include: isAdmin | ||
72 | + ? resolve("code/admin/src") | ||
73 | + : resolve("code/client/src"), | ||
74 | + }, | ||
75 | + { | ||
76 | + test: /\.vue$/, | ||
77 | + loader: "vue-loader", | ||
78 | + include: isAdmin | ||
79 | + ? resolve("code/admin/src") | ||
80 | + : resolve("code/client/src"), | ||
81 | + }, | ||
82 | + { | ||
83 | + test: /\.css$/, | ||
84 | + use: [ | ||
85 | + !isProd | ||
86 | + ? { loader: "vue-style-loader" } | ||
87 | + : MiniCssExtractPlugin.loader, | ||
88 | + { loader: "css-loader" }, | ||
89 | + ], | ||
90 | + }, | ||
91 | + // 开发环境使用vue-style-loader可以重载样式模块 | ||
92 | + { | ||
93 | + test: /\.less$/, | ||
94 | + use: [ | ||
95 | + !isProd | ||
96 | + ? { loader: "vue-style-loader" } | ||
97 | + : MiniCssExtractPlugin.loader, | ||
98 | + { loader: "css-loader" }, | ||
99 | + { loader: "less-loader" }, | ||
100 | + { | ||
101 | + loader: "style-resources-loader", | ||
102 | + options: { | ||
103 | + patterns: path.resolve(__dirname, "../styles/theme.less"), | ||
104 | + }, | ||
105 | + }, | ||
106 | + ], | ||
107 | + }, | ||
108 | + { | ||
109 | + test: /\.(png|jpe?g|gif|svg|ico)(\?.*)?$/, | ||
110 | + loader: "url-loader", | ||
111 | + options: { | ||
112 | + limit: 10000, | ||
113 | + name: assetsPath("img/[name].[hash:7].[ext]"), | ||
114 | + }, | ||
115 | + }, | ||
116 | + { | ||
117 | + test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, | ||
118 | + loader: "url-loader", | ||
119 | + options: { | ||
120 | + limit: 10000, | ||
121 | + name: assetsPath("fonts/[name].[hash:7].[ext]"), | ||
122 | + }, | ||
123 | + }, | ||
124 | + ], | ||
125 | + }, | ||
126 | +}; |
rf-blog/build/webpack.dev.conf.js
0 → 100644
1 | +"use strict"; | ||
2 | +const webpack = require("webpack"); | ||
3 | +// 合并配置 | ||
4 | +const { merge } = require("webpack-merge"); | ||
5 | +// 配置需打包的html入口信息,并创建一个新的html文件 | ||
6 | +const HtmlWebpackPlugin = require("html-webpack-plugin"); | ||
7 | +// 编译提示 | ||
8 | +const FriendlyErrorsPlugin = require("friendly-errors-webpack-plugin"); | ||
9 | +// 系统桌面通知 | ||
10 | +const notifier = require("node-notifier"); | ||
11 | + | ||
12 | +const isAdmin = process.env.NODE_ENV_TYPE === "admin"; | ||
13 | +// 开发环境配置参数 | ||
14 | +const devConf = isAdmin | ||
15 | + ? require("./config").admin.dev | ||
16 | + : require("./config").client.dev; | ||
17 | +const baseConf = require("./webpack.base.conf"); | ||
18 | + | ||
19 | +const dev = merge(baseConf, { | ||
20 | + mode: "development", | ||
21 | + output: { | ||
22 | + filename: "[name]-[hash].js", | ||
23 | + // html引用资源路径,在dev-server中,引用的是内存中文件 | ||
24 | + publicPath: devConf.publicPath, | ||
25 | + }, | ||
26 | + module: {}, | ||
27 | + // 生成sourceMap(方便调试) | ||
28 | + devtool: devConf.devtoolType, | ||
29 | + // 启动一个本地服务器,可进行本地开发 | ||
30 | + devServer: { | ||
31 | + hot: true, // 热加载 | ||
32 | + open: true, // 自动打开浏览器 | ||
33 | + historyApiFallback: true, // 在开发单页应用时非常有用,它依赖于HTML5 history API,如果设置为true,所有的跳转将指向index.html | ||
34 | + host: devConf.host, | ||
35 | + port: devConf.port, | ||
36 | + proxy: devConf.proxyTable, // 配置反向代理解决跨域 | ||
37 | + compress: true, // 压缩代码 | ||
38 | + client: { | ||
39 | + // 在浏览器上全屏显示编译的errors | ||
40 | + overlay: { | ||
41 | + errors: true, | ||
42 | + warnings: false, | ||
43 | + }, | ||
44 | + }, | ||
45 | + }, | ||
46 | + watchOptions: { | ||
47 | + ignored: ["**/.#*.vue", "node_modules/**"], | ||
48 | + }, | ||
49 | + plugins: [ | ||
50 | + // 开启HMR(热替换功能,替换更新部分,不重载页面!) | ||
51 | + new webpack.HotModuleReplacementPlugin(), | ||
52 | + new HtmlWebpackPlugin({ | ||
53 | + filename: "index.html", | ||
54 | + template: isAdmin ? "code/admin/index.html" : "code/client/index.html", | ||
55 | + inject: true, | ||
56 | + }), | ||
57 | + // 编译提示 | ||
58 | + new FriendlyErrorsPlugin({ | ||
59 | + // 编译成功 | ||
60 | + compilationSuccessInfo: { | ||
61 | + messages: [ | ||
62 | + `Your application is running here: http://${devConf.host}:${devConf.port}`, | ||
63 | + ], | ||
64 | + }, | ||
65 | + // 编译出错 | ||
66 | + onErrors: (severity, errors) => { | ||
67 | + if (severity !== "error") { | ||
68 | + return; | ||
69 | + } | ||
70 | + const error = errors[0]; | ||
71 | + // 编译出错时,系统右下角弹出错误提示 | ||
72 | + notifier.notify({ | ||
73 | + title: "Webpack error", | ||
74 | + message: severity + ": " + error.name, | ||
75 | + subtitle: error.file || "", | ||
76 | + }); | ||
77 | + }, | ||
78 | + clearConsole: true, // 每次编译之间清除控制台 | ||
79 | + }), | ||
80 | + ], | ||
81 | +}); | ||
82 | +module.exports = dev; |
rf-blog/build/webpack.prod.conf.js
0 → 100644
1 | +"use strict"; | ||
2 | +const path = require("path"); | ||
3 | +const webpack = require("webpack"); | ||
4 | +// 合并配置 | ||
5 | +const { merge } = require("webpack-merge"); | ||
6 | +// 配置需打包的html入口信息,并创建一个新的html文件 | ||
7 | +const HtmlWebpackPlugin = require("html-webpack-plugin"); | ||
8 | +// 压缩js | ||
9 | +const TerserPlugin = require("terser-webpack-plugin"); | ||
10 | +// 压缩css | ||
11 | +const CssMinimizerPlugin = require("css-minimizer-webpack-plugin"); | ||
12 | +// 开启Gzip压缩,nginx需要配置 | ||
13 | +const CompressionPlugin = require("compression-webpack-plugin"); | ||
14 | + | ||
15 | +const isAdmin = process.env.NODE_ENV_TYPE === "admin"; | ||
16 | +// 生产环境配置参数 | ||
17 | +const prodConf = isAdmin | ||
18 | + ? require("./config").admin.build | ||
19 | + : require("./config").client.build; | ||
20 | +const baseConf = require("./webpack.base.conf"); | ||
21 | +// 资源路径 | ||
22 | +const assetsPath = (dir) => { | ||
23 | + return path.posix.join(prodConf.assetsSubDirectory, dir); | ||
24 | +}; | ||
25 | + | ||
26 | +const prod = merge({}, baseConf, { | ||
27 | + mode: "production", | ||
28 | + output: { | ||
29 | + // build后所有文件存放的位置 | ||
30 | + path: path.resolve(__dirname, `../public/${isAdmin ? "admin" : "client"}`), | ||
31 | + // html引用资源路径,可在此配置cdn引用地址 | ||
32 | + publicPath: prodConf.publicPath, | ||
33 | + filename: assetsPath("js/[name].[chunkhash].js"), | ||
34 | + // 用于打包require.ensure(代码分割)方法中引入的模块 | ||
35 | + chunkFilename: assetsPath("js/[name].[chunkhash].js"), | ||
36 | + }, | ||
37 | + module: {}, | ||
38 | + optimization: { | ||
39 | + moduleIds: "deterministic", // 被哈希转化成的小位数值模块名 | ||
40 | + minimizer: [ | ||
41 | + new TerserPlugin({ | ||
42 | + parallel: true, | ||
43 | + terserOptions: { | ||
44 | + format: { | ||
45 | + comments: false, // 删除注释 | ||
46 | + }, | ||
47 | + }, | ||
48 | + }), | ||
49 | + new CssMinimizerPlugin({ | ||
50 | + parallel: true, | ||
51 | + minimizerOptions: { | ||
52 | + preset: [ | ||
53 | + "default", | ||
54 | + { | ||
55 | + discardComments: { removeAll: true }, // 删除注释 | ||
56 | + }, | ||
57 | + ], | ||
58 | + }, | ||
59 | + }), | ||
60 | + ], | ||
61 | + splitChunks: { | ||
62 | + chunks: "all", | ||
63 | + minSize: 30000, // 形成一个新代码块最小的体积 | ||
64 | + maxAsyncRequests: 5, // 按需加载时候最大的并行请求数 | ||
65 | + maxInitialRequests: 3, // 最大初始化请求数 | ||
66 | + automaticNameDelimiter: "~", // 打包分割符 | ||
67 | + cacheGroups: { | ||
68 | + // 打包第三方库 | ||
69 | + vendors: { | ||
70 | + name: `chunk-vendors`, | ||
71 | + test: /[/]node_modules[/]/, | ||
72 | + priority: -10, // 优先级 | ||
73 | + chunks: "initial", | ||
74 | + }, | ||
75 | + // 打包其余的的公共代码 | ||
76 | + common: { | ||
77 | + name: `chunk-common`, | ||
78 | + minChunks: 2, // 引入两次及以上被打包 | ||
79 | + priority: -20, | ||
80 | + chunks: "initial", | ||
81 | + reuseExistingChunk: true, | ||
82 | + }, | ||
83 | + }, | ||
84 | + }, | ||
85 | + }, | ||
86 | + plugins: [ | ||
87 | + // 作用域提升,提升代码在浏览器执行速度 | ||
88 | + new webpack.optimize.ModuleConcatenationPlugin(), | ||
89 | + new HtmlWebpackPlugin({ | ||
90 | + filename: "index.html", | ||
91 | + template: isAdmin ? "code/admin/index.html" : "code/client/index.html", | ||
92 | + inject: true, | ||
93 | + minify: { | ||
94 | + removeComments: true, // 删除html注释 | ||
95 | + collapseWhitespace: true, // 去除空格 | ||
96 | + removeRedundantAttributes: true, // 删除多余的属性 | ||
97 | + }, | ||
98 | + }), | ||
99 | + new CompressionPlugin({ | ||
100 | + filename: "[path][base].gz", | ||
101 | + algorithm: "gzip", | ||
102 | + test: /\.js$|\.css$|\.html$/, | ||
103 | + threshold: 10240, | ||
104 | + minRatio: 0.8, | ||
105 | + }), | ||
106 | + ], | ||
107 | +}); | ||
108 | +// 项目打包后,进行性能分析 | ||
109 | +if (process.env.analyz_npm_config_report) { | ||
110 | + const BundleAnalyzerPlugin = require("webpack-bundle-analyzer") | ||
111 | + .BundleAnalyzerPlugin; | ||
112 | + prod.plugins.push(new BundleAnalyzerPlugin()); | ||
113 | +} | ||
114 | + | ||
115 | +module.exports = prod; |
rf-blog/package.json
0 → 100644
1 | +{ | ||
2 | + "name": "rf-blog", | ||
3 | + "version": "1.0.0", | ||
4 | + "author": "rf", | ||
5 | + "description": "A blog website sharing front-end technology", | ||
6 | + "keywords": [ | ||
7 | + "vue", | ||
8 | + "node", | ||
9 | + "koa", | ||
10 | + "mongodb" | ||
11 | + ], | ||
12 | + "main": "index.js", | ||
13 | + "scripts": { | ||
14 | + "dev:admin": "cross-env NODE_ENV_TYPE=admin webpack-dev-server --config build/webpack.dev.conf.js", | ||
15 | + "dev:client": "cross-env NODE_ENV_TYPE=client webpack-dev-server --config build/webpack.dev.conf.js", | ||
16 | + "build:admin": "cross-env NODE_ENV_TYPE=admin NODE_ENV=prod node build/build.js", | ||
17 | + "build:client": "cross-env NODE_ENV_TYPE=client NODE_ENV=prod node build/build.js", | ||
18 | + "analyz:admin": "cross-env analyz_npm_config_report=true npm run build:admin", | ||
19 | + "analyz:client": "cross-env analyz_npm_config_report=true npm run build:client", | ||
20 | + "server": "cross-env NODE_ENV=development nodemon code/server/index.js", | ||
21 | + "start": "pm2 start code/server/index.js", | ||
22 | + "stop": "pm2 stop code/server/index.js", | ||
23 | + "restart": "pm2 restart code/server/index.js" | ||
24 | + }, | ||
25 | + "license": "ISC", | ||
26 | + "devDependencies": { | ||
27 | + "babel-core": "^6.26.0", | ||
28 | + "babel-loader": "^7.1.2", | ||
29 | + "babel-plugin-transform-runtime": "^6.23.0", | ||
30 | + "babel-polyfill": "^6.26.0", | ||
31 | + "babel-preset-env": "^1.6.1", | ||
32 | + "babel-preset-es2015": "^6.24.1", | ||
33 | + "babel-preset-stage-2": "^6.24.1", | ||
34 | + "babel-register": "^6.26.0", | ||
35 | + "chalk": "^2.3.0", | ||
36 | + "compression-webpack-plugin": "^8.0.1", | ||
37 | + "cross-env": "^5.1.3", | ||
38 | + "css-loader": "^0.28.8", | ||
39 | + "css-minimizer-webpack-plugin": "^3.0.2", | ||
40 | + "file-loader": "^1.1.6", | ||
41 | + "friendly-errors-webpack-plugin": "^1.6.1", | ||
42 | + "html-webpack-plugin": "^5.3.2", | ||
43 | + "less": "^2.7.3", | ||
44 | + "less-loader": "^4.0.5", | ||
45 | + "mini-css-extract-plugin": "^2.2.0", | ||
46 | + "node-notifier": "^5.1.2", | ||
47 | + "nodemon": "^1.12.1", | ||
48 | + "ora": "^1.3.0", | ||
49 | + "postcss-loader": "^2.0.10", | ||
50 | + "rimraf": "^2.6.2", | ||
51 | + "style-resources-loader": "^1.4.1", | ||
52 | + "terser-webpack-plugin": "^5.1.4", | ||
53 | + "url-loader": "^0.6.2", | ||
54 | + "vue-loader": "^15.7.0", | ||
55 | + "vue-style-loader": "^4.1.3", | ||
56 | + "vue-template-compiler": "^2.5.13", | ||
57 | + "webpack": "^5.51.1", | ||
58 | + "webpack-bundle-analyzer": "^4.4.2", | ||
59 | + "webpack-cli": "^4.8.0", | ||
60 | + "webpack-dev-server": "^4.0.0", | ||
61 | + "webpack-merge": "^5.8.0" | ||
62 | + }, | ||
63 | + "dependencies": { | ||
64 | + "axios": "^0.17.0", | ||
65 | + "babel-polyfill": "^6.26.0", | ||
66 | + "busboy": "^0.2.14", | ||
67 | + "clipboard": "^2.0.8", | ||
68 | + "element-ui": "^2.0.11", | ||
69 | + "highlight.js": "^10.7.0", | ||
70 | + "ip": "^1.1.5", | ||
71 | + "js-md5": "^0.7.3", | ||
72 | + "jsonwebtoken": "^8.1.0", | ||
73 | + "koa": "^2.4.1", | ||
74 | + "koa-bodyparser": "^4.2.0", | ||
75 | + "koa-router": "^7.3.0", | ||
76 | + "koa-static": "^4.0.2", | ||
77 | + "log4js": "^2.4.1", | ||
78 | + "marked": "^0.3.12", | ||
79 | + "mongoose": "^4.13.9", | ||
80 | + "nprogress": "^0.2.0", | ||
81 | + "qs": "^6.5.1", | ||
82 | + "vue": "^2.5.13", | ||
83 | + "vue-color": "^2.8.1", | ||
84 | + "vue-lazyload": "^1.3.3", | ||
85 | + "vue-router": "^3.0.1", | ||
86 | + "vuex": "^3.0.1" | ||
87 | + } | ||
88 | +} |
rf-blog/postcss.config.js
0 → 100644
rf-blog/public/images/022d0c7ae8b9e.gif
0 → 100644
30.6 KB
rf-blog/public/images/026bfb9b62aa9.png
0 → 100644
3.77 KB
rf-blog/public/images/0547305faec2c.png
0 → 100644
2.42 KB
rf-blog/public/images/0ac18a435fb43.jpeg
0 → 100644
211 KB
rf-blog/public/images/0dc71df08cfbf.jpeg
0 → 100644
54 KB
rf-blog/public/images/0e4056fcc85b3.jpg
0 → 100644
25.9 KB
rf-blog/public/images/14f6acacad92b.jpg
0 → 100644
33 KB
rf-blog/public/images/1e4a605794d23.jpeg
0 → 100644
54 KB
rf-blog/public/images/1e969facc1f23.png
0 → 100644
884 Bytes
rf-blog/public/images/25ae929dc969d.jpeg
0 → 100644
65.2 KB
rf-blog/public/images/26585ac9c856e.jpg
0 → 100644
599 KB
rf-blog/public/images/26e9a8aec10dd.jpeg
0 → 100644
65.2 KB
rf-blog/public/images/2cae0e279699f.jpg
0 → 100644
220 KB
rf-blog/public/images/3c88c640eb581.png
0 → 100644
2.42 KB
rf-blog/public/images/3ddcfe3f856da.jpg
0 → 100644
19.5 KB
rf-blog/public/images/4c244338fa558.png
0 → 100644
3.77 KB
rf-blog/public/images/4db1fc002fc3b.jpeg
0 → 100644
65.2 KB
rf-blog/public/images/5fcdda186cdf6.jpeg
0 → 100644
57.8 KB
rf-blog/public/images/64ea7432d9d37.jpg
0 → 100644
185 KB
rf-blog/public/images/668d0e3fd8e85.jpeg
0 → 100644
65.2 KB
rf-blog/public/images/66b407544788.jpg
0 → 100644
149 KB
rf-blog/public/images/74a65b54995f3.jpeg
0 → 100644
57.8 KB
rf-blog/public/images/8127418141b63.jpeg
0 → 100644
65.2 KB
rf-blog/public/images/826cd18e18895.webp
0 → 100644
No preview for this file type
rf-blog/public/images/88b4903e27008.jpeg
0 → 100644
33.8 KB
rf-blog/public/images/8a58b622cbda1.jpeg
0 → 100644
211 KB
rf-blog/public/images/91ff78752a921.jpeg
0 → 100644
211 KB
rf-blog/public/images/96ea094016c1b.jpeg
0 → 100644
211 KB
rf-blog/public/images/98432b803c046.jpg
0 → 100644
68.2 KB
rf-blog/public/images/98b0af51c8431.jpeg
0 → 100644
211 KB
rf-blog/public/images/99f7fe0ba38a9.jpg
0 → 100644
28 KB
rf-blog/public/images/9ca054e6af227.jpg
0 → 100644
243 KB
rf-blog/public/images/a1abeea4e0e0e.jpeg
0 → 100644
211 KB
rf-blog/public/images/a1fa8b415d673.jpg
0 → 100644
28 KB
rf-blog/public/images/a3f91beded1ae.jpg
0 → 100644
291 KB
rf-blog/public/images/a72676c3536c2.jpg
0 → 100644
195 KB
rf-blog/public/images/afb2681ccc5ec.png
0 → 100644
167 KB
rf-blog/public/images/c9afe8db36631.jpg
0 → 100644
168 KB
rf-blog/public/images/ca9df952ddff4.jpeg
0 → 100644
65.2 KB
rf-blog/public/images/cacb478709284.jpeg
0 → 100644
211 KB
rf-blog/public/images/cf3472ebc95d4.jpeg
0 → 100644
34 KB
rf-blog/public/images/d27428aace5ee.jpeg
0 → 100644
211 KB
rf-blog/public/images/e078d010f74ba.jpeg
0 → 100644
33.8 KB
rf-blog/public/images/ed122c811a3c.jpg
0 → 100644
42.6 KB
rf-blog/public/images/f6c60cfa9c63a.jpg
0 → 100644
40 KB
rf-blog/public/images/f91a6d7b08ddd.jpeg
0 → 100644
211 KB
rf-blog/public/images/fdaa4dd9114fb.jpeg
0 → 100644
65.2 KB
rf-blog/static/.gitkeep
0 → 100644
File mode changed
rf-blog/static/project-structure.png
0 → 100644
30.7 KB
rf-blog/styles/theme.less
0 → 100644
1 | +/** | ||
2 | + * 变量样式 | ||
3 | + */ | ||
4 | +@mainColor: #333; // 主颜色 | ||
5 | +@thinColor: #555; // 描述色 | ||
6 | +@assistColor: #999; // 辅助色 | ||
7 | +@warningColor: #ff6c1a; // 提醒色 | ||
8 | +@errorColor: #fe3438; //错误、禁用色 | ||
9 | +@highlightColor: #009688; // 高亮色 | ||
10 | +@thinHighlightColor: #20b2aa; // 高亮浅色 | ||
11 | +@borderColor: #ededed; // 边框色 | ||
12 | +@borderBoldColor: #ccc; // 边框辅色 | ||
13 | +@cuttingLineColor: #f0f0f0; // 分割线色 | ||
14 | +@backgroundColor: rgba(233, 234, 237, 0.7); // 背景色 | ||
15 | +@thinBgColor: #f6f6f6; // 背景色 | ||
16 | + | ||
17 | +@baseSpH: 24px; // 基础左右间距 | ||
18 | +@baseSp: 20px; // 基础间距 | ||
19 | + | ||
20 | +@min-body-height: calc(~"100vh - 50px"); // 页面最小高度,去除顶部的高度 | ||
21 | + | ||
22 | +.ellipsis-line-clamp (@line: 1) { | ||
23 | + display: -webkit-box; | ||
24 | + text-overflow: ellipsis; | ||
25 | + -webkit-line-clamp: @line; | ||
26 | + -webkit-box-orient: vertical; | ||
27 | + overflow: hidden; | ||
28 | +} |
rf-blog/yarn.lock
0 → 100644
This diff could not be displayed because it is too large.
-
Please register or login to post a comment