在 Node-Browser(Isomorphic) 库中使用流或任何 Node.js 库

问题描述

我正在开发一个 Node-browser (Isomorphic) 库,其中的源代码是用 TypeScript 编写的,然后被转换成 CJS 和 ES 模块。 转译后的代码按原样发送,在发布前未使用模块捆绑器进行捆绑。

我需要使用 node core 的 stream 模块,我打算在浏览器部分使用 stream-browserify 包。

  1. 在库中使用 Node.js 流或任何特定于节点的库的最佳方法是什么?
  2. 如何在无需重写相同代码或尽量减少重复的情况下包含流浏览器?
  3. 我遇到了一些使用 package.json 中的 browser 字段的示例,如下所示 -
   "browser" : {
       "stream":"stream-browserify";
   } 

这是如何工作的?

解决方法

您将需要配置用于转换代码以了解已安装模块的任何工具。

如果您不捆绑代码,则意味着您在导入每个单独的文件时加载它(我不确定您如何或打算如何使用 CJS 执行此操作,因为没有 require()浏览器中的 API)。但是,如果我 import foo from "some-library";some-library 是第三方包,需要加载的 JavaScript 文件需要以某种方式导入。

这意味着三件事:

  1. 您需要模块的代码,这意味着您需要实际安装它(您将使用 dependencies 中的 package.json 散列执行此操作)。
  2. 您需要能够导入代码。这意味着您的 import 语句需要由您的转译器/捆绑器/等重写。指向可访问的路径。 import foo from 'some-library'; 需要将 'some-library' 翻译成类似 node_modules/some-library/src/index.js 的内容。否则浏览器如何知道要加载什么以及从哪里加载?
  3. 您需要对要导入的库的内部执行相同的操作,因为它们还需要重写其导入。

您提到的 browser 哈希将代码中导入的模块名称映射到模块的浏览器友好版本。您列出的示例意味着 require('stream') 在为浏览器编译时变为 require('stream-browserify'),在为 Node 编译时变为 require('stream')

对于上面的 #2 和 #3,TypeScript(或者更确切地说,tsc)不会为你做这些。 听起来你想要一个像Snowpack这样的工具。但是,有一些事情需要注意。

首先,你不能在浏览器中运行任何 Node 模块,或者至少没有像 Webpack 这样更高级的工具来模拟/重写/替换需要 Node 并且不能的依赖项 在浏览器中运行。如果您导入的模块需要另一个不是浏览器安全的模块,您将不会知道它不是浏览器安全的,直到它在运行时抛出错误(无论是 JS 错误还是来自您的服务器的 404)。

其次,您可能确实想要一个打包器。如果你使用 Node 模块,依赖树会变得很深。如果您的 node_modules/ 目录中有 5,000 个 JS 文件,那就是 5,000 个网络请求——其中许多需要串行加载、解析和执行(即,在导入它们的模块加载和解析之后)。像摇树这样的优化离不开打包器:即使是用于生产目的的 Snowpack recommends creating an optimized build

也就是说,如果您要发布一个包(也就是说,您将其上传到 NPM,而不是将其部署到您自己的服务器),这几乎没有实际意义。只需按照通常的方式编写代码,在 dependencies 中列出您的依赖项,在 browser 中列出浏览器安全的等效项,然后发布您的转译源。实际使用你的库的人会担心如何加载它。如果您不发布到 NPM(也就是说,您自己将这些代码放到网络上),请考虑使用打包程序。打包器并不妨碍您拥有同构库:您可以拥有一个在浏览器和 Node 中运行的单个 JS 文件,或者您可以拥有从同一源编译的两个输出文件(一个浏览器,一个 Node)。您如何实现这一目标取决于您的目标。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...