Angular2应用程序无法在Play框架中运行

时间:2017-07-16 16:48:17

标签: angular intellij-idea playframework playframework-2.3

下面,Angular相关代码来自Joost' g代码。我认为Joost使用了Activator。当我使用IntelliJ时,我不得不做出一些改变。总之,我的Angular2应用程序并不适用于IntelliJ和Play框架2.6.x。

步骤:

  • 我从Play网站(2.6.x版)下载了Scala启动项目

    SDN4/OGM Cypher query and duplicates at Result

  • 我解压缩了zip并执行了sbt run

    C:\...\play-scala-starter-example>sbt run
    
  • 我验证了应用程序在localhost:9000上运行正常。

  • 然后我在IntelliJ中导入了项目。我收到了Info: SBT compilation for play framework 2.x disabled by default的消息。 问题1 - 我不明白它的含义。

  • 我在IntelliJ中构建并运行项目以检查项目是否仍在运行正常(选择编辑配置选项作为Play 2应用程序)。它是。

  • 我在assets文件夹中添加了一个app文件夹,其中包含以下Angular2相关文件(大多数文件来自joost-de-vries项目。我对它们进行了一些修改以编译代码)。

1)assets \ app文件夹,其中包含3个文件 - app.component.ts,app.module.ts,main.ts

app.component.ts

import { Component } from '@angular/core';

@Component({
    selector: 'my-root',
    template: `
    <h1>{{title}}</h1>
      `
})
export class AppComponent {
    title = 'Tour of Heroes';
}

app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppComponent } from './app.component';

@NgModule({
    imports: [
        BrowserModule,
    ],
    declarations: [
        AppComponent,
    ],
    bootstrap: [AppComponent]
})
export class AppModule { }

main.ts

import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app.module';

const platform = platformBrowserDynamic();
platform.bootstrapModule(AppModule);

2)assets \ systemjs.config.js文件

/**
 * System configuration for Angular samples
 * Adjust as necessary for your application needs.
 */
(function (global) {
    System.config({
        paths: {
            // paths serve as alias
            'npm:': 'assets/lib/'
        },
        // map tells the System loader where to look for things
        map: {
            // our app is within the app folder
            'app': 'assets/app',

            // angular bundles
            '@angular/core': 'npm:angular__core/bundles/core.umd.js',
            '@angular/common': 'npm:angular__common/bundles/common.umd.js',
            '@angular/compiler': 'npm:angular__compiler/bundles/compiler.umd.js',
            '@angular/platform-browser': 'npm:angular__platform-browser/bundles/platform-browser.umd.js',
            '@angular/platform-browser-dynamic': 'npm:angular__platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js',
            '@angular/http': 'npm:angular__http/bundles/http.umd.js',
            '@angular/router': 'npm:angular__router/bundles/router.umd.js',
            '@angular/forms': 'npm:angular__forms/bundles/forms.umd.js',

            // other libraries
            'rxjs':                      'npm:rxjs',
            'angular-in-memory-web-api': 'npm:angular-in-memory-web-api/bundles/in-memory-web-api.umd.js'
        },
        // packages tells the System loader how to load when no filename and/or no extension
        packages: {
            app: {
                defaultExtension: 'js',
                meta: {
                    './*.js': {
                        loader: 'assets/systemjs-angular-loader.js'
                    }
                }
            },
            rxjs: {
                defaultExtension: 'js'
            }
        }
    });
})(this);

3)assets \ systemjs-angular-loader.js文件

