【问题标题】:Node.js module lookup in Electron+Angular 2 & TypeScript applicationElectron+Angular 2 和 TypeScript 应用程序中的 Node.js 模块查找
【发布时间】:2016-12-09 09:39:37
【问题描述】:

我正在使用 Angular 2 开发一个 Electron 应用程序。
我按照this 教程初步设置了环境。
我的设置有点复杂,但总的来说非常相似。
tsconfig.json:

{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "moduleResolution": "node",
    "sourceMap": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "removeComments": false,
    "noImplicitAny": false
  },
  "exclude": [
    "node_modules",
    "app/node_modules",
    "dist"
  ]
}

systemjs.config.js 和教程中一样,index.html

我的一个模块(位于app 文件夹内的某处 - app/*/*/*/module)依赖于node-ffi。所以我在typings.json 中添加了必要的类型:

{
  "globalDependencies": {
    "core-js": "registry:dt/core-js",
    "jasmine": "registry:dt/jasmine",
    "node": "registry:dt/node",
    "ref": "registry:dt/ref",
    "ref-struct": "registry:dt/ref-struct",
    "ffi": "registry:dt/node-ffi"
  }
}

现在,模块尝试像这样使用ffi

import { DynamicLibrary, Library, types } from 'ffi';

export class CppProxy { 
   //Some code
}

最终转译为:

var ffi_1 = require('ffi');
//Utilize ffi_1 exported stuff

根据this 文章,node.js 模块查找有一种明确定义的方式,根据这种方式,它应该找到node-ffi 模块,因为node-ffi 驻留在app/node_modules 中。然而,事实并非如此。它只在app 文件夹中查找ffi.js,显然找不到它。
我第一次尝试修复它是将ffi 条目添加到systemjs.config.js 的地图部分,如下所示:

  var map = {
    'app': '.', // 'dist',
    '@angular': 'node_modules/@angular',
    'angular2-in-memory-web-api': 'node_modules/angular2-in-memory-web-api',
    'rxjs': 'node_modules/rxjs',
    'node-binary': 'node_modules/systemjs-plugin-node-binary/node-binary.js',
    'ffi': 'node_modules/ffi/lib/ffi.js'
  };

它有助于加载ffi,但带来了新问题。 ffi本身依赖于其他模块:

var ref = require('ref')
var assert = require('assert')
var debug = require('debug')('ffi:ffi')
var Struct = require('ref-struct')
var bindings = require('./bindings')

所以现在应用程序找不到这些模块。我也尝试将其中一些添加到地图中,但它再次解决了一级依赖关系。

在我看来,require 不应该只在 app 文件夹中查找,而且我不想将所有依赖项递归地添加到 systemjs.config.js 的映射部分。 我究竟做错了什么?

更新:
还有另一个question 处理一个非常相似的问题,但它专门询问使用require('remote')
我在问如何在仍然使用System.js 作为模块加载器的同时使用Node.js 模块解析机制。

【问题讨论】:

  • SystemJS 未设置为进行传递依赖配置。您可以使用jspm,它将为您设置systemjs.config.js,或者您可以等待angular-cli 支持安装,或者您可以使用webpack(完全避免使用SystemJS)。
  • 所以为了让它只与 System.js 一起工作,我必须递归地映射所有库?我不明白......我的意思是,依赖是由require()指定的,它是node.js函数......为什么它不能以node.js的方式工作?
  • 我应该更清楚一点。 SystemJS 是传递性的,就像 NodeJS 一样,它以递归方式进行查找(即在找到 ffi 之后,它会去查找 ref)。但是,SystemJS 不能使用 NodeJS 的依赖解析机制(查找 node_modules,上一个目录并再次查找 node_modules,递归)。它不能使用这种机制,因为网站通常不会将所有的 node_modules 复制到它们的静态分发目录中(你的网站会很大!)前端配置总是非常平坦(例如bower<script>)。
  • 我怀疑您遇到了一个统一的front-end/back-end 包管理解决方案的问题,即人们可能会无意中抓取一个仅用于后端使用的包并尝试使用它在浏览器中。我不确定node-ffi 是否适合在浏览器中使用,或者它是否可能。
  • 我真的不知道,但鉴于this comment 似乎 systemjs 在设置时替换了节点的要求。

标签: node.js typescript angular electron systemjs


【解决方案1】:

正如Pace 在他的一个cmets 中提到的,System.js 覆盖Node.jsrequire 方法并使用它自己的解析机制。这就是require 方法不会遵循Node.js lookup mechanism 的原因。但是有一种方法可以使用后者:

System.jsNode.jsrequire 存储在_nodeRequire 变量中。所以使用Node.js机制加载模块的方式是通过

var module = System._nodeRequire('./path/to/module/')

Here 是帮助我想出这个解决方案的讨论。

【讨论】:

猜你喜欢
  • 2019-08-09
  • 2016-12-19
  • 2022-08-02
  • 2017-12-02
  • 1970-01-01
  • 2016-10-17
  • 2019-12-30
  • 2016-07-29
  • 2018-01-17
相关资源
最近更新 更多