欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

多人博客网站第一版上线啦,欢迎围观,吐槽

程序员文章站 2022-05-18 21:09:34
网站地址 代码开源地址 时间大概是在两年前吧,那时候刚接触到 nodejs,立志成为一名优秀全栈攻城狮的我,心心念着得有一个属于自己的网站。于是说干就干,一边学着一边捣鼓的各种花样。 曾梦想仗剑走天涯,然而后面因为工作忙就没去成,我的这个网站也因为各种原因迟迟没能上线,这其中也做过了好几个版本,一开 ......

时间大概是在两年前吧,那时候刚接触到 nodejs,立志成为一名优秀全栈攻城狮的我,心心念着得有一个属于自己的网站。于是说干就干,一边学着一边捣鼓的各种花样。

曾梦想仗剑走天涯,然而后面因为工作忙就没去成,我的这个网站也因为各种原因迟迟没能上线,这其中也做过了好几个版本,一开始是前后端分离的,前端使用 angularjs(后面又改成了 vue),后端是 nodejs + mongodb,等这一版的也差不多做好的时候,感觉不是自己想要的样子,所以也就没上线。到后面觉得 golang 好玩,又去用它写了一些后端的接口。

到了今年三月份的时候,终于发现网站这个目标确实是拖了很长时间了。抽时间好好想了下自己想要做什么,决定抛弃之前的那套代码,不用自己比较熟悉的 前后端分离,vue 等技术,而使用 ejs 模板渲染,nodejs 的 sequelize orm 库,使用 session 而不是 jwt 来持久化用户登录等。

代码基本上是晚上抽时间写的,后面因为加班,也停了一段时间。中途如果遇到一些问题,有时候进度也会耽搁个几天。再加上一些设计以及前端展示上的修修补补,导致整个项目也是花了比较长的时间。好在是一个萝卜一个坑的慢慢踩了过来,现在觉得网站终于可以上线了,后面要做的工作就是完善网站的一些没有功能(包括后端的管理界面等),修改一些的实现方式(准确的说就是优化代码),以及更重要的是丰富网站内容,也就是写博客记录一些成长路上的风景吧。

到此为止,废话也不多说了,代码也开源到了github上,有兴趣的朋友可以去围观一下,欢迎 start,也欢迎在 issue 里提出,指正各种问题。

说一下项目的运行方式吧,首先要 nodejs 环境,需要全局安装 gulp、nodemon 等包,然后数据存储使用的 mysql + redis。等环境准备好了之后,就需要添加一些配置文件,比如在 config/env/ 下创建 development.js 文件,里面需要提供发邮箱的邮件地址,以及 github 第三方登录的 clientid 等。

module.exports = {
	email: {
		account: '',
		pwd: ''
	},
    github: {
        clientid: '',
        clientsecret: '',
        callbackurl: ``
    }
};

接下来就是安装开发运行所需要的各种依赖包吧,跑一下 yarn install 就行了,这个过程可能需要花个几分钟时间。
等到所有的包都安装完毕后,直接跑 npm start 命令,看到 终端上显示 所有的 gulp 任务 finished,server is running at port 3000 的时候,就可以打开浏览器访问 localhost:3000 了。
接下来贴上一些项目里面的代码吧,如果上不了首页就悲剧了。

 1 require('dotenv').config()
 2 
 3 const express = require('express')
 4 const passport = require('passport')
 5 const models = require('./config/db/model')
 6 const port = process.env.port
 7 
 8 const app = express()
 9 
10 require('./config/passport')(passport)
11 require('./config/express')(app, passport)
12 require('./config/routes')(app, passport)
13 
14 models
15     .sequelize
16     .sync()
17     .then(() => {
18         app.listen(port, () => {
19             console.log(`server is running at port ${port}`)
20         })
21     })
22 
23 module.exports = app

 



