鲁鹏

鲁鹏 查看完整档案

北京编辑河北工业大学  |  计算机应用技术 编辑京东方大学  |  运营经理 编辑 lupeng.me 编辑
编辑
  • 伪程序员
  • 关注移动互联网
  • 算不上果粉的Apple产品热爱者
  • Linux爱好者
  • 享受命令行的快感

个人动态

鲁鹏 发布了文章 · 2019-05-29

全栈开发入门实战:后台管理系统

本文首发于 GitChat 平台,免费 Chat,链接:全栈开发入门实战:后台管理系统


感谢你打开了这篇 Chat,在阅读之前,需要让你了解一些事情。

第一,本 Chat 虽然免费,不代表没有价值,我会将个人全栈开发的经历叙述给你,希望对你有一些帮助;
第二,文中所使用的技术栈并非最新,也并非最优。后台管理系统更多是 2B 端的产品,通常是业务优先。本 Chat 的目的是为了让你能够快速上手全栈开发。
第三,本 Chat 虽然名为全栈开发,但是不会带你做完一个完整的后台管理系统项目。一是由于篇幅有限,二是由于时间关系,个人精力也有限。

正文

本 Chat 的内容,正如 Chat 简介中所描述,将分为以下 5 大块:

  1. 开发准备
  2. 前台样式
  3. 数据库连接
  4. 前后台交互
  5. 线上部署

你可能会发现,好像不知道要做什么,没错,后台管理系统一般都是企业内部定制开发,通常是对业务的数据管理,具体做什么功能由业务决定,但多数功能都是围绕着表格或者表单。

上面列举的仅仅是全栈开发的大致流程。首先,要做一些准备工作,例如:开发环境、编辑器环境以及依赖包配置等等工作;其次,我们要选定一个后台模版样式,快速套用,实现业务功能。(当然,你要自己开发也行,但不建议这么做,除非为了学习);然后,根据业务做数据库的设计,编写后台数据处理逻辑,以及前后台数据交互等功能;最后,测试并部署上线。

这里的示例,将实现一个学生数据的在线管理需求,其实就是一个在线表格,包括添加,删除功能,系统层面包括登录退出功能。麻雀虽小,五脏俱全,整体架子搭好了,再在上面添加功能就简单多了。好了,现在就开始全栈之旅吧。

开发准备

启动项目

首先要做的是,开发环境的安装,这里就不多说了,关于 Node 环境的安装,默认你已经搞定了。

既然采用 Express 作为 Web 框架,Express 也是要安装的,有了 Node 环境,安装 Express 就简单多了。我们直接上手 Express 的脚手架,全栈开发关键要速度。

npm install express-generator -g

一定记得是全局安装。安装完成之后,输入 express -h 可以查看帮助。这里选用 ejs 模版引擎,为什么?因为我顺手而已,这个不重要。找个合适的目录,运行下面命令:

express -e node-web-fullstack-demo

生成项目目录之后,首先要安装依赖,如下命令:

cd example-node-web-fullstack
npm install

等待安装完成,我们就可以启动项目了,使用命令 npm start ,去浏览器中,打开网址:http://localhost:3000,看到写着 Express 的首页,代表你的项目启动成功了。

编辑器环境配置

一个好的编码环境,可以让你项目开发效率加倍。

首先介绍一个编辑器配置 EditorConfig,这是一个编辑器的小工具。它有什么作用呢?简而言之,就是让你可以在不同的编辑器上,获得相同的编码风格,例如:空格缩进还是 Tab 缩进?缩进几个空格?

你可能觉得诧异,这个不是在编辑器上设置就可以了吗?没错,假设你从始至终都是在同一个电脑同一个编辑器上编码,那么可以忽略它。如果存在多电脑配合,亦或是多个编辑器配合,那么它就是神器。它几乎支持所有的主流编辑器,不用单独去编辑器中设置,配置文件就在项目中,用那个编辑器打开项目,都能获得一致的编码风格。

使用方法很简单,在根目录中新建 .editorconfig 文件即可。

# EditorConfig is awesome: https://EditorConfig.org

# top-most EditorConfig file
root = true

# Unix-style newlines with a newline ending every file
[*]
end_of_line = lf
insert_final_newline = true

# Matches multiple files with brace expansion notation
# Set default charset
[*.*]
charset = utf-8

# 4 space indentation
[*.js]
indent_style = space
indent_size = 4

