В последнее время я занят работой, и у меня с каждым днем остается все меньше времени на получение знаний, я глубоко чувствую, что это не способствует моему техническому совершенствованию. просто помнидядя волкСказал: «Лучший способ изучить Node.js, когда вы потерялись —Смотрите десять модулей npm в день«Хотя у меня не так много времени, чтобы читать десять модулей в день, время как губка, и все же можно читать один модуль в день, когда его сжимаешь.
Я надеюсь, что с помощью этой серии статей, с одной стороны, я напомню себе о необходимости помнить об изначальном замысле технологии в своей работе, а с другой стороны, я буду поощрять себя продолжать двигаться вперед по пути Node. .js.
вступление в одно предложение
Первый модуль npm, который я выбираю, этоusername, используется для получения имени пользователя текущего пользователя, текущая версия — 3.0.0, а еженедельный объем загрузки — более 60 000.
использование
usernameПоддерживает синхронную и асинхронную запись Promise:
const username = require('username');
// 同步
console.log(username.sync()); // => 'elvin'
// 异步
username().then(username => {
console.log(username); // => 'elvin'
});
Изучение исходного кода
Здесь более 20 строк основного кода, и основная логика такова:
- сначала через
process.env
Значение в переменной получает имя пользователя, если оно существует, возвращает его напрямую; - Тогда, если есть
os.userinfo
функцию, черезos.userinfo().username
получить имя пользователя и вернуться; - Если все вышеперечисленные методы не помогли, под OS X/Linux, выполнив
id -un
команда, через Windowswhoami
Команда получает имя пользователя и возвращает.
Далее мы рассмотрим эти три шага в сочетании с исходным кодом.
process.env
// 源代码 1-1
function getEnvVar() {
const env = process.env;
return env.SUDO_USER ||
env.C9_USER /* Cloud9 */ ||
env.LOGNAME ||
env.USER ||
env.LNAME ||
env.USERNAME;
}
const envVar = getEnvVar();
if (envVar) {
return Promise.resolve(envVar);
}
process.env
Возвращает объект, содержащий текущие переменные среды пользователя, которые можно выполнить в командной строке.printenv
команда для просмотра всех переменных среды, вы также можетеprintenv v_name
Команда для получения значения переменной окружения:
$ printenv
// => LANG=zh_CN.UTF-8
// => PWD=/Users/elvin/
// => SHELL=/bin/zsh
// => USER=elvin
// => ...
$ printenv USER
// => elvin
Переменные оболочки легко спутать с переменными окружения.
set
Команда для просмотра всех переменных оболочки. Чтобы узнать о разнице между ними и предложениях по использованию, обратитесь к этому материалу на английском языке.How To Read and Set Environmental and Shell Variables on a Linux VPS.
В Node.js оprocess.env
Есть еще три места, которые нужно знать:
-
в состоянии пройти
process.env.foo = "bar"
Способ установки переменных среды, в настоящее время разрешены все типы значений и они будут преобразованы в строковый тип, согласноофициальная документация, в будущих версиях будут разрешены только значения типа string, number и boolean, установка значений других типов вызовет исключение.process.env.foo = undefined; console.log(process.env.foo, typeof process.env.foo); // => 'undefined', 'string' process.env.foo = {}; console.log(process.env.foo, typeof process.env.foo); // => '[object Object]', 'string'
-
в состоянии пройти
delete
способ удаления переменных окружения.process.env.foo = undefined; delete process.env.foo console.log(process.env.foo) // => undefined
-
в Node.js
process.env
Модификации не будут отражаться за пределами процесса ноды, но переменные окружения можно задавать извне, а затем получать через код Node.js, который на практике часто задается таким образомNODE_ENV
переменная, а затем прочитайте ее значение в коде конфигурации веб-пакета, чтобы определить среду для разных сборок.$ node -e 'process.env.foo = "bar"' && echo $foo // => 空 $ NODE_ENV=production node -e 'console.log(process.env.NODE_ENV)' // => 'production'
Напрямую не поддерживается под Windows
NODE_ENV=production
Таким образом, вам нужно установитьcross-envпакет для совместимости.
вернуться к исходному коду 1-1getEnvVar
функции, вы можете видеть, что последовательные попытки выполняются изprocess.env
Переменные среды SUDO_USER, C9_USER, LOGNAME, USER, LNAME и USERNAME получают имя пользователя, которое здесь выделено.SUDO_USER
иC9_USER
Эти две переменные:
-
Если идентификатор пользователя root,
USER
переменная возвращает корень, аSUDO_USER
Переменная возвращает имя учетной записи, вошедшей в систему как root, например: когда я вхожу в систему как учетная запись elvinsudo su
Став пользователем root,USER
вернет корень,SUDO_USER
вернется эльф.$ sudo su // => input password $ printenv USER // => root $ printenv SUDO_USER // => elvin
-
C9_USER
Судя по комментариям, это дляCloud9Это облачная среда разработки, запущенная Amazon для написания, запуска и отладки кода. Заинтересованные студенты могут попробовать ее.
os.userInfo
исходный код изprocess.env
Когда имя пользователя не может быть получено, оно попытается передатьos.userInfo()
Функция для получения:
// 源代码 1-2
if (os.userInfo) {
return Promise.resolve(os.userInfo().username);
}
os.userinfo()
Возвращается некоторая информация о текущем пользователе по сравнению сprocess.env
С точки зрения информации информации намного меньше, и поддерживается только Node.js V6.0 и выше:
const os = require('os');
console.log(os.userInfo());
// => {
// => uid: 501,
// => gid: 20,
// => username: 'elvin',
// => homedir: '/Users/elvin',
// => shell: '/bin/zsh'
// => }
Вышеуказанные поля означают:
- uid: идентификатор пользователя (user id), каждый пользователь идентифицируется уникальным идентификатором в системе, например id 501 означает пользователя elvin. В системах Linux информация об uid хранится в
/etc/passwd
В файле uid пользователя root равен 0. - gid: идентификатор группы (идентификатор группы), к которой принадлежит пользователь. Пользователь может принадлежать к нескольким группам. Например, gid 20 означает, что пользователь elvin принадлежит к группе с идентификатором 20. В системах OS X/Linux информация gid хранится в
/etc/group
В файле gid пользователя root равен 0. - имя пользователя: Текущее имя пользователя, при входе в систему под пользователем elvin оно возвращает root вместо elvin.
- homedir: домашний каталог текущего пользователя.
- shell: путь к оболочке текущего пользователя.
выполнить команду командной строки
Если имя пользователя не может быть получено двумя текущими методами, оно будет передано под OS X/Linux.id -un
Команда для получения имени пользователя, под Windows оно будет переданоwhoami
Команда для получения имени пользователя.
// 源代码 1-3
function cleanWinCmd(x) {
return x.replace(/^.*\\/, '');
}
function noop() {}
if (process.platform === 'darwin' || process.platform === 'linux') {
return execa('id', ['-un']).then(x => x.stdout).catch(noop);
} else if (process.platform === 'win32') {
return execa('whoami').then(x => cleanWinCmd(x.stdout)).catch(noop);
}
Приведенный выше код сначала проходитprocess.platform
Определите операционную систему, если это OS X (т.е. darwin) или Linux, выполнитеid -un
Получите имя пользователя; если это Windows (например, win32), выполнитеwhoami
Получите платформу и имя пользователя, затем пройдитеcleanWinCmd
Функция использует регулярные выражения для извлечения имен пользователей. Фактически, его также можно передать на OS X/Linux.whoami
Получите имя пользователя, но в документации оно объявлено какid
Команда устарела.
в соответствии сДокументация Node.js,process.platform
Он вернет текущую платформу, в том числе aix | darwin | freebsd | linux | openbsd | sunos | win32 | android, поэтому на самом деле видно, что приведенный выше код рассматривает только три случая, и я лично думаю, что некоторые модификации могут быть сделано следующим образом:
if (process.platform === 'win32') {
return execa('whoami').then(x => cleanWinCmd(x.stdout)).catch(noop);
} else {
return execa('id', ['-un']).then(x => x.stdout).catch(noop);
}
Предложенные здесь улучшения принятыPR #20Слился с последним кодом 😊
В исходном коде 1-3,noop
Также стоит изучить использование пустых функций: когда выполнение команды ненормально, передатьnoop
Функция проглатывает ошибку и возвращаетundefined
. Сначала мне было бы любопытно, почему подробная информация об исключении не возвращается, чтобы облегчить поиск при возникновении ошибки, но затем, с точки зрения пользователя пакета, я думаю, что она возвращается напрямую.undefined
Есть два преимущества:
- Как пользователь, вы, как правило, заботитесь только о том, сможете ли вы получить правильный результат, и не заботитесь о ненормальной информации внутри пакета.В настоящее время подробная информация об ошибке является своего рода помехой.
- возвращение
undefined
Если это так, пользователю будет проще писать код вызова, конечно, это связано с личным стилем.
Кроме того, следует отметить, что здесь используются сторонние пакеты.execaвместо встроенного Node.jschild_process.exec
модуль для выполнения команд командной строки,execaОн был улучшен на основе нативного модуля, и текущий еженедельный объем загрузки составляет около 6 млн. Здесь он в основном использует свой интерфейс для предоставления Promise.
напиши в конце
пройти сегодняusernameШестьдесят строк кода:
- Понимание переменных системной среды, понимание
SUDO_USER
иUSER
разница между переменными; - Изучите Node.js
process.env
добавления, удаления и исправления; - Узнайте о Node.js
os.userInfo()
информация возвращена; - знание
process.platform
Возвращает больше, чем darwin | win32 | Linux, может бытьusername
Здесь может быть лучшая управляемость; -
noop
Преимущество пустых функций в том, что они проглатывают исключения, когда промисы терпят неудачу.
фактическиusernameтакже прошлоmemПакет буферизует результаты для повышения эффективности, прочитаю завтраmemпакет для обучения.
О себе: Окончил Хуаке, работаю в Tencent,блог ЭлвинаДобро пожаловать в гости ^_^