feat(compiler-core): support mode: cjs in codegen

This commit is contained in:
Evan You 2020-01-30 17:49:42 -05:00
parent 87e8c8094f
commit 04da2a82e8
2 changed files with 11 additions and 6 deletions

View File

@ -71,7 +71,7 @@ function createCodegenContext(
ast: RootNode, ast: RootNode,
{ {
mode = 'function', mode = 'function',
prefixIdentifiers = mode === 'module', prefixIdentifiers = mode === 'module' || mode === 'cjs',
sourceMap = false, sourceMap = false,
filename = `template.vue.html`, filename = `template.vue.html`,
scopeId = null scopeId = null
@ -176,18 +176,21 @@ export function generate(
const genScopeId = !__BROWSER__ && scopeId != null && mode === 'module' const genScopeId = !__BROWSER__ && scopeId != null && mode === 'module'
// preambles // preambles
if (mode === 'function') { if (mode === 'function' || mode === 'cjs') {
const VueBinding = mode === 'function' ? `Vue` : `require("vue")`
// Generate const declaration for helpers // Generate const declaration for helpers
// In prefix mode, we place the const declaration at top so it's done // In prefix mode, we place the const declaration at top so it's done
// only once; But if we not prefixing, we place the declaration inside the // only once; But if we not prefixing, we place the declaration inside the
// with block so it doesn't incur the `in` check cost for every helper access. // with block so it doesn't incur the `in` check cost for every helper access.
if (hasHelpers) { if (hasHelpers) {
if (prefixIdentifiers) { if (prefixIdentifiers) {
push(`const { ${ast.helpers.map(helper).join(', ')} } = Vue\n`) push(
`const { ${ast.helpers.map(helper).join(', ')} } = ${VueBinding}\n`
)
} else { } else {
// "with" mode. // "with" mode.
// save Vue in a separate variable to avoid collision // save Vue in a separate variable to avoid collision
push(`const _Vue = Vue\n`) push(`const _Vue = ${VueBinding}\n`)
// in "with" mode, helpers are declared inside the with block to avoid // in "with" mode, helpers are declared inside the with block to avoid
// has check cost, but hoists are lifted out of the function - we need // has check cost, but hoists are lifted out of the function - we need
// to provide the helper here. // to provide the helper here.
@ -196,7 +199,7 @@ export function generate(
.filter(helper => ast.helpers.includes(helper)) .filter(helper => ast.helpers.includes(helper))
.map(s => `${helperNameMap[s]}: _${helperNameMap[s]}`) .map(s => `${helperNameMap[s]}: _${helperNameMap[s]}`)
.join(', ') .join(', ')
push(`const { ${staticHelpers} } = Vue\n`) push(`const { ${staticHelpers} } = _Vue\n`)
} }
} }
} }

View File

@ -57,8 +57,10 @@ export interface CodegenOptions {
// - Function mode will generate a single `const { helpers... } = Vue` // - Function mode will generate a single `const { helpers... } = Vue`
// statement and return the render function. It is meant to be used with // statement and return the render function. It is meant to be used with
// `new Function(code)()` to generate a render function at runtime. // `new Function(code)()` to generate a render function at runtime.
// - CommonJS mode is like function mode except it retrives helpers from
// `require('vue')`.
// - Default: 'function' // - Default: 'function'
mode?: 'module' | 'function' mode?: 'module' | 'function' | 'cjs'
// Prefix suitable identifiers with _ctx. // Prefix suitable identifiers with _ctx.
// If this option is false, the generated code will be wrapped in a // If this option is false, the generated code will be wrapped in a
// `with (this) { ... }` block. // `with (this) { ... }` block.