Skip to content
This repository has been archived by the owner on Jan 18, 2022. It is now read-only.

build(deps): bump ini from 1.3.5 to 1.3.8 #425

Open
wants to merge 8 commits into
base: next
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,10 @@
"changelog": "conventional-changelog -p angular -i CHANGELOG.md -s -r 2"
},
"dependencies": {
"@rollup/pluginutils": "^4.1.0",
"debug": "^4.1.1",
"hash-sum": "^2.0.0",
"rollup-pluginutils": "^2.8.2"
"source-map": "^0.6.1"
},
"peerDependencies": {
"@vue/compiler-sfc": "*"
Expand All @@ -38,6 +39,7 @@
"lint-staged": "^10.1.7",
"npm-run-all": "^4.1.5",
"prettier": "^2.0.5",
"pug": "^3.0.0",
"rollup": "^2.7.2",
"rollup-plugin-postcss": "^3.1.8",
"ts-jest": "^26.0.0",
Expand All @@ -55,7 +57,6 @@
},
"prettier": {
"printWidth": 80,
"trailingComma": "es5",
"semi": false,
"singleQuote": true
}
Expand Down
192 changes: 192 additions & 0 deletions src/handleHotUpdate.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
import fs from 'fs'
import _debug from 'debug'
import { parse, SFCBlock, SFCDescriptor } from '@vue/compiler-sfc'
import {
getDescriptor,
setDescriptor,
setPrevDescriptor,
} from './utils/descriptorCache'
import { getResolvedScript, setResolvedScript } from './script'

const debug = _debug('vite:hmr')

/**
* Vite-specific HMR handling
*/
export async function handleHotUpdate(file: string, modules: any[]) {
if (!file.endsWith('.vue')) {
return
}

const prevDescriptor = getDescriptor(file)
if (!prevDescriptor) {
// file hasn't been requested yet (e.g. async component)
return
}

let content = fs.readFileSync(file, 'utf-8')
if (!content) {
await untilModified(file)
content = fs.readFileSync(file, 'utf-8')
}

const { descriptor } = parse(content, {
filename: file,
sourceMap: true,
})
setDescriptor(file, descriptor)
setPrevDescriptor(file, prevDescriptor)

let needRerender = false
const filteredModules = new Set()
const mainModule = modules.find(
(m) => !/type=/.test(m.id) || /type=script/.test(m.id)
)
const templateModule = modules.find((m) => /type=template/.test(m.id))

if (
!isEqualBlock(descriptor.script, prevDescriptor.script) ||
!isEqualBlock(descriptor.scriptSetup, prevDescriptor.scriptSetup)
) {
filteredModules.add(mainModule)
}

if (!isEqualBlock(descriptor.template, prevDescriptor.template)) {
// when a <script setup> component's template changes, it will need correct
// binding metadata. However, when reloading the template alone the binding
// metadata will not be available since the script part isn't loaded.
// in this case, reuse the compiled script from previous descriptor.
if (!filteredModules.has(mainModule)) {
setResolvedScript(descriptor, getResolvedScript(prevDescriptor)!)
}
filteredModules.add(templateModule)
needRerender = true
}

let didUpdateStyle = false
const prevStyles = prevDescriptor.styles || []
const nextStyles = descriptor.styles || []

// force reload if CSS vars injection changed
if (descriptor.cssVars) {
if (prevDescriptor.cssVars.join('') !== descriptor.cssVars.join('')) {
filteredModules.add(mainModule)
}
}

// force reload if scoped status has changed
if (prevStyles.some((s) => s.scoped) !== nextStyles.some((s) => s.scoped)) {
// template needs to be invalidated as well
filteredModules.add(templateModule)
filteredModules.add(mainModule)
}

// only need to update styles if not reloading, since reload forces
// style updates as well.
for (let i = 0; i < nextStyles.length; i++) {
const prev = prevStyles[i]
const next = nextStyles[i]
if (!prev || !isEqualBlock(prev, next)) {
didUpdateStyle = true
const mod = modules.find((m) => m.id.includes(`type=style&index=${i}`))
if (mod) {
filteredModules.add(mod)
} else {
// new style block - force reload
filteredModules.add(mainModule)
}
}
}
if (prevStyles.length > nextStyles.length) {
// style block removed - force reload
filteredModules.add(mainModule)
}

const prevCustoms = prevDescriptor.customBlocks || []
const nextCustoms = descriptor.customBlocks || []

// custom blocks update causes a reload
// because the custom block contents is changed and it may be used in JS.
for (let i = 0; i < nextCustoms.length; i++) {
const prev = prevCustoms[i]
const next = nextCustoms[i]
if (!prev || !isEqualBlock(prev, next)) {
const mod = modules.find((m) =>
m.id.includes(`type=${prev.type}&index=${i}`)
)
if (mod) {
filteredModules.add(mod)
} else {
filteredModules.add(mainModule)
}
}
}
if (prevCustoms.length > nextCustoms.length) {
// block rmeoved, force reload
filteredModules.add(mainModule)
}

let updateType = []
if (needRerender) {
updateType.push(`template`)
// template is inlined into main, add main module instead
if (!templateModule) {
filteredModules.add(mainModule)
}
}
if (didUpdateStyle) {
updateType.push(`style`)
}
if (updateType.length) {
debug(`[vue:update(${updateType.join('&')})] ${file}`)
}
return [...filteredModules].filter(Boolean)
}

