react 服务端渲染项目相关配置(typescript + nextjs + koajs + log4js + crypto + jest)

这是一个基于脚手架 create-next-app 的应用

// package.json

"scripts": {
    "dev": "node ./server.js",
    "build": "next build",
    "start": "next start",
    "test": "jest"
  },
  "dependencies": {
    "@zeit/next-css": "^1.0.1",
    "@zeit/next-less": "^1.0.1",
    "classnames": "^2.2.6",
    "got": "^11.8.1",
    "js-cookie": "^2.2.1",
    "koa": "^2.13.0",
    "less": "^4.0.0",
    "moment": "^2.29.1",
    "next": "10.0.3",
    "next-compose-plugins": "^2.2.1",
    "querystring": "^0.2.0",
    "rc-notification": "^4.5.4",
    "react": "17.0.1",
    "react-dom": "17.0.1",
    "rmc-dialog": "^1.1.1",
    "umi-request": "^1.3.5"
  },
  "devDependencies": {
    "@types/classnames": "^2.2.11",
    "@types/jest": "^26.0.19",
    "@types/js-cookie": "^2.2.6",
    "@types/koa": "^2.11.6",
    "@types/log4js": "^2.3.5",
    "@types/next": "^9.0.0",
    "@types/node": "^14.14.14",
    "@types/react": "^17.0.0",
    "babel-plugin-module-resolver": "^4.1.0",
    "jest": "^26.6.3",
    "ts-jest": "^26.4.4",
    "ts-node": "^9.1.1",
    "typescript": "^4.1.3"
  }
// tsconfig.json
{
  "compilerOptions": {
    "target": "esnext",
    "module": "esnext",
    "types": [
      "node"
    ],
    "moduleResolution": "node",
    "lib": [
      "dom",
      "es2018"
    ],
    "allowSyntheticDefaultImports": true,
    "noImplicitAny": true,
    "noUnusedLocals": true,
    "removeComments": true,
    "resolveJsonModule": true,
    "strict": true,
    "jsx": "preserve",
    "baseUrl": "./",
    "paths": {
      "@/public/*": [
        "public/*"
      ],
      "@/*": [
        "src/*"
      ],
      
    },
    "typeRoots": [
      "src/**/*.d.ts"
    ],
    "allowJs": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
    "noEmit": true,
    "esModuleInterop": true,
    "isolatedModules": true
  },
  "include": [
    "next-env.d.ts",
    "node_modules/@types",
    "**/*.ts",
    "**/*.tsx"
  ],
  "exclude": [
    "node_modules"
  ]
}
// next-env.d.ts

/// <reference types="next" />
/// <reference types="next/types/global" />

declare module '*.css';
declare module '*.jpg';
declare module '*.png';
declare module '*.gif';

// 测试模块
declare var test: any;
declare var expect: any;

declare var global: {
  pin: string;
}

 

// next.config.js

const withPlugins = require("next-compose-plugins");
const withCSS = require("@zeit/next-css");
const withLess = require("@zeit/next-less");

const config = {
  // all your options here
  cssModules: false
};

module.exports = withPlugins([withLess, withCSS], config);
// server.js

const Koa = require('koa')
const next = require('next')

const dev = process.env.NODE_ENV === 'production'
const app = next({dev})
const handle = app.getRequestHandler()

app.prepare().then(() => {
  const server = new Koa()
  server.use(async (ctx, next) => {
    await handle(ctx.req, ctx.res)
    ctx.respond = false
    next()
  })

  server.listen(3000, () => {
    console.log('server is running at http://localhost:3000')
  })
})
// Log4Js.ts

import log4js from "log4js";

