多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
[TOC] # 入口 如果需要编译 ES6 ~~~ // start.js require('@babel/register') require("@babel/polyfill") require('./server/index') ~~~ 中间件 ~~~ import bodyParser from 'koa-bodyparser' import logger from 'koa-logger' export const addBodyParser = app => { app.use(bodyParser()) } export const addLogger = app => { app.use(logger()) } ~~~ 入口文件 ~~~ const Koa = require('koa') const {resolve} = require('path') const {connect, initSchemas, initAdmin} = require('./database/init') const R = require('ramda') const MIDDLEWARES = ['common', 'router'] // 1 MIDDLEWARES每一项依次执行R.map的一个回调参数 // 2 从右往左执行R.compose的参数 // 3 执行 name = > resolve(),返回文件路径 // 4 将上一步返回的结果作为参数,执行require('文件路径'),返回 { addBodyParser: [Function: addBodyParser], addLogger: [Function: addLogger]} // 5 将上一步返回的结果作为参数,执行R.forEachObjIndexed,遍历参数的每一项,执行 addBodyParser(app), addLogger(app) const useMiddlewares = (app) => { R.map( R.compose( R.forEachObjIndexed( initWith => initWith(app) ), require, name => resolve(__dirname, `./middleware/${name}`) ) )(MIDDLEWARES) } ;(async() => { await connect() // 连接数据库 initSchemas() // 导入Model const app = new Koa() await useMiddlewares(app) // 传入 Koa实例给中间件初始化 app.listen(8888) })() ~~~ <br> # sequelize事务 ~~~javascript sequelize.transaction().then(transaction => { // 开启事务 let finished = 0; let sum = save.length; for (let i = 0; i < save.length; i++) { achievementModel.findOrCreate({ // 查询记录是否存在,不存在则创建记录 where: { userId: userId, achievementId: save[i].achievementId, receiveTime: save[i].receiveTime, effective: 1 }, transaction: transaction }).spread((achi, create) => { finished++; if (finished == sum) { transaction.commit().then(() => { // 提交事务 res.json({ result: 1, msg: '成功' }); }); } }).catch(err => { finished++; if (finished == sum) { transaction.rollback().then(() => { // 出现错误,回滚事务 resERROR(err, res); }); } }); } }); ~~~ <br> ## 需要登录 ~~~javascript exports.userRequired = function (req, res, next) { if (!req.session || !req.session.user || !req.session.user._id) { return res.status(403).send('forbidden!'); } next(); } ~~~ <br> # 错误中间件 ~~~javascript exports.errorPage = function (req, res, next) { res.render404 = function (error) { return res.status(404).render('notify/notify', { error: error }); }; res.renderError = function (error, statusCode) { if (statusCode === undefined) { statusCode = 400; } return res.status(statusCode).render('notify/notify', { error: error }); }; next(); }; ~~~ # 自动加载 参考 [https://zhuanlan.zhihu.com/p/26865999](https://zhuanlan.zhihu.com/p/26865999) 如果浏览器不认识 `<script type="xxx">`中的属性,里面的内容不会执行,因此,如果浏览器不支持 nomodule 属性,需要将其删除 ## 均以跨域资源共享方式载 module 脚本都是通过跨域资源共享的方式载入的。这意味着载入的 module 脚本必须返回正确的CORS头 ~~~js <!-- This will not execute, as it fails a CORS check --> <script type="module" src="https://….now.sh/no-cors"></script> <!-- This will not execute, as one of its imports fails a CORS check --> <script type="module"> import 'https://….now.sh/no-cors'; addTextToBody("This will not execute."); </script> <!-- This will execute as it passes CORS checks --> <script type="module" src="https://….now.sh/cors"></script> ~~~ ## 默认延迟 ~~~js <!-- This script will execute after… --> <script type="module" src="1.js"></script> <!-- …this script… --> <script src="2.js"></script> <!-- …but before this script. --> <script defer src="3.js"></script> ~~~ 顺序应该是 2.js, 1.js, 3.js。 脚本阻塞HTML加载是非常糟糕的情况。 你可以为脚本标签添加一个 defer 属性来防止页面阻塞发生,同时也会使得这段脚本在文档完成解析之后才会运行。默认的,module 类型的脚本的加载也类似于添加 defer 属性的脚本 - 毕竟我们毫无理由让这些脚本阻塞页面的加载。 module 脚本与添加 defer 属性的脚本使用相同的执行队列。 ## 代码 ``` // index.html <script type="module"> import("/scripts/index.js").then((_) => { console.log(_.default); }) </script> <script type="nomodule" src="https://cdn.bootcss.com/systemjs/3.1.6/system.js"></script> <script type="nomodule"> System.import("/scripts/index-bundle.js").then((_) => { console.log(_.default); }) </script> ``` ``` // .babelrc { "presets": [ [ "@babel/preset-env", { "modules": "systemjs" } ] ] } ```