我有一个Play
应用程序。应用程序的UI
在Angular
中。我已经创建了一个顶层Angular
目录的文件夹ui
。
build.sbt
`ui-dev-build` := {
implicit val UIroot = baseDirectory.value / "ui"
if (runDevBuild != Success) throw new Exception("Oops! UI Build crashed.")
}
def runDevBuild(implicit dir: File): Int = ifUiInstalled(runScript("npm run build"))
package.json
"build": "ng build --output-path ../public/ui",
在构建Angular
应用程序时,我将输出传输到Play
框架的public
文件夹。从那里,Play
将public
文件夹的联系人传输到target
文件夹进行部署。在index.html
(主页html文件)中,我通过包含在Angular
build中创建的脚本来访问angular
。
<script src="@routes.Assets.versioned("ui/runtime.js")" type="text/javascript"></script>
<script src="@routes.Assets.versioned("ui/vendor.js")" type="text/javascript"></script>
<script src="@routes.Assets.versioned("ui/styles.js")" type="text/javascript"></script>
<script src="@routes.Assets.versioned("ui/main.js")" type="text/javascript"></script>
<script src="@routes.Assets.versioned("ui/scripts.js")" type="text/javascript"></script>
这可以很好地工作。
我想在我的应用程序https://github.com/fxmontigny/ng2-ace-editor中使用ng-ace2-editor
。我已经将其添加到package.json
- "ng2-ace-editor": "0.3.9"
中,并且我可以看到ng2-ace-editor
目录存在于node_modules
中。
当我运行应用程序时,我得到了错误
GET http://localhost:9000/mode-html.js net::ERR_ABORTED 404 (Not Found)
exports.loadScript @ index.js:3802
exports.loadModule @ index.js:4174
setMode @ index.js:10152
push../node_modules/ng2-ace-editor/src/component.js.AceEditorComponent.setMode
我不明白如何让我的应用程序找到mode-html.js
。该文件位于位置"./node_modules/ace-builds/src-min/mode-html.js
。我已经在package.json
的"script":[]
中添加了此路径,但仍然收到错误。
"scripts":[
"./node_modules/ace-builds/src-min/ace.js",
"./node_modules/ace-builds/src-min/theme-eclipse.js",
"./node_modules/ace-builds/src-min/mode-html.js"
]
有趣的是,如果我在主页文件中包含ace.js
,就可以正常工作
<script src="@routes.Assets.versioned("ui/runtime.js")" type="text/javascript"></script>
<script src="@routes.Assets.versioned("ui/vendor.js")" type="text/javascript"></script>
<script src="@routes.Assets.versioned("ui/styles.js")" type="text/javascript"></script>
<script src="@routes.Assets.versioned("ui/main.js")" type="text/javascript"></script>
<script src="@routes.Assets.versioned("ui/scripts.js")" type="text/javascript"></script>
<script src="@routes.Assets.versioned("javascripts/common/vendor/ace/src-min/ace.js")" type="text/javascript"></script> <!-- this makes things work-->
所以我知道这个问题是我的mode-html.js
文件没有得到服务,很可能是路径解析问题,但我不知道是什么问题。
进一步分析表明,ace.js
中的以下代码导致了该错误。
exports.loadModule = function(moduleName, onLoad) {
var module, moduleType;
if (Array.isArray(moduleName)) {
moduleType = moduleName[0];
moduleName = moduleName[1];
}
try {
module = require(moduleName);
} catch (e) {}
if (module && !exports.$loading[moduleName])
return onLoad && onLoad(module);
if (!exports.$loading[moduleName])
exports.$loading[moduleName] = [];
exports.$loading[moduleName].push(onLoad);
if (exports.$loading[moduleName].length > 1)
return;
var afterLoad = function() {
require([moduleName], function(module) {
exports._emit("load.module", {name: moduleName, module: module});
var listeners = exports.$loading[moduleName];
exports.$loading[moduleName] = null;
listeners.forEach(function(onLoad) {
onLoad && onLoad(module);
});
});
};
if (!exports.get("packaged"))
return afterLoad();
net.loadScript(exports.moduleUrl(moduleName, moduleType), afterLoad);
reportErrorIfPathIsNotConfigured();
};
var reportErrorIfPathIsNotConfigured = function() {
if (
!options.basePath && !options.workerPath
&& !options.modePath && !options.themePath
&& !Object.keys(options.$moduleUrls).length
) {
console.error(
"Unable to infer path to ace from script src,",
"use ace.config.set('basePath', 'path') to enable dynamic loading of modes and themes",
"or with webpack use ace/webpack-resolver"
);
reportErrorIfPathIsNotConfigured = function() {};
}
};
为什么显式调用<script src="@routes.Assets.versioned("javascripts/common/vendor/ace/src-min/ace.js")" type="text/javascript"></script>
可以让代码正常工作。根据Angular打包方法https://upgradetoangular.com/angular-news/the-angular-cli-is-a-great-way-to-build-your-angular-app-but-what-it-does-can-be-a-mystery-what-are-those-files-it-generates/,此脚本是否已在ui/scripts.js
中可用
发布于 2020-02-18 07:50:57
我终于能够让我的代码正常工作了。我的设置是不同的。我构建了我的Angular应用程序,它是由我的Play服务器提供的。angular构建存储在Play的/public/ui文件夹中。请求的格式应为/assets/ui/..它被映射到/public/ui/...由于播放路由文件中的规则
GET /assets/*file controllers.Assets.versioned(path="/public", file: Asset)
当我运行代码时,我得到了错误。
Uncaught DOMException: Failed to execute 'importScripts' on 'WorkerGlobalScope': The script at 'http://localhost:9000/worker-javascript.js' failed to load.
at blob:http://localhost:9000/3df21e42-fecb-4026-8bd6-f2b0d1d0540a:1:1
早些时候,我也收到了错误Unable to infer path to ace from script src, use ace.config.set('basePath', 'path') to enable dynamic loading of modes and themes or with webpack use ace/webpack-resolver
似乎ng-ace-editor
根据编辑器的theme
和mode
导入了.js
脚本(主题、模式、工作者)。theme
和mode
js
文件可以包含在scripts.js
中,但一些worker-.js
文件不能包含(我不知道为什么,可能是因为worker文件是使用importScript动态加载的。
Angular.json
中的脚本部分是(这将全部打包到Angular的最终包中的scripts.js中)
"scripts": [
"./node_modules/ace-builds/src/ace.js",
"./node_modules/ace-builds/src/theme-eclipse.js",
"./node_modules/ace-builds/src/theme-monokai.js",
"./node_modules/ace-builds/src/mode-html.js"
]]
为了包含worker-.js
文件,我添加了这个规则,因为它似乎不能从node_modules
加载angular-cli
。因此,我必须将文件从node modules
复制到我的ui
build - How to include assets from node_modules in angular cli project的根目录
"assets": [
"src/assets",
"src/favicon.ico",
{
"glob": "**/*",
"input": "./node_modules/ace-builds/src/",
"output": "/"
}
],
当我执行代码时,我发现了http://localhost:9000/worker-javascript.js can't be loaded
的错误。我意识到我的文件加载在/assets/ui/
路径中,而不是服务器的根目录中。因此,我在组件的.ts
文件中将basepath
设置为/assets/ui
import * as ace from 'ace-builds/src-noconflict/ace';
ace.config.set('basePath', '/assets/ui/');
ace.config.set('modePath', '');
ace.config.set('themePath', '');
总之,basePath
似乎是用于动态加载脚本的工具(例如工作者脚本) modePath
和themePath
是/
,因为模式和主题脚本捆绑在scripts.js
中,并且在根级别可用。由于angular_cli不能从node_modules
复制资产,因此需要将worker-.js
文件复制到node_modules
外部
https://stackoverflow.com/questions/60176763
复制