refactor(compiler): prefix all imported helpers to avoid scope collision
This commit is contained in:
		
							parent
							
								
									c44d9fbe3d
								
							
						
					
					
						commit
						51317af6e8
					
				@ -80,6 +80,7 @@ function createCodegenContext(
 | 
			
		||||
    sourceMap = false,
 | 
			
		||||
    filename = `template.vue.html`,
 | 
			
		||||
    scopeId = null,
 | 
			
		||||
    optimizeBindings = false,
 | 
			
		||||
    runtimeGlobalName = `Vue`,
 | 
			
		||||
    runtimeModuleName = `vue`,
 | 
			
		||||
    ssr = false
 | 
			
		||||
@ -91,6 +92,7 @@ function createCodegenContext(
 | 
			
		||||
    sourceMap,
 | 
			
		||||
    filename,
 | 
			
		||||
    scopeId,
 | 
			
		||||
    optimizeBindings,
 | 
			
		||||
    runtimeGlobalName,
 | 
			
		||||
    runtimeModuleName,
 | 
			
		||||
    ssr,
 | 
			
		||||
@ -102,8 +104,7 @@ function createCodegenContext(
 | 
			
		||||
    indentLevel: 0,
 | 
			
		||||
    map: undefined,
 | 
			
		||||
    helper(key) {
 | 
			
		||||
      const name = helperNameMap[key]
 | 
			
		||||
      return prefixIdentifiers ? name : `_${name}`
 | 
			
		||||
      return `_${helperNameMap[key]}`
 | 
			
		||||
    },
 | 
			
		||||
    push(code, node) {
 | 
			
		||||
      context.code += code
 | 
			
		||||
@ -282,7 +283,6 @@ export function generate(
 | 
			
		||||
function genFunctionPreamble(ast: RootNode, context: CodegenContext) {
 | 
			
		||||
  const {
 | 
			
		||||
    ssr,
 | 
			
		||||
    helper,
 | 
			
		||||
    prefixIdentifiers,
 | 
			
		||||
    push,
 | 
			
		||||
    newline,
 | 
			
		||||
@ -293,13 +293,16 @@ function genFunctionPreamble(ast: RootNode, context: CodegenContext) {
 | 
			
		||||
    !__BROWSER__ && ssr
 | 
			
		||||
      ? `require(${JSON.stringify(runtimeModuleName)})`
 | 
			
		||||
      : runtimeGlobalName
 | 
			
		||||
  const aliasHelper = (s: symbol) => `${helperNameMap[s]}: _${helperNameMap[s]}`
 | 
			
		||||
  // Generate const declaration for helpers
 | 
			
		||||
  // 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
 | 
			
		||||
  // with block so it doesn't incur the `in` check cost for every helper access.
 | 
			
		||||
  if (ast.helpers.length > 0) {
 | 
			
		||||
    if (!__BROWSER__ && prefixIdentifiers) {
 | 
			
		||||
      push(`const { ${ast.helpers.map(helper).join(', ')} } = ${VueBinding}\n`)
 | 
			
		||||
      push(
 | 
			
		||||
        `const { ${ast.helpers.map(aliasHelper).join(', ')} } = ${VueBinding}\n`
 | 
			
		||||
      )
 | 
			
		||||
    } else {
 | 
			
		||||
      // "with" mode.
 | 
			
		||||
      // save Vue in a separate variable to avoid collision
 | 
			
		||||
@ -310,7 +313,7 @@ function genFunctionPreamble(ast: RootNode, context: CodegenContext) {
 | 
			
		||||
      if (ast.hoists.length) {
 | 
			
		||||
        const staticHelpers = [CREATE_VNODE, CREATE_COMMENT, CREATE_TEXT]
 | 
			
		||||
          .filter(helper => ast.helpers.includes(helper))
 | 
			
		||||
          .map(s => `${helperNameMap[s]}: _${helperNameMap[s]}`)
 | 
			
		||||
          .map(aliasHelper)
 | 
			
		||||
          .join(', ')
 | 
			
		||||
        push(`const { ${staticHelpers} } = _Vue\n`)
 | 
			
		||||
      }
 | 
			
		||||
@ -321,7 +324,7 @@ function genFunctionPreamble(ast: RootNode, context: CodegenContext) {
 | 
			
		||||
    // ssr guaruntees prefixIdentifier: true
 | 
			
		||||
    push(
 | 
			
		||||
      `const { ${ast.ssrHelpers
 | 
			
		||||
        .map(helper)
 | 
			
		||||
        .map(aliasHelper)
 | 
			
		||||
        .join(', ')} } = require("@vue/server-renderer")\n`
 | 
			
		||||
    )
 | 
			
		||||
  }
 | 
			
		||||
@ -335,7 +338,14 @@ function genModulePreamble(
 | 
			
		||||
  context: CodegenContext,
 | 
			
		||||
  genScopeId: boolean
 | 
			
		||||
) {
 | 
			
		||||
  const { push, helper, newline, scopeId, runtimeModuleName } = context
 | 
			
		||||
  const {
 | 
			
		||||
    push,
 | 
			
		||||
    helper,
 | 
			
		||||
    newline,
 | 
			
		||||
    scopeId,
 | 
			
		||||
    optimizeBindings,
 | 
			
		||||
    runtimeModuleName
 | 
			
		||||
  } = context
 | 
			
		||||
 | 
			
		||||
  if (genScopeId) {
 | 
			
		||||
    ast.helpers.push(WITH_SCOPE_ID)
 | 
			
		||||
@ -346,17 +356,35 @@ function genModulePreamble(
 | 
			
		||||
 | 
			
		||||
  // generate import statements for helpers
 | 
			
		||||
  if (ast.helpers.length) {
 | 
			
		||||
    push(
 | 
			
		||||
      `import { ${ast.helpers.map(helper).join(', ')} } from ${JSON.stringify(
 | 
			
		||||
        runtimeModuleName
 | 
			
		||||
      )}\n`
 | 
			
		||||
    )
 | 
			
		||||
    if (optimizeBindings) {
 | 
			
		||||
      // when bundled with webpack with code-split, calling an import binding
 | 
			
		||||
      // as a function leads to it being wrapped with `Object(a.b)` or `(0,a.b)`,
 | 
			
		||||
      // incurring both payload size increase and potential perf overhead.
 | 
			
		||||
      // therefore we assign the imports to vairables (which is a constant ~50b
 | 
			
		||||
      // cost per-component instead of scaling with template size)
 | 
			
		||||
      push(
 | 
			
		||||
        `import { ${ast.helpers
 | 
			
		||||
          .map(s => helperNameMap[s])
 | 
			
		||||
          .join(', ')} } from ${JSON.stringify(runtimeModuleName)}\n`
 | 
			
		||||
      )
 | 
			
		||||
      push(
 | 
			
		||||
        `\n// Binding optimization for webpack code-split\nconst ${ast.helpers
 | 
			
		||||
          .map(s => `_${helperNameMap[s]} = ${helperNameMap[s]}`)
 | 
			
		||||
          .join(', ')}\n`
 | 
			
		||||
      )
 | 
			
		||||
    } else {
 | 
			
		||||
      push(
 | 
			
		||||
        `import { ${ast.helpers
 | 
			
		||||
          .map(s => `${helperNameMap[s]} as _${helperNameMap[s]}`)
 | 
			
		||||
          .join(', ')} } from ${JSON.stringify(runtimeModuleName)}\n`
 | 
			
		||||
      )
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (ast.ssrHelpers && ast.ssrHelpers.length) {
 | 
			
		||||
    push(
 | 
			
		||||
      `import { ${ast.ssrHelpers
 | 
			
		||||
        .map(helper)
 | 
			
		||||
        .map(s => `${helperNameMap[s]} as _${helperNameMap[s]}`)
 | 
			
		||||
        .join(', ')} } from "@vue/server-renderer"\n`
 | 
			
		||||
    )
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -73,6 +73,9 @@ export interface CodegenOptions {
 | 
			
		||||
  scopeId?: string | null
 | 
			
		||||
  // we need to know about this to generate proper preambles
 | 
			
		||||
  prefixIdentifiers?: boolean
 | 
			
		||||
  // option to optimize helper import bindings via variable assignment
 | 
			
		||||
  // (only used for webpack code-split)
 | 
			
		||||
  optimizeBindings?: boolean
 | 
			
		||||
  // for specifying where to import helpers
 | 
			
		||||
  runtimeModuleName?: string
 | 
			
		||||
  runtimeGlobalName?: string
 | 
			
		||||
 | 
			
		||||
@ -15,19 +15,19 @@ export const SSR_RENDER_DYNAMIC_MODEL = Symbol(`ssrRenderDynamicModel`)
 | 
			
		||||
export const SSR_GET_DYNAMIC_MODEL_PROPS = Symbol(`ssrGetDynamicModelProps`)
 | 
			
		||||
 | 
			
		||||
export const ssrHelpers = {
 | 
			
		||||
  [SSR_INTERPOLATE]: `_ssrInterpolate`,
 | 
			
		||||
  [SSR_RENDER_COMPONENT]: `_ssrRenderComponent`,
 | 
			
		||||
  [SSR_RENDER_SLOT]: `_ssrRenderSlot`,
 | 
			
		||||
  [SSR_RENDER_CLASS]: `_ssrRenderClass`,
 | 
			
		||||
  [SSR_RENDER_STYLE]: `_ssrRenderStyle`,
 | 
			
		||||
  [SSR_RENDER_ATTRS]: `_ssrRenderAttrs`,
 | 
			
		||||
  [SSR_RENDER_ATTR]: `_ssrRenderAttr`,
 | 
			
		||||
  [SSR_RENDER_DYNAMIC_ATTR]: `_ssrRenderDynamicAttr`,
 | 
			
		||||
  [SSR_RENDER_LIST]: `_ssrRenderList`,
 | 
			
		||||
  [SSR_LOOSE_EQUAL]: `_ssrLooseEqual`,
 | 
			
		||||
  [SSR_LOOSE_CONTAIN]: `_ssrLooseContain`,
 | 
			
		||||
  [SSR_RENDER_DYNAMIC_MODEL]: `_ssrRenderDynamicModel`,
 | 
			
		||||
  [SSR_GET_DYNAMIC_MODEL_PROPS]: `_ssrGetDynamicModelProps`
 | 
			
		||||
  [SSR_INTERPOLATE]: `ssrInterpolate`,
 | 
			
		||||
  [SSR_RENDER_COMPONENT]: `ssrRenderComponent`,
 | 
			
		||||
  [SSR_RENDER_SLOT]: `ssrRenderSlot`,
 | 
			
		||||
  [SSR_RENDER_CLASS]: `ssrRenderClass`,
 | 
			
		||||
  [SSR_RENDER_STYLE]: `ssrRenderStyle`,
 | 
			
		||||
  [SSR_RENDER_ATTRS]: `ssrRenderAttrs`,
 | 
			
		||||
  [SSR_RENDER_ATTR]: `ssrRenderAttr`,
 | 
			
		||||
  [SSR_RENDER_DYNAMIC_ATTR]: `ssrRenderDynamicAttr`,
 | 
			
		||||
  [SSR_RENDER_LIST]: `ssrRenderList`,
 | 
			
		||||
  [SSR_LOOSE_EQUAL]: `ssrLooseEqual`,
 | 
			
		||||
  [SSR_LOOSE_CONTAIN]: `ssrLooseContain`,
 | 
			
		||||
  [SSR_RENDER_DYNAMIC_MODEL]: `ssrRenderDynamicModel`,
 | 
			
		||||
  [SSR_GET_DYNAMIC_MODEL_PROPS]: `ssrGetDynamicModelProps`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Note: these are helpers imported from @vue/server-renderer
 | 
			
		||||
 | 
			
		||||
@ -2,22 +2,22 @@
 | 
			
		||||
export { renderToString } from './renderToString'
 | 
			
		||||
 | 
			
		||||
// internal runtime helpers
 | 
			
		||||
export { renderComponent as _ssrRenderComponent } from './renderToString'
 | 
			
		||||
export { ssrRenderSlot as _ssrRenderSlot } from './helpers/ssrRenderSlot'
 | 
			
		||||
export { renderComponent } from './renderToString'
 | 
			
		||||
export { ssrRenderSlot } from './helpers/ssrRenderSlot'
 | 
			
		||||
export {
 | 
			
		||||
  ssrRenderClass as _ssrRenderClass,
 | 
			
		||||
  ssrRenderStyle as _ssrRenderStyle,
 | 
			
		||||
  ssrRenderAttrs as _ssrRenderAttrs,
 | 
			
		||||
  ssrRenderAttr as _ssrRenderAttr,
 | 
			
		||||
  ssrRenderDynamicAttr as _ssrRenderDynamicAttr
 | 
			
		||||
  ssrRenderClass,
 | 
			
		||||
  ssrRenderStyle,
 | 
			
		||||
  ssrRenderAttrs,
 | 
			
		||||
  ssrRenderAttr,
 | 
			
		||||
  ssrRenderDynamicAttr
 | 
			
		||||
} from './helpers/ssrRenderAttrs'
 | 
			
		||||
export { ssrInterpolate as _ssrInterpolate } from './helpers/ssrInterpolate'
 | 
			
		||||
export { ssrRenderList as _ssrRenderList } from './helpers/ssrRenderList'
 | 
			
		||||
export { ssrInterpolate } from './helpers/ssrInterpolate'
 | 
			
		||||
export { ssrRenderList } from './helpers/ssrRenderList'
 | 
			
		||||
 | 
			
		||||
// v-model helpers
 | 
			
		||||
export {
 | 
			
		||||
  ssrLooseEqual as _ssrLooseEqual,
 | 
			
		||||
  ssrLooseContain as _ssrLooseContain,
 | 
			
		||||
  ssrRenderDynamicModel as _ssrRenderDynamicModel,
 | 
			
		||||
  ssrGetDynamicModelProps as _ssrGetDynamicModelProps
 | 
			
		||||
  ssrLooseEqual,
 | 
			
		||||
  ssrLooseContain,
 | 
			
		||||
  ssrRenderDynamicModel,
 | 
			
		||||
  ssrGetDynamicModelProps
 | 
			
		||||
} from './helpers/ssrVModelHelpers'
 | 
			
		||||
 | 
			
		||||
@ -6,6 +6,7 @@ export const ssrMode = ref(false)
 | 
			
		||||
export const compilerOptions: CompilerOptions = reactive({
 | 
			
		||||
  mode: 'module',
 | 
			
		||||
  prefixIdentifiers: false,
 | 
			
		||||
  optimizeBindings: false,
 | 
			
		||||
  hoistStatic: false,
 | 
			
		||||
  cacheHandlers: false,
 | 
			
		||||
  scopeId: null
 | 
			
		||||
@ -29,96 +30,134 @@ const App = {
 | 
			
		||||
          },
 | 
			
		||||
          `@${__COMMIT__}`
 | 
			
		||||
        ),
 | 
			
		||||
        ' | ',
 | 
			
		||||
        h(
 | 
			
		||||
          'a',
 | 
			
		||||
          {
 | 
			
		||||
            href:
 | 
			
		||||
              'https://app.netlify.com/sites/vue-next-template-explorer/deploys',
 | 
			
		||||
            target: `_blank`
 | 
			
		||||
          },
 | 
			
		||||
          'History'
 | 
			
		||||
        ),
 | 
			
		||||
 | 
			
		||||
        h('div', { id: 'options' }, [
 | 
			
		||||
          // mode selection
 | 
			
		||||
          h('span', { class: 'options-group' }, [
 | 
			
		||||
            h('span', { class: 'label' }, 'Mode:'),
 | 
			
		||||
            h('input', {
 | 
			
		||||
              type: 'radio',
 | 
			
		||||
              id: 'mode-module',
 | 
			
		||||
              name: 'mode',
 | 
			
		||||
              checked: isModule,
 | 
			
		||||
              onChange() {
 | 
			
		||||
                compilerOptions.mode = 'module'
 | 
			
		||||
              }
 | 
			
		||||
            }),
 | 
			
		||||
            h('label', { for: 'mode-module' }, 'module'),
 | 
			
		||||
            h('input', {
 | 
			
		||||
              type: 'radio',
 | 
			
		||||
              id: 'mode-function',
 | 
			
		||||
              name: 'mode',
 | 
			
		||||
              checked: !isModule,
 | 
			
		||||
              onChange() {
 | 
			
		||||
                compilerOptions.mode = 'function'
 | 
			
		||||
              }
 | 
			
		||||
            }),
 | 
			
		||||
            h('label', { for: 'mode-function' }, 'function')
 | 
			
		||||
          ]),
 | 
			
		||||
        h('div', { id: 'options-wrapper' }, [
 | 
			
		||||
          h('div', { id: 'options-label' }, 'Options ↘'),
 | 
			
		||||
          h('ul', { id: 'options' }, [
 | 
			
		||||
            // mode selection
 | 
			
		||||
            h('li', { id: 'mode' }, [
 | 
			
		||||
              h('span', { class: 'label' }, 'Mode: '),
 | 
			
		||||
              h('input', {
 | 
			
		||||
                type: 'radio',
 | 
			
		||||
                id: 'mode-module',
 | 
			
		||||
                name: 'mode',
 | 
			
		||||
                checked: isModule,
 | 
			
		||||
                onChange() {
 | 
			
		||||
                  compilerOptions.mode = 'module'
 | 
			
		||||
                }
 | 
			
		||||
              }),
 | 
			
		||||
              h('label', { for: 'mode-module' }, 'module'),
 | 
			
		||||
              ' ',
 | 
			
		||||
              h('input', {
 | 
			
		||||
                type: 'radio',
 | 
			
		||||
                id: 'mode-function',
 | 
			
		||||
                name: 'mode',
 | 
			
		||||
                checked: !isModule,
 | 
			
		||||
                onChange() {
 | 
			
		||||
                  compilerOptions.mode = 'function'
 | 
			
		||||
                }
 | 
			
		||||
              }),
 | 
			
		||||
              h('label', { for: 'mode-function' }, 'function')
 | 
			
		||||
            ]),
 | 
			
		||||
 | 
			
		||||
          // SSR
 | 
			
		||||
          h('input', {
 | 
			
		||||
            type: 'checkbox',
 | 
			
		||||
            id: 'ssr',
 | 
			
		||||
            name: 'ssr',
 | 
			
		||||
            checked: ssrMode.value,
 | 
			
		||||
            onChange(e: Event) {
 | 
			
		||||
              ssrMode.value = (e.target as HTMLInputElement).checked
 | 
			
		||||
            }
 | 
			
		||||
          }),
 | 
			
		||||
          h('label', { for: 'ssr' }, 'SSR'),
 | 
			
		||||
            // SSR
 | 
			
		||||
            h('li', [
 | 
			
		||||
              h('input', {
 | 
			
		||||
                type: 'checkbox',
 | 
			
		||||
                id: 'ssr',
 | 
			
		||||
                name: 'ssr',
 | 
			
		||||
                checked: ssrMode.value,
 | 
			
		||||
                onChange(e: Event) {
 | 
			
		||||
                  ssrMode.value = (e.target as HTMLInputElement).checked
 | 
			
		||||
                }
 | 
			
		||||
              }),
 | 
			
		||||
              h('label', { for: 'ssr' }, 'SSR')
 | 
			
		||||
            ]),
 | 
			
		||||
 | 
			
		||||
          // toggle prefixIdentifiers
 | 
			
		||||
          h('input', {
 | 
			
		||||
            type: 'checkbox',
 | 
			
		||||
            id: 'prefix',
 | 
			
		||||
            disabled: isModule || isSSR,
 | 
			
		||||
            checked: usePrefix || isSSR,
 | 
			
		||||
            onChange(e: Event) {
 | 
			
		||||
              compilerOptions.prefixIdentifiers =
 | 
			
		||||
                (e.target as HTMLInputElement).checked || isModule
 | 
			
		||||
            }
 | 
			
		||||
          }),
 | 
			
		||||
          h('label', { for: 'prefix' }, 'prefixIdentifiers'),
 | 
			
		||||
            // toggle prefixIdentifiers
 | 
			
		||||
            h('li', [
 | 
			
		||||
              h('input', {
 | 
			
		||||
                type: 'checkbox',
 | 
			
		||||
                id: 'prefix',
 | 
			
		||||
                disabled: isModule || isSSR,
 | 
			
		||||
                checked: usePrefix || isSSR,
 | 
			
		||||
                onChange(e: Event) {
 | 
			
		||||
                  compilerOptions.prefixIdentifiers =
 | 
			
		||||
                    (e.target as HTMLInputElement).checked || isModule
 | 
			
		||||
                }
 | 
			
		||||
              }),
 | 
			
		||||
              h('label', { for: 'prefix' }, 'prefixIdentifiers')
 | 
			
		||||
            ]),
 | 
			
		||||
 | 
			
		||||
          // toggle hoistStatic
 | 
			
		||||
          h('input', {
 | 
			
		||||
            type: 'checkbox',
 | 
			
		||||
            id: 'hoist',
 | 
			
		||||
            checked: compilerOptions.hoistStatic && !isSSR,
 | 
			
		||||
            disabled: isSSR,
 | 
			
		||||
            onChange(e: Event) {
 | 
			
		||||
              compilerOptions.hoistStatic = (e.target as HTMLInputElement).checked
 | 
			
		||||
            }
 | 
			
		||||
          }),
 | 
			
		||||
          h('label', { for: 'hoist' }, 'hoistStatic'),
 | 
			
		||||
            // toggle hoistStatic
 | 
			
		||||
            h('li', [
 | 
			
		||||
              h('input', {
 | 
			
		||||
                type: 'checkbox',
 | 
			
		||||
                id: 'hoist',
 | 
			
		||||
                checked: compilerOptions.hoistStatic && !isSSR,
 | 
			
		||||
                disabled: isSSR,
 | 
			
		||||
                onChange(e: Event) {
 | 
			
		||||
                  compilerOptions.hoistStatic = (e.target as HTMLInputElement).checked
 | 
			
		||||
                }
 | 
			
		||||
              }),
 | 
			
		||||
              h('label', { for: 'hoist' }, 'hoistStatic')
 | 
			
		||||
            ]),
 | 
			
		||||
 | 
			
		||||
          // toggle cacheHandlers
 | 
			
		||||
          h('input', {
 | 
			
		||||
            type: 'checkbox',
 | 
			
		||||
            id: 'cache',
 | 
			
		||||
            checked: usePrefix && compilerOptions.cacheHandlers && !isSSR,
 | 
			
		||||
            disabled: !usePrefix || isSSR,
 | 
			
		||||
            onChange(e: Event) {
 | 
			
		||||
              compilerOptions.cacheHandlers = (e.target as HTMLInputElement).checked
 | 
			
		||||
            }
 | 
			
		||||
          }),
 | 
			
		||||
          h('label', { for: 'cache' }, 'cacheHandlers'),
 | 
			
		||||
            // toggle cacheHandlers
 | 
			
		||||
            h('li', [
 | 
			
		||||
              h('input', {
 | 
			
		||||
                type: 'checkbox',
 | 
			
		||||
                id: 'cache',
 | 
			
		||||
                checked: usePrefix && compilerOptions.cacheHandlers && !isSSR,
 | 
			
		||||
                disabled: !usePrefix || isSSR,
 | 
			
		||||
                onChange(e: Event) {
 | 
			
		||||
                  compilerOptions.cacheHandlers = (e.target as HTMLInputElement).checked
 | 
			
		||||
                }
 | 
			
		||||
              }),
 | 
			
		||||
              h('label', { for: 'cache' }, 'cacheHandlers')
 | 
			
		||||
            ]),
 | 
			
		||||
 | 
			
		||||
          // toggle scopeId
 | 
			
		||||
          h('input', {
 | 
			
		||||
            type: 'checkbox',
 | 
			
		||||
            id: 'scope-id',
 | 
			
		||||
            disabled: !isModule,
 | 
			
		||||
            checked: isModule && compilerOptions.scopeId,
 | 
			
		||||
            onChange(e: Event) {
 | 
			
		||||
              compilerOptions.scopeId =
 | 
			
		||||
                isModule && (e.target as HTMLInputElement).checked
 | 
			
		||||
                  ? 'scope-id'
 | 
			
		||||
                  : null
 | 
			
		||||
            }
 | 
			
		||||
          }),
 | 
			
		||||
          h('label', { for: 'scope-id' }, 'scopeId')
 | 
			
		||||
            // toggle scopeId
 | 
			
		||||
            h('li', [
 | 
			
		||||
              h('input', {
 | 
			
		||||
                type: 'checkbox',
 | 
			
		||||
                id: 'scope-id',
 | 
			
		||||
                disabled: !isModule,
 | 
			
		||||
                checked: isModule && compilerOptions.scopeId,
 | 
			
		||||
                onChange(e: Event) {
 | 
			
		||||
                  compilerOptions.scopeId =
 | 
			
		||||
                    isModule && (e.target as HTMLInputElement).checked
 | 
			
		||||
                      ? 'scope-id'
 | 
			
		||||
                      : null
 | 
			
		||||
                }
 | 
			
		||||
              }),
 | 
			
		||||
              h('label', { for: 'scope-id' }, 'scopeId')
 | 
			
		||||
            ]),
 | 
			
		||||
 | 
			
		||||
            // toggle optimizeBindings
 | 
			
		||||
            h('li', [
 | 
			
		||||
              h('input', {
 | 
			
		||||
                type: 'checkbox',
 | 
			
		||||
                id: 'optimize-bindings',
 | 
			
		||||
                disabled: !isModule || isSSR,
 | 
			
		||||
                checked: isModule && !isSSR && compilerOptions.optimizeBindings,
 | 
			
		||||
                onChange(e: Event) {
 | 
			
		||||
                  compilerOptions.optimizeBindings = (e.target as HTMLInputElement).checked
 | 
			
		||||
                }
 | 
			
		||||
              }),
 | 
			
		||||
              h('label', { for: 'optimize-bindings' }, 'optimizeBindings')
 | 
			
		||||
            ])
 | 
			
		||||
          ])
 | 
			
		||||
        ])
 | 
			
		||||
      ]
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -14,6 +14,7 @@ body {
 | 
			
		||||
  border-bottom: 1px solid #333;
 | 
			
		||||
  padding: 0.3em 1.6em;
 | 
			
		||||
  color: #fff;
 | 
			
		||||
  z-index: 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
h1 {
 | 
			
		||||
@ -22,17 +23,34 @@ h1 {
 | 
			
		||||
  margin-right: 15px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#options-wrapper {
 | 
			
		||||
  position: absolute;
 | 
			
		||||
  top: 20px;
 | 
			
		||||
  right: 10px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#options-wrapper:hover #options {
 | 
			
		||||
  display: block;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#options-label {
 | 
			
		||||
  cursor: pointer;
 | 
			
		||||
  text-align: right;
 | 
			
		||||
  padding-right: 10px;
 | 
			
		||||
  font-weight: bold;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#options {
 | 
			
		||||
  float: right;
 | 
			
		||||
  margin-top: 1em;
 | 
			
		||||
  display: none;
 | 
			
		||||
  margin-top: 15px;
 | 
			
		||||
  list-style-type: none;
 | 
			
		||||
  background-color: #1e1e1e;
 | 
			
		||||
  border: 1px solid #333;
 | 
			
		||||
  padding: 15px 30px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.options-group {
 | 
			
		||||
  margin-right: 30px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#header span, #header label, #header input, #header a {
 | 
			
		||||
  display: inline-block;
 | 
			
		||||
#options li {
 | 
			
		||||
  margin: 8px 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#header a {
 | 
			
		||||
@ -45,7 +63,6 @@ h1 {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#header input {
 | 
			
		||||
  margin-left: 12px;
 | 
			
		||||
  margin-right: 6px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user