eval
и exec
удобны быстро и грязно, чтобы получить некоторый исходный код динамически, возможно, немного его немного, а затем выполнить его - но они вряд ли когда-либо будут лучшим способом, особенно в производстве кода, в отличие от «быстрых и грязных» прототипов и
Например, если мне приходилось иметь дело с такими динамическими источниками Python, я бы дошел до ast - ast.literal_eval
МНОГО безопаснее, чем eval
(вы можете вызывать его непосредственно в строковой форме выражения, если оно одноразовое и полагается только на простые константы или сначала node = ast.parse(source)
, затем сохраняйте node
вокруг, возможно, набросайте его подходящими посетителями, например, для поиска переменных, затем literal_eval
на узле) - или, поставив узел в правильной форме и проверив его для проблем безопасности, я мог бы compile
его ( приводящий к созданию объекта кода), и построим из него новый объект функции. Гораздо менее просто (за исключением того, что ast.literal_eval
так же просто, как eval
для простейших случаев!), Но безопаснее и предпочтительнее в коде качества продукции.
Для многих задач я видел людей (ab -) использовать exec
и eval
для, мощные встроенные модули Python, такие как getattr
и setattr
, индексирование в globals()
и & amp; c, обеспечивают предпочтительные и фактически часто более простые решения. Для конкретных целей, таких как синтаксический анализ JSON, библиотечные модули, такие как json
, лучше (например, см. Комментарий SilentGhost по тиннитусному ответу на этот самый вопрос). Etc и т. Д. ...
tl; dr Поскольку ваш вопрос показывает использование cross-var
, я предположил, что требуется кроссплатформенное решение. В этом случае см. Решение A . Однако, если моё предположение неверно, обратитесь либо к решению B , либо к C .
Для кроссплатформенного решения (то есть того, которое успешно работает в Windows, Linux и macOS ...) вам нужно будет использовать nodejs для достижения ваших требований. Есть несколько различных подходов к этому, как описано в следующих двух подразделах:
Примечание оба подхода фактически одинаковы
[ 1178] run-ng-build.js
const uuid = require('uuid/v1');
const execSync = require('child_process').execSync;
process.env.UUID = uuid();
execSync('ng build', { stdio: [0, 1, 2]} );
В разделе scripts
вашего package.json замените ваш текущий build
скрипт следующим:
package.json
"scripts": {
"build": "node run-ng-build"
}
Объяснение:
execSync()
. UUID
мы используем встроенную в nodejs process.env
и присваиваем ей значение uuid , вызывая uuid()
. ng build
, используя execSync
. options.stdio
настраивает каналы между родительским и дочерним процессами - [0, 1, 2]
эффективно наследует stdin
, stdout
и stderr
. В качестве альтернативы вы можете встроить свой код nodejs / JavaScript в раздел scripts
вашего package.json .
В разделе scripts
вашего package.json замените ваш текущий скрипт build
следующим:
package.json
"scripts": {
"build": "node -e \"process.env.UUID = require('uuid/v1')(); require('child_process').execSync('ng build', { stdio: [0, 1, 2]} );\""
}
Объяснение:
.js
, однако использование отдельного сценария / файла nodejs теперь излишне. -e
используется для оценки встроенного JavaScript. Важно Пакет cross-env является избыточным с использованием любого из двух вышеупомянутых решений. Чтобы удалить его, запустите: npm un -D cross-env
через CLI.
Только для платформ * nix это становится очень кратким, вы можете просто определить свой скрипт build
в package.json выглядит следующим образом:
package.json
"scripts": {
"build": "cross-env UUID=$(uuid) ng build"
}
Это использует функцию Bash, известную как команда замещение , т.е. $(uuid)
. Однако, если * nix - единственная платформа, которую вам нужно поддерживать, тогда cross-env
действительно не требуется. Вместо этого используйте встроенную функцию экспорта . Например:
package.json
"scripts": {
"build": "export UUID=$(uuid) && ng build"
}
package.json
"scripts": {
"build": "FOR /F %U IN ('uuid') DO cross-env UUID=%~U node -e \"process.env.UUID = require('uuid/v1')(); require('child_process').execSync('ng buuld', { stdio: [0, 1, 2] });\""
}
This аналогичен первому примеру, показанному в Решение B , однако подстановка команд выполняется (очень) по-другому в cmd.exe . См. Этот ответ для дальнейшего объяснения.