Node.js® is a JavaScript runtime built on Chrome's V8 JavaScript engine.
提到 Node.js, 绕不过 JavaScript.
December 4, 1995
SpiderMonkey | |
Chakra | |
JavaScriptCore | |
V8 |
2009
历史上曾经出现过运行在 JVM 上的 Rhino, .Net 上的 JScript, 以及其他五花八门的实现.
/* https://tc39.es */
@Get('/users') getUsers() {};
let result = do {
let v = f();
v * v + 1
};
let data = url
|> await fetch
|> await %.json();
const res = await fetch(api);
match (res) {
when ({
status: 200, headers: { 'Content-Length': size }
}):
console.log('size is', size);
when ({ status: 404 }):
console.log('API not found');
when ({ status }) if (status >= 400): do {
throw new RequestError(res);
}
};
Web API 是用于开发 Web 时使用的浏览器接口, 它们不是 JavaScript 的必要组成部分. 例如:
window.getSelection
document.getElementById
location.href
localStorage
fetch
console.log
没有统一的标准库.
本身没有 IO, 写不出 Hello world.
😅
每个前端的电脑上都安装了 Node.js.
很多 JS 代码能在 Node.js 里跑起来.
ls
// #!/usr/bin/env node const fs = require('fs/promises'); const files = await fs.readdir('.') const result = files.join('\n'); console.log(result);
读写文件能做很多事, 例如
const fs = require('fs/promises');
fs.readFile('App.jsx');
// transform code
fs.writeFile('App.js');
ECMAScript 是标准, JavaScript 是实现.
ES3 ES5 ES6
ES2015 ES2016 ... ES2022
ESNext
Babel 可以把高版本代码编译到低版本.
const http = require('http'); const server = http.createServer((req, res) => { const time = new Date(); const json = JSON.stringify({ time }); res.statusCode = 200; res.setHeader('Content-Type', 'application/json'); res.end(json); }); server.listen(3000);
const express = require('express'); const app = express(); app.get('/', (req, res) => { res.send('<h1>Hello express!</h1>'); }) app.listen(3000);
const Koa = require('koa'); const app = new Koa(); app.use(async ctx => { ctx.body = '<h1>Hello koa!</h1>'; }); app.listen(3000);
import { Get, Controller, Render } from '@nestjs/common';
import { PostsService } from './posts/posts.service';
@Controller()
export class AppController {
constructor(private readonly postsService: PostsService) {}
@Get('/posts')
@Render('posts')
render() {
const posts = this.postsService.getPosts();
return { posts };
}
}
把变量塞进模板, 输出 HTML.
import ejs from 'ejs';
const template = '<h1>Hello {<%= name %>!</h1>';
/* <h1>Hello ejs!</h1> */
ejs.render(template, { name: 'ejs' });
拼接字符串? 类似, 但不完全是.
const name = 'world';
`<h1>Hello ${name}!</h1>`;
ejs 语法
<!-- 条件 -->
<% if (user) { %>
<h2><%= user.name %></h2>
<% } %>
<!-- 循环 -->
<ul>
<% users.forEach(function(user){ %>
<!-- 引用 -->
<%- include('user/show', {user: user}); %>
<% }); %>
</ul>
pug 语法
<!-- 缩进 -->
#root.container.m-auto
h1.text-red Hello pug!
<div id="root" class="container m-auto">
<h1 class="text-red">Hello pug!</h1>
</div>
多如牛毛的 template engines
{
ejs: '<h1>Hello {<%= name %>!</h1>',
pug: 'h1 Hello #{ name }!',
lodash: '<% _.forEach(l, function(n) { %><li><%- n %></li><% }); %>',
mustache: '{{title}} spends {{calc}}',
nunjucks: '{% block nav %} <h1>{{ logo }}</h1> {% endblock %}'
react: '<App title={title} />',
}
React template
const App = () => { const [value, setValue] = React.useState(0); return ( <button style={{ fontSize: 96 }} onClick={() => setValue(value + 1)}> 👍<sup>{value}</sup> </button> ); }; new Koa() .use(async (ctx) => { ctx.body = ` <div id="app">${ReactDOMServer.renderToString(<App />)}</div> `; }) .listen();