Socket
Socket
Sign inDemoInstall

@quasar/ssr-helpers

Package Overview
Dependencies
Maintainers
4
Versions
15
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@quasar/ssr-helpers - npm Package Compare versions

Comparing version 2.2.2 to 3.0.0

263

create-renderer.js
/*
* Forked from vue-bundle-runner v0.0.3 NPM package
* Inspired from vue-bundle-runner v0.0.3 NPM package
*/
const { extname } = require('path')
const serialize = require('serialize-javascript')
const createBundle = require('./lib/create-bundle')
const jsRE = /\.js(\?[^.]+)?$/
const cssRE = /\.css(\?[^.]+)?$/
const jsCssRE = /\.(js|css)($|\?)/
const queryRE = /\?.*/
const trailingSlashRE = /([^/])$/
function createRenderContext (clientManifest) {
const { publicPath, initial, modules } = clientManifest
const addPublicPath = file => publicPath + file
const [ firstBodyFile, ...otherBodyFiles ] = initial.b.map(addPublicPath)
/**
* Creates a mapper that maps components used during a server-side render
* to async chunk files in the client-side build, so that we can inline them
* directly in the rendered HTML to avoid waterfall requests.
*/
function createMapper (clientManifest) {
const map = new Map()
return {
initialHeadFiles: initial.h.map(addPublicPath),
Object.keys(clientManifest.modules).forEach(id => {
map.set(id, mapIdToFile(id, clientManifest))
})
getBodyFiles: firstBodyFile
? asyncFiles => ([ firstBodyFile, ...asyncFiles, ...otherBodyFiles ])
: asyncFiles => asyncFiles,
// map server-side moduleIds to client-side files
return function mapper (moduleIds) {
const res = new Set()
for (let i = 0; i < moduleIds.length; i++) {
const mapped = map.get(moduleIds[i])
if (mapped) {
for (let j = 0; j < mapped.length; j++) {
const entry = mapped[j]
if (entry !== void 0) {
res.add(mapped[j])
}
}
}
}
return Array.from(res)
}
}
getAsyncFiles: moduleIds => {
const head = new Set()
const body = new Set()
function mapIdToFile (id, clientManifest) {
const files = []
const fileIndices = clientManifest.modules[id]
for (let i = 0; i < moduleIds.length; i++) {
const list = modules[ moduleIds[ i ] ]
if (fileIndices !== void 0) {
fileIndices.forEach(index => {
const file = clientManifest.all[index]
// if it has no mapping...
if (list === void 0) continue
// only include async files or non-js, non-css assets
if (
clientManifest.async.includes(file) ||
(jsCssRE.test(file) === false)
) {
files.push(file)
if (list.h !== void 0) list.h.forEach(file => head.add(file))
if (list.b !== void 0) list.b.forEach(file => body.add(file))
}
})
}
return files
}
function normalizeFile (file) {
const fileWithoutQuery = file.replace(queryRE, '')
const extension = extname(fileWithoutQuery).slice(1)
return {
file,
extension,
fileWithoutQuery
return {
head: Array.from(head).map(addPublicPath),
body: Array.from(body).map(addPublicPath)
}
}
}
}
function ensureTrailingSlash (path) {
return path === ''
? path
: path.replace(trailingSlashRE, '$1/')
}
const autoRemove = 'document.currentScript.remove()'
function createRenderContext (clientManifest) {
return {
clientManifest,
publicPath: ensureTrailingSlash(clientManifest.publicPath || '/'),
preloadFiles: (clientManifest.initial || []).map(normalizeFile),
mapFiles: createMapper(clientManifest)
}
function renderStoreState (ssrContext) {
const nonceAttr = ssrContext.nonce !== void 0
? ` nonce="${ ssrContext.nonce }"`
: ''
const state = serialize(ssrContext.state, { isJSON: true })
return `<script${nonceAttr}>window.__INITIAL_STATE__=${state};${autoRemove}</script>`
}
function renderStyles (renderContext, usedAsyncFiles, ssrContext) {
const initial = renderContext.preloadFiles
const cssFiles = initial.concat(usedAsyncFiles).filter(({ file }) => cssRE.test(file))
function renderHeadTags ({ renderContext, asyncFiles, renderPreloadTagMap, ssrContext }) {
return (
// render head assets
[ ...renderContext.initialHeadFiles, ...asyncFiles.head ]
.map(renderPreloadTagMap)
.join('')
return (
// render links for css files
(
cssFiles.length
? cssFiles.map(({ file }) => `<link rel="stylesheet" href="${renderContext.publicPath}${file}">`).join('')
: ''
) +
// ssrContext.styles is a getter exposed by vue-style-loader which contains
// the inline component styles collected during SSR
(ssrContext.styles || '')
+ (ssrContext.styles || '')
)
}
const autoRemove = 'document.currentScript.remove()'
function renderStoreState (ssrContext, nonce) {
const state = serialize(ssrContext.state, { isJSON: true })
return `<script${nonce}>window.__INITIAL_STATE__=${state};${autoRemove}</script>`
function renderBodyTags ({ renderContext, asyncFiles, renderPreloadTagMap }) {
return renderContext.getBodyFiles(asyncFiles.body)
.filter(entry => entry !== void 0)
.map(renderPreloadTagMap)
.join('')
}
function renderScripts(renderContext, usedAsyncFiles, nonce) {
if (renderContext.preloadFiles.length > 0) {
const initial = renderContext.preloadFiles.filter(({ file }) => jsRE.test(file))
const async = usedAsyncFiles.filter(({ file }) => jsRE.test(file))
return [ initial[0] ].concat(async, initial.slice(1))
.map(({ file }) => `<script${nonce} src="${renderContext.publicPath}${file}" defer></script>`)
.join('')
}
return ''
}
module.exports = function createRenderer (opts) {
const renderContext = createRenderContext(opts.clientManifest)
const { evaluateEntry, rewriteErrorTrace } = createBundle(opts)
async function runApp(ssrContext) {
function createRenderToStringFn (data) {
return async function renderToString (ssrContext) {
try {
const entry = await evaluateEntry()
return await entry(ssrContext)
}
catch (err) {
await rewriteErrorTrace(err)
throw err
}
}
return async function renderToString (ssrContext, renderTemplate) {
try {
const onRenderedList = []

@@ -155,8 +83,5 @@

const app = await runApp(ssrContext)
const resourceApp = await opts.vueRenderToString(app, ssrContext)
const usedAsyncFiles = renderContext
.mapFiles(Array.from(ssrContext._modules))
.map(normalizeFile)
const runtimePageContent = await data.getRuntimePageContent(ssrContext)
onRenderedList.forEach(fn => { fn() })

@@ -168,19 +93,25 @@

const nonce = ssrContext.nonce !== void 0
? ` nonce="${ ssrContext.nonce }" `
: ''
const renderTagOptions = {
renderContext: data.renderContext,
asyncFiles: data.renderContext.getAsyncFiles(Array.from(ssrContext._modules)),
renderPreloadTagMap: file => data.renderPreloadTag(file, ssrContext),
ssrContext
}
Object.assign(ssrContext._meta, {
resourceApp,
resourceStyles: renderStyles(renderContext, usedAsyncFiles, ssrContext),
resourceScripts: (
(opts.manualStoreSerialization !== true && ssrContext.state !== void 0 ? renderStoreState(ssrContext, nonce) : '')
+ renderScripts(renderContext, usedAsyncFiles, nonce)
endingHeadTags: renderHeadTags(renderTagOptions) + ssrContext._meta.endingHeadTags,
runtimePageContent,
afterRuntimePageContent: (
(data.manualStoreSerialization !== true && ssrContext.state !== void 0 ? renderStoreState(ssrContext) : '')
+ renderBodyTags(renderTagOptions)
)
})
return renderTemplate(ssrContext)
return data.renderTemplate(ssrContext)
}
catch (err) {
await rewriteErrorTrace(err)
if (data.rewriteErrorTrace !== void 0) {
await data.rewriteErrorTrace(err)
}
throw err

@@ -190,1 +121,69 @@ }

}
module.exports.getProdRenderFunction = function getProdRenderFunction (opts) {
return createRenderToStringFn({
renderContext: createRenderContext(opts.clientManifest),
renderTemplate: opts.renderTemplate,
renderPreloadTag: opts.renderPreloadTag,
manualStoreSerialization: opts.manualStoreSerialization,
getRuntimePageContent: async ssrContext => {
const app = await opts.serverEntry(ssrContext)
return await opts.vueRenderToString(app, ssrContext)
}
})
}
module.exports.createDevRenderer = function createDevRenderer (opts) {
const data = {
renderContext: null,
evaluateEntry: null,
rewriteErrorTrace: null,
renderTemplate: null,
renderPreloadTag: null,
manualStoreSerialization: opts.manualStoreSerialization,
getRuntimePageContent: async ssrContext => {
const entry = await data.evaluateEntry()
const app = await entry(ssrContext)
return await opts.vueRenderToString(app, ssrContext)
}
}
const dataKeys = Object.keys(data)
let checkIfReady = () => {
if (dataKeys.every(key => data[ key ] !== null)) {
checkIfReady = () => {}
opts.onReady()
}
}
const updateClientManifest = clientManifest => {
data.renderContext = createRenderContext(clientManifest)
checkIfReady()
}
const updateServerManifest = serverManifest => {
const { evaluateEntry, rewriteErrorTrace } = createBundle(serverManifest, opts.basedir)
data.evaluateEntry = evaluateEntry
data.rewriteErrorTrace = rewriteErrorTrace
checkIfReady()
}
const updateRenderTemplate = renderTemplate => {
data.renderTemplate = renderTemplate
checkIfReady()
}
const updateRenderPreloadTag = renderPreloadTag => {
data.renderPreloadTag = renderPreloadTag
checkIfReady()
}
return {
renderToString: createRenderToStringFn(data),
updateClientManifest,
updateServerManifest,
updateRenderTemplate,
updateRenderPreloadTag
}
}

@@ -79,3 +79,3 @@ /*

function createEvaluateModule (files, { basedir, runningScriptOptions }) {
function createEvaluateModule (files, basedir) {
const _evalCache = {}

@@ -93,3 +93,3 @@ const compile = createCompile()

const compiledWrapper = script.runInThisContext(runningScriptOptions)
const compiledWrapper = script.runInThisContext()

@@ -184,5 +184,5 @@ const module = createModule({ filename, id: filename, require })

module.exports = function createBundle (opts) {
const bundle = loadBundle(opts.serverManifest, opts.basedir)
const evaluateModule = createEvaluateModule(bundle.files, opts)
module.exports = function createBundle (serverManifest, basedir) {
const bundle = loadBundle(serverManifest, basedir)
const evaluateModule = createEvaluateModule(bundle.files, basedir)

@@ -189,0 +189,0 @@ return {

{
"name": "@quasar/ssr-helpers",
"version": "2.2.2",
"version": "3.0.0",
"description": "Quasar Framework helper package for SSR",

@@ -5,0 +5,0 @@ "author": {

@@ -5,6 +5,13 @@ ![Quasar Framework logo](https://cdn.quasar.dev/logo-v2/header.png)

> This package contains forks of multiple other packages and is being used and maintained by Quasar Framework.<br>
> **Used internally by Quasar CLI.**
> **Used internally by Quasar CLI (@quasar/app-webpack).**
<img src="https://img.shields.io/npm/v/%40quasar/ssr-helpers.svg?label=@quasar/ssr-helpers">
## Version mapping
| @quasar/app-webpack | @quasar/ssr-helpers |
| --- | --- |
| v4 | v3 |
| v3 | v2 |
## Contents

@@ -11,0 +18,0 @@ * @quasar/ssr-helpers/webpack-client-plugin

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc