Angular + AOT + Webpack + NgTools - 问题生成ngFactory

时间:2017-05-03 20:33:27

标签: angular webpack angular2-aot aot

我一直在尝试使用在我的Angular应用程序中工作的ngTools设置AOT(使用Webpack进行模块加载)并且有一个绝对的噩梦。我已经浏览了文档herehere中的各种资源,并阅读了ngTools自述文件,查看了隐藏在Angular CLI中的示例(此应用程序不是使用Angular CLI构建的但我认为这至少是一个有用的参考资料)通过this resource在Angular + Webpack + Sass + ngTools上找到(我也使用SASS但是我的webpack.config.aot.js编译得很好 - 它会阻止我从切换到ngc,至少据我所知,这是我在一些例子中看到过的,以及我在过去几天发现的每个github问题或stackoverflow帖子无论我做什么尝试构建aot都会产生以下错误:

 ERROR in window is not defined

 ERROR in /Users/nataliecoley/development/company-app-name/src/main-aot.ts (2,36): Cannot find module '../aot/src/app/app.module.ngfactory'.

 ERROR in ./src/main-aot.ts

找不到模块:错误:无法解析'/ Users / nataliecoley / development / company-app-name / src'中的'../aot/src/app/app.module.ngfactory'  @ ./src/main-aot.ts 2:0-73

目前我一直在忽略第一个问题(部分是因为我似乎无法在网上发现任何其他人有此错误,部分原因是我搜索了整个代码库,不包括节点模块,{{1} }并没有出现在代码中的任何地方)但如果有人知道可能来自哪里(或者你认为它与错误2和3有关),我愿意接受建议。

虽然我认为第二个和第三个错误消息是我的问题的主要来源,因为很明显windowapp.module.ts之前没有被编译,所以到main-aot.ts时编译它无法找到该文件。但是,我根据我发现的文档进行了设置,以便在编译器到达main-aot.ts时已经编译好app.module.ngfactory

很明显,我的设置中缺少一些部分,因为我在网上找到的每个解决方案设置都略有不同,我似乎无法缩小范围。所有我知道的是,到目前为止我没有尝试过的任何内容消除了这个错误(或产生任何其他新的错误),并且我很乐意帮助那些成功设置AOT + ngTools + webpack + Angular以缩小正在发生的事情的人这里。

这是我的文件结构(简化):

main-aot.ts

我用来运行我的aot构建的命令(我从我分享给角文档的第一个链接中的设置中提取)是我的package.json中的. +-- config/ | +-- helpers.js | +-- webpack.common.js | +-- webpack.dev.js | +-- webpack.prod.js +-- src/ | +-- app/ | +-- assets/ | +-- vendor/ | +-- index.html | +-- main.ts | +-- main-aot.ts | +-- polyfills.ts | +-- tsconfig.json +-- package.json +-- server.js +-- tsconfig-aot.json +-- webpack.config.aot.js +-- webpack.config.js (only contains: module.exports = require('./config/webpack.dev.js');) 。至于相关的软件包版本,我在4.1.0上对所有角度软件包使用"build:aot": "webpack --config webpack.config.aot.js",@ngtools/webpack v1.3.1webpack v 2.3.3

注意:我已经看到了一些关于aot和某些打字稿/角度版本的问题,但我们真的希望坚持这些部分以与我们的其他Angular应用程序保持一致(现在生产超过一年且目前在v4.1.0上没有兴趣降级)以及支持strictnullchecks等等。我知道我听说有人让AOT使用这些版本,任何人都不得不使用旧版本似乎很荒谬Angular只是为了使用AOT所以我觉得必须有一种方法让它工作。

这是我的tsconfig-aot.json:

typescript v2.3.0

这是我的webpack.config.aot.js:

{
  "compilerOptions": {
    "target": "es5",
    "module": "es2015",
    "moduleResolution": "node",
    "sourceMap": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "lib": [ "es2015", "dom" ],
    "noImplicitAny": true,
    "suppressImplicitAnyIndexErrors": true,
    "removeComments": false,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "strictNullChecks": true,
    "skipLibCheck": true,
    "skipCodeGeneration": false,
    "typeRoots": [
      "../node_modules/@types/"
    ]
 },
  "files": [
    "src/app/app.module.ts",
    "src/main-aot.ts"
  ],
  "compileOnSave": true,
  "angularCompilerOptions": {
    "genDir": "aot",
    "entryModule": "src/app/app.module#AppModule",
    "skipMetadataEmit": true
  }
}

关于entryModule的说明。在一些资源中,我看到stateModule选项必须在const ngtools = require('@ngtools/webpack'); const webpack = require('webpack'); const helpers = require('./config/helpers'); module.exports = { devtool: 'source-map', entry: { main: './src/main-aot.ts' }, resolve: { extensions: ['.ts', '.js'] }, target: 'node', output: { path: helpers.root('dist'), filename: 'build.js' }, plugins: [ new ngtools.AotPlugin({ tsConfigPath: helpers.root('tsconfig-aot.json'), entryModule: helpers.root('src', 'app', 'app.module#AppModule') }), new webpack.optimize.UglifyJsPlugin({ sourceMap: true }) ], module: { rules: [ { test: /\.(png|jpe?g|gif|svg|woff|woff2|ttf|eot|ico)$/, loader: 'file-loader?name=assets/[name].[hash].[ext]' }, { test: /\.css$/, loader: 'raw-loader' }, { test: /\.scss$/, loaders: ['to-string-loader', 'style-loader', 'css-loader', 'resolve-url-loader', 'sass-loader?sourceMap'] }, { test: /\.html$/, loader: 'raw-loader' }, { test: /\.ts$/, loader: '@ngtools/webpack' } ] } } 中,而不在tsconfig-aot.json内,我见过的其他例子只在webpack.config.aot.js中。我在tsconfig-aot.json中尝试了它只是webpack.config.aot.js及以上的两者 - 这些选项似乎都无法解决问题。我也尝试编辑各种文件的路径(比如我的tsconfig-aot.json中的文件数组),以防我设置它,因为它在我的文件的错误位置找不到它。

这是我的主要内容:

webpack.config.aot.js

我担心它会成为我错过的一个愚蠢的小作品,但到目前为止我一直在尝试一切,似乎很多其他人在网上也在努力使用这个设置并且似乎没有如何做正确的在线任何明确的信息,所以我想我会发布在这里希望实际上成功地在Angular + Webpack应用程序中工作的人可以指出我正确的方向或共享资源,帮助他们搞清楚了。提前谢谢!

1 个答案:

答案 0 :(得分:0)

我可以理解你在通过Webpack生成构建时的困难。 我,我自己在最近几天做了很多研究,就在Angular 5发布之后 很明显,Angular 5现在完全专注于AOT Builds,我们也应该这样做,因为它可以很好地用于生产构建。

我不习惯Angular,但已经找到了关于它的构建程序的几个关键点......

Typescript(以及tsconfig.json)在Angular Builds中起着关键作用......

注意: ANGULAR 4特定

你可以查看Angular-CLI video,虽然理解使用Webpack的构建设置也没什么帮助...

首先,使用Webpack创建自己的构建系统时要记住几个关键点:

  • Typescript / Angular库的版本号非常重要,请检查Angular Upgrade以找到适合您的版本的版本号。我建议使用Angular v4.4和Typscript v2.5.3精确构建版本
  • 从NPM下载最新的@ ngtools / webpack
  • 为AOT Builds {/ 1>提供tsconfig.json的正确配置文件
  • 你的应用程序中的导入应该使用相对路径,或者应该使用index.ts Barrels,(虽然使用桶非常混乱,花了一整天我的:()

基本上有两种从Webpack获取AOT构建的方法:

  • 首先,使用Angular-CLI命令工具ngc -p tsconfig.json
  • 其次,使用Angulars Official @ ngtools / webpack v ^ 1.7.0。最新的NgTools是非常好的加载器,但是对于Angular的Old Builds(即,4以下的Angular版本),最好使用ngc-webpack作为加载器(尽管我从未尝试过这个加载器,但是它已经全面的文档帮助我理解Angular AOT Compilations)...

第一种方法(I):

查看this Youtube tutorial以了解设置...

TLDR; (可以找到所需的文件列表here

  1. 在源目录中创建bootstrap.aot.ts文件:bootstrap.aot.ts
  2. 创建正确的tsconfig-aot.json文件:tsconfig-aot.json
  3. 为AOT设置您的webpack.config.js,我将只分享一个示例,而不是整个文件......以下文件是webpack.prod.js并合并到webpack.common.js
  4. 正确设置您的package.json 脚本,以便同步运行一些有助于生成构建的命令... package.json

    npm run start:prod:test,是你需要从上面生成AOT Build的命令...... 释:

    1. 清理所有构建目录......
    2. 将ur src / files复制到build /
    3. 从SASS生成CSS,这是ngc的主要问题,即使在Docs中他们声明他们支持SASS / LESS,他们 还没有,至少不恰当......
    4. 更改内部文件TEXT' .scss'到' .css',./config/replace-scss.js如下:
  5. 生成* .ngfactory.ts文件。生成的文件转到dist /文件夹,tsconfig.json决定。这里,ngfactory文件的路径对bootstrap.aot.ts至关重要。如果您在此处收到错误,请记住检查您的文件夹结构....

  6. 我在这里是:

    /
    |---src/                             // Main Source Folder
        |---bootstrap.aot.ts
    |---build/                           // Copied files and Sass->Css in here
    |---dist/
    
    1. 使用打字稿加载器运行Webpack Build,直到现在,ngc已完成AOT编译...
    2.   

      注意:这种方法非常糟糕,可能会破坏。第二种方法更适合工作。

      第二种方法(II):

        

      DO Remeber设置相对路径导入...   *.ngfactory.ts的路径应该是正确的,请检查以上5.点

      bootstrap.aot.tstsconfig-aot.json无需更改,(但在tsconfig中我们现在可以删除文件属性)

      webpack.prod.ts

      package.json

      另外,确认您的Angular,ngtools和打字稿版本......我的

      "@angular/animations": "~4.4.4",
      "@angular/common": "~4.4.4",
      "@angular/compiler": "~4.4.4",
      "@angular/core": "~4.4.4",
      "@angular/forms": "~4.4.4",
      "@angular/http": "~4.4.4",
      "@angular/platform-browser": "~4.4.4",
      "@angular/platform-browser-dynamic": "~4.4.4",
      "@angular/router": "~4.4.4",
      "core-js": "^2.5.1",
      "immutable": "^3.8.2",
      "rxjs": "^5.4.3",
      "zone.js": "~0.8.18"
      "@angular-devkit/build-optimizer": "^0.0.32",
      "@angular/cli": "^1.5.5",
      "@angular/compiler-cli": "^4.4.4",
      "@ngtools/webpack": "^1.7.0",
      "@types/jasmine": "2.5.45",
      "@types/jquery": "^3.2.15",
      "@types/node": "~6.0.60",
      "angular2-template-loader": "^0.6.2",
      "autoprefixer": "^7.1.4",
      "awesome-typescript-loader": "^3.2.3",
      "chalk": "^2.3.0",
      "clean-webpack-plugin": "^0.1.16",
      "codelyzer": "~4.0.1",
      "compodoc": "0.0.41",
      "concurrently": "^3.5.1",
      "copy-webpack-plugin": "^4.0.0",
      "cpx": "^1.5.0",
      "cross-env": "^5.0.5",
      "css-loader": "^0.28.7",
      "extract-text-webpack-plugin": "^3.0.1",
      "file-loader": "^0.11.2",
      "html-webpack-plugin": "^2.30.1",
      "node-sass": "^4.5.3",
      "npm-run-all": "^4.1.1",
      "postcss": "^5.2.11",
      "postcss-loader": "^1.2.2",
      "progress-bar-webpack-plugin": "^1.10.0",
      "raw-loader": "^0.5.1",
      "replace": "^0.3.0",
      "rimraf": "^2.6.2",
      "sass-loader": "^6.0.6",
      "source-map-loader": "^0.2.1",
      "style-loader": "^0.18.2",
      "to-string-loader": "^1.1.5",
      "ts-node": "~3.0.4",
      "tslint": "~5.3.2",
      "tslint-loader": "^3.5.3",
      "typescript": "~2.5.3",
      "uglify-js": "^3.0.28",
      "webpack": "^3.8.1",
      "webpack-bundle-analyzer": "^2.9.1",
      "webpack-combine-loaders": "^2.0.3",
      "webpack-dev-server": "^2.9.3",
      "webpack-merge": "^4.1.0",
      "webpack-notifier": "^1.5.0"
      

      以上所有设置仅适用于生产构建,我从未进行过正确的测试,所以不确定webpack.test.js设置

      我希望这有助于你,如果你还有一些问题,你可以给一个样本回购来复制这个问题。

      进一步的参考文献:(我猜你已经调查过,但可能对其他人有帮助,但它们都是回购,任何人都必须通过那里的资料来了解发生了什么)

      Angular 5

      我试过,但是得到了这个issue,这仍然是一个悬而未决的问题。虽然有Hack可以使用它,但我不能搞乱生产版本。

      每当我获得更多详细信息时,都会更新答案。

      以上链接将指导您更多链接:P