浏览代码

wip(ssr): element scopeId

Evan You 6 年之前
父节点
当前提交
797cc18967

+ 40 - 21
packages/compiler-core/src/codegen.ts

@@ -44,7 +44,8 @@ import {
   CREATE_TEXT,
   PUSH_SCOPE_ID,
   POP_SCOPE_ID,
-  WITH_SCOPE_ID
+  WITH_SCOPE_ID,
+  CREATE_BLOCK
 } from './runtimeHelpers'
 import { ImportItem } from './transform'
 
@@ -333,14 +334,28 @@ function genModulePreamble(
   context: CodegenContext,
   genScopeId: boolean
 ) {
-  const { push, helper, newline, scopeId, runtimeModuleName } = context
-  // generate import statements for helpers
-  if (genScopeId) {
-    ast.helpers.push(WITH_SCOPE_ID)
-    if (ast.hoists.length) {
-      ast.helpers.push(PUSH_SCOPE_ID, POP_SCOPE_ID)
+  const { push, helper, newline, scopeId, runtimeModuleName, ssr } = context
+
+  if (!__BROWSER__) {
+    // in ssr mode, `withId` helper is only needed if the template contains
+    // de-optimized component slots (which uses the createVNode helper)
+    if (
+      ssr &&
+      !(
+        ast.helpers.includes(CREATE_VNODE) || ast.helpers.includes(CREATE_BLOCK)
+      )
+    ) {
+      genScopeId = false
+    }
+    if (genScopeId) {
+      ast.helpers.push(WITH_SCOPE_ID)
+      if (ast.hoists.length) {
+        ast.helpers.push(PUSH_SCOPE_ID, POP_SCOPE_ID)
+      }
     }
   }
+
+  // generate import statements for helpers
   if (ast.helpers.length) {
     push(
       `import { ${ast.helpers.map(helper).join(', ')} } from ${JSON.stringify(
@@ -348,21 +363,25 @@ function genModulePreamble(
       )}\n`
     )
   }
-  if (!__BROWSER__ && ast.ssrHelpers && ast.ssrHelpers.length) {
-    push(
-      `import { ${ast.ssrHelpers
-        .map(helper)
-        .join(', ')} } from "@vue/server-renderer"\n`
-    )
-  }
-  if (ast.imports.length) {
-    genImports(ast.imports, context)
-    newline()
-  }
-  if (genScopeId) {
-    push(`const withId = ${helper(WITH_SCOPE_ID)}("${scopeId}")`)
-    newline()
+
+  if (!__BROWSER__) {
+    if (ast.ssrHelpers && ast.ssrHelpers.length) {
+      push(
+        `import { ${ast.ssrHelpers
+          .map(helper)
+          .join(', ')} } from "@vue/server-renderer"\n`
+      )
+    }
+    if (ast.imports.length) {
+      genImports(ast.imports, context)
+      newline()
+    }
+    if (genScopeId) {
+      push(`const withId = ${helper(WITH_SCOPE_ID)}("${scopeId}")`)
+      newline()
+    }
   }
+
   genHoists(ast.hoists, context)
   newline()
   push(`export `)

+ 2 - 0
packages/compiler-core/src/options.ts

@@ -49,6 +49,8 @@ export interface TransformOptions {
   //   analysis to determine if a handler is safe to cache.
   // - Default: false
   cacheHandlers?: boolean
+  // SFC scoped styles ID
+  scopeId?: string | null
   ssr?: boolean
   onError?: (error: CompilerError) => void
 }

+ 2 - 0
packages/compiler-core/src/transform.ts

@@ -118,6 +118,7 @@ function createTransformContext(
     nodeTransforms = [],
     directiveTransforms = {},
     isBuiltInComponent = NOOP,
+    scopeId = null,
     ssr = false,
     onError = defaultOnError
   }: TransformOptions
@@ -130,6 +131,7 @@ function createTransformContext(
     nodeTransforms,
     directiveTransforms,
     isBuiltInComponent,
+    scopeId,
     ssr,
     onError,
 

+ 1 - 0
packages/compiler-ssr/src/index.ts

@@ -31,6 +31,7 @@ export function compile(
     // apply DOM-specific parsing options
     ...parserOptions,
     ssr: true,
+    scopeId: options.mode === 'function' ? null : options.scopeId,
     // always prefix since compiler-ssr doesn't have size concern
     prefixIdentifiers: true,
     // disalbe optimizations that are unnecessary for ssr

+ 4 - 0
packages/compiler-ssr/src/transforms/ssrTransformElement.ts

@@ -246,6 +246,10 @@ export const ssrTransformElement: NodeTransform = (node, context) => {
         removeStaticBinding(openTag, 'class')
       }
 
+      if (context.scopeId) {
+        openTag.push(` ${context.scopeId}`)
+      }
+
       openTag.push(`>`)
       if (rawChildren) {
         openTag.push(rawChildren)