首页 > 解决方案 > TypeError:无法读取 Angular Universal 中未定义的属性“使用”

问题描述

我已经在我的 Angular 项目中使用 @ng-toolkit/universal 包实现了 Angular Universal,当我在 AWS Lambda 中部署应用程序时,我遇到了以下错误

"TypeError: Cannot read property 'use' of undefined",
        "    at Object.<anonymous> (/var/task/lambda.js:26:12)",
        "    at Module._compile (internal/modules/cjs/loader.js:778:30)",
        "    at Object.Module._extensions..js (internal/modules/cjs/loader.js:789:10)",
        "    at Module.load (internal/modules/cjs/loader.js:653:32)",
        "    at tryModuleLoad (internal/modules/cjs/loader.js:593:12)",
        "    at Function.Module._load (internal/modules/cjs/loader.js:585:3)",
        "    at Module.require (internal/modules/cjs/loader.js:692:17)",
        "    at require (internal/modules/cjs/helpers.js:25:18)",
        "    at _tryRequire (/var/runtime/UserFunction.js:75:12)",
        "    at _loadUserApp (/var/runtime/UserFunction.js:95:12)"

lambda.js

// generated by @ng-toolkit/serverless
const awsServerlessExpress = require('aws-serverless-express');
const server = require('./dist/server');
const awsServerlessExpressMiddleware = require('aws-serverless-express/middleware');

const binaryMimeTypes = [
  'application/javascript',
  'application/json',
  'application/octet-stream',
  'application/xml',
  'image/jpeg',
  'image/png',
  'image/gif',
  'text/comma-separated-values',
  'text/css',
  'text/html',
  'text/javascript',
  'text/plain',
  'text/text',
  'text/xml',
  'image/x-icon',
  'image/svg+xml',
    'application/x-font-ttf'
];

server.app.use(awsServerlessExpressMiddleware.eventContext());

const serverProxy = awsServerlessExpress.createServer(server.app, null, binaryMimeTypes);
module.exports.universal = (event, context) => awsServerlessExpress.proxy(serverProxy, event, context);

包.json

{
  "name": "blogapp",
  "version": "0.0.0",
  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e",
    "compile:server": "webpack --config webpack.server.config.js --progress --colors",
    "serve:ssr": "node dist/server",
    "build:ssr": "ng build --prod && ng run blogapp:server:production && npm run compile:server",
    "build:client-and-server-bundles": "ng build --prod && ng run blogapp:server:production --bundleDependencies all",
    "server": "node local.js",
    "build:prod": "npm run build:browser:prod && npm run build:server:prod",
    "serve:prerender": "node static.js",
    "build:prerender": "npm run build:prod && node dist/prerender.js",
    "build:browser:prod": "ng build --prod",
    "build:browser:serverless": "ng build --prod --base-href /production/",
    "build:serverless": "npm run build:browser:serverless && npm run build:server:serverless",
    "build:prod:deploy": "npm run build:prod && npm run deploy",
    "build:serverless:deploy": "npm run build:serverless && npm run deploy",
    "deploy": "serverless deploy",
    "build:server:prod": "ng run blogapp:server:production && npm run compile:server",
    "build:server:serverless": "ng run blogapp:server:serverless && npm run compile:server",
    "terminate": "serverless remove"
  },
  "private": true,
  "dependencies": {
    "@angular-devkit/schematics": "^9.1.0",
    "@angular/animations": "~9.1.6",
    "@angular/common": "~9.1.6",
    "@angular/compiler": "~9.1.6",
    "@angular/core": "~9.1.6",
    "@angular/forms": "~9.1.6",
    "@angular/platform-browser": "~9.1.6",
    "@angular/platform-browser-dynamic": "~9.1.6",
    "@angular/platform-server": "~9.1.6",
    "@angular/router": "~9.1.6",
    "@ng-toolkit/serverless": "^8.1.0",
    "@ng-toolkit/universal": "^8.0.3",
    "@nguniversal/common": "8.1.0",
    "@nguniversal/express-engine": "v8.2.6",
    "@nguniversal/module-map-ngfactory-loader": "v8.2.6",
    "@schematics/angular": "^9.1.0",
    "@syncfusion/ej2-angular-richtexteditor": "^18.2.56",
    "@vendia/serverless-express": "^4.3.4",
    "aws-sdk": "^2.797.0",
    "aws-serverless-express": "^3.3.6",
    "bootstrap": "^3.3.7",
    "cors": "^2.8.5",
    "domino": "^2.1.3",
    "express": "^4.15.2",
    "font-awesome": "^4.7.0",
    "jquery": "^3.5.1",
    "ng-lazyload-image": "^9.1.0",
    "ngx-spinner": "^10.0.1",
    "rxjs": "~6.5.4",
    "tslib": "^1.10.0",
    "web-animations-js": "^2.3.2",
    "zone.js": "~0.10.2"
  },
  "devDependencies": {
    "@angular-devkit/build-angular": "^0.901.15",
    "@angular/cli": "^9.1.6",
    "@angular/compiler-cli": "~9.1.6",
    "@types/express": "^4.17.0",
    "@types/jasmine": "~3.5.0",
    "@types/jasminewd2": "~2.0.3",
    "@types/node": "^12.19.6",
    "codelyzer": "^5.1.2",
    "jasmine-core": "~3.5.0",
    "jasmine-spec-reporter": "~4.2.1",
    "karma": "~5.0.0",
    "karma-chrome-launcher": "~3.1.0",
    "karma-coverage-istanbul-reporter": "~2.1.0",
    "karma-jasmine": "~3.0.1",
    "karma-jasmine-html-reporter": "^1.4.2",
    "opencollective": "^1.0.3",
    "protractor": "~5.4.3",
    "serverless": "^2.29.0",
    "serverless-api-compression": "^1.0.1",
    "serverless-apigw-binary": "^0.4.4",
    "ts-loader": "^6.2.1",
    "ts-node": "~8.3.0",
    "tslint": "~6.1.0",
    "typescript": "~3.8.3",
    "webpack-cli": "^3.3.10"
  }
}

