likes
comments
collection
share

向全栈靠齐的前端分享内卷如此厉害,不拿点本事出来,他们都当前端是hello kity。程序员的思考总结,让众多初学者开箱

作者站长头像
站长
· 阅读数 51

背景与思考

前端在很多后端开发人员中,总是觉得没啥技术含量。尤其是在老java眼中,深深感觉存在严重的鄙视链。然后就是自己的职业规划,也不想一直做前端敲代码。毕竟自己的付出不少,也想收获属于自己的成就感。然后自己的横向发展就成了必然。

后端技术首推Node

  1. 前后端编程环境和语法一致,上手非常快。
  2. 轻量级,部署简单。
  3. 生态丰富,文档颇多,碰到问题,百度查询方便。
  4. 高效的异步I/O模型,易处理大并发和连接。

Node框架推荐Koa

向全栈靠齐的前端分享内卷如此厉害,不拿点本事出来,他们都当前端是hello kity。程序员的思考总结,让众多初学者开箱

  1. 相对于express,Koa更加的轻便,上手主打一个简单易学好用。
  2. 语法上它的中间件和前端的模块化很像,开发思路一致。
  3. 前端熟悉的async await,promise方式,很好的解决了多层嵌套,地狱回调问题。
  4. 借助 co 和 generator,很好地解决了异步流程控制和异常捕获问题。

学习推荐

我当初学习也是想看了一下官网,发现确实如介绍般的简单,但是对于入门者来说,有点简单的过分了。在此推荐阮一峰老师的网络日志(不是打广告,确实是我当初前端起步阶段的老师之一,受益匪浅)。

主要代码解析

项目结构

向全栈靠齐的前端分享内卷如此厉害,不拿点本事出来,他们都当前端是hello kity。程序员的思考总结,让众多初学者开箱

app.js源码

const Koa = require('koa');
const Router = require('koa-router');

// 跨域模块
var cors = require('koa2-cors');
//文件模块
const fs = require('fs');

const { historyApiFallback } = require('koa2-connect-history-api-fallback');
//静态文件加载
const serve = require('koa-static');
//路径管理
const path = require('path');

//koa-body对文件上传进行配置
const koaBody = require('koa-body')

//实例化koa
const app = new Koa();

app.use(historyApiFallback());

app.use(cors());
const router = new Router();
const bodyParser = require('koa-bodyparser');
const controller = require('./controller');
app.use(async (ctx, next) => {
  ctx.set("Access-Control-Allow-Origin", "*")
  await next()
})
app.use(bodyParser());
// 处理跨域

app.use(controller());

app.use(koaBody({
	multipart:true,
	formidable:{
		maxFileSize:50000*1024*1024, //设置上传文件大小最大限制,默认为2m,2000*1024*1024
		keepExtensions: true // 保留文件拓展名
	}
}))


// 1.主页静态网页 把静态页统一放到public中管理
const main = serve(path.join(__dirname) + '/build');

//配置路由
app.use(router.routes()).use(router.allowedMethods());

const port = 5000;
app.use(main)

app.listen(port, () => {
	console.log(`server started on ${port}`)
});

依赖包讲解

const Koa = require('koa');

这是引入koa框架,这是重中之重,只有引入了才能够在项目中使用。在项目中会通过new来实例化,比如代码中的const app = new Koa();。然后再定义一个监听的端口,app.listen()方法来进行监听。

const fs = require('fs');

这是koa自带的文件模块,如果你想对系统文件进行读取,修改。或者文件上传保存,都离不开整个fs模块,fs.readFilefs.readFileSync

const koaBody = require('koa-body')

Koa-body是基于Koa的中间件模型构建的,主要用于文件上传,以及在中间件中对请求体的解析。对请求体的解析中,我们主要使用koa-bodyparser,它可以将http请求中的数据,解析成我们需要的JavaScript对象。

