Nodejs:真正的一份代码,到处运行

Nodejs:真正的一份代码,到处运行

本质上还是前后端用相同的编程语言导致的复用

23 回复

Node.js: 真正的一份代码,到处运行

Node.js 的核心优势之一在于它允许开发者使用 JavaScript 这种单一语言来构建全栈应用。这意味着你可以在服务器端、客户端以及命令行工具中重用代码,从而实现所谓的“一份代码,到处运行”。

前后端统一语言

JavaScript 在浏览器中的广泛使用已经让前端开发人员非常熟悉这门语言。而随着 Node.js 的出现,同样的 JavaScript 代码也可以运行在服务器端,从而实现了前后端技术栈的统一。

示例:

假设我们有一个简单的计算器服务,需要同时提供给前端用户和后端 API 使用。我们可以编写一个通用的计算函数,并在前后端分别调用它。

// common/math.js
function add(a, b) {
    return a + b;
}

function subtract(a, b) {
    return a - b;
}

module.exports = {
    add,
    subtract
};

在前端(例如 React 应用):

import { add } from './common/math';

console.log(add(5, 3)); // 输出 8

在后端(Node.js 服务器):

const express = require('express');
const { add, subtract } = require('./common/math');

const app = express();

app.get('/add/:a/:b', (req, res) => {
    const a = parseInt(req.params.a);
    const b = parseInt(req.params.b);
    res.send({ result: add(a, b) });
});

app.listen(3000, () => console.log('Server is running on port 3000'));

跨平台命令行工具

除了 Web 应用之外,Node.js 还非常适合用来开发跨平台的命令行工具。这些工具可以利用 JavaScript 的异步特性来处理文件系统、网络请求等任务。

示例:

假设我们需要一个命令行工具来统计文件夹中所有文件的总行数。

// countlines.js
const fs = require('fs');
const path = require('path');

function countLines(filePath, callback) {
    fs.readFile(filePath, 'utf-8', (err, data) => {
        if (err) return callback(err);
        const lines = data.split('\n').length;
        callback(null, lines);
    });
}

function processDirectory(dirPath, callback) {
    fs.readdir(dirPath, (err, files) => {
        if (err) return callback(err);

        let totalLines = 0;
        const pendingFiles = files.length;

        files.forEach(file => {
            const filePath = path.join(dirPath, file);
            countLines(filePath, (err, lines) => {
                if (err) return callback(err);
                totalLines += lines;
                if (--pendingFiles === 0) {
                    callback(null, totalLines);
                }
            });
        });
    });
}

processDirectory(process.argv[2], (err, totalLines) => {
    if (err) throw err;
    console.log(`Total lines in directory: ${totalLines}`);
});

你可以通过以下命令运行该脚本:

node countlines.js /path/to/directory

总结

Node.js 的统一语言特性使得开发者能够更加高效地进行前后端开发,并且还能创建跨平台的命令行工具。这种“一份代码,到处运行”的能力极大地提高了开发效率和代码复用率。


但是给我们一个启示:在nodejs下,前端和后端是一个整体,代码一样可以复用

是的,不用过度去区分前端和后端

我觉得后端只靠扩展名检测无法有效防止恶意上传吧?

但现状还是很遗憾前端的各种兼容性问题还是得处理,因为JS引擎不一致,至少需要一个adapter,比如trim方法…

正解!扩展名是个小儿科的把戏,识别mime type才是王道。

Node. 如果是这样,还有必要在前后端都调用完全一样的逻辑判断过程吗?对于文中提到的两点:前端永远不可信;前端和后端使用不同的编程语言。并没有解决第一个担忧啊。

前后两端的复用能力,是值得实践和积累的。前端的兼容问题,并不妨碍未来的开发趋势。

本人平常一直在强调并信奉前端工程师的职责范围包括:客户端开发(PC/手持设备)、Web页面制作、与用户的交互(JS/AS/…)、与服务器的交互(Ajax/JSONP/…)、服务器端应用展现层开发。 <br/>虽然因人而异、因业务而异,只要认可这一点,那个人就会最大限度的利用各种技术和资源来提高复用和开发效率,推广本nodejs也会更加自然。

前端和后端统一了语言,对程序员而言nodejs最大的好处莫过于此。

本来所有用户的输入都是不可信的,你所谓的第一个担忧实际上只是一个原则不要完全相信用户输入,由于前端的验证等都可能被绕过。 <br/>而正常逻辑下,用户在页面上填写的内容没有填写完毕,即可立即进行客户端校验,这只是减轻服务器端压力的一种做法,你完全可以客户端不做任何验证,但是这一方面增加服务器压力,另外一方面也在一定程度上降低了可用性。

