从零搭建一个全栈项目(三)—— 打包优化及登录注册功能

540 阅读3分钟

一、内容简介

前面已经基本的实现了页面的运行及前后端接口调试,那么这部分就主要实现一些项目中比较重要的部分,webpack提取公共部分代码及项目中的登录注册(session)。

二、webpack优化

在我们做项目时经常会有一种情况,就是我们可能多个页面会依赖到第三方库或者我们会自己封装一些项目中的公共代码,在每个页面中使用import进行调用,那么这时候,如果我们还是想前面一样,直接进行打包,虽然运行也是可以的,但是由于我们重复的调用,会导致打包后的代码中公共部分重复打包,打包出来的代码特别大。比如我这个项目中在多个页面中使用jquery,这时候打包出来的js就会很大,打开打包后的文件看一下会发现jquery被重复打包了。那么我们就需要提取出这些公共的代码。
在webpack4中已经不支持CommonsChunkPlugin了,取而代之的是SplitChunksPlugin,我这里目前是配置了第三方库( vendors ) 和 项目中的公共js( common ):

  build/webpack.config.js
  
  optimization: {
    runtimeChunk: {
      name: 'manifest'
    },
    splitChunks: {
      cacheGroups: {
        chunks: 'async',
        common: {
          name: 'common',
          chunks: 'all',
          minSize: 1,
          priority: 0
        },
        vendors: {
          name: "vendors",
          chunks: "all",
          priority: 10,
          test: /[\\/]node_modules[\\/]/
        },
        default: {
          minChunks: 2,
          priority: -20,
          reuseExistingChunk: true
        }
      }
    }
  }

配置好以后我还在webpack的 HtmlWebpackPlugin 设置了 chunks: 例如 login.js

new HtmlWebpackPlugin({
  template: './pages/login/index.html',
  filename: 'html/login.html',
  chunks: ['login', 'manifest', 'vendors', 'common']
})

另外还安装了几个其他的webpack插件,BundleAnalyzerPlugin、CleanWebpackPlugin、 UglifyJsPlugin等,不过起到对代码分离提取作用的还是前面的SplitChunksPlugin。配置了这个打包后我们就会发现打包后的js中多了common.[hash].js 和 vendors.[hash].js 再看我们的页面js,例如 login.js。

;(window.webpackJsonp = window.webpackJsonp || []).push([
  ['login'],
  [],
  [['./pages/login/index.js', 'manifest', 'vendors', 'common']]
])

会发现我们的jquery和axios是打包在vendors 中,还有项目中的公共代码会包在common中,这时候发现打包后的总大小比之前小了很多。目前webpack的优化就做了这么些(能力有限),我最近也还在在学习webpack,后面如果有了更好的方法也会对代码进行继续的优化。

三、注册功能

这里我先简单介绍一下注册功能,因为比较简单,只是请求接口,然后在数据库插入了一条数据而已,而链接数据库和接口调试已经在前面实现了,所以直接新加一个注册接口即可:

server/router/user.js
// 注册功能
if (method === 'POST' && req.path === '/api/user/register') {
    const { account, password } = await getPostData(req)
    return registerUser(account, password).then(() => {
      return new SuccessModel({
        msg: '注册成功'
      })
    })
}

server/controller/user.js
const registerUser = (account, password) => {
  const s = '`password`'
  const sql = `insert into users(username,${s},realname)values('${account}', '${password}', '');`
  return exec(sql)
}

三、登录功能

先简单介绍一下我的实现思路,登录功能我是使用的session,当用户第一次访问时创建一个id(我使用了userId)做唯一标识,并将userId存入cookie中,后续如果用户登录成功后,将用户登录信息(username等)存入session中,这样当我们继续访问其他页面时,只要拿到cookie中存入的userId,然后到session中获取实际的用户信息即可知道用户的登录状态和用户信息。
下面我们来分步实现一下:

  1. 在代码中新建一个 SESSION_DATA = {} 用于存储session数据,然后在app.js中,当用户发起网络请求时判断用户的cookie中有没有userId, 如果有,则说明不是第一次进入,这时候继续判断用户的登录状态或者用户的信息;如果没有userId,说明用户第一次进入,这时创建一个唯一标识,并存入cookie中。
server/app.js

// session 数据
const SESSION_DATA = {}

let userId = req.cookie.userid
  if (userId) {
    if (!SESSION_DATA[userId]) {
      SESSION_DATA[userId] = {}
    }
  } else {
    userId = `${Date.now()}_${Math.random()}`
    // 设置cookie
    res.setHeader(
      'Set-Cookie',
      `userid=${userId}; path=/; httpOnly; expires=${getCookieExpiress()}`
    )
    SESSION_DATA[userId] = {}
  }
 req.session = SESSION_DATA[userId]
  1. 当用户登录后,直接向session中存入用户登录信息:
server/router/user.js

  if (method === 'POST' && req.path === '/api/user/login') {
    try {
      const postData = await getPostData(req)
      if (postData.account && postData.password) {
        const userData = await getUser(postData)
        // 设置sessionData
        req.session.username = userData[0].username
        return new SuccessModel(userData[0])
      }
    } catch (err) {
      return new ErrorModel('登录失败')
    }
  }
  1. 添加一个检验登录的接口,判断用户的登录状态,如果有返回用户信息,否则返回尚未登录。
server/router/user.js

  // 判断登录状态
  if (method === 'GET' && req.path === '/api/user/loginCheck') {
    if (req.session.username) {
      const userInfo = await getUser('', req.session.username)
      return new SuccessModel(userInfo[0])
    }
    return new ErrorModel('尚未登录')
  }

这样我们就实现了简单的登录功能,这里因为cookie中可能会暴露一些用户信息,比如username等,所以我们生成一个唯一的id做识别,然后将这个唯一的id存入cookie,每次请求接口的时候通过这个id在session中拿到用户信息。

四、总结

本章介绍了

  1. 利用webpack对代码进行优化;
  2. 登录注册功能的实现;

下一章主要内容:

  1. 丰富项目内容(发布编辑查看博客);
  2. 代码中其他部分的优化;

五、最后

GitHub地址:戳这里

本项目仅为学习交流使用,如果有小伙伴有更好的建议欢迎提出来大家一起讨论,另外感兴趣的小伙伴就点个star吧! ^_^