const Router = require('koa-router');
```门口
Router模块就是路由,此路由和前端路由有差异,此路由可以理解为前端理解的api接口,只是叫法不一样而已。

```js
const { historyApiFallback } = require('koa2-connect-history-api-fallback');

koa2-connect-history-api-fallback是一个专门为 Koa2 框架设计的中间件,它的主要目的是在SPA应用中处理URL重定向,尤其是在用户直接输入或者通过后退按钮访问非根URL时。 这个中间件会将所有未匹配到特定路由的请求转发到默认HTML文件(通常是 index.html),确保SPA可以正常启动并处理路由。还记得当初自己终于完成了一整套的项目线上部署,可把自己开心坏了,但是同事在一次用着发现,刷新页面时,页面直接变成了404,你说吓不吓人。盘查一下发现自己在vue前端中的路由为何在后端中变成了一个get请求。

向全栈靠齐的前端分享内卷如此厉害,不拿点本事出来,他们都当前端是hello kity。程序员的思考总结,让众多初学者开箱

controller.js源码

const fs = require('fs')

// add url-route in /controllers:

function addMapping (router, mapping) {
  for (var url in mapping) {
    if (url.startsWith('GET ')) {
      var path = url.substring(4)
      router.get(path, mapping[url])
      // console.log(`register URL mapping: GET ${path}`);
    } else if (url.startsWith('POST ')) {
      var path = url.substring(5)
      router.post(path, mapping[url])
      // console.log(`register URL mapping: POST ${path}`);
    } else if (url.startsWith('PUT ')) {
      var path = url.substring(4)
      router.put(path, mapping[url])
      // console.log(`register URL mapping: PUT ${path}`);
    } else if (url.startsWith('DELETE ')) {
      var path = url.substring(7)
      router.del(path, mapping[url])
      // console.log(`register URL mapping: DELETE ${path}`);
    } else {
      // console.log(`invalid URL: ${url}`);
    }
  }
}

function addControllers (router, dir) {
  fs.readdirSync(__dirname + '/' + dir)
    .filter(f => {
      return f.endsWith('.js')
    })
    .forEach(f => {
      // console.log(`process controller: ${f}...`);
      let mapping = require(__dirname + '/' + dir + '/' + f)
      addMapping(router, mapping)
    })
}

module.exports = function (dir) {
  let controllers_dir = dir || 'controllers',
    router = require('koa-router')()
  addControllers(router, controllers_dir)
  return router.routes`()`
}

controller讲解

在这个controller中,我们主要做了一件事,那就是路由映射逻辑处理。

function addControllers()

这个方法用于自动加载指定目录下的js文件,它使用fs.readdirSync读取目录,然后通过filterforEach方法来处理每个文件名,只选择以.js结尾的文件,并将这些文件的路由映射添加到router

function addMapping()

这个函数用于将HTTP方法(如GET、POST、PUT、DELETE)和对应的URL路径映射到处理函数上。它遍历传入的mapping对象,根据URL的前缀(如GET POST 等)来确定使用哪个HTTP方法,并将路径和处理函数注册到router上。

controllers下路由POST方法

const jwt = require('jsonwebtoken')
module.exports = {
  'POST /login': async (ctx, next) => {
    var key = ctx.request.body
    if (key.username && key.password) {
      return new Promise(function (resolve, reject) {
        var MongoClient = require('mongodb').MongoClient
        var MG_URL = 'mongodb://***********/'
        MongoClient.connect(
          MG_URL,
          { useUnifiedTopology: true },
          function (err, db) {
            if (err) throw err
            var dbo = db.db('website')
            dbo
              .collection('user')
              .find({ username: key.username, password: key.password })
              .toArray(function (err, result) {
                if (result.length) {
                  const TOKEN = jwt.sign(
                    {
                      name: result[0].username
                    },
                    'MY_TOKEN',
                    { expiresIn: '24h' }
                  )
                  let data = {
                    username: result[0].username,
                    token: TOKEN
                  }
                  ctx.response.body = {
                    result: 1,
                    status: 200,
                    code: 200,
                    data: data
                  }
                } else {
                  ctx.response.body = {
                    result: 0,
                    status: 200,
                    code: 0,
                    msg: '该用户不存在'
                  }
                }

                if (err) throw err
                resolve(result)
                db.close()
              })
          }
        )
      })
    } else {
      ctx.response.body = {
        result: 0,
        status: 200,
        code: 0,
        msg: 'error'
      }
    }
  }
}

