如何在不使用 Module Bundler 的情况下在节点模块中需要一个函数

How do I require a function in a node modules without using a Module Bundler

我在任何地方都找不到准确的答案。我知道浏览器不识别 commonJS 语法,因此如果将 require() 加载到浏览器中,会出现这样的引用错误

let isEven = require('is-even') // ReferenceError: Can't find variable: require
console.log(isEven(6)); // this doesn't run

所以我尝试像这样使用 ES6 模块:

import isEven from "is-even";
console.log(isEven(6));

然后我在控制台中收到此错误:

TypeError: Module specifier, 'is-even' does not start with "/", "./", or "../".

我目前的解决方法是 运行 像 Webpack 这样的模块捆绑器,它允许我有效地使用这两种语法,而且我没有遇到任何问题。但是我宁愿找到一个替代方案,因为我发现在使用模块捆绑器时更难修复错误,因为很难找到导致错误的代码。除了使用模块捆绑器在提供给浏览器之前转换为旧的 Javascript 模块之外,还有其他选择吗?

试试这个

export { isEven }; // module exports a function:

模块从 is-even.mjs

导入函数
import { isEven } from './is-even.mjs';
console.log(is-even(6));
浏览器中的

import 不允许从纯文件名导入。您至少必须构造某种以 "/""./""../" 开头的路径,甚至是完整的 URL,因为 import 在浏览器中没有从中加载纯文件名的“默​​认”位置。您必须明确说明路径是什么。

并且请记住,来自浏览器的 import 将向您的服务器发出请求,并且您的服务器必须配置为在请求时向浏览器提供该文件。

因此,根据您配置服务器的方式,您可能需要这样的东西:

import isEven from "/is-even.js";
console.log(isEven(6));

或者,如果您的服务器单独处理脚本,您甚至可能拥有:

import isEven from "/scripts/is-even.js";
console.log(isEven(6));

然后,Web 服务器有责任知道如何接收这些请求之一,知道实际脚本文件在服务器文件系统中的位置,获取它并将其发送回浏览器。


请记住,client-side 代码使用捆绑器的主要原因是网页加载大量脚本模块效率不高,每个脚本模块都是单独加载的,因为每个脚本加载都是一个 http round-trip 请求到你的服务器。加载可以从 client-side 缓存中获益,但您仍然不希望 web-site 的主页在用户第一次访问您的主页时加载 50 个单独的模块只是为了获取您的所有内容脚本加载到浏览器中。

因此,在 client-side 代码中为 isEven() 这样的一个函数导入脚本通常效率不高。这就是捆绑器存在的原因,这样您就可以在漂亮的、模块化的、可单独测试的模块中编写代码,然后让捆绑器获取特定 client-side 操作所需的所有代码,并将其收集到一个通用脚本文件中然后可以更有效地将其加载到 client-side 环境中。