# Indentation override for all JS under lib directory
[views/**.ejs]
indent_style = space
indent_size = 2

上面这个示例,设置了 js, ejs 的缩进,并通过 insert_final_newline 设置了文档末尾默认插入一个空行。还有一些有意思配置,建议你查看一下官方文档,就明白了,非常好用的一个小插件。

代码检查工具

使用 js 编码,建议最好使用一款代码检查的工具,不然写到后面就会很尴尬,往往一个小的语法错误,会让你抓狂好久。代码检查工具推荐 ESLint

使用方法也很简单,首先安装要它,npm install eslint --save-dev,代码检查工具通常只需要安装在开发依赖里即可。紧接着你应该设置一个配置文件:./node_modules/.bin/eslint --init,然后,你就可以在项目根目录下运行 ESLint:./node_modules/.bin/eslint yourfile.js 用来校验代码了。如果你使用的是 IDE 编码,一般都会有 ESLint 的插件来校验代码,例如在 VS Code 中安装 eslint 插件,就可以实时校验正在编辑的文件了。

配置文件里的设置参数就多了,建议自行查看官方文档。如下示例:

{
    "rules": {
        "semi": ["error", "always"],
        "no-undef": "off",
        "no-unused-vars": "off",
        "no-console": "off"
    },
    "env": {
        "node": true,
        "es6": true
    },
    "extends": "eslint:recommended",
    "globals": {
        "Atomics": "readonly",
        "SharedArrayBuffer": "readonly"
    },
    "parserOptions": {
        "ecmaVersion": 2018,
        "sourceType": "module"
    }
}

有时候你可能会觉得很烦,默认推荐的 eslint 校验规则管得太多了,上述中我就手动关掉了「不允许使用 console」「不允许存在未定义变量」等配置。有些人可能干脆关掉了校验,但是,我还是强烈建议启用,毕竟规范的编码效率会更高。

前台样式

前面做了那么多工作,但似乎一点效果也看不到,别着急,这一部分的内容,就能让你直接看到效果。

前端的工作其实是非常费时的,它包括页面设计及布局等等,往往一个页面光调样式就要花费很长的时间。假如你是想快速搭建一个后台管理系统,不建议自己去写前端页面代码。很有可能,页面样式还没有出来,就已经放弃了。除非你是单纯想要学习。

建议的做法是,快速套用一个前端模版库,将大体的页面结构搭建出来,然后在上面添加业务功能。 这里采用 AdminLTE 这套模版库,大概效果图如下:

它是基于 bootstrap3 的后台模版,几乎不再需要做 CSS 的开发,一下子就解决了前端界面设计的大问题。下面来看看如何套用它。

下载安装

推荐采用 bower 包管理器来安装,安装命令:bower install adminlte 等待下载就可以了。下载完成后,你会发现bower_components/ 目录里多了好多目录,这些都是它的依赖包。

接下来,我们还要将整个项目下载下来,得到它的示例代码,打开其中的 index.html 文件,分析一下它的页面结构,好便于后面的拆解。如下图:

拆解页面结构

这是后台首页的一个基本结构,分为:main-headermain-sidebarcontent-wrappermain-footercontrol-sidebar ,于是,我们按照这几大模块,拆分页面,分别保存为 layout 模版。在项目 views 下新建两个目录:backend 以及 frontend ,分别对应后台页面以及前台页面。

backend 里再新建 layout 目录以及 index.ejs 文件,layout 中用来保存通用的页面代码,index.ejs 则代表后台首页。拆解完的 index.ejs 代码如下:

<% include ./layout/head.ejs %>
<!-- custom css files -->

<% include ./layout/header.ejs %>
<% include ./layout/main-sidebar.ejs %>

<!-- Content Wrapper. Contains page content -->
<div class="content-wrapper">
  ... 页面代码 ...
</div>

<% include ./layout/control-sidebar.ejs %>
<% include ./layout/footer.ejs %>

<!-- custom javascript files -->

<% include ./layout/foot.ejs %>

相信你一眼就能看出上面这段代码的意思,将一个页面拆分后,再重组,这就是最终的首页。其他的所有页面都可以通过这样的方式,进行重组,我们要写的代码,仅仅只是修改 <div class="content-wrapper"></div> 里的页面即可。

配置静态资源目录

现在的页面,我们还不能访问,因为页面中链接的 CSS 以及 JS 文件路径都不对,模版里引用的都是相对路径,我们需要将它改为本项目里的绝对路径。打开 layout/head.ejs 文件,部分代码如下:

<!-- Bootstrap 3.3.7 -->
<link rel="stylesheet" href="bower_components/bootstrap/dist/css/bootstrap.min.css">
<!-- Font Awesome -->
<link rel="stylesheet" href="bower_components/font-awesome/css/font-awesome.min.css">
<!-- Ionicons -->
<link rel="stylesheet" href="bower_components/Ionicons/css/ionicons.min.css">
<!-- Theme style -->
<link rel="stylesheet" href="dist/css/AdminLTE.min.css">

套用模块的好处就是,这些链接库的地址基本上没太大的变化,我们只需要修改一下根目录就可以了。修改之前,我们需要先配置一下项目的静态资源目录,打开项目根目录下的 app.js 文件,加上一行代码如下:

...
app.use(express.static(path.join(__dirname, 'public')));
// 新添静态资源目录 bower_componennts
app.use(express.static(path.join(__dirname, 'bower_components')));
...

新加的这句代码意思是,将项目中 bower_components/ 目录设置为静态资源访问的根目录,那么以上的那些静态资源,我们就知道怎么引入了,修改如下:

<!-- Bootstrap 3.3.7 -->
<link rel="stylesheet" href="/bootstrap/dist/css/bootstrap.min.css">
<!-- Font Awesome -->
<link rel="stylesheet" href="/font-awesome/css/font-awesome.min.css">
<!-- Ionicons -->
<link rel="stylesheet" href="/Ionicons/css/ionicons.min.css">
<!-- Theme style -->
<link rel="stylesheet" href="/admin-lte/dist/css/AdminLTE.min.css">

同样的,JS 文件的引用路径也要进行修改,打开 footer.ejs 文件,以 bower_components/ 为根目录,修改对应的 JS 文件路径即可。好了,该页面所有引用的静态资源路径,都已经修改正确了,接下来就是编写页面路由了。

PS. 页面中的 JS 库并非都与自己的项目相匹配,后续要根据实际情况,进行增减。

编写页面路由

页面准备好了,我们需要去编写访问路由,在这点上,Node 就与 PHP 和 Java 有所区别了,Node Web 开发不需要再搭建一个 Web 服务器,PHP 需要 Apache ,Java 需要 Tomcat,而 Node 把它交给你,让你去自定义。我们打开项目 routes/index.js 路由文件,编写代码如下:

var express = require('express');
var router = express.Router();

/* GET home page. */
router.get('/', function(req, res, next) {
  res.render('index', { title: 'Express' });
});

// My backend index page
router.get('/backend', function(req, res, next){
  res.render('backend/index.ejs', {});
});

module.exports = router;

我们加了一个路由 /backend ,渲染了上面准备好的 index.ejs 页面,好了,我们重启一下项目,哦,对,如果已经安装了 supervisor ,不需要手动重启了,直接访问 http://localhost:3000/backend

细心的你可能发现,这个页面有些元素显示不正常,这是因为有些静态资源,我们没有安装而导致的加载失败,这个无需担心,因为实际页面还需要很多的时间去打磨,这个要根据实际业务来决定页面的内容,这里就不去展开了。

接下来的事情,就是改写页面代码了,整体的样式结构都有了,剩下就是对页面的删删减减了。

数据库连接

根据上面的内容,相信你能够添加完页面路由。当全部页面改写完毕之后,我们就相当于得到了,一个静态的后台管理系统。要达到的效果就是:点击左侧相应的导航,可以实现页面跳转,但是没有实际的数据,页面中的数据都是写「死的」,因为我们还没有连接数据库,接下来的工作就涉及到数据库的连接了。

设计数据表

不管你选择哪一个数据库,首先都要做设计数据表,对于数据表的设计以及业务埋点等内容,都可以当作一本书来讲,这里不会有那么详细的内容,来教你如何设计数据表,以及业务功能埋点。但有个建议需要提一下:不要着急去学习 SQL 语言,你可能会说,不学习 SQL 怎么设计数据表呢?怎么操作数据库呢?

这里需要强调的是,不是不需要学,而是开始的时候,不用着急去学。全栈开发重要的是快,不然你全栈干啥呢?在实际的场景中,业务才是最重要的。

首先打开你的 Excel(或在线表格应用) 把表的设计做出来再说。例如下图是我当时一个项目的数据表设计:

最重要的是要去做这个事情,而不是去学数据库,别担心做得不够好,一次一次的实战会让你越来越熟练。做完这个工作,全栈开发基本算是完成了 40%,在这个过程中,一定要深入去分析业务流程,把该用到的不该用到的都要考虑进去,前期可以不做开发,但是必要的字段一定要预留。

编写数据库模块

通常情况下,最好找一个趁手的数据库 GUI 工具,把数据库以及相关的表创建出来。这一步做完之后就是编写连接数据数据的代码了,建议在项目的根目录中,新建名为 db 的目录,用来存放所有关于数据库操作的代码。

这里我们选用 MySQL 数据库,Node 连接 MySQL 还需要安装一个数据库模块。在项目目录,执行命令 npm install --save mysql 即可,安装完成之后,就可以通过下面的示例,尝试连接数据库了。

var mysql = require('mysql');
var connection = mysql.createConnection({
  host: 'localhost',
  user: 'me',
  password : 'secret',
  database : 'my_db'
});
connection.connect();
connection.query('SELECT 1 + 1 AS solution', function(err, rows, fields) {
  if (err) throw err;
  console.log('The solution is: ', rows[0].solution);
});
connection.end();

这是官方提供的一个简单例子,从上面的例子可以得出:使用createConnection(option)方法创建一个连接对象,然后连接对象的connect()方法创建连接,最后使用query()方法执行SQL语句,返回结果作为回调函数的参数rows返回,rows为数组类型。

通常情况下,我们会使用连接池进行连接,连接池具体实现原理就不多展开了,可以查看一下官方文档。下面直接给出使用示例。

// connect.js 使用getConnection方法
var mysql = require('mysql');
var config = require('./config.json');
// 将配置写入配置文件中
var pool = mysql.createPool(config.mysql);
exports.querySQL = function(sql, callback){
    pool.getConnection(function(err,conn){
        conn.query(sql,function(err,rows,fields){
            callback(err,rows,fields); 
            conn.release();   // 不要忘了释放
        });        
    });
}

使用的时候,直接使用querySQL方法即可,如下:

// db.js 查询用户信息
var connect = require('./connect.js');
exports.getUser = function(username,callback){
    var sql = 'select * from user where username = "' + username + '"';
    connect.querySQL(sql,function(err,rows,fields){
        callback(err,rows,fields);        
    });
};

上面示例中,直接将 sql 语句写进代码中了,通过执行 sql 语句来获得数据库数据。

这种方式优点是比较直观,但是缺点就太多了。不安全拼接字符串容易错可扩展性差等等。在实际项目中,我们往往都会选用一款 ORM 框架来连接数据库。

使用 ORM 框架

关于 Node 使用 ORM 框架的介绍,我之前单独写了一篇 Chat,同样是免费的,这里我就不再赘述了。

请点击链接查看:如何使用 Sequelize 框架快速进行 Node Web 开发

前后台交互

通常情况下,前后台交互的开发会涉及到多个部门多个岗位协作完成,除了前后台,近几年也分离出中台的概念,专门提供接口服务。

而对于全栈开发来说,这个环节显然要简单得多了,虽然工作流程可以省,但是,必要的前中后台的框架还是要有的,分离开的好处是尽量降低功能耦合性,便于后期维护。

前台页面获取动态数据通常有的两种方式:

  • 一是,被动获取,页面被渲染,后台传参给前台;
  • 二是,主动获取,前台主动请求,异步获取数据。

后台传参方式

关于页面展示,前面已经讲过了,根据模块改写页面,然后编写路由,就可以进行访问了。但问题是,目前页面上的一些内容都是静态的,例如:站点的名称,Logo以及标题等等。

通常情况下,这些内容不应该是写死在页面中的,而应该是动态的,从后台传来的,甚至应该是写入数据库的,将来做个修改页面,就可以随时修改网站标题以及 Logo 等信息。

这里就涉及到后台传参的相关知识点了。Express 框架给我们提供了三种传参的方式:

(1)应用级别的传参

使用 app.locals 定义参数。例如:在 app.js 文件中,routes(app); 语句之前加入 app.locals.hello = "Node",我们在任何页面中,使用 hello 这个参数都是没问题的。如何使用?建议先了解下模版引擎的用法,这里是 ejs。

(2)路由级别的传参

使用 res.locals 定义参数。例如下面例子:

app.use(function (req, res, next) {
    res.locals.web = {
        title: 'STU INFO',
        name: '数据管理',
        desc: '学生数据管理',
        verifier: 0
    };
    res.locals.userInfo = {
        username: 'admin',
        title: '管理员'
    };
    res.locals.url = req.url.split('?')[0];
    next();
});

通过一个中间件,将站点信息写入 res.locals 对象中,于是我们在对应的页面中,就可以使用 web 以及 userInfo 等对象参数了。例如下面登陆页面部分代码(注意:这里是 ejs 模版引擎的写法):

<div class="login-logo">
    <a href="/" title="<%= web.desc %>"><b><%= web.title %> </b><%= web.name %></a>
</div>

(3)页面级别的传参

使用 res.render() 方法定义参数,这应该是最常用的一种方式,例如页面的 title 属性,每个页面都是不一样的,所以在渲染模版的时候,传入 title 参数,是最合适的。例如登陆页面的路由:

router.get('/login', function(req, res, next) {
  res.render('login', {
      pageInfo:{
          title: '登陆页面',
      }
  });
});

示例中,定义了一个 pageInfo 的对象,将其当作参数传输到了前台。

前台异步获取

前台主动获取数据的例子很多,通常都是通过 Ajax 异步的方式。典型的例子就是在线表格功能,因为后台管理系统几乎离不开在线表格的功能。

关于在线表格的内容,我之前写过一篇 Chat,建议阅读,同样是免费的。链接:如何快速将线下表格数据线上化

这里我重点介绍下,后台数据如何产出?首先要明白,数据肯定从数据库中获得,我们编写数据库 API 的时候,就应该将对应的方法封装好,前台通过访问数据路由,路由调用对应的数据库 API 即可获得数据,并返回前台。

下面看下路由的代码示例:

// api
const studentHandler = require('../../db/handler/studentHandler.js');
// 当前学生列表
router.get('/list', function(req, res, next) {
    let state = 0 ; // 代表当前在校
    studentHandler.getStudentList(state, function(p){
        res.send(p);
    });
});

对应的数据 API 封装在了 db/handler 目录中,路由通过调用 getStudentList 方法,即可获得对应的学生列表,并通过 res.send(p) 方法返回给前台。

再来看看数据库 API 是如何编写的?代码示例如下:

const { Student } = require('../relation.js');
const Sequelize = require('sequelize');
const Op = Sequelize.Op;
module.exports = {
    // 根据状态查询学生列表
    getStudentList: function(state, callback){
        Student.findAll({
            where: {
                state: state
            }
        }).then(function(data){
            callback(data);
        }).catch(function(err){
            callback(err);
        });
    },
    // 批量添加学生
    uploadStudent: function(data, callback){
        Student.bulkCreate(data).then(function(){
            callback();
        }).catch(function(err){
            callback(err);
        });
    }
};

重点看下 module.exports 对外的接口,篇幅原因,这里只提供了两个调用方法。如果这里的代码看不明白,请翻回去查看「使用 ORM 框架」这节内容中,推荐的那篇 Chat。

通常情况下,大部分功能都是通过「后台传参」以及「异步获取」这两种方式配合来实现的。

有时候甚至是取代关系,你可能会发现有些后台管理系统,进去之后,从始至终 URL 就没有变过,这一类的后台管理系统的功能实现,全部采用前台异步获取的方式。我本人不太推荐这种方式,因为想要单独展现某个页面的时候,就非常的尴尬,同时也非常不利于页面维护。

线上部署

当项目开发完成,本地测试完毕之后。下一步,就是部署上线了。上线部署原本是个比较繁琐的工作流程,特别针对多系统联动的情况。这里我们不考虑复杂的情况,单纯讲独立开发的后台管理系统如何快速部署到线上?

你可能会说,这有啥好讲的,把本地代码同步到服务器上,然后在服务器上启动不就得了。没错,大体是这么个意思,但是其中还是有一些点需要注意的。

使用进程管理工具启动项目

这里我推荐使用 supervisor,也没其他原因,顺手而已。它是一个进程管理工具,当线上的 Web 应用崩溃的时候,它可以帮助你重新启动应用,让应用一直保持线上状态。

安装方法很简单,在命令行中,输入 npm install -g supervisor 即可。安装完成之后,我们需要修改一下项目的启动命令,打开 package.json 文件,编辑如下:

...
"scripts": {
  "start": "supervisor --harmony -i views/,public/ ./bin/www",
},
...

supervisor --help 查看使用方式,以上命令,配置了 --harmony 模式启动 Node ,同时,使用 -i 参数忽略了 views/ 以及 public/ 目录。

修改完成后,我们依然使用 npm start 启动项目,不一样的是,当我们修改了除 views/ 以及 public/ 目录以外的文件后,服务将会自动重启,以确保线上一直运行的是最新版项目。

使用 Git 同步代码

将代码从本地拷贝到线上,有很多种办法。这里推荐使用 Git 工具,如果没有自己的 Git 服务器,那么就使用 GitHub 类公共 Git 服务平台。大可不必担心代码泄露的问题,GitHub 不是已经提供私有仓库免费的功能了嘛,没事,放心用吧。

具体操作我就不再赘述了。

使用 Nginx 反向代理服务器

为了确保性能,不建议直接在线上环境,通过 npm 或 supervisor 直接启动项目,虽然 node 本身的性能并不差,建议还是在 node 服务中间,再加一层 Web 服务器当作方向代理,与 Node 最配的当然是 Nginx 了。

安装 Nginx 不必多说,下面贴出 Nginx 对应的配置文件内容供参考。

server {
    listen       80;
    server_name xxx.com

    charset utf-8;

    #此处配置你的访问日志,请手动创建该目录:
    access_log  /var/log/nginx/js/access.log;

    location / {
        try_files /_not_exists_ @backend;
    }

    # 这里为具体的服务代理配置
    location @backend {
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_set_header Host            $http_host;
        proxy_set_header   X-Forwarded-Proto $scheme;

        #此处配置程序的地址和端口号
        proxy_pass http://127.0.0.1:8080;
    }
}

关键记住最后一句:proxy_pass 代理的是哪个程序地址和端口号。

最后,启动 Node 服务,启动 Nginx 服务,然后访问对应服务地址,大功告成。

总结

这篇 Chat 从 5 个方面讲述了全栈开发一个后台管理系统的大致流程以及部分实战内容。由于内容量远超出了预期,在写的过程中,不断的删减了很多篇幅。使得 Chat 的整体效果,没有达到我的预期。

也许这个内容,通过一篇 Chat 确实很难容下吧。所以,我计划写完整个课程,内容包括 Node 基础、进阶应用以及Web 实战等。从最基本的原理开始介绍,到最后全栈开发实战。

课程以开源免费的形式公开,GitHub 仓库地址:Node 全栈开发入门课程,更新频率不定,欢迎关注。

同时,也可以关注我的微信公众号:个人学习,以便了解最新进展。

谢谢观看~

查看原文

赞 4 收藏 3 评论 0

鲁鹏 发布了文章 · 2019-04-28

为了用 Markdown 写微信公众号,自定义了一个编辑器

身边应该有不少朋友在写公众号,不知道你们用的是什么编辑器呢?

上面这些编辑器,应该是小编们用得最多的几款,它可以快速添加各种样式插件,使文章更吸引眼球,让用户看起来很爽,欲罢不能。毕竟他们最注重的是阅读量,而非内容。

我也有写文章的习惯,但我不是小编,格式上只追求简约大方即可,重点在文字上,希望内容能产生一些价值。自从用了 Markdown 标记语言后,写文章就再也没用过其他的编辑器。

什么是 Markdown?

什么是 Markdown?它是目前最流行的写作标记语言,没有之一。它能够通过简单标记就能实现文档格式,让写作者专注于内容

由于它是纯文本,所以它可以像代码一样进行版本管理,同时,它对 Web 也非常友好,方便转成 HTML,甚至直接将 Markdown 文档生成静态站点,很多免费的自建博客服务都是采用的这种方案。目前几乎所有主流的写作平台,其编辑器都支持 Markdown。

一些 Markdown 编辑器,甚至在其基础上,扩展了很多功能。例如:公式及表格的支持。前段时间,一个外国小哥的数学笔记火了,全程像敲代码一般,紧追数学老师板书,记了 1700 + 页笔记。感兴趣可以看下这篇文章:

1700页数学笔记火了!全程敲代码,速度飞快易搜索,硬核小哥教你上手LaTeX+Vim

为什么不支持 Markdown?

虽然支持它的编辑器多到数不过来,可是国内最著名的内容发布平台 —— 微信公众号,它的编辑器就不支持 Markdown,可算折腾坏了一帮写作者。为什么不支持?可能有两个原因吧。

用户学习成本

Markdown 语法虽然简单,但对大部分人来说,毕竟也是一门新的知识,这就增加了用户的学习使用成本。你要知道,绝大部分的人,哪怕一点点的新东西都是接受不了的,微信没把编辑器做成 Word 的样式,我觉得已经是克制了的。

支持的样式并不完整

Markdown 只提供了简单的样式标签,例如:标题,引用,链接等等,而对于复杂的样式,例如文字背景色等等,它是不支持的。

而微信面对的是全体创作者,单纯使用 Markdown 编辑器定然不能满足基本需求,而兼容 Markdown 的需求优先级并不高。

所以,一直以来,微信并不支持 Markdown,但我猜测,支持 Markdown 的功能迟早还是会做的。

Markdown 写公众号的痛

你不是说了 Markdown 对 Web 非常友好嘛,转成富文本样式,然后贴到微信公众号的编辑器里,就可以了呀。道理是没错,但这正是折腾人的关键所在,因为 Markdown 只定义了基础的标签,而没有样式。

于是,各家的 Markdown 编辑器导出的样式都是有差异的,并且,跟微信公众号上的默认样式也不兼容。所以,贴进去后,显示出来的样式各不相同,如果文章里再有一些非标准的 Markdown 语法,显示出来更是五花八门了。一直以来都很纠结,对于一些样式复杂的文章,几乎就不发公众号了,因为调整样式,就要耗费大量的精力。

除了样式兼容性问题,还有微信公众号对外部链接限制问题,公众号内文章只允许引用微信内部链接,不支持外部链接。文章里若添加了第三方链接,我们只能硬生生的将 链接重新再贴进去。或者通过「阅读原文」链接原文地址。

解决方案

微信公众号编辑器都几乎成为一种新的行业了,文章开头的那些编辑器,都能自力更生了,说明对小编们来说,公众号编辑器问题真的是一个痛点。

而对于适配公众号样式的 Markdown 编辑器,几乎没有,之前接触过 Md2All,功能上很完整,但是它并非只针对微信公众号,所以在细节方面的处理,总是差强人意。

一直想着,应该写一款符合自己样式风格的公众号编辑器。然而,一个偶然机会,发现了它,花三小时写这个工具,只为一分钟拯救公众号排版

在程序世界里,有句老话说「不要重复造轮子」,你费好大劲去研究怎么做,没准别人已经都出成品了,这样就造成了资源浪费。幸运的是,我的「轮子」还没有开始动手呢。

总要做点自己的贡献

这款公众号编辑器基本符合我的心里预期,简单的界面,优雅的样式风格,你看到的这篇文章的样式,就是通过它生成的。

它还有一些特殊的增强项,比如将外部链接自动生成脚注,放在文章底部;支持日语注音假名和汉语拼音,例如:小夜時雨【さ・よ・しぐれ】 上海【Shàng・hǎi】

虽然默认的样式已经基本满足我了,但还是缺少一些自定义的功能,比如字体大小的设置,以及主题切换等功能,作者并没有实现。但是,作者已经将源代码开源了,而我们不能只知道一味索取,而不懂得付出。

于是,我便动手实现了这部分的功能。好在代码并不复杂,简单研究一下,周末花了点时间,就把这部分的功能填补上了。

最后

这个过程还是很有趣,不仅解决了自己的痛点,还学到了知识,同时还做出了一点点自己的贡献。

如果你也喜欢这篇文章的样式,这个微信公众号编辑器分享给你。微信公众号格式化编辑器 - 作者原版本

根据源代码,我重写了一个后台服务版本,计划提供一些在线 API 的功能。仓库地址:wechat-format-server: 基于 wechat-format 的服务端版本


查看原文

赞 1 收藏 1 评论 0

鲁鹏 发布了文章 · 2019-04-19

我做了一个开源项目,本着帮助他人的目的

不要努力成为一个成功的人,而要成为一个有价值的人。 —— 爱因斯坦

1.

每次全栈做项目的时候,往往前端最费时间,对于一个注重用户体验的人来说,一个按钮的颜色、大小或是布局,就要纠结好久。

犹记得,因为画不好一个首页,导致项目迟迟不想往下走的扎心,直到发现了 bootstrap …

前端的知识点并不复杂,但在样式这块总也学不好,并非不会写 CSS,而是做出来的东西,总是差点意思,渐渐也失去了信心,认为自己不是这块料,天生缺少艺术细胞。

好在,这是一个开源世界,你不擅长的东西,也许别人早就做好了。正是由于这些优秀插件的存在,才让我有精力,在保证基本视觉体验的前提下,更多时间去思考产品逻辑,快速开发迭代产品功能,让项目在最短时间内上线。

2.

为了回馈这些插件的帮助,同时,帮助更多的人,我发起了一个开源项目—— JS 前端插件文档库协作项目。计划整理并记录那些优秀的 JS 前端插件库,形成实战类文档,希望能帮助到更多的人。

单看文档库,可能有些枯燥无味,如果有在线演示就更直观了,于是,我就简单的做了在线演示 JS 插件在线演示

有些插件的功能非常复杂,可调控的参数也多,文档介绍并不能面面俱到,如果能自己调试就好了,于是,我将源代码开源,并教你快速部署在本地,方便调试。代码仓库:JS 插件文档库示例代码 · GitHub,方便的话,点个 star 再走。

3.

截止目前为止,我已经整理了基于 jQuery & bootstrap 的若干插件,你说 jQuery 都已经过时,还整理干啥?技术有进步,会有淘汰,但是知识不会,知识永远是累积的,整理出来,总能对一些人产生帮助。对他人有帮助,就是价值。

该文档库起于 jQuery,但不止于 jQuery,后面将逐渐加入基于 Vue 的插件,逐渐去完善 JS 前端插件知识库。

但是,个人的力量毕竟有限,期待你的加入,一起维护该文档库,做出自己的一点贡献,哪怕就会一个也行。

文档放在了语雀 · 专业的云端知识库上,在文档的编辑以及协作上,它有不错的用户体验,期待你加入。

以上


个人公众号

查看原文

赞 0 收藏 0 评论 0

鲁鹏 发布了文章 · 2019-04-15

bootstrap-table 插件文档

更多 JS 插件:JS 插件文档及在线演示

简单介绍

官方地址:Bootstrap Table · An extended table to integration with some of the most widely used CSS frameworks. (Supports Bootstrap, Semantic UI, Bulma, Material Design, Foundation)

bootstrap table 是一款基于 Bootstrap 的 jQuery 表格插件,功能比较完备,能够实现数据异步获取,编辑,排序等一系列功能,最可贵的是,只需要一些简单的配置就可以实现一个功能完备的在线表格。

image.png

HTML 部分

bootstrap-table 具备异步获取数据功能,然后在前台渲染出表格。所以,前台只需要一句代码就解决了:

<table id="table"></table>

虽然它也支持将参数写在 HTML 页面中,但是我建议直接写在 JS 文件里,便于管理。

引入文件

由于 bootstrap-table 除了自身提供的功能外,还支持很多第三方的插件,所以,引入文件的部分就显得尤其重要了,没准你调试半天的 Bug,只是因为忘了引入某个库文件。

首先关注 3 个文件,dist 目录下的 bootstrap-table.cssbootstrap-table.js,如果使用中文,还要引用 locale/bootstrap-table-zh-CN.js注意每个文件均提供了min版本以及正常版本,建议在开发测试阶段引入正常版本,便于调试。当然最后不要忘了引入 bootstrap 以及 jQuery,最终效果如下:

<!-- CSS 部分 -->
<!-- Bootstrap 3.3.7 -->
<link rel="stylesheet" href="/bootstrap/dist/css/bootstrap.min.css">
<!-- Bootstrap table -->
<link rel="stylesheet" href="/bootstrap-table/dist/css/booststrap-table.min.css">

js 文件建议放到页面最底下,在 </body> 之前引入即可,如下所示:

<!-- JS 部分 -->
<!-- jQuery 3 -->
<script data-original="/jquery/dist/jquery.min.js"></script>
<!-- Bootstrap 3.3.7 -->
<script data-original="/bootstrap/dist/js/bootstrap.min.js"></script>
<!-- bootstrap-table -->
<script data-original="/bootstrap-table/dist/bootstrap-table.js"></script>
<script data-original="/bootstrap-table/dist/locale/bootstrap-table-zh-CN.js"></script>

注意:1. 顺序不要乱;2. 根目录依据自己项目而定

JS 调用

前台放一个 table 标签即可,表格的结构,甚至于表格的操作都放到JS中实现,如下代码即可生成一个表格:

$('#table').bootstrapTable({
    url: '/bootstrap-table/data',        // 表格数据来源
    columns: [{
        field: 'id',
        title: 'Item ID'
    }, {
        field: 'name',
        title: 'Item Name'
    }, {
        field: 'price',
        title: 'Item Price'
    },{
        field: 'column1',
        title: '列1'
    },{
        field: 'column2',
        title: '列2' 
    },{
        field: 'column3',
        title: '列3'
    },{
        field: 'column4',
        title: '列4'
    } ]
});

url 中定义了表格的数据来源,返回数据的格式依然是包含数据对象的数组。由于该框架提供的参数比较多,而实际项目并用不着这么多配置,这里给出,我建议的一个方案,供参考。

右上角的一些功能,通过配置一些参数即可实现,无需多余的代码。这个查看官方文档,基本没有什么问题,这里不多介绍了。

左上角是一些自定义的一些功能,这里有添加数据,筛选数据(本地&异步),再加上编辑数据,基本就完成了表格的增删改查需求,这个我在后面会一一介绍。

添加功能

根据一些实际项目的经验,采用弹出模态框的方式,是最优雅的添加方式。如下图所示:

这个是bootstrap自带的一个插件,直接引入页面中即可,至于表单的提交方式是采用form原生提交,还是使用ajax异步提交,就取决于你的喜好了。这块内容不在文章范围内,就不多介绍了。

需要注意的是:假如你采用的是ajax异步提交表单,那么就需要调用bootstrap-table的refresh方法,用来更新表格数据。

$('#table').bootstrapTable('refresh');

导入功能

每次在做信息化类项目的时候,导出功能是我最不愿意去做,但也必须要实现的功能。不愿做并不是因为很难实现,这是一个原则问题,信息化就是为了减少或是废除线下操作,然而在传统企业却根本行不通,因为不管你的用户体验做得有多好,也改变不了用户「不愿尝试改变」的劣根性。

bootstrap-table提供了导出扩展模块,简单配置就可以轻松实现导出功能。首先需要引入两个文件,一个是bootstrap-tableextensions中的bootstrap-table-export扩展;另一个是tableExport的插件。效果如下:

<!-- bootstrap-table export -->
<script data-original="/bootstrap-table/dist/extensions/export/bootstrap-table-export.min.js"></script>
<script data-original="/tableexport.jquery.plugin/tableExport.min.js"></script>

引入扩展文件后,在表格参数中加入如下一句配置即可:

showExport: true

筛选功能

这个是在线表格最重要的功能之一。因为我们不可能一次性将后台所有数据都拉到前台展示。如果你之前使用过bootstrap-table,你可能知道它提供了一个sidePagination的参数,这个参数是定义在哪里进行分页,可选值为 client 或者 server。默认为client,当你设置为 server时,每次请求后台服务器,都会加上limit, offset, search, sort, order这几个参数,传到后台让你去处理数据分页。

这里我想告诉你,完全没有必要这么麻烦,实际项目中,我们都是通过参数条件,筛选一部分数据展示到前台。所以你定义好默认的参数就可以了,分页的事就交给前端处理即可。那么参数如何自定义呢?使用queryParams表格参数即可。举个例子:

queryParams: function(params){
  return {
    startDate: '2018/09/01',
    endDate: '2019/09/01'
  };
},

查看Chrome Network请求,可以看出传递参数情况。

通过上述自定义参数方式,就可以筛选部分数据到前台,然后通过配置分页参数就可以实现筛选功能了。那么一般设置什么参数筛选呢?其实就是想问一次性筛选多少条数据最合适呢?我的建议是在500以内,这样既方便处理数据,也不会太影响性能。

前台分页的好处,主要体现在搜索这块,完全不用自己去实现代码,简单配置搜索框即可,而且提供的是全局搜索,很强大了。如果想配置个本地筛选也是很方便的,使用resetSearch方法即可。

// 本地筛选
$('#localFilter li a').click(function(e){
    e.preventDefault();
    var filter = $(this).data('filter');
    $table.bootstrapTable('resetSearch', filter);
});

有时候,我还是想要从后台筛选部分数据,通过前台表单,使用 refresh方法即可。

// 异步筛选
$('#Filter').submit(function(e){
    e.preventDefault();
    var filter = $('input[name=filter]').val();
    $table.bootstrapTable('refresh',{
        query: {
          startDate: '2001/09/01',
          endDate: '2008/09/01',
          filter: filter
        }
    });
});

筛选功能就到这,这里只是介绍了参数传递的方法,具体筛选,还需要结合后台代码去实现。

搜索功能

搜索分为前台搜索以及后台搜索。

  • 前台搜索:学会使用5个表格参数(search、searchOnEnterKey、searchText、trimOnSearch、customSearch(自定义搜索)),2个列参数(searchable、searchFormatter),1个方法(resetSearch)即可
  • 后台搜索,就类似于筛选功能的传参了,在后台处理字符串,返回表格数据,此不在本文范围内,不多赘述。

编辑功能

在线表格的编辑,其实是最不好处理的一个功能。一方面,添加编辑功能需要增加很多额外的代码量;另一方面,从业务上来讲,编辑并不是一个好的用户体验。在做编辑功能之前,我总是问自己,这块功能真的需要编辑吗?删除了重新添加行不行?

bootstrap-table 提供了 editable 编辑模块,简单配置即可实现表格的编辑,但是我还是想要提醒,使用编辑功能需要有节制,越自由并不代表用户体验越好。

还是老套路,引入3个文件(其中:1个css,2个js):

<!-- X-editable -->
<link rel="stylesheet" href="/X-editable/dist/bootstrap3-editable/css/bootstrap-editable.css">

<!-- booststrap-table editable -->
<script data-original="/bootstrap-table/dist/extensions/editable/bootstrap-table-editable.js"></script>
<script data-original="/X-editable/dist/bootstrap3-editable/js/bootstrap-editable.min.js"></script>

引入之后,直接在列参数上加上editable: true,即可启用该字段的标记功能,效果图如下:

样式没有问题后,接下来看看如何使用,使用方法完全沿用了X-editable插件,bootstrap-table-editable仅仅只是做了嵌入的工作,所以你需要查看X-editable的文档,这里我举个简单的例子介绍一下,如下为其中一列的参数设置:

{
  field: 'column2',
  title: '列2',
  editable: {
    url: '/test',
  },
}

url参数用来异步访问后台,那么传递的参数有哪些呢?

pkX-editable中定义为主键,在bootstrap-table中,通过设置表格参数idField: 'id',可以定义行数据的主键。若改成idField: 'name',再来看下:

明白了如何传参数,相信你就知道后面如何处理了。

删除功能

介绍完编辑功能,不知道你有没有发现,假如我们要编辑的字段非常多,这种处理方式会给后台造成很大的工作量,能不能一个表单就解决编辑需求呢?当然是可以的。

我们在每一行的最后加上一列,放上一些功能按钮,如下图:

columns表格参数中,加上一列如下:

{
    field: 'operator',
    title: '操作',
    align: 'center',
    valign: 'middle',
    width: '10%',
    // visible: false,
    formatter: function (value, row, index) {
        // var sid_code = base64encode(row.sid + '');   //  sid 加密处理
        // alert(sid_code);
        return '<a href="#">' + 
            '<i class="glyphicon glyphicon-eye-open" title="显示"></i> ' + 
            '</a>'+ 
            '<a href="#editProject" data-toggle="modal" title="修改">' + 
            '<i class="glyphicon glyphicon-pencil"></i> ' + 
            '</a>'+
            '<a href="javascript:void(0)" title="删除">' +
            '<i class="glyphicon glyphicon-trash text-danger"></i> ' + 
            '</a>';
    },
    events: {
      'click a[title=删除]': function (e, value, row, index) {
          if(confirm('此操作不可逆,请确认是否删除?')){
              $.ajax();
          }
      },
      'click a[title=修改]': function (e, value, row, index) {
          // e.preventDefault();
          alert('click change button');
      },
    }
}

4个参数分别是:

  • event: the jQuery event.
  • value: the field value.
  • row: the row record data.
  • index: the row index.

相信看完这个示例,就能一并解决「查看」「编辑」「删除」等功能。bootstrap-table的使用就介绍到这里了,官方文档里还有好多参数以及方法没有介绍到,篇幅有限就不再介绍了,需自行查看文档学习。

后台返回数据

对象数组,每一行数据为一个对象

查看原文

赞 4 收藏 3 评论 0

鲁鹏 发布了文章 · 2019-04-12

JS 插件文档库邀你一起协同创作

项目概览

项目介绍

如今,随着大前端的发展,曾经的霸主:jQuery 也渐渐的陨落,随之一起没落的,也包含基于 jQuery 的一些优秀的插件。这些优秀的插件,让我们在前端的开发中,节省了大量的时间。自己的项目中也使用了大部分基于 jQuery 的前端插件,帮助我实现了很多的功能,节省了大量的开发时间。

所以,我计划发起一个开源项目,整理并收集这些优秀的前端插件的使用方法,并提供示例代码,可供调试和学习。一来为了留个存档,二来也是为了分享出去,帮助到需要的人。

该文档起于 jQuery 框架,但不止于 jQuery,希望能整理所有的 Web 前端框架。

期待你的加入,一起维护文档,语雀文档协作邀请链接,如果链接过期,请加个人微信号:P_lu0503,并备注:文档协作

为了文档的可用性,我希望每一个插件都有一篇独立文档,以及独立在线演示。

文档介绍

文档在语雀平台上,期待你的加入进行协作编写,不要求所有的配置项都介绍到,列举一些最常见的即可。文档主要包括以下几个方面的描述:

  • 简单介绍:插件的用途,使用场景,以及官方文档链接;
  • 开始使用:如何正确的引入库文件到页面中,这一点对于初学者很重要;
  • 使用示例(需要代码演示):

    • 前台 HTML 如何编写
    • 前台 JS 如何调用
    • 后台数据返回的格式(不限后台技术,重点关注返回数据的格式)

在线演示

每一个插件都有一个独立的页面可供访问,在线演示原代码在 GitHub 上,采用 Node 语言编写,可以自行部署在本地,便于调试,尝试插件不同参数的用法。

熟悉 Node + Express 框架的可以直接 fork 项目,并提交 pull requests,如果不熟悉 Node 开发,也没关系,我会定期将文档中新增的插件,做成演示示例,push 到 GitHub 仓库。

另外,也提供了在线预览

本地部署步骤

  1. 安装 Node 环境
  2. 安装 supervisor,安装方法:npm i -g supervisor
  3. 安装 bower 包管理器,安装方法:npm i -g bower
  4. 克隆代码到本地,顺便点个 Star
  5. 进入项目目录,安装依赖,npm install 以及 bower install
  6. 运行项目,npm start
  7. 浏览器打开项目:http://localhost:3030/page
查看原文

赞 3 收藏 3 评论 0

鲁鹏 关注了用户 · 2018-04-18

海岛心hey @hdxhey

「Gridea」一个静态博客写作客户端: https://github.com/getgridea/...
每只菜鸟都有鹰的梦想!
推特:@eryouhao

关注 32

鲁鹏 发布了文章 · 2018-03-21

想做一个线上待办清单引发的思考 - Node开发

启动服务
打开VS
久违的动作
幸好自己还没有忘记

领导有个习惯,每次都会把部门的待办事项用excel列出来,然后邮件发送给下属并抄送给上级,便于跟进工作事项,任务列表一更改然后再发送一遍邮件,这种管理方式没什么问题,但是这种操作方式实在是低效。

我决定做一个简单的线上待办清单,领导添加待办事项,下属可以更改状态,还有一个最关键的功能就是发送邮件功能,一键发送待办清单给下属并抄送上级领导,在传统企业里邮件真是必不可少的。

1. 数据库准备

动手开发前先把数据库创建了,由于上次学习了ORM模块,不用再在数据库里操作SQL语句了,直接上代码写上数据表的结构以及一些初始数据的导入代码。具体示例可以参照: 初步使用sequelize模块 - Node实战

2. 前端页面折腾

数据库结构搞定之后,开始折腾前端页面的设计,也不想重新写页面了,直接copy之前项目的代码,短短半个小时,前端页面就搞定了,如下图:「PS. 结果后面又调了两天,醉了」

前端表格使用的bootstrap table制作,与后台数据库的交互直接使用Ajax异步处理,现在先编写获取数据的API,简单如下:

// find: 获取table的数据
router.get('/bootstrapTable', function (req, res, next) {
  todolist.findAll({
    order: [['id', 'desc']]
  }).then(function (r) {
    res.send(r);
  });
});

一并写完增删改查,前台页面就可以简单的调用API就能实现一些功能了,例如添加列表功能,更改列表以及删除列表。

3. 清单编辑功能

最近几次开发都是使用Bootstrap Table来展现列表,这块也是最折腾时间的地方,每次写这个表格,总是有一堆奇奇怪怪的想法想要去实现,没有一个整体的规划,功能来回调整,于是在这上面浪费很多时间。这次主要折腾了字段编辑功能,以及更改列表功能。

更改表单的功能有两种方式:一是使用modal弹出表单的方式;另一种是行内编辑的方式;modal弹出表单的方式会添加大量的js脚本,后期管理起来非常的不方便。而行内编辑的方式,虽然不用写大量的代码,但是功能上就比较单一了。

总体来说,两种方式都不是挺理想,我觉得我应该学习一些新的技术了,例如Vue。后来还是选择了modal弹出编辑的方式,功能做了一半,我突然就想,为什么要有更改功能呢?,总是用开发者的思维去做产品肯定不行,开发者认为增删改查是最基本的功能点,而用户在用产品的时候,其实并不一样,用户关心的是功能点,我做这个产品,面对的用户是谁?我得好好想想再动手......

4. 邮件功能

起初想着,在每条列表的后面加上一个操作功能-发邮件,使用简单的mailto:lupeng@xxx.com链接,来触发系统默认邮件客户端来发送邮件。

后来仔细考虑了一下实际使用场景,放弃了这种方式,平常使用的时候,基本上都是表格所有的内容一并发送,来达到提醒的作用,而非督促完成每一条任务清单。另外,发送邮件最好能真正意义上的一键发送,需要省掉中间弹出邮件客户端的环节。

想明白实际的使用场景后,那么邮件的功能就需要更深入一点,需要引入邮件模块,取代使用客户端的作用。

开发过程中的一些想法,作参考,希望能给你一些启示,项目地址:https://github.com/pengloo53/info

查看原文

赞 0 收藏 0 评论 0

鲁鹏 赞了问题 · 2018-03-13

解决为什么会出现函数未定义?

<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>test</title>
    <script data-original="js/jquery.min.js"></script>
</head>

<body>
        <div class="xtsz">
            <div class="xtsz-con">
                <form action="" method="post" onsubmit="return user()">
                    <input type="text">
                    <button type="submit">提交</button>
                </form>
        </div>
    </div>
    <script type="text/javascript">
    $(function(){
        function user() {
        
        }
    })
    </script>
</body>

</html>

这样的编写方式为什么报user函数未定义?

关注 3 回答 4

鲁鹏 赞了回答 · 2018-01-25

vscode有没有格式化ejs的插件?

设置vscode用户配置的文件关联,把ejs关联到html。

"files.associations": {
  "*.ejs": "html"
}

soonfy

关注 8 回答 4

鲁鹏 发布了文章 · 2018-01-22

日志 - Node实战

express模块简单集成了一个日志模块morgan,可以将请求的一些消息打印在后台终端上,然而在实际的生产系统中,我们通常需要更完备的日志功能,以便供运维人员定期查看。

这里简单介绍winston模块的引入,实现最简单的日志写入文件功能,首先项目中安装模块,如下命令:

npm install --save express-winston
npm install --save winston

然后在项目app.js文件中引入对应的模块,如下代码所示:

var winston = require('winston');
var expressWinston = require('express-winston');
// 正常请求的日志
app.use(expressWinston.logger({
  transports: [
    new (winston.transports.Console)({
        json: true,
        colorize: true
    }),
    new winston.transports.File({
      filename: 'logs/success.log'
    })
  ]
}));
// 正常访问路由
routes(app);
// 错误请求的日志
app.use(expressWinston.errorLogger({
  transports: [
    new winston.transports.Console({
        json: true,
        colorize: true
    }),
    new winston.transports.File({
      filename: 'logs/error.log'
    })
  ]
}));

日志文件分为success.logerror.log,放在正常路由之前则为成功日志,放在正常访问路由之后,则为错误日志。如不需过多功能,这样放进项目里即可,详细了解可查看官方文档: winstonjs/winston: A logger for just about everything.


查看原文

赞 0 收藏 1 评论 0

认证与成就

  • 获得 34 次点赞
  • 获得 3 枚徽章 获得 0 枚金徽章, 获得 0 枚银徽章, 获得 3 枚铜徽章

擅长技能
编辑

开源项目 & 著作
编辑

  • JS 插件文档库

    整理并收集前端插件的使用方法,并提供示例代码,可供调试和学习。 一来为了留个存档,二来也是为了分享出去,帮助到需要的人。 该文档起于 jQuery 框架,但不止于 jQuery,希望能整理所有的 Web 前端框架。

  • Hexo 主题

    The Hexo theme base on hexo-theme-light.

注册于 2014-06-10
个人主页被 815 人浏览