// vitejs/vite#610 when hot-reloading Vue files, we read immediately on file
// change event and sometimes this can be too early and get an empty buffer.
// Poll until the file's modified time has changed before reading again.
async function untilModified(file: string) {
const mtime = fs.statSync(file).mtimeMs
return new Promise((r) => {
let n = 0
const poll = async () => {
n++
const newMtime = fs.statSync(file).mtimeMs
if (newMtime !== mtime || n > 10) {
r(0)
} else {
setTimeout(poll, 10)
}
}
setTimeout(poll, 10)
})
}

function isEqualBlock(a: SFCBlock | null, b: SFCBlock | null) {
if (!a && !b) return true
if (!a || !b) return false
// src imports will trigger their own updates
if (a.src && b.src && a.src === b.src) return true
if (a.content !== b.content) return false
const keysA = Object.keys(a.attrs)
const keysB = Object.keys(b.attrs)
if (keysA.length !== keysB.length) {
return false
}
return keysA.every((key) => a.attrs[key] === b.attrs[key])
}

export function isOnlyTemplateChanged(
prev: SFCDescriptor,
next: SFCDescriptor
) {
return (
isEqualBlock(prev.script, next.script) &&
isEqualBlock(prev.scriptSetup, next.scriptSetup) &&
prev.styles.length === next.styles.length &&
prev.styles.every((s, i) => isEqualBlock(s, next.styles[i])) &&
prev.customBlocks.length === next.customBlocks.length &&
prev.customBlocks.every((s, i) => isEqualBlock(s, next.customBlocks[i]))
)
}
58 changes: 33 additions & 25 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,24 +14,25 @@ import {
import fs from 'fs'
import createDebugger from 'debug'
import { Plugin } from 'rollup'
import { createFilter } from 'rollup-pluginutils'
import { transformSFCEntry } from './sfc'
import { transformTemplate } from './template'
import { createFilter } from '@rollup/pluginutils'
import { genSfcFacade } from './sfcFacade'
import { transformTemplateAsModule } from './template'
import { transformStyle } from './style'
import { createCustomBlockFilter } from './utils/customBlockFilter'
import { getDescriptor, setDescriptor } from './utils/descriptorCache'
import { parseVuePartRequest } from './utils/query'
import { normalizeSourceMap } from './utils/sourceMap'
import { getResolvedScript } from './script'
import { handleHotUpdate } from './handleHotUpdate'

const debug = createDebugger('rollup-plugin-vue')

export interface Options {
include: string | RegExp | (string | RegExp)[]
exclude: string | RegExp | (string | RegExp)[]
target: 'node' | 'browser'
vite: boolean
hmr: boolean
exposeFilename: boolean

customBlocks?: string[]

// if true, handle preprocessors directly instead of delegating to other
Expand All @@ -58,6 +59,8 @@ export interface Options {
const defaultOptions: Options = {
include: /\.vue$/,
exclude: [],
vite: false,
hmr: false,
target: 'browser',
exposeFilename: false,
customBlocks: [],
Expand All @@ -69,6 +72,10 @@ export default function PluginVue(userOptions: Partial<Options> = {}): Plugin {
...userOptions,
}

if (options.vite) {
options.preprocessStyles = false
}

const isServer = options.target === 'node'
const isProduction =
process.env.NODE_ENV === 'production' || process.env.BUILD === 'production'
Expand Down Expand Up @@ -109,23 +116,21 @@ export default function PluginVue(userOptions: Partial<Options> = {}): Plugin {
return fs.readFileSync(query.filename, 'utf-8')
}
const descriptor = getDescriptor(query.filename)
if (descriptor) {
const block =
query.type === 'template'
? descriptor.template!
: query.type === 'script'
? getResolvedScript(descriptor, isServer)
: query.type === 'style'
? descriptor.styles[query.index]
: typeof query.index === 'number'
? descriptor.customBlocks[query.index]
: null

if (block) {
return {
code: block.content,
map: normalizeSourceMap(block.map, id),
}
const block =
query.type === 'template'
? descriptor.template!
: query.type === 'script'
? getResolvedScript(descriptor, isServer)
: query.type === 'style'
? descriptor.styles[query.index]
: typeof query.index === 'number'
? descriptor.customBlocks[query.index]
: null

if (block) {
return {
code: block.content,
map: block.map as any,
}
}
}
Expand All @@ -139,7 +144,7 @@ export default function PluginVue(userOptions: Partial<Options> = {}): Plugin {
// generate an entry module that imports the actual blocks of the SFC
if (!query.vue && filter(id)) {
debug(`transform SFC entry (${id})`)
const output = transformSFCEntry(
const output = await genSfcFacade(
code,
id,
options,
Expand All @@ -165,14 +170,17 @@ export default function PluginVue(userOptions: Partial<Options> = {}): Plugin {
}
if (query.type === 'template') {
debug(`transform template (${id})`)
return transformTemplate(code, id, options, query, this)
return transformTemplateAsModule(code, options, query, this)
} else if (query.type === 'style') {
debug(`transform style (${id})`)
return transformStyle(code, id, options, query, isProduction, this)
return transformStyle(code, options, query, isProduction, this)
}
}
return null
},

// @ts-ignore
handleHotUpdate,
}
}

Expand Down
12 changes: 10 additions & 2 deletions src/script.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,19 @@ const serverCache = new WeakMap<SFCDescriptor, SFCScriptBlock | null>()

export function getResolvedScript(
descriptor: SFCDescriptor,
isServer: boolean
isServer = false
): SFCScriptBlock | null | undefined {
return (isServer ? serverCache : clientCache).get(descriptor)
}

export function setResolvedScript(
descriptor: SFCDescriptor,
script: SFCScriptBlock,
isServer = false
) {
;(isServer ? serverCache : clientCache).set(descriptor, script)
}

export function resolveScript(
descriptor: SFCDescriptor,
scopeId: string,
Expand All @@ -40,7 +48,7 @@ export function resolveScript(
resolved = compileScript(descriptor, {
id: scopeId,
isProd,
inlineTemplate: true,
inlineTemplate: !options.hmr,
templateOptions: getTemplateCompilerOptions(
options,
descriptor,
Expand Down
Loading