Image may be NSFW.
Clik here to view.
$ mkdir textlint-test
$ cd textlint-test
$ npm init --yes$ npm install--save-dev textlint
$ npm install--save-dev textlint-rule-no-todo
$ npm install--save-dev textlint-rule-max-kanji-continuous-len
$ npm install--save-dev express
$ npm install--save-dev ejs
$ npm install--save-dev cors
$ mkdir views
app.js
// vim:set ts=2 et:// https://qiita.com/chenglin/items/5e563e50d1c32dadf4c3 express.jsのcors対応constTextLintEngine=require('textlint').TextLintEngine;constexpress=require('express');constcors=require('cors')constbodyParser=require('body-parser');constapp=express();// 他からAPIリクエストできるように許可app.set("view engine","ejs");// postデータのjsonをパースするおまじないapp.use(bodyParser.urlencoded({extended:true}));app.use(bodyParser.json());// allow corsapp.use(cors());// 18080番ポートで待ちうけるapp.listen(18080,()=>{console.log('Running at Port 18080...');});//app.post('/api/request', (req, res, next) => {app.post(['/api/request','/textlint/api/request'],(req,res,next)=>{constreq_text=req.body.text;constoptions={rules:["no-todo","max-kanji-continuous-len",],rulesConfig:{"no-todo":true,"max-kanji-continuous-len":true,},};constengine=newTextLintEngine(options);engine.executeOnText(req_text).then(results=>{res.json({messages:results[0].messages});});});app.get("/",function(req,res){res.render("index.ejs");});// その他のリクエストに対する404エラーapp.use((req,res)=>{varurl=req.protocol+'://'+req.headers.host+req.url;console.log(url);res.sendStatus(404);});
index.ejs
<!DOCTYPE html><htmllang="ja"><head><metacharset="UTF-8"><title>Title</title><linkrel="stylesheet"href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T"crossorigin="anonymous"><script src="https://code.jquery.com/jquery-3.3.1.min.js"integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="crossorigin="anonymous"></script><script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM"crossorigin="anonymous"></script></head><body><form><divclass="form-group"><labelfor="lint_textarea">Example textarea</label><textareaclass="form-control"id="lint_textarea"rows="10"placeholder="Write something here..."></textarea><buttontype="button"class="btn btn-primary"id="btn_lint">Save</button></div></form><div><p><strong>lint結果</strong><p><ulid="textlint_output"></ul></div><script type="text/javascript">(function(){'use strict';$('#btn_lint').on('click',function(){lettext=$('#lint_textarea').val();lettextData=JSON.stringify({'text':text,});lettextlint_url=location.protocol+"//"+location.host+"/textlint/api/request";$.ajax({type:'POST',url:textlint_url,data:textData,contentType:'application/json',}).done(function(data,textStatus,jqXHR){// https://qiita.com/georgeOsdDev@github/items/34197e63d0fad307fba6$("#textlint_output").empty();letlines=text.split('\n');data.messages.forEach(function(m){letli=document.createElement('li');$(li).text(m.line+"行目"+m.column+"文字目 ["+m.ruleId+"]: <"+m.message+">「"+lines[m.line-1]+"」")$("#textlint_output").append(li);});}).fail(function(jqXHR,textStatus,errorThrown){console.log("failed");});});}());</script></body></html>
$ node app.js
Running at Port 18080...