Угловая универсальная / серверная рендеринг отсутствующих файлов - PullRequest
0 голосов
/ 15 февраля 2019

Я пытаюсь сделать свое угловое приложение для ssr, в официальной документации написано, что я должен запустить

webpack --config webpack.server.config.js --progress --colors

Но я могу 'заставить его правильно скомпилироваться:

ERROR in ./server.ts
Module not found: Error: Can't resolve './server/main' in '/home/lucaswxp/reduza/reduza-angular'
 @ ./server.ts 18:9-33

Строка с проблемой:

const { AppServerModuleNgFactory, LAZY_MODULE_MAP } = require('./server/main');

Предполагается, что эти файлы создаются динамически, поэтому они требуются с помощью "require", но естьв папке dist нет файла "server / main.js", вот что я получил в папке dist:

out-tsc/
   e2e/
   src/
   node_modules/
reduza-ui/ <-- my project name
   main.08ht283hg20s3.js
server.js
server.js.map

И мой конфиг angular.json:

"server": {
          "builder": "@angular-devkit/build-angular:server",
          "options": {
            "outputPath": "dist/reduza-ui",
            "main": "src/server.main.ts",
            "tsConfig": "src/server.tsconfig.app.json"
          },
          "configurations": {
            "stable": {
              "optimization": true,
              "outputHashing": "all",
              "sourceMap": false,
              "namedChunks": false,
              "extractLicenses": true,
              "vendorChunk": false,
              "fileReplacements": [
                { 
                  "replace": "src/environments/environment.ts",
                  "with": "src/environments/environment.prod.ts"
                }
              ]
            }
          }
        }

Там нет "серверной" папки.Я не могу понять, что я пропустил?Я попытался включить вручную файл dist/reduza-ui/main.08ht283hg20s3.js, этот скомпилированный, но я получил следующую ошибку при обработке localhost:4000:

TypeError: Cannot read property 'moduleType' of undefined
    at /home/lucaswxp/reduza/reduza-angular/dist/server.js:151:1457
    at e.invoke (/home/lucaswxp/reduza/reduza-angular/dist/server.js:1809:7001)
    at Object.onInvoke (/home/lucaswxp/reduza/reduza-angular/dist/server.js:137:1986)
    at e.invoke (/home/lucaswxp/reduza/reduza-angular/dist/server.js:1809:6941)
    at t.run (/home/lucaswxp/reduza/reduza-angular/dist/server.js:1809:2171)
    at e.run (/home/lucaswxp/reduza/reduza-angular/dist/server.js:137:2710)
    at e.bootstrapModuleFactory (/home/lucaswxp/reduza/reduza-angular/dist/server.js:151:1388)
    at md (/home/lucaswxp/reduza/reduza-angular/dist/server.js:1673:888)
    at p.engine (/home/lucaswxp/reduza/reduza-angular/dist/server.js:1794:10074)
    at p.render (/home/lucaswxp/reduza/reduza-angular/dist/server.js:1984:1029)

1 Ответ

0 голосов
/ 03 марта 2019

Это ошибка в документации.

Код их документации:

const { AppServerModuleNgFactory, LAZY_MODULE_MAP } = require('./server/main');

Однако это не правильно или, по крайней мере, не очень ясно.

Пункт 1: Вам не следует создавать рабочий режим.

Хотя вы видите в одной строке документации, что они хотят, чтобы вы включили в раздел сценариев вашего package.json такую ​​строку, как

ng run my-project:server:production

Вы не должны этого делать по двум причинам: во-первых, их инструкция по изменению angular.json не включает в себя производственную сборку.Во-вторых, производственная сборка (если вы только что скопировали с производства вашего фактического несерверного приложения) выполняется таким образом, чтобы включить хэш в имя файла, что приводит к файлу с именем, например main.a220df2.js.Это, конечно, не идеально, так как это означает, что вы должны постоянно менять свой server.ts.

Итак, либо отключите хеширование "outputHashing": "none", либо просто не производите производственную сборку, вызвав ng run my-project:server (просто удалите :production).

Пункт 2: используйте правильный require

Фактический вызов require () должен указывать на ваш встроенный main.server.ts, который является ссылками в вашем angular.json в разделе projects:PROJECTNAME:architect:server.Документация определила outputPath как "outputPath": "dist/my-project-server",, что означает, что у нас есть файл в dist/my-project-server/main.js, лежащий вокруг (сначала позаботьтесь о пункте 1 и отключите outputHashing или вообще не создавайте в рабочем режиме).Именно этот файл должен быть require d в вашем server.ts.

Так что, в вашем случае, это файл ./dist/reduza-ui/main.js, который вы должны включить, как только вы отключили outputHasing или прекратили сборку в производственном режиме.

const { AppServerModuleNgFactory, LAZY_MODULE_MAP } = require('./dist/reduza-ui/main');

Дополнительный совет: в самом верху документации вы видите ссылку на полный код всей статьи: https://angular.io/generated/zips/universal/universal.zip. Там вы можете увидеть, как должен выглядеть настоящий кодкак.

Два последних совета, чтобы он полностью заработал:

Первый

Документация говорит в server.ts что-то вроде:

const template = readFileSync(join(DIST_FOLDER, 'browser', 'index.html')).toString();

browser - это актуальная версия вашего приложения по умолчанию, поэтому ваша обычная сборка.Если вы сделаете ng build, у вас будет папка в dist/, которая является вашим текущим приложением по умолчанию.Это приложение имеет в виду browser.В вашем случае вы назвали версию своего сервера reduza-ui, так что, возможно, ваше реальное приложение называется reduza-ui-default в dist.В server.ts должен быть 'reduza-ui-default' вместо 'browser' в нескольких местах.

Second

В этот момент, когда вы скомпилировали сервер, запустили его и запросили первую страницув вашем браузере вы получаете в консоли:

StaticInjectorError(Platform: core)[InjectionToken Application Initializer -> InjectionToken DocumentToken]:
  Right-hand side of 'instanceof' is not an object

Это потому, что webpack минимизирует ваш server.ts.Отключите использование

optimization: {
    minimize: false
},

в webpack.server.config.js.

...