首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无法从Three.js示例导入(“三个/示例/jsm/加载器/OBJLoader2 2”的脚本错误)

无法从Three.js示例导入(“三个/示例/jsm/加载器/OBJLoader2 2”的脚本错误)
EN

Stack Overflow用户
提问于 2020-10-05 13:46:40
回答 3查看 1.3K关注 0票数 1

我有一个带有基本Three.js设置的角度应用程序。我使用Bazel构建并运行这个应用程序。在我尝试从OBJLoader2导入three/examples/jsm/loaders/OBJLoader2之前,一切都很好。

代码语言:javascript
复制
const module = await import('three/examples/jsm/loaders/OBJLoader2')
const loader = new module.OBJLoader2()

上面的代码片段不适用于devserver。我在浏览器控制台中得到了这个错误:

代码语言:javascript
复制
GET http://localhost:4200/three/examples/jsm/loaders/OBJLoader2.js net::ERR_ABORTED 404 (Not Found)
Error: Script error for "three/examples/jsm/loaders/OBJLoader2"
    at makeError (ts_scripts.js?v=03400874:175)
    at HTMLScriptElement.onScriptError (ts_scripts.js?v=03400874:1745)

因此,devserver无法找到导入的脚本。但是在生产中运行这个应用程序非常好。

最小再生产

你可以自己试试:https://github.com/drakery3d/angular-bazel-three-starter/tree/ac0c89abf267af094a555c5e4867a46e2ee33a8f

只需运行yarn install,然后运行yarn dev (它会导致浏览器控制台@http://localhost:4200中的错误)。而不是yarn pwa @ http://localhost:8080工作得很好!

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2020-10-11 23:44:40

最后一个答案是不完全正确的,因为它得到了下一个错误:TypeError: Cannot read property 'Objloader2' of undefined。我错过了它,因为我在开发控制台中查看了Network。但是不管怎么说,从服务器获取文件会返回200条信息,这是有意义的。

在那里发生的事情是,ts_devserver只期望UMD输入,但是我们的脚本是另一回事。所以,接下来我要做的就是通过npm_umd_bundle包装它

代码语言:javascript
复制
load("@build_bazel_rules_nodejs//internal/npm_install:npm_umd_bundle.bzl", "npm_umd_bundle")

npm_umd_bundle(
    name = "objloader_umd",
    package_name = "objloader",
    entry_point = "@npm//:node_modules/three/examples/jsm/loaders/OBJLoader2.js",
    package = "@npm//three",
)

并将其作为脚本添加到ts_devserver中:

代码语言:javascript
复制
ts_devserver(
  ...,
  scripts = [
    ...,
    ":objloader_umd",
  ],
)

它给了我们什么?现在我们可以从人工创建的模块objloader中导入东西了!

代码语言:javascript
复制
await import('objloader')

一般情况下,可能就是这样。但为了方便,我们再做一件事吧。我们已经有了用于rxjs深度导入的rxjs_shims.js。让我们以类似的方式再添加一个类似的脚本:

代码语言:javascript
复制
// three/examples/jsm/loaders/OBJLoader2 -> objloader
(function (factory) {
  if (typeof module === 'object' && typeof module.exports === 'object') {
    var v = factory(require, exports);
    if (v !== undefined) module.exports = v;
  } else if (typeof define === 'function' && define.amd) {
    define('three/examples/jsm/loaders/OBJLoader2', ['exports', 'objloader'], factory);
  }
})(function (exports, objloader) {
  'use strict';
  Object.keys(objloader).forEach(function (key) {
    exports[key] = objloader[key];
  });
  Object.defineProperty(exports, '__esModule', {value: true});
});

它主要做的是将three/examples/jsm/loaders/OBJLoader2导入路径混叠到objloader,特别是对devserver。

因此,现在我们甚至不需要区分dev和prod构建,因为导入可以是相同的。不需要更改TS源代码!

票数 2
EN

Stack Overflow用户

发布于 2020-10-11 05:50:54

Bazel不支持development mode中的代码拆分(或延迟导入js文件)。

请阅读他们的从他们的angular-bazel-example。跟随的问题在吉特布。

注意:开发模式中还不支持代码拆分,因此//src:devserver目标不提供代码拆分包。dynamic ()语句将解析到初始JS有效负载中服务的模块。

票数 1
EN

Stack Overflow用户

发布于 2020-10-11 21:00:48

所以,它试图得到http://localhost:4200/three/examples/jsm/loaders/OBJLoader2.js,却无法得到它。合乎道理。

第一个注意事项:如果将导入路径更改为

代码语言:javascript
复制
// @ts-ignore
await import('npm/node_modules/three/examples/jsm/loaders/OBJLoader2')

效果很好!(绕开tsc需要忽略tsc)。您甚至不需要添加这些additional_root_paths或任何其他three-related字段。

第二个注意事项:如果我们将"npm/node_modules/three"添加到additional_root_paths并将导入修正为

代码语言:javascript
复制
// @ts-ignore
await import('examples/jsm/loaders/OBJLoader2')

那它也能用。

但不幸的是,以类似的方式添加"npm/node_modules"并不能使原始导入工作.嗯。

因此,我不知道如何使这个导入在dev和prod中都能工作。但我可以提出一个解决办法!由于它是一个动态导入,所以可以使用类似于以下内容的方法:

代码语言:javascript
复制
let module;
if (isDev) {
  // @ts-ignore
  module = await import('npm/node_modules/three/examples/jsm/loaders/OBJLoader2')
} else {
  module = await import('three/examples/jsm/loaders/OBJLoader2')
}

我相信您已经知道如何区分dev和prod构建,并且可以自己形成isDev var ;)

另外,我听说把变量直接导入函数是不好的模式,因为它会破坏静态分析器。所以我不建议这么做:

代码语言:javascript
复制
const prefix = isDev ? 'npm/node_modules/' : '';
const module = await import(`${prefix}examples/jsm/loaders/OBJLoader2`)

但是,不能完全确定是否为-else子句,因为import的参数仍然是静态的。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64209912

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档