"Это седьмой день моего участия в ноябрьском испытании обновлений, ознакомьтесь с подробностями события:Вызов последнего обновления 2021 г."
привет всем, 🙎🏻♀️🙋🏻♀️🙆🏻♀️
Я автор, который любит передавать знания и учится писать,ClyingDeng
Табурет!
Принцип работы:
-
type="module"
Встроенная поддержка модуля ES в браузерах. если браузер это поддерживаетtype="module"
, мы можем написать модульным способом es6. Браузер отправит еще один http-запрос к файлу, который нам нужно импортировать, а затем отправит его на сервер. Не требуется упаковка во время разработки - Сторонние зависимости предварительно упакованы
- Запустите сервер разработки для обработки запросов ресурсов
Картинка для объяснения принципа вите:
Что делает браузер?
Хост-файл index.html
<script type="module" src="/src/main.js"></script>
После того, как браузер получает ресурсы в файле хоста, он обнаруживает, что ему нужно снова запросить файл main.js. Запрос ресурса main.js будет снова отправлен на сервер.
main.js
В основном можно обнаружить, что браузер инициирует паруvue.js?v=d253a66c
,App.vue?t=1637479953836
Запрос ресурсов для двух файлов.
Сервер скомпилирует содержимое в App.vue и вернет его в браузер., на следующем рисунке показано, что изображение логотипа и текст компилируются в_hoisted_
статический узел.
Из заголовка запроса также видно, что файл sfc стал файлом js, который может распознать браузер (содержимое скрипта в файле app.vue будет скомпилировано в js). Для браузера выполняется часть кода js.
Другие голые модули
Если в зависимости vue есть другие зависимости, браузер все равно снова инициирует запрос ресурса, чтобы получить соответствующий ресурс.
Узнать о расфасовке
Для загрузки сторонних зависимостей (голых модулей) vite заранее упакует их и поместит в node_modules/.vite. При запуске проекта загружайте файлы прямо по этому пути.
На приведенном выше рисунке видно, что путь изменился при введении голого модуля.
Что делает сервер?
Подводя итог в одном предложении:Сервер обрабатывает файлы со специальными суффиксами и возвращает их на внешний дисплей..
Мы можем смоделировать devServe vite и запустить локальную службу, используя промежуточное ПО koa.
// 引入依赖
const Koa = require('koa')
const app = new Koa()
const fs = require('fs')
const path = require('path')
const compilerSfc = require('@vue/compiler-sfc')
const compilerDom = require('@vue/compiler-dom')
app.use(async (ctx) => {
const { url, query } = ctx.request
// 处理请求资源代码都写这
})
app.listen(3001, () => {
console.log('dyVite start!!')
})
Запросить главную страницу index.html
if (url === '/') {
const p = path.join(__dirname, './index.html') // 绝对路径
// 首页
ctx.type = 'text/html'
ctx.body = fs.readFileSync(p, 'utf8')
}
Увидев картинку выше, мы знаем, что наш хост-файл был успешно запрошен. Это просто запрос файла main.js, отправляемого браузером на сервер. В это время нам также нужно оценить и обработать файл main.js.
Запросить файлы, оканчивающиеся на .js
После того, как мы разберемся с вышеописанной ситуацией, эммммм. . . Выяснилось, что в файле main все еще есть много других запросов на ресурсы.
базовый js-файл
основной файл:
console.log(1)
Процесс Главная:
else if (url.endsWith('.js')) {
// 响应js请求
const p = path.join(__dirname, url)
ctx.type = 'text/javascript'
ctx.body = rewriteImport(fs.readFileSync(p, 'utf8')) // 处理依赖函数
}
Обработка зависимостей в main
Вы думаете, что в main есть только один выход? слишком наивен. Можно ли с этим справиться?
основной файл:
import { createApp, h } from 'vue'
createApp({ render: () => h('div', 'helllo dyVite!') }).mount('#app')
эммм. . . должно быть нормально!
Мы можем превратить адрес, импортированный в main, в относительный адрес.
Добавьте путь к голому модулю/@modules/
. идентифицировать/@modules/
Файл ie (голый файл модуля).
// 把能读出来的文件地址变成相对地址
// 正则替换 重写导入 变成相对地址
// import { createApp } from 'vue' => import { createApp } from '/@modules/vue'
function rewriteImport(content) {
return content.replace(/ from ['|"](.*)['|"]/g, function (s0, s1) {
// s0匹配字符串,s1分组内容
// 是否是相对路径
if (s1.startsWith('./') || s1.startsWith('/') || s1.startsWith('../')) {
// 直接返回
return s0
} else {
return ` from '/@modules/${s1}'`
}
})
}
Для сторонних зависимостей vite внутренне использует предварительно упакованные запросы к своему собственному серверу./node_modules/.vite/
Внутренние ресурсы под.
Мы можем немного упростить его, мы получимимя зависимостиПерейдите в node_modules под клиентом, чтобы получить соответствующие ресурсы.
else if (url.startsWith('/@modules/')) {
// 裸模块的加载
const moduleName = url.replace('/@modules/', '')
const pre![1637477009328](imgs/1637477009328.png)![1637477009368](imgs/1637477009368.png)的地址
const module = require(prefix + '/package.json').module
const filePath = path.join(prefix, module) // 拿到文件加载的地址
// 读取相关依赖
const ret = fs.readFileSync(filePath, 'utf8')
ctx.type = 'text/javascript'
ctx.body = rewriteImport(ret) //依赖内部可能还存在依赖,需要递归
}
При рендеринге в main будет сообщено о следующей ошибке:
Загружаемые файлы — это все библиотеки, исполняемые сервером, и код среды узла может быть сгенерирован внутри, поэтому нам нужно оценить переменные среды. Если вы разрабатываете, некоторые предупреждающие сообщения будут выводиться, но не во внешнем интерфейсе. Поэтому нам нужно смоделировать его и сообщить браузеру нашу текущую среду.
Добавьте переменную среды процесса в html.
<script>
window.process = { env: { NODE_ENV: 'dev' } }
</script>
В этот момент загружается основной файл.
Но это далеко не поражение нашей цели!
Что нам нужно, так это сервер, который может компилировать файлы vue!
иметь дело с.vue
документ
файл main.js:
import { createApp, h } from 'vue'
import App from './App.vue'
createApp(App).mount('#app')
В файле vue он загружается модульно.
Нам нужно иметь дело с файлами vue, правильно.vue
Перенесенные позже параметры обрабатываются.
Здесь мы упрощаем и рассматриваем только случаи шаблона и sfc.
else if (url.indexOf('.vue') > -1) {
// 处理vue文件 App.vue?vue&type=style&index=0&lang.css
// 读取vue内容
const p = path.join(__dirname, url.split('?')[0])
// compilerSfc解析sfc 获得ast
const ret = compilerSfc.parse(fs.readFileSync(p, 'utf8'))
// App.vue?type=template
// 如果请求没有query.type 说明是sfc
if (!query.type) {
// 处理内部的script
const scriptContent = ret.descriptor.script.content
// 将默认导出配置对象转为常量
const script = scriptContent.replace(
'export default ',
'const __script = ',
)
ctx.type = 'text/javascript'
ctx.body = `
${rewriteImport(script)}
// template解析转换为单独请求一个资源
import {render as __render} from '${url}?type=template'
__script.render = __render
export default __script
`
} else if (query.type === 'template') {
const tpl = ret.descriptor.template.content
// 编译包含render模块
const render = compilerDom.compile(tpl, { mode: 'module' }).code
ctx.type = 'text/javascript'
ctx.body = rewriteImport(render)
}
}
Пути образа процесса
Читайте напрямую с клиента.
else if (url.endsWith('.png')) {
ctx.body = fs.readFileSync('src' + url)
}
В конце текста есть сюрприз
Спасибо за вашу постоянную поддержку и поощрение.Сегодня, наконец, мои статьи перевалили за 100!
может сначалаобращать внимание🙋♀️, не заблудитесь!
Если более 20 человек взаимодействуют в области комментариев,один лайк один комментарий👍!
мне нужноизвлекатьодинудачливый читатель, ОтправитьНаггетс Маркчашка (илиЭмалированная чашка Nuggets) а 🙇♀️!
все такой же (Не нужно платить за доставкуо) 😁!
Крайний срок30 ноября! Действие хуже биения сердца 🎈🎈🎈!
Метод розыгрыша: используйте метод случайных чисел, чтобы разыграть первый призrandomрецензент ✨.
случайное числоrandomИнтервал: взять максимальное значениеНравитсяа такжеколичество комментариевминимальное значение .
На этот раз счастливчикам не нужно беспокоиться об истечении срока действия, я подожду, пока вы мне ответите, ха 🤞🤞🤞!
Заинтересованные друзья могут подписатьсясерияКолонка или нажмите, чтобы подписаться на автора (●'◡'●)! . Если не хватит, подскажите.
Лаки раскрыл секрет 🎊
Кто станет счастливчиком? !
Эта статья имеет в общей сложности 65 комментариев! Удалите дубликат, всего 64.
Пришло интересное время! 📢
Поздравляем счастливого 37-го комментатора!