источник
После того, как вы привыкнете к написанию бизнес-кода, если вы хотите узнать о webpack или vue-cli, вам будет сложно начать с этого 🙁 . Взяв в качестве примера webpack, мы можем быть знакомы с конфигурацией, но часто забываем ее через некоторое время, и кажется, что понять ее не так-то просто. На самом деле, как и с такими инструментами для упаковки и создания инструментов, мы должны сначала изучить некоторые базовые знания об узле, а затем оглянуться на эти инструменты, у нас будет ощущение другой деревни, потому что эти инструменты написаны на узле 🤯.
Подумайте, видим ли мы такие вещи время от времени:const path = require('path');
. Предположим, вы изучили интерфейсный фреймворк, но не ноду.Когда вы увидите это предложение, вы будете в замешательстве, как будто знаете, что это путь, но откуда он берется и для чего часто используется — неизвестно. , так я чувствовала сначала 🤨.
Позже я узнал, что на самом деле это встроенный модуль узла, потому что эти инструменты сборки или инструменты упаковки выполняются с узлом, Пока мы установили узел, на встроенные в него модули можно напрямую ссылаться без дополнительной установки. . Поэтому настоятельно рекомендуется, если вы хотите разобраться в таких инструментах, лучше всего сначала изучить node, иначе вы всегда будете путаться🧐.
Слова на пенсии, в этой статье кратко рассказывается о некоторых часто используемых встроенных модулях Node.
Первое знакомство с узлом
что такое узел
Во-первых, node - это не фоновый язык, а окружение, окружение, позволяющее запускать js на сервере, это как браузер на сервере (хоть и не очень уместно), но именно из-за него что js меняется, стал фоновым языком.
Спецификации, которым следует узел
Во-вторых, узел следует спецификации CommonJs, что это значит? По сути, он указывает способ импорта и экспорта😬, который выглядит следующим образом:
require('./module')
module.exports = {
a: 1,
}
exports.a = 1;
Это спецификация узла, использующаяrequire
импортировать, использоватьmodule.exports
экспорт. Тогда почему узел не поддерживает ESM (то есть использоватьimport
импортировать, использоватьexport
Export), потому что она появилась относительно рано, вот и все, и ее нельзя менять какое-то время, и ее надо поддерживать в будущем. Кроме того, мы часто видим в webpackrequire()
не увидел надписьimport()
Это связано с тем, что веб-пакет выполняется с узлом, а узел в настоящее время поддерживает толькоrequire()
.
Вот картинка с различными спецификациями (о таких вещах легко забыть, просто смотрите на это как на историю 🙄), а именно:
require находит зависимости
require()
Есть два способа записи параметров внутри: один с путем и один без пути. Как следующее:
require('./module'); // 带相对路径
require('/module'); // 带绝对路径
require('module'); // 不带路径
это бездорожьеrequire('module')
Методом внедрения может быть встроенный модуль или сторонний модуль.Сначала ищется встроенный модуль.Если нет, то это сторонний модуль.Он будет запускаться из текущего каталога.node_modules
Найдите его внутри, если нет, перейдите в родительский каталогnode_modules
Найдите его внутри и так далее до корневого каталогаnode_modules
Если каталога нет, он пойдет в глобальный, чтобы найти его, что, вероятно, является таким процессом поиска.
Другой способ с указанием пути будет искать его по пути, если не найдет, попытается загрузить текущую директорию как пакет. Кроме того, скорость использования абсолютных путей самая высокая, конечно, node также кэширует поиск путей.
оболочка модуля узла
Когда узел анализирует каждый модуль (файл js), он оборачивает каждый модуль, то есть добавляет замыкание вне кода и передает ему пять параметров, что обеспечивает независимость между каждым модулем.
(function(exports, require, module, __filename, __dirname) {
// module: 表示当前模块
// __filename: 当前模块的带有完整绝对路径的文件名
// __dirname: 当前模块的完整绝对路径
module.exports = exports = this = {};
// 我们的代码就在这里...
return module.exports;
})()
Подумайте, обычно ли мы видим это в webpack__dirname
Такого рода вещи мы не ввели и не задекларировали, поэтому их можно использовать напрямую именно по этой причине😮.
Сценарии применения узла
Вообще говоря, узел в основном используется в следующих аспектах:
- Такие инструменты, как автоматизированная сборка
- средний слой
- Небольшие проекты
Первый пункт должен быть высшим приоритетом для студентов, изучающих интерфейс. Любые инженерные и автоматические инструменты построения написаны в узле. Это один из основных водоразделов в интерфейсе, и его трудно взломать, поэтому мы должны принять его. , или узкое место скоро появится. Если вы умеете умело применять различные модули ноды (системные модули + сторонние модули), то поздравляю, вы лучше других😎.
Преимущества узла
- Подходит для передней части
- На основе ведомого события и безблокирующего ввода / вывода (подходит для обработки параллельных запросов)
- Лучшая производительность (другие провели анализ производительности)
встроенные модули узла
хорошо, много чепухи, давайте взглянем на некоторые распространенные базовые модули узлов. Я считаю, что их освоение поможет вам освоить такие инструменты, как webpack и vue-cli ✊ .
http-модуль
Это самая основная функция узла, мы используемnode http.js
Запустите следующий файл, чтобы запустить сервер, введите в браузереhttp://localhost:8888
То есть доступ к http.js выглядит следующим образом:
// http.js
const http = require('http');
http.createServer((req, res) => { // 开启一个服务
console.log('请求来了'); // 如果你打开 http://localhost:8888,控制台就会打印此消息
res.write('hello'); // 返回给页面的值,也就是页面会显示 hello
res.end(); // 必须有结束的标识,否则页面会一直处于加载状态
}).listen(8888); // 端口号
файловая система фс
Поскольку js изначально разрабатывался для браузеров, его возможности ограничены браузерами и не могут напрямую работать с локальными файлами на стороне клиента. Целью этого является обеспечение информационной безопасности на стороне клиента. Конечно, с помощью некоторых средств также можно манипулировать клиентскими содержание (как<input type='file'>
), но требует ручного управления пользователем.
Но когда в качестве фонового языка используется js, вы можете напрямую выполнять операции ввода-вывода с файлами ресурсов на сервере. Это также один из самых важных модулей в узле (возможность манипулировать файлами), который обычно используется при автоматизированной сборке и проектировании. Его основная обязанность заключается в чтении и записи файлов, а также в перемещении, копировании, удалении и т. д. fs похожа на добавление, удаление, изменение и проверку базы данных, разница в том, что она работает с файлами. Давайте подробно рассмотрим вариант использования кода:
const fs = require('fs');
// 写入文件:fs.writeFile(path, fileData, cb);
fs.writeFile('./text.txt', 'hello xr!', err => {
if (err) {
console.log('写入失败', err);
} else {
console.log('写入成功');
}
});
// 读取文件:fs.readFile(path, cb);
fs.readFile('./text.txt', (err, fileData) => {
if (err) {
console.log('读取失败', err);
} else {
console.log('读取成功', fileData.toString()); // fileData 是二进制文件,非媒体文件可以用 toString 转换一下
}
});
Следует отметить, что fileData в readFile — это исходный двоичный файл 🤨 (em... — это формат файла, который понимает только компьютер), для файлов не медиа-типа (таких как обычный текст) вы можете использоватьtoString()
Конвертируйте его, файл типа медиа будет читаться потоковым способом, если его принудительно использоватьtoString()
Если вы конвертируете его, вы потеряете исходную информацию, поэтому вы не сможете его изменить. двоичная суммаtoString
Эффект следующий:Кроме того, соответствующим fs.readFile (асинхронный) и fs.writeFile (асинхронный) есть fs.readFileSync (синхронный) и fs.writeFileSync (синхронный), большинство методов fs также имеют две версии, синхронную и асинхронную, в зависимости от выбора Для бизнеса обычно используется асинхронный режим, а также асинхронный режим, если вы не знаете, что использовать.
путь путь
Этот модуль должен быть знаком всем, 🧐 Любой, кто видел webpack, должен был видеть этот материал. Очевидно, что путь предназначен для работы с вещами, связанными с путем, мы можем увидеть это непосредственно, рассмотрев следующие распространенные варианты использования:
const path = require('path');
let str = '/root/a/b/index.html';
console.log(path.dirname(str)); // 路径
// /root/a/b
console.log(path.extname(str)); // 后缀名
// .html
console.log(path.basename(str)); // 文件名
// index.html
// path.resolve() 路径解析,简单来说就是拼凑路径,最终返回一个绝对路径
let pathOne = path.resolve('rooot/a/b', '../c', 'd', '..', 'e');
// 一般用来打印绝对路径,就像下面这样,其中 __dirname 指的就是当前目录
let pathTwo = path.resolve(__dirname, 'build'); // 这个用法很常见,你应该在 webpack 中有见过
console.log(pathOne, pathTwo, __dirname);
// pathOne => /Users/lgq/Desktop/node/rooot/a/c/e
// pathTwo => /Users/lgq/Desktop/node/build
// __dirname => /Users/lgq/Desktop/node
Что ж, в следующий раз, когда вы увидите путь, вы не запутаетесь.
URL-модуль
Очевидно, что это используется для обработки вещей, связанных с URL-адресами, мы также должны понять основной маршрут, используемый для получения адресов и параметров, следующим образом:
const url = require('url');
let site = 'http://www.xr.com/a/b/index.html?a=1&b=2';
let { pathname, query } = url.parse(site, true); // url.parse() 解析网址,true 的意思是把参数解析成对象
console.log(pathname, query);
// /a/b/index.html { a: '1', b: '2' }
строка запроса
Это в основном используется для преобразования строк, подобных этомуa=1&b=2&c=3
(& и = можно заменить чем-то другим) решает{ a: '1', b: '2', c: '3' }
Object, в свою очередь, объект может быть объединен в строку, указанный выше параметр url также может быть проанализирован с помощью строки запроса, конкретная демонстрация выглядит следующим образом:
const querystring = require('querystring');
let query = 'a=1&b=2&c=3'; // 形如这样的字符串就能被解析
let obj = querystring.parse(query);
console.log(obj, obj.a); // { a: '1', b: '2', c: '3' } '1'
query = 'a=1&b=2&c=3&a=3'; // 如果参数重复,其所对应的值会变成数组
obj = querystring.parse(query);
console.log(obj); // { a: [ '1', '3' ], b: '2', c: '3' }
// 相反的我们可以用 querystring.stringify() 把对象拼接成字符串
query = querystring.stringify(obj);
console.log(query); // a=1&a=3&b=2&c=3
утверждать утверждение
Мы можем увидеть, что он делает, взглянув на код ниже:
// assert.js
const assert = require('assert');
// assert(条件,错误消息),条件这部分会返回一个布尔值
assert(2 < 1, '断言失败');
node assert.js
Запустите код, и вы увидите следующие результаты:На приведенном выше рисунке показан пример ошибки утверждения.Если утверждение верно, подсказки не будет, и программа будет продолжать выполняться в автоматическом режиме. Таким образом, роль утверждения состоит в том, чтобы сначала решить, правильно ли условие (что-то вроде if), и возвращает ли условие значениеfalse
препятствует запуску программы и выдает ошибку, если возвращаемое значение равноtrue
Затем продолжите выполнение, обычно используемое для промежуточной функции и оценки параметров.
Кроме того, вот еще два использования equals (в assert много equals, вот два из них):
// assert.js
const assert = require('assert');
const obj1 = { a: { b: 1 } };
const obj2 = { a: { b: 1 } };
const obj3 = { a: { b: '1' } };
// assert.deepEqual(变量,预期值,错误信息) 变量 == 预期值
// assert.deepStrictEqual(变量,预期值,错误信息) 变量 === 预期值
// 同样也是错误的时候抛出信息,正确的时候继续默默执行
assert.deepEqual(obj1, obj2, '不等哦'); // true
assert.deepEqual(obj1, obj3, '不等哦'); // true
assert.deepStrictEqual(obj1, obj2, '不等哦'); // true
assert.deepStrictEqual(obj1, obj3, '不等哦'); // false,这个会抛出错误信息
поток поток
Поток еще называют потоком, вы должны были более или менее слышать об этом понятии, что оно означает? Здесь вы можете думать об этом, как было сказано ранееfs.readFile
а такжеfs.writeFile
обновленная версия.
нам нужно знатьreadFile
а такжеwriteFile
Рабочий процесс заключается в том, чтобы сначала прочитать весь файл в память, а затем записать его снова.Этот метод не подходит для файлов немного большего размера, потому что легко вызвать нехватку памяти, так что же лучше? Это просто чтение и запись. Промышленность часто называет это конвейерным потоком, точно так же, как поток воды через водопроводную трубу. Количество воды на входе равно количеству воды на выходе. Распределение памяти вместо того, чтобы есть толстяка в один раз есть риск перегрузиться (то есть память взорвется 🤐).
const fs = require('fs');
// 读取流:fs.createReadStream();
// 写入流:fs.createWriteStream();
let rs = fs.createReadStream('a.txt'); // 要读取的文件
let ws = fs.createWriteStream('a2.txt'); // 输出的文件
rs.pipe(ws); // 用 pipe 将 rs 和 ws 衔接起来,将读取流的数据传到输出流(就是这么简单的一句话就能搞定)
rs.on('error', err => {
console.log(err);
});
ws.on('finish', () => {
console.log('成功');
})
Потоковая работа означает постоянное чтение.Это непрерывный процесс.Не имеет значения, если одна сторона работает быстро, а другая медленно, или если есть ошибка и соединение не установлено, оно будет обработано автоматически, и нам не нужно корректировать ошибку самостоятельно, это отличный модуль 👍. Кроме того, мы не использовали модуль stream напрямую, потому что модуль fs ссылается на него и инкапсулирует его, поэтому можно использовать fs.
сжатие zlib
Это использование простое, и функция понятна, просто посмотрите на следующий код, чтобы понять:
const fs = require('fs');
const zlib = require('zlib');
let rs = fs.createReadStream('tree.jpg');
let gz = zlib.createGzip();
let ws = fs.createWriteStream('tree.jpg.gz');
rs.pipe(gz).pipe(ws); // 原始文件 => 压缩 => 写入
rs.on('error', err => {
console.log(err);
});
ws.on('finish', () => {
console.log('成功');
})
резюме
ok👌, вышеизложенное — это часть знаний об узлах, которые будут рассмотрены в этой главе (это более основное, давайте просто посмотрим). Конечно, в дополнение к этому есть и другие встроенные модули, такие как util, Buffer, Event, crypto и process.Я не буду здесь вдаваться в подробности.Я надеюсь, что каждый сможет сделать больше практических действий, больше печатать и больше практики. Если вы сможете эффективно использовать различные модули узла, то у вас будут безграничные возможности переключиться на бэкенд😋 (на самом деле яма фронтенда больше, чем вы можете себе представить😭).
Наконец, в конце дня Амвей посмотрит на свою статью, не распыляйтесь, ха-ха!
1. Создайте свою собственную библиотеку пользовательского интерфейса на основе vue-cli3.
2. Создайте свои собственные леса, имитируя vue-cli
3. А как насчет этого.$toast()?