_ почему AoT удаляет это значение?

#angular

#angular

Вопрос:

У меня есть проект angular 5 с переменными среды.. Я использовал общий файл.ts в среде / папке, подобной этой:

environment.prod.ts

 import common from './common/common';

export const environment: any = {
  ... common,

  production: true,
  devEnvironment: false,
  ...
  

построение с --prod помощью приводит к тому, что общие значения не определены (это очень очевидно, поскольку свойство environment.startupProject, исходящее от common, определяет маршрут по умолчанию в маршрутизации приложений), но мы находим это странным, поскольку мы можем видеть Object.assign в скомпилированном javascript, и там есть значения:

где-то глубоко в main …ts

     kZql: function(t, e, n) {
        "use strict";
        n.d(e, "a", function() {
            return r
        });
        var r = (this amp;amp; this.__assign || Object.assign || function(t) {
            for (var e, n = 1, r = arguments.length; n < r; n  )
                for (var i in e = arguments[n])
                    Object.prototype.hasOwnProperty.call(e, i) amp;amp; (t[i] = e[i]);
            return t
        }
        )({}, {
            projectName: "accounts",
            startupProject: "/dashboard",
...
        }, {
            production: !0,
            devEnvironment: !1,
...
        })
    },
  

Обратите внимание, что это верно, даже если исходные карты отключены..


обновление: если я изменю main.ts на консоль.регистрируйте тот же общий:

 import common from '@src/environments/common/common';

if (environment.production) {
  enableProdMode();
  console.log(common);
}
  

оно определено! это только из контекста самого environment.prod, что оно не определено.


Если я использую отладчик и включаю sourcemaps, а затем устанавливаю точку останова при инициализации объекта среды в environment.prod, я вижу, что common (или, скорее, это базовая искаженная переменная) на самом деле не определена. Итак, я предполагаю, что фрагмент чуть выше, который на самом деле не executing..at по крайней мере, до того, как доступ к среде будет осуществлен в нашем модуле маршрутов. Очевидно, где-то также генерируется другая копия того же кода, и она выполняется. что заставляет меня думать, что AoT, честно говоря, не очень хорошо справляется.

это почти похоже на то, что есть оставшийся бит встряхивания дерева, который фактически встроен в наш проект и ведет себя иначе, чем встряхивание дерева, которое происходит во время компиляции.

Почему это происходит?

Хуже того, я не могу исправить это ни одним из обычных способов:

избегание экспорта по умолчанию ничего не дает.

преобразование его в класс и добавление в app-module не работает!:

 @Injectable()
export class Common {
  static startupProject = '/dashboard';
}

//... and in app.module
...
providers: [
  Common,
...

//... then in environment.prod:
import { Common as common } from ...

export environment: any = {
  ...common, // this works without --prod, of course, but not with it
}
  

оба вышеперечисленных действия в сочетании с переносом папки common/ , которая будет находиться под app/ , также не работают.

Избегая оператора splat, подобного Object.assign({}, common, {/* ...env ...*/}) … это тоже не работает.

присвоение значения (window as any).common не работает (это было предписано как способ предотвращения сотрясения дерева в ответах в репозитории angular). На самом деле, это все равно не работает, даже если я также использую ...(window as any).common, вместо импортированной копии в среде!

Есть ли какой-либо способ помимо отключения AoT заставить это работать, чтобы нам не приходилось хранить дубликаты информации? Что происходит на самом деле — почему файл существует в скомпилированном выводе JS, но все еще не определен во время выполнения?

Комментарии:

1. В чем разница между environment.prod.ts и environment.ts в отношении common ?

2. что касается общего? ничего. они идентичны в первых двух строках. причина, по которой у нас общий файл, заключается в том, что вместо того, чтобы устанавливать одни и те же переменные в каждом, мы хотим избежать дублирования и просто установить их один раз

Ответ №1:

если вы просмотрите angular.json, вы найдете такую часть конфигурации

 "fileReplacements": [
      {
        "replace": "src/environments/environment.ts",
        "with": "src/environments/environment.prod.ts"
      }
    ],
  

ведьма выбрасывает ваш environment.ts и вместо этого создает ваше приложение с помощью environment.prod.ts. чтобы устранить вашу проблему, я думаю, вам нужно просто удалить раздел «fileReplacements» из конфигурации

Комментарии:

1. Извините, если я не был ясен. это находится в файле environment.prod.ts. Но обратите внимание, что второй фрагмент в моем сообщении всегда четко показывал, что содержимое common.ts объединяется с содержимым файла среды в этом месте в скомпилированном коде, поэтому я не знаю, почему вы думаете, что это будет ответ.

2. не могли бы вы проверить, является ли это aot или оптимизация terser, которая нарушает вашу конфигурацию? попробуйте ng serve —aot; или ng serve —prod —optimization=false и ng serve —prod —aot=false

3. конечно, это хорошая идея 🙂 ng serve --aot выдает ту же ошибку (также в сочетании с --optimization=false ). То же ng serve --prod --aot=false самое продолжает демонстрировать то же поведение… Я не уверен, что «ложные» переключатели работают так, как вы надеетесь. ng serve --env=prod --optimization=true работает. Я просто должен отметить, что aot вызывает проблему, но не удаляет общий файл из скомпилированного кода, как видно из фрагмента в моем сообщении.

4. Я думаю, что это была просто опечатка с моей стороны в отношении : ng serve --prod --aot=false .. Я только что переделал его, и он работает, остальные остаются такими, как сообщалось