log4js.configure({
  appenders: {
    logFile: {
      type: "dateFile",
      filename: "./logs/logFile", // 你要写入日志文件的路径
      alwaysIncludePattern: true, // 将模式包含在当前日志文件的名称及其备份中
      pattern: "yyyy-MM-dd-hh.log",
      encoding: "utf-8",
      maxLogSize: 10240, // 文件最大存储空间
    },
    logErrorFile: {
      type: "dateFile",
      filename: "./logs/logFile", // 你要写入日志文件的路径
      alwaysIncludePattern: true, // 将模式包含在当前日志文件的名称及其备份中
      pattern: "yyyy-MM-dd-hh.error.log",
      encoding: "utf-8",
      maxLogSize: 10240, // 文件最大存储空间
    },
    apiLogFile: {
      type: "dateFile",
      filename: "./logs/apiLogFile", // 你要写入日志文件的路径
      alwaysIncludePattern: true, // 将模式包含在当前日志文件的名称及其备份中
      pattern: "yyyy-MM-dd-hh.log",
      encoding: "utf-8",
      maxLogSize: 10240, // 文件最大存储空间
    },
    apiLogErrorFile: {
      type: "dateFile",
      filename: "./logs/apiLogFile", // 你要写入日志文件的路径
      alwaysIncludePattern: true, // 将模式包含在当前日志文件的名称及其备份中
      pattern: "yyyy-MM-dd-hh.error.log",
      encoding: "utf-8",
      maxLogSize: 10240, // 文件最大存储空间
    },
    logConsole: {
      type: "console",
    },
  },
  categories: {
    default: {
      appenders: ["logFile"],
      level: "all",
    },
    info: {
      appenders: ["logFile"],
      level: "all",
    },
    error: {
      appenders: ["logErrorFile"],
      level: "error",
    },
    apiInfo: {
      appenders: ["apiLogFile"],
      level: "all",
    },
    apiError: {
      appenders: ["apiLogErrorFile"],
      level: "error",
    },
    console: {
      appenders: ["logConsole"],
      level: log4js.levels.ALL.levelStr,
    }
  },
});

export default {
  info: function(msg: string, ...args: any[]) {
    const logger = log4js.getLogger(process.env.mode === "production" ? "info": "console")
    logger.info(msg, ...args)
  },
  debug: function(msg: string, ...args: any[]) {
    const logger = log4js.getLogger(process.env.mode === "production" ? "info": "console")
    logger.debug(msg, ...args)
  },
  error: function(msg: string, ...args: any[]) {
    const logger = log4js.getLogger(process.env.mode === "production" ? "error": "console")
    logger.error(msg, ...args)
  },
  apiInfo: function(msg: string, ...args: any[]) {
    const logger = log4js.getLogger(process.env.mode === "production" ? "apiInfo": "console")
    logger.info(msg, ...args)
  },
  apiDebug: function(msg: string, ...args: any[]) {
    const logger = log4js.getLogger(process.env.mode === "production" ? "apiInfo": "console")
    logger.debug(msg, ...args)
  },
  apiError: function(msg: string, ...args: any[]) {
    const logger = log4js.getLogger(process.env.mode === "production" ? "apiError": "console")
    logger.error(msg, ...args)
  },
}
// Crypto.ts

const cryptoUtils = require("crypto");
const DEFAULT_KEY = '16位字符'
const DEFAULT_IV = '16位字符'

interface I_EncodeParam {
  key?: string;
  plain_text: string;
  algorithm?: string;
  iv?: string;
  autoPadding?: boolean;
  input_encoding?:
    | "hex"
    | "base64"
    | "utf8"
    | "utf-8"
    | "utf16le"
    | "latin1"
    | "ascii"
    | "binary"
    | "ucs2"
    | "ucs-2"
    | undefined;
  output_encoding?: "hex" | "base64";
}

interface I_DecodeParam {
  key?: string;
  encrypted: string;
  algorithm?: string;
  iv?: string;
  autoPadding?: boolean;
  input_encoding?: "hex" | "base64";
  output_encoding?:
    | "hex"
    | "base64"
    | "utf8"
    | "utf-8"
    | "utf16le"
    | "latin1"
    | "ascii"
    | "binary"
    | "ucs2"
    | "ucs-2"
    | undefined;
}

export function aesEncrypt(encodeParam: I_EncodeParam): string {
  const {
    algorithm = "aes-128-cbc",
    key = Buffer.from(DEFAULT_KEY, 'utf8'),
    iv = Buffer.from(DEFAULT_IV, 'utf8'),
    plain_text,
    input_encoding = 'utf8',
    output_encoding = "hex",
  } = encodeParam;
  try {
    const cipher = cryptoUtils.createCipheriv(algorithm, key, iv);
    let crypted = cipher.update(plain_text, input_encoding, output_encoding);
    crypted += cipher.final(output_encoding)
    return crypted;
  } catch (e) {
    throw e
  }
}

export function aesDecrypt(decodeParam: I_DecodeParam): string {
  const {
    algorithm = "aes-128-cbc",
    key = Buffer.from(DEFAULT_KEY, 'utf8'),
    iv = Buffer.from(DEFAULT_IV, 'utf8'),
    encrypted,
    input_encoding = "utf8",
    output_encoding = 'hex',
  } = decodeParam;
  try{
    const decipher = cryptoUtils.createDecipheriv(algorithm, key, iv)
    let decrypted = decipher.update(encrypted, output_encoding, input_encoding)
    decrypted += decipher.final(input_encoding)
    return decrypted;
  } catch (e) {
    throw e
  }
  
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值