var templateUrlRegex = /templateUrl\s*:(\s*['"`](.*?)['"`]\s*)/gm;
var stylesRegex = /styleUrls *:(\s*\[[^\]]*?\])/g;
var stringRegex = /(['`"])((?:[^\\]\\\1|.)*?)\1/g;

module.exports.translate = function(load){
    if (load.source.indexOf('moduleId') != -1) return load;

    var url = document.createElement('a');
    url.href = load.address;

    var basePathParts = url.pathname.split('/');

    basePathParts.pop();
    var basePath = basePathParts.join('/');

    var baseHref = document.createElement('a');
    baseHref.href = this.baseURL;
    baseHref = baseHref.pathname;

    if (!baseHref.startsWith('/base/')) { // it is not karma
        basePath = basePath.replace(baseHref, '');
    }

    load.source = load.source
        .replace(templateUrlRegex, function(match, quote, url){
            var resolvedUrl = url;

            if (url.startsWith('.')) {
                resolvedUrl = basePath + url.substr(1);
            }

            return 'templateUrl: "' + resolvedUrl + '"';
        })
        .replace(stylesRegex, function(match, relativeUrls) {
            var urls = [];

            while ((match = stringRegex.exec(relativeUrls)) !== null) {
                if (match[2].startsWith('.')) {
                    urls.push('"' + basePath + match[2].substr(1) + '"');
                } else {
                    urls.push('"' + match[2] + '"');
                }
            }

            return "styleUrls: [" + urls.join(', ') + "]";
        });

    return load;
};

将build.sbt更改为以下(再次归功于Joost)

name := """play-scala-starter-example"""
version := "0.2.2"
lazy val root = (project in file(".")).enablePlugins(PlayScala)

scalaVersion := "2.11.11"
incOptions := incOptions.value.withNameHashing(true)
updateOptions := updateOptions.value.withCachedResolution(cachedResoluton = true)

//we use nodejs to make our typescript build as fast as possible
JsEngineKeys.engineType := JsEngineKeys.EngineType.Node

resolvers ++= Seq(
  Resolver.jcenterRepo,
  Resolver.bintrayRepo("webjars","maven")
)

libraryDependencies ++= {
  val ngVersion="4.2.5"
  Seq(
    guice,
    ehcache,

    "com.typesafe.play" %% "play-json" % "2.6.1",

    //angular2 dependencies
    "org.webjars.npm" % "angular__common" % ngVersion,
    "org.webjars.npm" % "angular__compiler" % ngVersion,
    "org.webjars.npm" % "angular__core" % ngVersion,
    "org.webjars.npm" % "angular__http" % ngVersion,
    "org.webjars.npm" % "angular__forms" % ngVersion,
    "org.webjars.npm" % "angular__router" % ngVersion,
    "org.webjars.npm" % "angular__platform-browser-dynamic" % ngVersion,
    "org.webjars.npm" % "angular__platform-browser" % ngVersion,
    "org.webjars.npm" % "systemjs" % "0.20.14",
    "org.webjars.npm" % "rxjs" % "5.4.2",
    "org.webjars.npm" % "reflect-metadata" % "0.1.8",
    "org.webjars.npm" % "zone.js" % "0.8.4",
    "org.webjars.npm" % "core-js" % "2.4.1",
    "org.webjars.npm" % "symbol-observable" % "1.0.1",

    "org.webjars.npm" % "typescript" % "2.4.1",

    //tslint dependency
    "org.webjars.npm" % "tslint-eslint-rules" % "3.4.0",
    "org.webjars.npm" % "tslint-microsoft-contrib" % "4.0.0"
    //"org.webjars.npm" % "codelyzer" % "3.1.1"
    //"org.webjars.npm" % "types__jasmine" % "2.5.53" % "test"
    //test
    //"org.webjars.npm" % "jasmine-core" % "2.6.4"
  )
}
dependencyOverrides += "org.webjars.npm" % "minimatch" % "3.0.0"

// use the webjars npm directory (target/web/node_modules ) for resolution of module imports of angular2/core etc
//resolveFromWebjarsNodeModulesDir := true

// compile our tests as commonjs instead of systemjs modules
//(projectTestFile in typescript) := Some("tsconfig.test.json")

// use the combined tslint and eslint rules plus ng2 lint rules
//(rulesDirectories in tslint) := Some(List(
//  tslintEslintRulesDir.value,
//  ng2LintRulesDir.value
//))

// the naming conventions of our test files
//jasmineFilter in jasmine := GlobFilter("*Test.js") | GlobFilter("*Spec.js") | GlobFilter("*.spec.js")
//logLevel in jasmine := Level.Info
//logLevel in tslint := Level.Info

添加了tsconfig.json

{
  /* the configuration of the typescript compiler. See docs https://github.com/Microsoft/TypeScript/wiki/Compiler-Options
  The settings outDir and rootDir are managed by sbt-typescript.
  */
  "compilerOptions": {
    "target": "es5",
    "module": "system",
    "moduleResolution": "node",
    /* the following two settings are required for angular2 annotations to work*/
    "emitDecoratorMetadata": true,
    "experimentalDecorators":true,
    /* for reading your ts source while debugging from a browser */
    "sourceMap": true,
    "mapRoot": "/assets",
    "sourceRoot": "/assets",
    "rootDirs": ["app/assets","test/assets"],
    "baseUrl": ".",
    "paths": {
      "*": [
        "*",
        "target/web/node-modules/main/webjars/*",
        "target/web/node-modules/test/webjars/*"
      ]
    },
    /* noImplicitAny when you want your typescript to be fully typed */
    "strict":true,
    "strictNullChecks":false, //doesn't work yet with @angular RC4
    "outDir": "./target/ts",
    "lib": ["es6", "dom"],
    "typeRoots": ["target/web/node-modules/main/webjars/@types","target/web/node-modules/test/webjars/@types"]
  }
  /* the information below is not used by sbt-typescript. but you can use it if you want to run tsc -p .*/

}

添加了tslint.json

{
  "lintOptions": {
    "fix": true
  },
  "rules": {
    "no-console": false,

    "callable-types": true,
    "class-name": true,
    "comment-format": [
      true,
      "check-space"
    ],
    "curly": true,
    "eofline": true,
    "forin": true,
    "import-blacklist": [true, "rxjs"],
    "import-spacing": true,
    "indent": [
      true,
      "spaces"
    ],
    "interface-over-type-literal": true,
    "label-position": true,
    "max-line-length": [
      true,
      140
    ],
    "member-access": false,
    "member-ordering": [
      true,
      "static-before-instance",
      "variables-before-functions"
    ],
    "no-arg": true,
    "no-bitwise": true,
    "no-console": [
      true,
      "debug",
      "info",
      "time",
      "timeEnd",
      "trace"
    ],
    "no-construct": true,
    "no-debugger": true,
    "no-duplicate-variable": true,
    "no-empty": false,
    "no-empty-interface": true,
    "no-eval": true,
    "no-inferrable-types": [true, "ignore-params"],
    "no-shadowed-variable": true,
    "no-string-literal": false,
    "no-string-throw": true,
    "no-switch-case-fall-through": true,
    "no-trailing-whitespace": true,
    "no-unused-expression": true,
    "no-use-before-declare": true,
    "no-var-keyword": true,
    "object-literal-sort-keys": false,
    "one-line": [
      true,
      "check-open-brace",
      "check-catch",
      "check-else",
      "check-whitespace"
    ],
    "prefer-const": true,
    "quotemark": [
      true,
      "single"
    ],
    "radix": true,
    "semicolon": [
      "always"
    ],
    "triple-equals": [
      true,
      "allow-null-check"
    ],
    "typedef-whitespace": [
      true,
      {
        "call-signature": "nospace",
        "index-signature": "nospace",
        "parameter": "nospace",
        "property-declaration": "nospace",
        "variable-declaration": "nospace"
      }
    ],
    "typeof-compare": true,
    "unified-signatures": true,
    "variable-name": false,
    "whitespace": [
      true,
      "check-branch",
      "check-decl",
      "check-operator",
      "check-separator",
      "check-type"
    ],


//    "directive-selector": [true, "attribute", "my", "camelCase"],
//    "component-selector": [true, "element", "my", "kebab-case"],
//    "use-input-property-decorator": true,
//    "use-output-property-decorator": true,
//    "use-host-property-decorator": true,
//    "no-input-rename": true,
//    "no-output-rename": true,
//    "use-life-cycle-interface": true,
//    "use-pipe-transform-interface": true,
//    "component-class-suffix": true,
//    "directive-class-suffix": true,
//    "no-access-missing-member": true,
//    "templates-use-public": true,
//    "invoke-injectable": true,


    "no-empty": true

  }
}

然后我添加了在编辑配置中编译Typescript的选项(我修改了之前使用过的Play2 App编辑配置)

然后我添加了Application.scala控制器(信用Joost)

package controllers

import play.api._
import play.api.mvc._

class Application extends InjectedController {

  def index = Action {

    Ok(views.html.index1())
  }
}

然后我添加了index1.scala.html

@()
<!doctype html>
<html lang="en" data-framework="angular2">
    <head>
        <base href="/" />
        @* In this version of the application the typescript compilation is done by the play framework.
        The browser downloads .js files. *@
        <meta charset="utf-8">
        <title>Angular Tour of Heroes</title>
        <script type='text/javascript' src='@routes.Assets.versioned("lib/core-js/client/shim.min.js")'></script>
        <script type='text/javascript' src='@routes.Assets.versioned("lib/zone.js/dist/zone.js")'></script>
        <script type='text/javascript' src='@routes.Assets.versioned("lib/systemjs/dist/system.src.js")'></script>

        <script type='text/javascript' src='@routes.Assets.versioned("systemjs.config.js")'></script>
        <script type='text/javascript' src='@routes.Assets.versioned("assets/app/main.js")'></script>

        <!--script>
                System.import('assets/app/main.js').catch(function(err){ console.error(err); });
        </script-->
    </head>
    <body>
        <my-root>Loading....</my-root>
    </body>
</html>

在上面的代码中,我最初尝试使用

<script>
                System.import('assets/app/main.js').catch(function(err){ console.error(err); });
</script>

但Chrome浏览器一直在抱怨安全问题。所以我想直接包含main.js,我假设它会由typescript编译器创建。我怀疑我在这里犯了一些错误。

最后修改了路线文件

GET     /                           controllers.Application.index

该应用程序无法运行。我看到Loading ....。浏览器控制台上的错误是它无法找到http://localhost:9000/assets/assets/app/main.js

我可以看到.js文件是在target \ ts \ app \ assets \ app文件夹中创建的。 问题2 - 我做错了什么?

0 个答案:

没有答案