Google搜索Nodejs路过。 <br/>对JS不太过敏,还是习惯用Python,Java类的语言来写后端。而且前后台根本不存在DRY的问题,前台作后缀分析只是为了降低一部分后端的负担,无论前端是否作判断,后端都一样要作判断。 <br/>而且这种趋势感觉会让WEB入门难度更大,同样的语言,分别用来开发前台和后台,对于刚刚入门的人可能会感到异常困惑…~而且JS的prototype继承方式也感觉比较怪。

语言统一还是比较支持的,但有一个的问题,前后端代码相互复用成为潮流的话,由于js在前端对用户来说是可见的,攻击者连猜测都不需要,就明确知道服务器端的验证逻辑了,+_+。

good point

由于js在前端对用户来说是可见的,攻击者连猜测都不需要,就明确知道服务器端的验证逻辑了 <br/> <br/>这个问题确实比较严重

原来的情况也是一样的

js引擎对html dom解析的支持现在所有后台语言都无法企及,如果在服务器端跑上jquery,那么从一个网页中抽取内容就不用正则表达式这种容易出错的方式了。 <br/> <br/>另外js对json的支持也是最方便的。

支持前后端可以共享一小部分逻辑。 <br/>不过,个人认为前后端同样的处理逻辑不可取: <br/>1. 前端主要是相对简单的校验,提高反应速度和减轻后端负担 (庞大的JS也影响载入速度) <br/>2. 后端主要是完整的检验,保证安全性和一致性

前后端不要划分的太清,不过后端的代码还是不要暴漏在外部的好

我想说一下我的理解,前端和后段的问题在于设计时候的问题而不是语言单方面可以解决的。 <br/> <br/>如果按照你这么说的话,用Java或者CGI在后面直接输出HTML和Javascript一样可以做到你所谓的“非冗余”开发。 <br/> <br/>业务逻辑的判断和界面的判断本身就是要分开处理,只能说明你平时设计系统的时候没有真正做到层之间的完善的解耦处理。

我认为不能复用,代码都透明了~有些做成公用函数透明我觉得无所谓~

从项目管理和配合来说,前后端开发语言的统一具有非常积极的意义,至少在中国,沟通成本是软件开发的最大成本。

在 Node.js 中实现“一份代码,到处运行”的理念主要依赖于其全栈 JavaScript 的特性。你可以使用相同的语言编写前端和后端代码,并且可以利用一些框架和工具来提高开发效率和代码重用率。例如,你可以使用 Express.js 来构建后端服务,同时使用 React 或 Vue.js 构建前端应用。

为了更好地理解这一理念,我们可以通过一个简单的示例来展示如何实现这一目标。假设我们需要创建一个 REST API,该 API 可以处理用户的注册请求。我们将在客户端和服务器端使用相同的验证逻辑。

首先,我们先创建一个简单的 Express.js 后端:

// server.js
const express = require('express');
const app = express();
app.use(express.json());

const validateUser = (user) => {
    if (!user.email || !user.password) {
        return false;
    }
    // 在这里添加更复杂的验证逻辑
    return true;
};

app.post('/register', (req, res) => {
    const user = req.body;

    if (!validateUser(user)) {
        return res.status(400).send({ error: 'Invalid user data' });
    }

    // 注册逻辑
    // ...

    res.send({ message: 'User registered successfully' });
});

app.listen(3000, () => console.log('Server running on port 3000'));

接下来,在客户端(例如使用 React)中,我们将使用相同的 validateUser 函数来验证用户输入的数据:

// client/src/utils/validation.js
export function validateUser(user) {
    if (!user.email || !user.password) {
        return false;
    }
    // 在这里添加更复杂的验证逻辑
    return true;
}

// client/src/components/RegisterForm.js
import { useState } from 'react';
import { validateUser } from '../utils/validation';

function RegisterForm() {
    const [email, setEmail] = useState('');
    const [password, setPassword] = useState('');

    const handleSubmit = (e) => {
        e.preventDefault();

        const user = { email, password };

        if (!validateUser(user)) {
            alert('Invalid user data');
            return;
        }

        // 发送注册请求
        fetch('http://localhost:3000/register', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify(user),
        })
        .then((res) => res.json())
        .then((data) => console.log(data))
        .catch((err) => console.error(err));
    };

    return (
        <form onSubmit={handleSubmit}>
            <input type="email" value={email} onChange={(e) => setEmail(e.target.value)} />
            <input type="password" value={password} onChange={(e) => setPassword(e.target.value)} />
            <button type="submit">Register</button>
        </form>
    );
}

通过这种方式,我们可以在前后端使用相同的验证逻辑,从而实现“一份代码,到处运行”。此外,还可以利用诸如 TypeScript、ESLint 和 Prettier 等工具来进一步提高代码质量和可维护性。

回到顶部