gulp 的打包配置

  1 // vinyl 是一个简单的描述文件的元数据对象
  2 // https://github.com/gulpjs/vinyl
  3 const path = require('path')
  4 const gulp = require('gulp')
  5 const del = require('del')
  6 const glob = require('glob')
  7 const babelify = require('babelify')
  8 const runsequence = require('run-sequence')
  9 const plumber = require('gulp-plumber')
 10 const notify = require('gulp-notify')
 11 const gulpif = require('gulp-if')
 12 const sass = require('gulp-sass')
 13 const debug = require('gulp-debug')
 14 const cached = require('gulp-cached')
 15 const remember = require('gulp-remember')
 16 const autoprefixer = require('gulp-autoprefixer')
 17 const sourcemaps = require('gulp-sourcemaps');
 18 const size = require('gulp-size');
 19 const cssnano = require('gulp-cssnano')
 20 const uglify = require('gulp-uglify')
 21 const rename = require('gulp-rename')
 22 const htmlmin = require('gulp-htmlmin')
 23 const imagemin = require('gulp-imagemin')
 24 const browserify = require('browserify')
 25 const source = require('vinyl-source-stream');
 26 const buffer = require('vinyl-buffer');
 27 const rev = require('gulp-rev');
 28 const watchify = require('watchify')
 29 const lazypipe = require('lazypipe')
 30 const revcollector = require('gulp-rev-collector');
 31 const es = require('event-stream')
 32 const argv = require('yargs').argv
 33 
 34 // 将打包后的静态资源 放到nginx服务器上
 35 const bundleassetsdir = argv.build_mode === 'deploy' && argv.assets_path ? argv.assets_path : './public/static/'
 36 const jsassetsdir = path.join(bundleassetsdir, 'js')
 37 const cssassetsdir = path.join(bundleassetsdir, 'css')
 38 const imgassetsdir = path.join(bundleassetsdir, 'image')
 39 const revassetsdir = path.join(bundleassetsdir, 'rev')
 40 const htmlassetsdir = path.join('./app/view')
 41 
 42 const autoprefixer_browsers = [
 43     'ie >= 10',
 44     'ff >= 30',
 45     'chrome >= 34',
 46     'safari >= 7',
 47     'opera >= 23'
 48 ];
 49 
 50 const jschannel = lazypipe()
 51     .pipe(uglify)
 52     .pipe(gulp.dest, jsassetsdir)
 53 
 54 let watch = false
 55 
 56 function getentryfiles (path, option) {
 57     return glob.sync(path, option)
 58 }
 59 
 60 /**
 61  * 打包js任务
 62  * @param {object} bundle 各入口文件的browserify对象
 63  * @param {string} filename 入口文件名
 64  * @return {stream} stream 对象
 65  */
 66 function jstask ({ bundle, filename }) {
 67     return bundle
 68     .bundle()
 69     .pipe(plumber({
 70         errorhandler: notify.onerror('error: <%= error.message %>')
 71     }))
 72     .pipe(source(filename))
 73     // 代替 gulp-streamify,来转换 vinyl 流
 74     .pipe(buffer())
 75     .pipe(rename({ dirname: '' }))
 76     .pipe(sourcemaps.init())
 77     .pipe(debug({ title: 'script' }))
 78     .pipe(size({ title: 'script' }))
 79     .pipe(sourcemaps.write(''))
 80     .pipe(gulp.dest(jsassetsdir))
 81 }
 82 
 83 /**
 84  * 如果一个文件被删除了,则将其忘记
 85  * @param {*} event
 86  */
 87 function watchdel (event) {
 88     if (event.type === 'deleted') {
 89         // gulp-cached 的删除 api
 90         delete cached.caches.scripts[event.path]
 91         // gulp-remember 的删除 api
 92         remember.forget('scripts', event.path)
 93     }
 94 }
 95 
 96 gulp.task('style', () => {
 97     return gulp.src('./src/scss/*.scss')
 98         .pipe(plumber({
 99             errorhandler: notify.onerror('error: <%= error.message %>')
100         }))
101         // .pipe(cached('style-task'))
102         .pipe(sourcemaps.init())
103         .pipe(sass())
104         .pipe(cssnano({
105             // 不修改 z-index
106             safe: true
107         }))
108         .pipe(autoprefixer(autoprefixer_browsers))
109         .pipe(debug({ title: 'style' }))
110         // .pipe(remember('style-task'))
111         .pipe(size({ title: 'style' }))
112         .pipe(sourcemaps.write(''))
113         .pipe(gulp.dest(cssassetsdir))
114 })
115 
116 gulp.task('script', () => {
117     let entryjs = getentryfiles('./src/js/*.js')
118     let bundletasks = entryjs.map(filename => {
119         const bundle = browserify({
120             entries: [filename],
121             cache: {},
122             packagecache: {},
123             plugin: [watch ? watchify : null],
124             transform: babelify
125         })
126         if (watch) {
127             bundle.on('update', function () {
128                 jstask.call(null, { bundle, filename })
129             })
130         }
131         return { bundle, filename }
132     })
133     return es.merge(bundletasks.map(jstask));
134 })
135 
136 gulp.task('image', () => {
137     return gulp.src(['./src/image/*', './src/image/**/*'])
138         .pipe(cached('image-task'))
139         .pipe(imagemin([
140             imagemin.gifsicle({ interlaced: true }),
141             imagemin.jpegtran({ progressive: true }),
142             imagemin.optipng({ optimizationlevel: 5 }),
143             imagemin.svgo({
144                 plugins: [
145                     { removeviewbox: true },
146                     { cleanupids: false }
147                 ]
148             })
149         ]))
150         .pipe(debug({ title: 'image' }))
151         .pipe(remember('image-task'))
152         .pipe(size({ title: 'image' }))
153         .pipe(gulp.dest(imgassetsdir))
154 })
155 
156 gulp.task('html', () => {
157     return gulp.src('./src/page/**/*.html')
158         .pipe(cached('html-task'))
159         .pipe(debug({ title: 'html' }))
160         .pipe(remember('html-task'))
161         .pipe(gulp.dest(htmlassetsdir))
162 
163 })
164 
165 gulp.task('rev', () => {
166     return gulp.src([path.join(jsassetsdir, '*.js'), path.join(cssassetsdir, '*.css')])
167         .pipe(rev())
168         .pipe(gulpif('*.js', jschannel()))
169         .pipe(gulpif('*.css', gulp.dest(cssassetsdir)))
170         .pipe(rev.manifest({
171             merge: true
172         }))
173         .pipe(gulp.dest(revassetsdir))
174 })
175 
176 gulp.task('rev-collector', () => {
177     return gulp.src([path.join(revassetsdir, '*.json'), path.join(htmlassetsdir, '*.html')])
178         .pipe(revcollector({
179             replacereved: true
180         }))
181         .pipe(htmlmin({
182             removecomments: true,
183             collapsewhitespace: true,
184             collapsebooleanattributes: true,
185             removeattributequotes: true,
186             removeredundantattributes: true,
187             removeemptyattributes: true,
188             removescripttypeattributes: true,
189             removestylelinktypeattributes: true,
190             removeoptionaltags: true
191         }))
192         .pipe(size({ title: 'html' }))
193         .pipe(gulp.dest(htmlassetsdir))
194 })
195 
196 gulp.task('clean', () => del([bundleassetsdir, htmlassetsdir], { force: true }))
197 
198 gulp.task('style:watch', () => {
199     const watcher = gulp.watch(['./src/scss/**/*.scss'], ['style'])
200     watcher.on('change', watchdel)
201 })
202 
203 gulp.task('image:watch', () => {
204     const watcher = gulp.watch(['./src/image/**/*'], ['image'])
205     watcher.on('change', watchdel)
206 }
207 )
208 gulp.task('html:watch', () => {
209     const watcher = gulp.watch(['./src/page/**/*.html'], ['html'])
210     watcher.on('change', watchdel)
211 })
212 
213 gulp.task('watch', () => {
214     watch = true
215     runsequence(
216         'clean',
217         ['script', 'style', 'html', 'image'],
218         ['style:watch', 'html:watch', 'image:watch']
219     )
220 })
221 
222 gulp.task('build', cb => {
223     watch = false
224     return runsequence(
225         'clean',
226         ['script', 'style', 'html', 'image'],
227         'rev',
228         'rev-collector',
229         cb
230     )
231 })
232 
233 gulp.task('default', ['build'])

最后再一次贴上网站以及开源地址,欢迎各路大佬围观,吐槽,指正。