#node.js #webpack #localhost #koa #webpack-hmr
#node.js #webpack #localhost #koa #webpack-hmr
Вопрос:
По какой-то причине большинство обновлений страницы повторно запрашивают bundle.js файл, и загрузка с локального хостинга занимает около 10-15-20 секунд. Все это с локального хоста, и bundle.js размер файла составляет около 1 МБ. Запрос на этот файл, похоже, только сканируется, загружая несколько килобайт за раз.
Некоторые наблюдения:
-
После некоторого копания кажется, что он останавливается при первоначальном вызове сервера из __webpack_hmr, но я не уверен, поскольку этот вызов происходит после вызова bundle.js . Ниже приведен журнал потока запросов сервера.
-
Это происходит медленно только на страницах, содержащих более одного или двух компонентов, т.Е.. что угодно, кроме домашней страницы. Это намекает на идею, что это может быть связано с перезагрузкой горячего модуля.
- Домашняя страница по-прежнему будет занимать> 5 секунд (иногда 10-20), как и другие страницы, но если я обновлю страницу с помощью Ctrl R, она вернется почти мгновенно. Если я выполняю обновление адресной строки, это занимает больше времени. Другие страницы по-прежнему занимают столько же времени, независимо от того, нажимаю ли я Ctrl R или перезагружаю адресную строку…
- Обновление: я удалил замену горячего модуля, и это определенно кажется источником проблемы, так как страницы загружаются мгновенно без него.
Журнал запросов:
— Время отклика GET / = 609
мс —> GET / 200 647ms 2,55кб
<— GET /main.aafc9fb7f6a0c7f127edb04734d29547.css
—> GET /main.aafc9fb7f6a0c7f127edb04734d29547.css 200 17 мс 3,43 кб
<— /bundle.js
-> ПОЛУЧИТЬ /bundle.js 200 18 мс 1.29мб
<— GET /__webpack_hmr
А затем в консоли Chrome для этого запроса отображается:
Вот моя настройка:
- Использование Koa в качестве серверной среды (с использованием потоковой передачи / фрагментации в начальном ответе)
- Использование webpack с перезагрузкой горячего модуля
- Использование Vue.js как фреймворк внешнего интерфейса, с рендерингом на стороне сервера
- bundle.js подается в обычной сервировочно-статической упаковке.
- bundle.js похоже, что он вообще не кэшируется. Почему это так?
Что касается Koa, я начал с какого-то стандартного пакета, чтобы выполнить весь этот рендеринг на стороне сервера и тому подобное. Это происходит с тех пор, как я начал возиться с этой настройкой и webpack в целом, поэтому я пытаюсь разобраться в этом. Это кажется немного случайным, иногда оно возвращается через <1 секунды, но в большинстве случаев это занимает более 10 секунд. Иногда более 30 секунд ?!
Я также пытался использовать разные библиотеки для обслуживания статических файлов, но все они, похоже, делают это.
Вот моя основная конфигурация webpack (‘webpack.client’, расширенная ниже):
'use strict'
const path = require('path')
const webpack = require('webpack')
const AssetsPlugin = require('assets-webpack-plugin')
const assetsPluginInstance = new AssetsPlugin({path: path.join(process.cwd(), 'build')})
const postcss = [
require('precss')()
//require('autoprefixer')({browsers: ['last 2 versions']}),
]
module.exports = {
entry: [
'./src/client-entry.js'
],
output: {
path: path.join(process.cwd(), 'build'),
filename: 'bundle.js',
publicPath: '/'
},
resolve: {
extensions: ['', '.vue', '.js', '.json']
},
module: {
loaders: [
{
test: /.vue$/,
loaders: ['vue']
},
{
test: /.js$/,
loaders: ['babel'],
exclude: [/node_modules/]
},
{
test: /.json$/,
loaders: ['json'],
exclude: [/node_modules/]
},
{
test: /.(png|jpg|gif|svg)$/,
loader: 'url?limit=10000amp;name=images/[hash].[ext]',
include: path.src,
},
{
test: /.woff($|?)|.woff2($|?)|.ttf($|?)|.eot($|?)|.svg($|?)/,
loader: 'url-loader',
include: path.src,
}
]
},
node: { net: 'empty', dns: 'empty' },
postcss,
vue: {
postcss,
loaders: {}
},
plugins: [
assetsPluginInstance
]
}
А также это (расширяет предыдущее):
'use strict'
const webpack = require('webpack')
const config = require('./webpack.client')
const ExtractTextPlugin = require('extract-text-webpack-plugin')
config.entry.push('webpack-hot-middleware/client')
//config.devtool = 'inline-eval-cheap-source-map'
config.plugins = config.plugins.concat([
new webpack.HotModuleReplacementPlugin(),
new webpack.NoErrorsPlugin(),
new webpack.DefinePlugin({
'__DEV__': true,
'process.env.NODE_ENV': JSON.stringify('development')
}),
new ExtractTextPlugin('[name].[contenthash].css')
])
config.vue.loaders = {
postcss: ExtractTextPlugin.extract(
'vue-style-loader',
'css-loader?sourceMap'
),
css: ExtractTextPlugin.extract(
'vue-style-loader',
'css-loader?sourceMap'
)
}
module.exports = config
Вот мой сервер index.js файл для Koa:
import path from 'path'
import fs from 'fs'
import Koa from 'koa'
import convert from 'koa-convert'
//import serve from 'koa-static-server'
import serveStatic from 'koa-static'
import {PassThrough} from 'stream'
import {createBundleRenderer} from 'vue-server-renderer'
import serialize from 'serialize-javascript'
import MFS from 'memory-fs'
import assets from '../build/webpack-assets'
import cookie from 'koa-cookie'
let renderer
const createRenderer = fs => {
const bundlePath = path.resolve(process.cwd(), 'build/server-bundle.js')
return createBundleRenderer(fs.readFileSync(bundlePath, 'utf-8'))
}
const app = new Koa();
app.use(cookie());
if (process.env.NODE_ENV === 'development') {
// DEVELOPMENT, with hot reload
const webpack = require('webpack')
const webpackConfig = require('../config/webpack.client.dev')
const compiler = webpack(webpackConfig)
const devMiddleware = require('koa-webpack-dev-middleware')
const hotMiddleware = require('koa-webpack-hot-middleware')
app.use(convert(devMiddleware(compiler, {
publicPath: webpackConfig.output.publicPath,
stats: {
colors: true,
modules: false,
children: false,
chunks: false,
chunkModules: false
}
})))
app.use(convert(hotMiddleware(compiler)))
// server renderer
const serverBundleConfig = require('../config/webpack.bundle')
const serverBundleCompiler = webpack(serverBundleConfig)
const mfs = new MFS()
serverBundleCompiler.outputFileSystem = mfs
serverBundleCompiler.watch({}, (err, stats) => {
if (err) throw err
stats = stats.toJson()
stats.errors.forEach(err => console.error(err))
stats.warnings.forEach(err => console.warn(err))
renderer = createRenderer(mfs)
})
}
else {
// PRODUCTION
// use nginx to serve static files in real
//app.use(convert(serve({rootDir: path.join(process.cwd(), 'build'), rootPath: '/static'})))
app.use(serveStatic(path.join(process.cwd(), 'build')));
renderer = createRenderer(fs)
}
app.use(ctx => {
var start = new Date;
ctx.type = 'text/html; charset=utf-8'
const context = {url: ctx.url}
const title = 'Tripora';
const stream = new PassThrough()
console.log("Checking if server-side cookie exists...");
// See if request sent over an authentication token in their cookies
if(ctx.cookie amp;amp; ctx.cookie.token) {
console.log("Found cookie token.");
context.token = ctx.cookie.token;
}
stream.write(`<!DOCTYPE html><html style="min-height: 100%;"><head><meta charset="utf-8"/><title>${title}</title>${assets.main.css ? `<link rel="stylesheet" href="${assets.main.css}"/>` : ''}</head><body style="min-height: 100%;">`)
const renderStream = renderer.renderToStream(context)
let firstChunk = true
renderStream.on('data', chunk => {
// we tell the request to ignore files as an initial reuqest
var isPage = ctx.url.split(".").length == 1;
if (firstChunk amp;amp; context.initialState amp;amp; isPage) {
stream.write(`<script>window.__INITIAL_STATE__=${serialize(context.initialState, {isJSON: true})}</script>${chunk}`)
firstChunk = false
} else {
stream.write(chunk)
}
})
renderStream.on('end', () => {
stream.write(`<script src="${assets.main.js}"></script></body></html>`)
var ms = new Date - start;
//ctx.set('X-Response-Time', ms 'ms');
console.log("-- Response time %s %s = %sms", ctx.method, ctx.originalUrl, ms);
ctx.res.end()
})
renderStream.on('error', err => {
console.log("ERROR", err.stack);
throw new Error(`something bad happened when renderToStream: ${err}`)
})
ctx.status = 200
ctx.body = stream
})
const port = process.env.NODE_PORT || 80
app.listen(port, () => {
console.log(`==> Listening at http://localhost:${port}`)
})
Кто-нибудь знает, почему первоначальный запрос HMR занимает так много времени и кажется таким случайным (иногда 5 секунд, иногда 30 секунд)? Технология.
Комментарии:
1. Вы когда-нибудь это понимали?