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

Commit

Permalink
wip: improve source map integration w/ vite
Browse files Browse the repository at this point in the history
  • Loading branch information
yyx990803 committed Dec 16, 2020
1 parent 90209a7 commit 4f5e698
Show file tree
Hide file tree
Showing 7 changed files with 286 additions and 38 deletions.
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": "^4.1.0"
"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
1 change: 0 additions & 1 deletion src/handleHotUpdate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ export async function handleHotUpdate(file: string, modules: any[]) {
const { descriptor } = parse(content, {
filename: file,
sourceMap: true,
sourceRoot: process.cwd(),
})
setDescriptor(file, descriptor)
setPrevDescriptor(file, prevDescriptor)
Expand Down
7 changes: 3 additions & 4 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ 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'

Expand Down Expand Up @@ -131,7 +130,7 @@ export default function PluginVue(userOptions: Partial<Options> = {}): Plugin {
if (block) {
return {
code: block.content,
map: normalizeSourceMap(block.map, id),
map: block.map as any,
}
}
}
Expand Down Expand Up @@ -171,10 +170,10 @@ export default function PluginVue(userOptions: Partial<Options> = {}): Plugin {
}
if (query.type === 'template') {
debug(`transform template (${id})`)
return transformTemplateAsModule(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
Expand Down
63 changes: 53 additions & 10 deletions src/sfcFacade.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { createRollupError } from './utils/error'
import { resolveScript } from './script'
import { transformTemplateInMain } from './template'
import { isOnlyTemplateChanged } from './handleHotUpdate'
import { RawSourceMap, SourceMapConsumer, SourceMapGenerator } from 'source-map'

export async function genSfcFacade(
code: string,
Expand All @@ -30,7 +31,6 @@ export async function genSfcFacade(
const { descriptor, errors } = parse(code, {
sourceMap: true,
filename,
sourceRoot,
})
setDescriptor(filename, descriptor)

Expand Down Expand Up @@ -68,9 +68,17 @@ export async function genSfcFacade(
!(descriptor.template && descriptor.template.src)
const hasTemplateImport = descriptor.template && !useInlineTemplate

const templateCode = hasTemplateImport
? genTemplateCode(descriptor, scopeId, options, isServer, pluginContext)
: ''
let templateCode = ''
let templateMap
if (hasTemplateImport) {
;({ code: templateCode, map: templateMap } = genTemplateCode(
descriptor,
scopeId,
options,
isServer,
pluginContext
))
}

const renderReplace = hasTemplateImport
? isServer
Expand Down Expand Up @@ -128,9 +136,34 @@ export async function genSfcFacade(
)
}

// if the template is inlined into the main module (indicated by the presence
// of templateMap, we need to concatenate the two source maps.
let resolvedMap = map
if (map && templateMap) {
const generator = SourceMapGenerator.fromSourceMap(
new SourceMapConsumer(map)
)
const offset = scriptCode.match(/\r?\n/g)?.length || 1
const templateMapConsumer = new SourceMapConsumer(templateMap)
templateMapConsumer.eachMapping((m) => {
generator.addMapping({
source: m.source,
original: { line: m.originalLine, column: m.originalColumn },
generated: {
line: m.generatedLine + offset,
column: m.generatedColumn,
},
})
})
resolvedMap = (generator as any).toJSON()
// if this is a template only update, we will be reusing a cached version
// of the main module compile result, which has outdated sourcesContent.
resolvedMap.sourcesContent = templateMap.sourcesContent
}

return {
code: output.join('\n'),
map: map || {
map: resolvedMap || {
mappings: '',
},
}
Expand All @@ -146,6 +179,9 @@ function genTemplateCode(
const renderFnName = isServer ? 'ssrRender' : 'render'
const template = descriptor.template!

// If the template is not using pre-processor AND is not using external src,
// compile and inline it directly in the main module. When served in vite this
// saves an extra request per SFC which can improve load performance.
if (!template.lang && !template.src) {
return transformTemplateInMain(
template.content,
Expand All @@ -160,9 +196,12 @@ function genTemplateCode(
const srcQuery = template.src ? `&src` : ``
const attrsQuery = attrsToQuery(template.attrs, 'js', true)
const query = `?vue&type=template${idQuery}${srcQuery}${attrsQuery}`
return `import { ${renderFnName} as _sfc_${renderFnName} } from ${JSON.stringify(
src + query
)}`
return {
code: `import { ${renderFnName} as _sfc_${renderFnName} } from ${JSON.stringify(
src + query
)}`,
map: undefined,
}
}
}

Expand All @@ -173,7 +212,10 @@ async function genScriptCode(
isServer: boolean,
options: Options,
pluginContext: TransformPluginContext
) {
): Promise<{
code: string
map: RawSourceMap
}> {
let scriptCode = `const _sfc_main = {}`
let map
const script = resolveScript(
Expand All @@ -185,7 +227,8 @@ async function genScriptCode(
pluginContext
)
if (script) {
// js or ts can be directly placed in the main module
// If the script is js/ts and has no external src, it can be directly placed
// in the main module.
if (
(!script.lang ||
(script.lang === 'ts' && (pluginContext as any).server)) &&
Expand Down
4 changes: 1 addition & 3 deletions src/style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,9 @@ import { TransformPluginContext } from 'rollup'
import { Options } from '.'
import { getDescriptor } from './utils/descriptorCache'
import { StyleBlockQuery } from './utils/query'
import { normalizeSourceMap } from './utils/sourceMap'

export async function transformStyle(
code: string,
request: string,
options: Options,
query: StyleBlockQuery,
isProduction: boolean,
Expand Down Expand Up @@ -85,7 +83,7 @@ export async function transformStyle(
} else {
return {
code: result.code,
map: normalizeSourceMap(result.map!, request),
map: result.map as any,
}
}
}
19 changes: 10 additions & 9 deletions src/template.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,9 @@ import { getResolvedScript } from './script'
import { getDescriptor } from './utils/descriptorCache'
import { createRollupError } from './utils/error'
import { TemplateBlockQuery } from './utils/query'
import { normalizeSourceMap } from './utils/sourceMap'

export function transformTemplateAsModule(
code: string,
request: string,
options: Options,
query: TemplateBlockQuery,
pluginContext: TransformPluginContext
Expand All @@ -37,7 +35,7 @@ export function transformTemplateAsModule(

return {
code: returnCode,
map: normalizeSourceMap(result.map!, request),
map: result.map as any,
}
}

Expand All @@ -52,11 +50,13 @@ export function transformTemplateInMain(
pluginContext: PluginContext
) {
const result = compileTemplate(code, descriptor, id, options, pluginContext)
// TODO figure out how to merge the source map with the script map
return result.code.replace(
/\nexport (function|const) (render|ssrRender)/,
'\n$1 _sfc_$2'
)
return {
...result,
code: result.code.replace(
/\nexport (function|const) (render|ssrRender)/,
'\n$1 _sfc_$2'
),
}
}

export function compileTemplate(
Expand All @@ -67,8 +67,9 @@ export function compileTemplate(
pluginContext: PluginContext
) {
const filename = descriptor.filename
const compileOptions = getTemplateCompilerOptions(options, descriptor, id)
const result = compile({
...getTemplateCompilerOptions(options, descriptor, id),
...compileOptions,
id,
source: code,
filename,
Expand Down
Loading

0 comments on commit 4f5e698

Please sign in to comment.