服务器.ts

/**
 * *** NOTE ON IMPORTING FROM ANGULAR AND NGUNIVERSAL IN THIS FILE ***
 *
 * If your application uses third-party dependencies, you'll need to
 * either use Webpack or the Angular CLI's `bundleDependencies` feature
 * in order to adequately package them for use on the server without a
 * node_modules directory.
 *
 * However, due to the nature of the CLI's `bundleDependencies`, importing
 * Angular in this file will create a different instance of Angular than
 * the version in the compiled application code. This leads to unavoidable
 * conflicts. Therefore, please do not explicitly import from @angular or
 * @nguniversal in this file. You can export any needed resources
 * from your application's main.server.ts file, as seen below with the
 * import for `ngExpressEngine`.
 */

import 'zone.js/dist/zone-node';

import  express from 'express';
import {join} from 'path';

// Express server
const app = express();

const PORT = process.env.PORT || 4000;
const DIST_FOLDER = join(process.cwd(), 'dist/browser');

// * NOTE :: leave this as require() since this file is built Dynamically from webpack
const {AppServerModuleNgFactory, LAZY_MODULE_MAP, ngExpressEngine, provideModuleMap} = require('./dist/server/main');

// Our Universal express-engine (found @ https://github.com/angular/universal/tree/master/modules/express-engine)
app.engine('html', ngExpressEngine({
  bootstrap: AppServerModuleNgFactory,
  providers: [
    provideModuleMap(LAZY_MODULE_MAP)
  ]
}));

app.set('view engine', 'html');
app.set('views', DIST_FOLDER);

// Example Express Rest API endpoints
// app.get('/api/**', (req, res) => { });
// Serve static files from /browser
app.get('*.*', express.static(DIST_FOLDER, {
  maxAge: '1y'
}));

// All regular routes use the Universal engine
app.get('*', (req, res) => {
  res.render('index', { req });
});


// Start up the Node server
app.listen(PORT, () => {
    // tslint:disable-next-line: no-console
    console.log(`Node Express server listening on http://localhost:${PORT}`);
});


webpack.server.config.js

// Work around for https://github.com/angular/angular-cli/issues/7200

const path = require('path');
const webpack = require('webpack');

module.exports = {
  mode: 'none',
  entry: {
    // This is our Express server for Dynamic universal
    server: './server.ts',
    prerender: './prerender.ts'
  },
  externals: {
    './dist/server/main': 'require("./server/main")'
  },
  target: 'node',
  resolve: { extensions: ['.ts', '.js'] },
  optimization: {
    minimize: false
  },
  output: {
    //libraryTarget: 'commonjs2',
    // Puts the output at the root of the dist folder
    path: path.join(__dirname, 'dist'),
    filename: '[name].js'
  },
  module: {
    noParse: /polyfills-.*\.js/,
    rules: [
      { test: /\.ts$/, loader: 'ts-loader' },
      {
        // Mark files inside `@angular/core` as using SystemJS style dynamic imports.
        // Removing this will cause deprecation warnings to appear.
        test: /(\\|\/)@angular(\\|\/)core(\\|\/).+\.js$/,
        parser: { system: true },
      },
    ]
  },
  plugins: [
    new webpack.ContextReplacementPlugin(
      // fixes WARNING Critical dependency: the request of a dependency is an expression
      /(.+)?angular(\\|\/)core(.+)?/,
      path.join(__dirname, 'src'), // location of your src
      {} // a map of your routes
    ),
    new webpack.ContextReplacementPlugin(
      // fixes WARNING Critical dependency: the request of a dependency is an expression
      /(.+)?express(\\|\/)(.+)?/,
      path.join(__dirname, 'src'),
      {}
    )
  ]
};

此外,我在使用命令运行应用程序时在本地遇到不同的错误

npm 运行构建:ssr npm 运行服务:ssr

Error: You must pass in a NgModule or NgModuleFactory to be bootstrapped
    at View.engine (/home/atif/Desktop/Code/BlogFE/blogui/BlogApp/dist/server/main.js:1:1181560)
    at View.render (/home/atif/Desktop/Code/BlogFE/blogui/BlogApp/dist/server.js:17439:8)
    at tryRender (/home/atif/Desktop/Code/BlogFE/blogui/BlogApp/dist/server.js:12672:10)
    at Function.render (/home/atif/Desktop/Code/BlogFE/blogui/BlogApp/dist/server.js:12624:3)
    at ServerResponse.render (/home/atif/Desktop/Code/BlogFE/blogui/BlogApp/dist/server.js:25036:7)
    at /home/atif/Desktop/Code/BlogFE/blogui/BlogApp/dist/server.js:137:9
    at Layer.handle [as handle_request] (/home/atif/Desktop/Code/BlogFE/blogui/BlogApp/dist/server.js:16056:5)
    at next (/home/atif/Desktop/Code/BlogFE/blogui/BlogApp/dist/server.js:14977:13)
    at Route.dispatch (/home/atif/Desktop/Code/BlogFE/blogui/BlogApp/dist/server.js:14952:3)
    at Layer.handle [as handle_request] (/home/atif/Desktop/Code/BlogFE/blogui/BlogApp/dist/server.js:16056:5)

标签: angularexpresswebpackserver-side-renderingangular-universal

解决方案


推荐阅读