检测 npm 包是否可以在浏览器、节点或两者上运行

发布于 2025-01-10 12:05:03 字数 1222 浏览 0 评论 0原文

我正在构建一个 NextJs 应用程序,它使用一组抽象来使来自 React(组件逻辑等)和节点(API 逻辑)的代码能够利用相同的类型和类。这里的动机是使客户端和服务器端的开发过程看起来无缝。

例如。对 User 类的 User.create 方法的调用将根据运行时环境(即浏览器或节点)而表现不同 - 在浏览器上,它将调用 api通过 POST 请求,在服务器上它将数据保存到数据库中。

到目前为止,这种模式运行得很好,我喜欢它在代码结构方面的表现。但是,为了使其正常工作,我必须将负责在服务器和浏览器上工作的模块导入到单个模块(在本例中为 User 类),这会在尝试解决每个模块中的依赖关系时导致严重错误。

例如,我在服务器中使用 firebase-admin 将数据保存到 Firebase Firestore。但它使用fs,当相同的代码在浏览器上运行时无法解析。

作为解决方法,我在 webpack 配置中将 firebase-admin 的解析别名设置为 false(假设它在浏览器上运行),请参阅下面的代码。

/** next.config.js **/
webpack: (config, { isServer }) => {
if (!isServer) {
    // set alias of node specific modules to false
    // eg: service dependencies
    config.resolve.alias = {
        ...config.resolve.alias,
        'firebase-admin': false,
    }
} else {
  // set alias of browser only modules to false.
    config.resolve.alias = {
      ...config.resolve.alias,
    }
}

虽然这确实有效,但用不了多久,在解析别名中包含所有此类依赖项的过程就会变得非常乏味。

因此,我的方法是编写一个在 npm run dev 之前运行的脚本(或手动),该脚本将读取 package.json 中的所有依赖项,并以某种方式识别包不会在特定的运行时环境上运行并将它们添加到 webpack 配置中。为此,应该有一种方法来识别每个依赖项的这种性质,我认为这不是 npm 或包本身开箱即用的东西。

任何关于如何实现这一目标的建议都非常感谢。谢谢`

I'm building a NextJs application which uses a set of abstractions to enable code from both react (Component logic etc.) and node (API logic) to utilize same types and classes. The motive here is to make the development process seem seamless across client side and server side.

For example. a call on User.create method of the User class will behave differently based on the runtime environment (ie. browser or node) - on the browser, it will call an api with a POST request and on server it will persist data to a database.

So far this pattern worked just fine, and I like how it all turned out in terms of the code structure. However, for this to work, I have to import modules responsible for working on the server and browser to a single module (which in this case is the User class) this leads to a critical error when trying to resolve dependencies in each module.

For example I'm using firebase-admin in the server to persist data to the Firebase Firestore. But it uses fs which cannot be resolved when the same code runs on the browser.

As a work around I set the resolve alias of firebase-admin to false inside the webpack configuration (given it runs on browser) see code below.

/** next.config.js **/
webpack: (config, { isServer }) => {
if (!isServer) {
    // set alias of node specific modules to false
    // eg: service dependencies
    config.resolve.alias = {
        ...config.resolve.alias,
        'firebase-admin': false,
    }
} else {
  // set alias of browser only modules to false.
    config.resolve.alias = {
      ...config.resolve.alias,
    }
}

While this does the trick, it won't be much long until the process gets really tedious to include all such dependencies within resolve aliases.

So, my approach to this is to write a script that runs prior to npm run dev (or manually) that will read all dependencies in package.json and SOMEHOW identify packages that will not run on a specific runtime environment and add them to the webpack config. In order to this, there should be a way to identify this nature of each dependency which I don't think is something that comes right out of the box from npm or the package itself.

Any suggestion on how this can be achieved is really appreciated. Thanks`

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文