передовой
через предыдущий постСоздайте приложение SSR с помощью vue-cli3Мы знаем, что такое SSR и как создать приложение SSR с помощью vue-cli3. Но в итоге остались некоторые проблемы, с которыми не справились, то есть не добавлена функция горячего обновления при разработке, нужно ли перекомпилировать и упаковывать каждый раз при обновлении кода? Явно не очень разумно. Затем мы добавим функцию горячего обновления в программу SSR.
1. Решения
Мы знаем, что эти два файла будут генерироваться каждый раз при упаковке и компиляции программы SSR.vue-ssr-client-manifest.jsonиvue-ssr-server-bundle.json
- vue-ssr-client-manifest.json
В основном записывает информацию о конфигурации статических файлов ресурсов.
- vue-ssr-server-bundle.json
В основном записывает содержимое файла js
Теперь проблема заключается в том, чтобы решить, как получить последнюю версию после сохранения кода.vue-ssr-client-manifest.jsonиvue-ssr-server-bundle.jsonэти два файла.
Из этого рисунка мы знаем, что, поскольку он будет обновляться в горячем режиме, сервер разработки webpack определенно не сможет работать.
Итак, шаги решения следующие:
- Запустите службу сервера разработки webpack и откройте порт 8080.
- Запустите компилятор веб-пакета, чтобы скомпилировать файл конфигурации веб-пакета, отслеживать изменения файла и компилировать в режиме реального времени, чтобы получить последнюю версию vue-ssr-server-bundle.json.
- Получите последнюю версию vue-ssr-client-manifest.json через сервер разработки webpack.
- Объедините vue-ssr-server-bundle.json и vue-ssr-client-manifest.json, чтобы отобразить html-страницу и вернуть ее в браузер.
2. Реализация кода
После того, как появилась идея, осталось подумать о том, как реализовать ее с помощью кода.
2.1, запустите службу сервера разработки webpack
Через npm run serve мы можем быстро запустить службу сервера разработки webpack.
npm run serve
2.2 Получите файл конфигурации веб-пакета и скомпилируйте его
чтениемофициальная документацияМы знаем, что файл конфигурации для веб-пакета находится в /node_modules/@vue/cli-service/webpack.config.js.
// 1、webpack配置文件
const webpackConfig = require('@vue/cli-service/webpack.config')
2.3. Скомпилируйте файл конфигурации веб-пакета и отслеживайте изменения файлов
// 2、编译webpack配置文件
const serverCompiler = webpack(webpackConfig)
const mfs = new MemoryFS()
// 指定输出到的内存流中
serverCompiler.outputFileSystem = mfs
// 3、监听文件修改,实时编译获取最新的 vue-ssr-server-bundle.json
let bundle
serverCompiler.watch({}, (err, stats) =>{
if (err) {
throw err
}
stats = stats.toJson()
stats.errors.forEach(error => console.error(error) )
stats.warnings.forEach( warn => console.warn(warn) )
const bundlePath = path.join(
webpackConfig.output.path,
'vue-ssr-server-bundle.json'
)
bundle = JSON.parse(mfs.readFileSync(bundlePath,'utf-8'))
console.log('new bundle generated')
})
2.4 Получите последнюю версию vue-ssr-client-manifest.json
// 4、获取最新的 vue-ssr-client-manifest.json
// 这边的 8080 是 dev server 的端口号
const clientManifestResp = await axios.get('http://localhost:8080/vue-ssr-client-manifest.json')
const clientManifest = clientManifestResp.data
2.5 Окончательный код после объединения ядра каждого шага
Установите необходимые библиотеки
npm install webpack memory-fs concurrently -D
npm install koa-router axios -S
Создайте новый server/dev.ssr.js в корневом каталоге проекта, код выглядит следующим образом
// server/dev.ssr.js
const webpack = require('webpack')
const axios = require('axios')
const MemoryFS = require('memory-fs')
const fs = require('fs')
const path = require('path')
const Router = require('koa-router')
// 1、webpack配置文件
const webpackConfig = require('@vue/cli-service/webpack.config')
const { createBundleRenderer } = require("vue-server-renderer");
// 2、编译webpack配置文件
const serverCompiler = webpack(webpackConfig)
const mfs = new MemoryFS()
// 指定输出文件到的内存流中
serverCompiler.outputFileSystem = mfs
// 3、监听文件修改,实时编译获取最新的 vue-ssr-server-bundle.json
let bundle
serverCompiler.watch({}, (err, stats) =>{
if (err) {
throw err
}
stats = stats.toJson()
stats.errors.forEach(error => console.error(error) )
stats.warnings.forEach( warn => console.warn(warn) )
const bundlePath = path.join(
webpackConfig.output.path,
'vue-ssr-server-bundle.json'
)
bundle = JSON.parse(mfs.readFileSync(bundlePath,'utf-8'))
console.log('new bundle generated')
})
// 处理请求
const handleRequest = async ctx => {
console.log('path', ctx.path)
if (!bundle) {
ctx.body = '等待webpack打包完成后在访问在访问'
return
}
// 4、获取最新的 vue-ssr-client-manifest.json
const clientManifestResp = await axios.get('http://localhost:8080/vue-ssr-client-manifest.json')
const clientManifest = clientManifestResp.data
const renderer = createBundleRenderer(bundle, {
runInNewContext: false,
template: fs.readFileSync(path.resolve(__dirname, "../src/index.temp.html"), "utf-8"),
clientManifest: clientManifest
});
const html = await renderToString(ctx,renderer)
ctx.body = html;
}
function renderToString(context,renderer) {
return new Promise((resolve, reject) => {
renderer.renderToString(context, (err, html) => {
err ? reject(err) : resolve(html);
});
});
}
const router = new Router()
router.get("*", handleRequest);
module.exports = router
Создайте новый server/ssr.js со следующим кодом
// server/ssr.js
const Koa = require('koa')
const koaStatic = require("koa-static");
const path = require('path')
const resolve = file => path.resolve(__dirname, file);
const app = new Koa()
const isDev = process.env.NODE_ENV !== 'production'
const router = isDev ? require('./dev.ssr') : require('./server')
app.use(router.routes()).use(router.allowedMethods())
// 开放目录
app.use(koaStatic(resolve("../dist")));
const port = process.env.PORT || 3000;
app.listen(port, () => {
console.log(`server started at localhost:${port}`);
});
module.exports = app
Измените package.json, чтобы добавить несколько сценариев выполнения.
// package.json scripts字段
"dev:serve": "cross-env WEBPACK_TARGET=node node ./server/ssr.js",
"dev": "concurrently \"npm run serve\" \"npm run dev:serve\" "
Выполните команду npm run dev
npm run dev
доступlocalhost:3000Вы обнаружите, что проблема все еще существует.
Статический файл ресурсов относится к службе сервера node.js, то есть он относится к порту 3000, но служба на порту 3000 не имеет этих файлов статических ресурсов. Эти файлы статических ресурсов находятся на сервере разработки webpack.
Как это решить?
- Измените сервер узла, чтобы проксировать запросы этих статических ресурсов на сервер разработки веб-пакета.
- Измените baseUrl веб-пакета и напрямую обратитесь к серверу разработки веб-пакета.
Очевидно, что второй метод относительно прост в реализации, тогда мы модифицируем конфигурацию baseUrl веб-пакета.
Изменить vue.config.js
// vue.config.js
// 添加一个字段,如果是开发环境,就指定到webpack dev server中
baseUrl: isDev ? 'http://127.0.0.1:8080' : '',
сноваnpm run dev, затем посетитеlocalhost:3000
Доступ к нему нормальный, тогда давайте попробуем посмотреть, можно ли реализовать горячее обновление, изменить кусок кода,
Вы обнаружите, что сервер узла перекомпилирует файл конфигурации веб-пакета, а затем проверит, был ли обновлен браузер.
Вы обнаружите, что браузер по-прежнему не может обновить контент в горячем режиме, откройте F12, вы найдете эту ошибку,
Это наше обычное сообщение об ошибке, что междоменное использование запрещено.
Решение:
- Настройте сервер разработки webpack, чтобы разрешить междоменный доступ
// vue.config.js
// 添加一个 devServer的字段
devServer: {
headers: {'Access-Control-Allow-Origin': '*'}
},
сноваnpm run dev, затем посетитеlocalhost:3000
Уже можно добиться горячего обновления.
3. Оптимизация
1. Проблема фавикона Откройте f12, все еще можете увидеть проблему
Для конкретной реализации, пожалуйста, обратитесь к моемукод гитхаба
2. Измените код на стороне сервера для автоматического перезапуска кода.
Его можно реализовать с помощью nodemon или pm2.
4. Резюме
через предыдущую статьюСоздайте приложение SSR с помощью vue-cli3В этой статье мы шаг за шагом построили ssr-приложение на основе vue-cli3 и добавили функцию горячего обновления, во время которого также наступили на множество ям. Но после окончательного осознания вы почувствуете, что эти усилия того стоят, потому что они закладывают основу для вашего собственного роста.
Если есть лучший метод реализации, добро пожаловать на обмен!
Если что-то не так, укажите на это!
5. Исходный код
Исходный код проекта:vue-cli-ssr-exampleприветственная звезда
публика
Добро пожаловать, чтобы обратить внимание на мой общедоступный номер"разработка кода", делитесь последней технической информацией каждый день. Подпишитесь, чтобы получать последние ресурсы