这是一个登录的login方法,用POST进行请求。在这个地方用了一下mongodb数据库存储。在api接口请求login方法时,获取请求中所携带的参数进行解析,并判断此用户以及密码是否在我们的数据库中,如果存在返回成功的提示以及相关数据,如果错误,则提示错误。当然如果还不会数据库的使用,可以去除数据库相关部分,直接用本地json数据,这个比较简单,就是fs读取本地json文件,然后返回给api接口。不在此做详细说明。

controllers下路由GET方法

module.exports = {
  'GET /getNews': async (ctx, next) => {
    return new Promise(function (resolve, reject) {
      var MongoClient = require('mongodb').MongoClient
      var MG_URL = 'mongodb://********'
      MongoClient.connect(
        MG_URL,
        { useUnifiedTopology: true },
        function (err, db) {
          if (err) throw err
          var dbo = db.db('website')
          dbo
            .collection('news')
            .find({})
            .toArray(function (err, result) {
              if (result.length) {
                ctx.response.body = {
                  result: 1,
                  status: 200,
                  code: 1,
                  data: result
                }
              } else {
                ctx.response.body = {
                  result: 0,
                  status: 200,
                  code: 0,
                  msg: '暂无数据'
                }
              }
              if (err) throw err
              resolve(result)
              db.close()
            })
        }
      )
    })
  }
}

这是一个获取新闻的getNews方法,用GET请求。主要用来查询数据库中的list的信息。DELETE,PUT等方法不在此处贴出更多源码。

数据库首推mondodb

向全栈靠齐的前端分享内卷如此厉害,不拿点本事出来,他们都当前端是hello kity。程序员的思考总结,让众多初学者开箱

  1. 面向集合存储,易存储对象类型的数据。
  2. 模式自由。
  3. 高性能、易部署、易使用。
  4. 文档型数据结构灵活,适应不同类型的数据。
  5. 支持动态查询。
  6. 非关系型数据库。

学习推荐

为啥选择MongoDB数据库,相对来说操作还是比较简单,而且存储的数据类型都是对象的形式,前端可以轻松拿捏。在这里直接推荐菜鸟的mongodb教程,看名字就知道,这是一个适合菜鸟初步学习的地方。讲解也比较详细,学完上面的内容,用mongodb数据库进行基本的数据存储和操作已经没有问题了。

总结

通过以上的分享,其实对大多数前端来说,开启一个简单的后端服务和接口请求,已经可以开箱即用了。想要完整的学习代码,也可以私信我。虽然不是很完善,但麻雀虽小五脏俱全。

思考

在前端行业已经接7载。曾经害怕java的恐惧而转入前端行业,所有受到鄙视也是有一部分原因吧,毕竟自己曾经年少无知,害怕吃苦选择了一个稍微简单的前端就稀里糊涂的就业了,保命要紧。但是在后来又想改变这个鄙视链,自己就开始了nodejs的学习,python的学习,数据库MongoDB,MySQL,PostgreSQL。学不完,压根学不完。 后面再无尽的内卷中,有的做开发不是自己的路,也想做做管理,毕竟前端做到前端组长就已经是极限了,在公司以java为尊的环境下,想做更高的级别几乎不可能。毕竟自己算是耿直死宅,不善交际,讨不到大领导的喜爱。然后又开始了原型的学习,PMP项目管理证书的考取(进行中),也曾有单独出去做产品的想法,面试过一个,但是与自己的预期薪资相差太大,没去。

转载自:https://juejin.cn/post/7415654362993639439
评论
请登录