Переменные среды в изоморфном приложении JS: найти и заменить Webpack?
Я использую webpack для объединения изоморфного приложения JS (на основе этого примера), чтобы браузер выполнял тот же код, что и сервер, Все работает плавно, за исключением того, что у меня есть config.js
с некоторыми настройками, которые извлекаются из переменных среды на сервере:
module.exports = {
servers:
auth: process.env.AUTH_SERVER_URL,
content: process.env.CONTENT_SERVER_URL
}
}
На сервере это грандиозно, но когда webpack делает это для клиента process
пустым, и это не работает.
Я надеюсь, что есть какой-то "найти и заменить" плагин webpack, который заменит их своим содержимым только в этом файле?
"…config.js content…".replace(/process\.env\.([a-z0-9_]+)/, function(match, varName) {
return process.env[varName];
})
Ответы
Ответ 1
В webpack.config.js
используйте preLoaders
(или postLoaders
),
module: {
preLoaders: [
{ test: /\.js$/, loader: "transform?envify" },
]
}
Другой способ: webpack.DefinePlugin
:
plugins: [
new DefinePlugin({
'process.env': Object.keys(process.env).reduce(function(o, k) {
o[k] = JSON.stringify(process.env[k]);
return o;
}, {})
})
]
ПРИМЕЧАНИЕ. Старый метод с использованием envify-loader
устарел:
DEPRECATED: вместо этого используйте transform-loader + envify.
Ответ 2
Обратите внимание, что использование DefinePlugin
, как предлагается в принятом ответе, потенциально опасно, поскольку оно полностью предоставляет process.env
. Как уже отмечал Тобиас, на самом деле есть плагин EnvironmentPlugin
, который делает именно это с добавленной способностью "белый список", используя DefinePlugin
внутренне.
В webpack.config.js
:
{
plugins: [
new webpack.EnvironmentPlugin([
'NODE_ENV',
'WHITELISTED_ENVIRONMENT_VARIABLE'
])
]
}
Ответ 3
Да; выглядит как envify-loader - это простое решение.
Я добавил к моим загрузчикам webpack следующее:
{
test: /config\.js$/, loader: "envify-loader"
}
И config.js
(и только тот файл) изменен, чтобы включить любые ссылочные переменные среды статически:)
Ответ 4
Мне нужен был способ использовать переменные env, установленные на машине, на которой запущен код, нет переменных env машины, создающей приложение.
Я пока не вижу решения для этого. Это то, что я сделал.
В publicEnv.js
:
// List of the env variables you want to use on the client. Careful on what you put here!
const publicEnv = [
'API_URL',
'FACEBOOK_APP_ID',
'GA_ID'
];
const isBrowser = typeof window !== 'undefined';
const base = (isBrowser ? window.__ENV__ : process.env) || {};
const env = {};
for (const v of publicEnv) {
env[v] = base[v];
}
export default env;
В файле шаблона HTML страницы у меня есть:
import publicEnv from 'publicEnv.js';
...
<script>
window.__ENV__ = ${stringify(publicEnv)};
// Other things you need here...
window.__INITIAL_STATE__ = ${stringify(initialState)};
</script>
Итак, теперь я могу получить значение переменной env как для frontend, так и для backend с помощью:
import publicEnv from 'publicEnv.js';
...
console.log("Google Analytic code is", publicEnv.GA_ID);
Надеюсь, это поможет.