#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
.. Я только что переделал его, и он работает, остальные остаются такими, как сообщалось