├── .eslintrc.js ├── .github ├── FUNDING.yml ├── ISSUE_TEMPLATE │ └── config.yml ├── commit-convention.md ├── contributing.md ├── dependabot.yml └── workflows │ ├── ci.yml │ └── release-tag.yml ├── .gitignore ├── .prettierrc ├── .vscode ├── launch.json └── settings.json ├── CHANGELOG.md ├── LICENSE ├── README.md ├── SECURITY.md ├── api-extractor.json ├── code.jpg ├── jest.config.js ├── netlify.toml ├── package.json ├── packages ├── compiler-core │ ├── LICENSE │ ├── README.md │ ├── __tests__ │ │ ├── __snapshots__ │ │ │ ├── codegen.spec.ts.snap │ │ │ ├── compile.spec.ts.snap │ │ │ ├── parse.spec.ts.snap │ │ │ └── scopeId.spec.ts.snap │ │ ├── codegen.spec.ts │ │ ├── compile.spec.ts │ │ ├── parse.spec.ts │ │ ├── scopeId.spec.ts │ │ ├── testUtils.ts │ │ ├── transform.spec.ts │ │ ├── transforms │ │ │ ├── __snapshots__ │ │ │ │ ├── hoistStatic.spec.ts.snap │ │ │ │ ├── transformExpressions.spec.ts.snap │ │ │ │ ├── transformText.spec.ts.snap │ │ │ │ ├── vFor.spec.ts.snap │ │ │ │ ├── vIf.spec.ts.snap │ │ │ │ ├── vMemo.spec.ts.snap │ │ │ │ ├── vModel.spec.ts.snap │ │ │ │ ├── vOnce.spec.ts.snap │ │ │ │ └── vSlot.spec.ts.snap │ │ │ ├── hoistStatic.spec.ts │ │ │ ├── noopDirectiveTransform.spec.ts │ │ │ ├── transformElement.spec.ts │ │ │ ├── transformExpressions.spec.ts │ │ │ ├── transformSlotOutlet.spec.ts │ │ │ ├── transformText.spec.ts │ │ │ ├── vBind.spec.ts │ │ │ ├── vFor.spec.ts │ │ │ ├── vIf.spec.ts │ │ │ ├── vMemo.spec.ts │ │ │ ├── vModel.spec.ts │ │ │ ├── vOn.spec.ts │ │ │ ├── vOnce.spec.ts │ │ │ └── vSlot.spec.ts │ │ └── utils.spec.ts │ ├── api-extractor.json │ ├── index.js │ ├── package.json │ └── src │ │ ├── ast.ts │ │ ├── babelUtils.ts │ │ ├── codegen.ts │ │ ├── compat │ │ ├── compatConfig.ts │ │ └── transformFilter.ts │ │ ├── compile.ts │ │ ├── errors.ts │ │ ├── index.ts │ │ ├── options.ts │ │ ├── parse.ts │ │ ├── runtimeHelpers.ts │ │ ├── transform.ts │ │ ├── transforms │ │ ├── hoistStatic.ts │ │ ├── noopDirectiveTransform.ts │ │ ├── transformElement.ts │ │ ├── transformExpression.ts │ │ ├── transformSlotOutlet.ts │ │ ├── transformText.ts │ │ ├── vBind.ts │ │ ├── vFor.ts │ │ ├── vIf.ts │ │ ├── vMemo.ts │ │ ├── vModel.ts │ │ ├── vOn.ts │ │ ├── vOnce.ts │ │ └── vSlot.ts │ │ ├── utils.ts │ │ └── validateExpression.ts ├── compiler-dom │ ├── LICENSE │ ├── README.md │ ├── __tests__ │ │ ├── __snapshots__ │ │ │ └── index.spec.ts.snap │ │ ├── decoderHtmlBrowser.spec.ts │ │ ├── index.spec.ts │ │ ├── parse.spec.ts │ │ └── transforms │ │ │ ├── __snapshots__ │ │ │ ├── stringifyStatic.spec.ts.snap │ │ │ ├── vModel.spec.ts.snap │ │ │ ├── vShow.spec.ts.snap │ │ │ └── warnTransitionChildren.spec.ts.snap │ │ │ ├── ignoreSideEffectTags.spec.ts │ │ │ ├── stringifyStatic.spec.ts │ │ │ ├── transformStyle.spec.ts │ │ │ ├── vHtml.spec.ts │ │ │ ├── vModel.spec.ts │ │ │ ├── vOn.spec.ts │ │ │ ├── vShow.spec.ts │ │ │ ├── vText.spec.ts │ │ │ └── warnTransitionChildren.spec.ts │ ├── api-extractor.json │ ├── index.js │ ├── package.json │ └── src │ │ ├── decodeHtml.ts │ │ ├── decodeHtmlBrowser.ts │ │ ├── errors.ts │ │ ├── index.ts │ │ ├── namedChars.json │ │ ├── parserOptions.ts │ │ ├── runtimeHelpers.ts │ │ └── transforms │ │ ├── ignoreSideEffectTags.ts │ │ ├── stringifyStatic.ts │ │ ├── transformStyle.ts │ │ ├── vHtml.ts │ │ ├── vModel.ts │ │ ├── vOn.ts │ │ ├── vShow.ts │ │ ├── vText.ts │ │ └── warnTransitionChildren.ts ├── compiler-sfc │ ├── LICENSE │ ├── README.md │ ├── __tests__ │ │ ├── __snapshots__ │ │ │ ├── compileScript.spec.ts.snap │ │ │ ├── compileScriptPropsTransform.spec.ts.snap │ │ │ ├── compileScriptRefTransform.spec.ts.snap │ │ │ ├── compileTemplate.spec.ts.snap │ │ │ ├── cssVars.spec.ts.snap │ │ │ ├── templateTransformAssetUrl.spec.ts.snap │ │ │ └── templateTransformSrcset.spec.ts.snap │ │ ├── compileScript.spec.ts │ │ ├── compileScriptPropsTransform.spec.ts │ │ ├── compileScriptRefTransform.spec.ts │ │ ├── compileStyle.spec.ts │ │ ├── compileTemplate.spec.ts │ │ ├── cssVars.spec.ts │ │ ├── fixture │ │ │ └── import.scss │ │ ├── parse.spec.ts │ │ ├── rewriteDefault.spec.ts │ │ ├── templateTransformAssetUrl.spec.ts │ │ ├── templateTransformSrcset.spec.ts │ │ ├── templateUtils.spec.ts │ │ └── utils.ts │ ├── api-extractor.json │ ├── package.json │ └── src │ │ ├── cache.ts │ │ ├── compileScript.ts │ │ ├── compileStyle.ts │ │ ├── compileTemplate.ts │ │ ├── cssVars.ts │ │ ├── index.ts │ │ ├── parse.ts │ │ ├── rewriteDefault.ts │ │ ├── shims.d.ts │ │ ├── stylePluginScoped.ts │ │ ├── stylePluginTrim.ts │ │ ├── stylePreprocessors.ts │ │ ├── templateTransformAssetUrl.ts │ │ ├── templateTransformSrcset.ts │ │ ├── templateUtils.ts │ │ └── warn.ts ├── compiler-ssr │ ├── LICENSE │ ├── README.md │ ├── __tests__ │ │ ├── ssrComponent.spec.ts │ │ ├── ssrElement.spec.ts │ │ ├── ssrInjectCssVars.spec.ts │ │ ├── ssrPortal.spec.ts │ │ ├── ssrScopeId.spec.ts │ │ ├── ssrSlotOutlet.spec.ts │ │ ├── ssrSuspense.spec.ts │ │ ├── ssrText.spec.ts │ │ ├── ssrVFor.spec.ts │ │ ├── ssrVIf.spec.ts │ │ ├── ssrVModel.spec.ts │ │ ├── ssrVShow.spec.ts │ │ └── utils.ts │ ├── api-extractor.json │ ├── package.json │ └── src │ │ ├── errors.ts │ │ ├── index.ts │ │ ├── runtimeHelpers.ts │ │ ├── ssrCodegenTransform.ts │ │ └── transforms │ │ ├── ssrInjectCssVars.ts │ │ ├── ssrInjectFallthroughAttrs.ts │ │ ├── ssrTransformComponent.ts │ │ ├── ssrTransformElement.ts │ │ ├── ssrTransformSlotOutlet.ts │ │ ├── ssrTransformSuspense.ts │ │ ├── ssrTransformTeleport.ts │ │ ├── ssrTransformTransitionGroup.ts │ │ ├── ssrVFor.ts │ │ ├── ssrVIf.ts │ │ ├── ssrVModel.ts │ │ └── ssrVShow.ts ├── global.d.ts ├── reactivity-transform │ ├── README.md │ ├── __tests__ │ │ ├── __snapshots__ │ │ │ └── reactivityTransform.spec.ts.snap │ │ └── reactivityTransform.spec.ts │ ├── api-extractor.json │ ├── package.json │ └── src │ │ ├── babelPlugin.ts │ │ ├── index.ts │ │ └── reactivityTransform.ts ├── reactivity │ ├── LICENSE │ ├── README.md │ ├── __tests__ │ │ ├── collections │ │ │ ├── Map.spec.ts │ │ │ ├── Set.spec.ts │ │ │ ├── WeakMap.spec.ts │ │ │ ├── WeakSet.spec.ts │ │ │ └── shallowReadonly.spec.ts │ │ ├── computed.spec.ts │ │ ├── deferredComputed.spec.ts │ │ ├── effect.spec.ts │ │ ├── effectScope.spec.ts │ │ ├── reactive.spec.ts │ │ ├── reactiveArray.spec.ts │ │ ├── readonly.spec.ts │ │ ├── ref.spec.ts │ │ ├── shallowReactive.spec.ts │ │ └── shallowReadonly.spec.ts │ ├── api-extractor.json │ ├── index.js │ ├── package.json │ └── src │ │ ├── baseHandlers.ts │ │ ├── collectionHandlers.ts │ │ ├── computed.ts │ │ ├── deferredComputed.ts │ │ ├── dep.ts │ │ ├── effect.ts │ │ ├── effectScope.ts │ │ ├── index.ts │ │ ├── operations.ts │ │ ├── reactive.ts │ │ ├── ref.ts │ │ └── warning.ts ├── runtime-core │ ├── LICENSE │ ├── README.md │ ├── __tests__ │ │ ├── apiAsyncComponent.spec.ts │ │ ├── apiCreateApp.spec.ts │ │ ├── apiExpose.spec.ts │ │ ├── apiInject.spec.ts │ │ ├── apiLifecycle.spec.ts │ │ ├── apiOptions.spec.ts │ │ ├── apiSetupContext.spec.ts │ │ ├── apiSetupHelpers.spec.ts │ │ ├── apiWatch.spec.ts │ │ ├── componentEmits.spec.ts │ │ ├── componentProps.spec.ts │ │ ├── componentPublicInstance.spec.ts │ │ ├── componentSlots.spec.ts │ │ ├── components │ │ │ ├── BaseTransition.spec.ts │ │ │ ├── KeepAlive.spec.ts │ │ │ ├── Suspense.spec.ts │ │ │ └── Teleport.spec.ts │ │ ├── directives.spec.ts │ │ ├── errorHandling.spec.ts │ │ ├── h.spec.ts │ │ ├── helpers │ │ │ ├── createSlots.spec.ts │ │ │ ├── renderList.spec.ts │ │ │ ├── renderSlot.spec.ts │ │ │ ├── resolveAssets.spec.ts │ │ │ ├── toHandlers.spec.ts │ │ │ └── withMemo.spec.ts │ │ ├── hmr.spec.ts │ │ ├── hydration.spec.ts │ │ ├── misc.spec.ts │ │ ├── rendererAttrsFallthrough.spec.ts │ │ ├── rendererChildren.spec.ts │ │ ├── rendererComponent.spec.ts │ │ ├── rendererElement.spec.ts │ │ ├── rendererFragment.spec.ts │ │ ├── rendererOptimizedMode.spec.ts │ │ ├── rendererTemplateRef.spec.ts │ │ ├── scheduler.spec.ts │ │ ├── scopeId.spec.ts │ │ ├── vnode.spec.ts │ │ └── vnodeHooks.spec.ts │ ├── api-extractor.json │ ├── index.js │ ├── package.json │ ├── src │ │ ├── apiAsyncComponent.ts │ │ ├── apiCreateApp.ts │ │ ├── apiDefineComponent.ts │ │ ├── apiInject.ts │ │ ├── apiLifecycle.ts │ │ ├── apiSetupHelpers.ts │ │ ├── apiWatch.ts │ │ ├── compat │ │ │ ├── attrsFallthrough.ts │ │ │ ├── compatConfig.ts │ │ │ ├── component.ts │ │ │ ├── componentAsync.ts │ │ │ ├── componentFunctional.ts │ │ │ ├── componentVModel.ts │ │ │ ├── customDirective.ts │ │ │ ├── data.ts │ │ │ ├── global.ts │ │ │ ├── globalConfig.ts │ │ │ ├── instance.ts │ │ │ ├── instanceChildren.ts │ │ │ ├── instanceEventEmitter.ts │ │ │ ├── instanceListeners.ts │ │ │ ├── props.ts │ │ │ ├── renderFn.ts │ │ │ └── renderHelpers.ts │ │ ├── component.ts │ │ ├── componentEmits.ts │ │ ├── componentOptions.ts │ │ ├── componentProps.ts │ │ ├── componentPublicInstance.ts │ │ ├── componentRenderContext.ts │ │ ├── componentRenderUtils.ts │ │ ├── componentSlots.ts │ │ ├── components │ │ │ ├── BaseTransition.ts │ │ │ ├── KeepAlive.ts │ │ │ ├── Suspense.ts │ │ │ └── Teleport.ts │ │ ├── customFormatter.ts │ │ ├── devtools.ts │ │ ├── directives.ts │ │ ├── errorHandling.ts │ │ ├── featureFlags.ts │ │ ├── h.ts │ │ ├── helpers │ │ │ ├── createSlots.ts │ │ │ ├── renderList.ts │ │ │ ├── renderSlot.ts │ │ │ ├── resolveAssets.ts │ │ │ ├── toHandlers.ts │ │ │ ├── typeUtils.ts │ │ │ ├── useSsrContext.ts │ │ │ └── withMemo.ts │ │ ├── hmr.ts │ │ ├── hydration.ts │ │ ├── index.ts │ │ ├── profiling.ts │ │ ├── renderer.ts │ │ ├── rendererTemplateRef.ts │ │ ├── scheduler.ts │ │ ├── vnode.ts │ │ └── warning.ts │ └── types │ │ ├── refBail.d.ts │ │ └── scriptSetupHelpers.d.ts ├── runtime-dom │ ├── LICENSE │ ├── README.md │ ├── __tests__ │ │ ├── createApp.spec.ts │ │ ├── customElement.spec.ts │ │ ├── customizedBuiltIn.spec.ts │ │ ├── directives │ │ │ ├── vCloak.spec.ts │ │ │ ├── vModel.spec.ts │ │ │ ├── vOn.spec.ts │ │ │ └── vShow.spec.ts │ │ ├── helpers │ │ │ ├── useCssModule.spec.ts │ │ │ └── useCssVars.spec.ts │ │ ├── nodeOps.spec.ts │ │ ├── patchAttrs.spec.ts │ │ ├── patchClass.spec.ts │ │ ├── patchEvents.spec.ts │ │ ├── patchProps.spec.ts │ │ ├── patchStyle.spec.ts │ │ └── rendererStaticNode.spec.ts │ ├── api-extractor.json │ ├── index.js │ ├── package.json │ ├── src │ │ ├── apiCustomElement.ts │ │ ├── components │ │ │ ├── Transition.ts │ │ │ └── TransitionGroup.ts │ │ ├── directives │ │ │ ├── vModel.ts │ │ │ ├── vOn.ts │ │ │ └── vShow.ts │ │ ├── helpers │ │ │ ├── useCssModule.ts │ │ │ └── useCssVars.ts │ │ ├── index.ts │ │ ├── modules │ │ │ ├── attrs.ts │ │ │ ├── class.ts │ │ │ ├── events.ts │ │ │ ├── props.ts │ │ │ └── style.ts │ │ ├── nodeOps.ts │ │ └── patchProp.ts │ └── types │ │ ├── jsx.d.ts │ │ └── refBail.d.ts ├── runtime-test │ ├── LICENSE │ ├── README.md │ ├── __tests__ │ │ └── testRuntime.spec.ts │ ├── api-extractor.json │ ├── index.js │ ├── package.json │ └── src │ │ ├── index.ts │ │ ├── nodeOps.ts │ │ ├── patchProp.ts │ │ ├── serialize.ts │ │ └── triggerEvent.ts ├── server-renderer │ ├── LICENSE │ ├── README.md │ ├── __tests__ │ │ ├── render.spec.ts │ │ ├── ssrAttrFallthrough.spec.ts │ │ ├── ssrCompilerOptions.spec.ts │ │ ├── ssrDirectives.spec.ts │ │ ├── ssrDynamicComponent.spec.ts │ │ ├── ssrInterpolate.spec.ts │ │ ├── ssrRenderAttrs.spec.ts │ │ ├── ssrRenderList.spec.ts │ │ ├── ssrScopeId.spec.ts │ │ ├── ssrSuspense.spec.ts │ │ ├── ssrTeleport.spec.ts │ │ ├── ssrVModelHelpers.spec.ts │ │ └── webStream.spec.ts │ ├── api-extractor.json │ ├── index.js │ ├── package.json │ └── src │ │ ├── helpers │ │ ├── ssrCompile.ts │ │ ├── ssrInterpolate.ts │ │ ├── ssrRenderAttrs.ts │ │ ├── ssrRenderComponent.ts │ │ ├── ssrRenderList.ts │ │ ├── ssrRenderSlot.ts │ │ ├── ssrRenderSuspense.ts │ │ ├── ssrRenderTeleport.ts │ │ └── ssrVModelHelpers.ts │ │ ├── index.ts │ │ ├── render.ts │ │ ├── renderToStream.ts │ │ └── renderToString.ts ├── sfc-playground │ ├── index.html │ ├── package.json │ ├── public │ │ └── logo.svg │ ├── src │ │ ├── App.vue │ │ ├── Header.vue │ │ ├── download │ │ │ ├── download.ts │ │ │ └── template │ │ │ │ ├── README.md │ │ │ │ ├── index.html │ │ │ │ ├── main.js │ │ │ │ ├── package.json │ │ │ │ └── vite.config.js │ │ ├── icons │ │ │ ├── Download.vue │ │ │ ├── GitHub.vue │ │ │ ├── Moon.vue │ │ │ ├── Share.vue │ │ │ └── Sun.vue │ │ ├── main.ts │ │ └── vue-dev-proxy.ts │ └── vite.config.ts ├── shared │ ├── LICENSE │ ├── README.md │ ├── __tests__ │ │ ├── __snapshots__ │ │ │ └── codeframe.spec.ts.snap │ │ ├── codeframe.spec.ts │ │ ├── escapeHtml.spec.ts │ │ ├── looseEqual.spec.ts │ │ ├── normalizeProp.spec.ts │ │ └── toDisplayString.spec.ts │ ├── api-extractor.json │ ├── index.js │ ├── package.json │ └── src │ │ ├── codeframe.ts │ │ ├── domAttrConfig.ts │ │ ├── domTagConfig.ts │ │ ├── escapeHtml.ts │ │ ├── globalsWhitelist.ts │ │ ├── index.ts │ │ ├── looseEqual.ts │ │ ├── makeMap.ts │ │ ├── normalizeProp.ts │ │ ├── patchFlags.ts │ │ ├── shapeFlags.ts │ │ ├── slotFlags.ts │ │ └── toDisplayString.ts ├── size-check │ ├── README.md │ ├── brotli.js │ ├── package.json │ ├── src │ │ └── index.ts │ └── vite.config.js ├── template-explorer │ ├── README.md │ ├── index.html │ ├── local.html │ ├── package.json │ ├── src │ │ ├── index.ts │ │ ├── options.ts │ │ └── theme.ts │ └── style.css ├── vue-compat │ ├── LICENSE │ ├── README.md │ ├── __tests__ │ │ ├── compiler.spec.ts │ │ ├── componentAsync.spec.ts │ │ ├── componentFunctional.spec.ts │ │ ├── componentVModel.spec.ts │ │ ├── filters.spec.ts │ │ ├── global.spec.ts │ │ ├── globalConfig.spec.ts │ │ ├── instance.spec.ts │ │ ├── misc.spec.ts │ │ ├── options.spec.ts │ │ ├── renderFn.spec.ts │ │ └── utils.ts │ ├── index.js │ ├── package.json │ └── src │ │ ├── createCompatVue.ts │ │ ├── dev.ts │ │ ├── esm-index.ts │ │ ├── esm-runtime.ts │ │ ├── index.ts │ │ └── runtime.ts └── vue │ ├── LICENSE │ ├── README.md │ ├── __tests__ │ ├── Transition.spec.ts │ ├── TransitionGroup.spec.ts │ ├── e2eUtils.ts │ ├── index.spec.ts │ ├── runtimeCompilerOptions.spec.ts │ ├── svgNamespace.spec.ts │ └── transition.html │ ├── api-extractor.json │ ├── compiler-sfc │ ├── index.d.ts │ ├── index.js │ ├── index.mjs │ └── package.json │ ├── examples │ ├── 01-init.html │ ├── 02-attrs.html │ ├── 03-patch.html │ ├── __tests__ │ │ ├── commits.mock.ts │ │ ├── commits.spec.ts │ │ ├── grid.spec.ts │ │ ├── markdown.spec.ts │ │ ├── svg.spec.ts │ │ ├── todomvc.spec.ts │ │ └── tree.spec.ts │ ├── classic │ │ ├── commits.html │ │ ├── grid.html │ │ ├── markdown.html │ │ ├── svg.html │ │ ├── todomvc.html │ │ └── tree.html │ ├── composition │ │ ├── commits.html │ │ ├── grid.html │ │ ├── markdown.html │ │ ├── svg.html │ │ ├── todomvc.html │ │ └── tree.html │ └── transition │ │ ├── list.html │ │ └── modal.html │ ├── index.js │ ├── index.mjs │ ├── macros-global.d.ts │ ├── macros.d.ts │ ├── package.json │ ├── ref-macros.d.ts │ ├── server-renderer │ ├── index.d.ts │ ├── index.js │ ├── index.mjs │ └── package.json │ └── src │ ├── dev.ts │ ├── index.ts │ └── runtime.ts ├── pnpm-lock.yaml ├── pnpm-workspace.yaml ├── rollup.config.js ├── scripts ├── bootstrap.js ├── build.js ├── dev.js ├── filter-e2e.js ├── filter-unit.js ├── preinstall.js ├── release.js ├── setupJestEnv.ts ├── utils.js └── verifyCommit.js ├── test-dts ├── README.md ├── component.test-d.ts ├── componentTypeExtensions.test-d.tsx ├── defineComponent.test-d.tsx ├── functionalComponent.test-d.tsx ├── h.test-d.ts ├── index.d.ts ├── inject.test-d.ts ├── reactivity.test-d.ts ├── reactivityMacros.test-d.ts ├── ref.test-d.ts ├── setupHelpers.test-d.ts ├── tsconfig.build.json ├── tsconfig.json ├── tsx.test-d.tsx └── watch.test-d.ts └── tsconfig.json /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | open_collective: vuejs 2 | patreon: evanyou 3 | github: yyx990803 4 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: Create new issue 4 | url: https://new-issue.vuejs.org/?repo=vuejs/vue-next 5 | about: Please use the following link to create a new issue. 6 | - name: Patreon 7 | url: https://www.patreon.com/evanyou 8 | about: Love Vue.js? Please consider supporting us via Patreon. 9 | - name: Open Collective 10 | url: https://opencollective.com/vuejs/donate 11 | about: Love Vue.js? Please consider supporting us via Open Collective. 12 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: npm 4 | directory: "/" 5 | schedule: 6 | interval: monthly 7 | open-pull-requests-limit: 10 8 | versioning-strategy: lockfile-only 9 | ignore: 10 | - dependency-name: "@types/node" 11 | versions: 12 | - 14.14.24 13 | - 14.14.37 14 | - dependency-name: "@babel/parser" 15 | versions: 16 | - 7.12.11 17 | - 7.12.13 18 | - 7.12.14 19 | - 7.12.15 20 | - 7.12.16 21 | - 7.12.17 22 | - 7.13.0 23 | - 7.13.10 24 | - 7.13.11 25 | - 7.13.13 26 | - 7.13.4 27 | - 7.13.9 28 | - dependency-name: eslint 29 | versions: 30 | - 7.23.0 31 | - dependency-name: postcss 32 | versions: 33 | - 8.2.4 34 | - 8.2.5 35 | - 8.2.7 36 | - 8.2.8 37 | - dependency-name: typescript 38 | versions: 39 | - 4.2.2 40 | - dependency-name: "@babel/types" 41 | versions: 42 | - 7.12.12 43 | - 7.12.13 44 | - 7.12.17 45 | - 7.13.0 46 | - dependency-name: pug-code-gen 47 | versions: 48 | - 2.0.3 49 | - dependency-name: estree-walker 50 | versions: 51 | - 2.0.2 52 | - dependency-name: "@typescript-eslint/parser" 53 | versions: 54 | - 4.14.2 55 | - 4.15.0 56 | - dependency-name: "@microsoft/api-extractor" 57 | versions: 58 | - 7.13.1 59 | - dependency-name: rollup 60 | versions: 61 | - 2.38.5 62 | - dependency-name: node-notifier 63 | versions: 64 | - 8.0.1 65 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: 'ci' 2 | on: 3 | push: 4 | branches: 5 | - '**' 6 | pull_request: 7 | branches: 8 | - master 9 | jobs: 10 | test: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: actions/checkout@v2 14 | 15 | - name: Install pnpm 16 | uses: pnpm/action-setup@v2.0.1 17 | with: 18 | version: 6.15.1 19 | 20 | - name: Set node version to 16 21 | uses: actions/setup-node@v2 22 | with: 23 | node-version: 16 24 | cache: 'pnpm' 25 | 26 | - run: pnpm install 27 | 28 | - name: Run unit tests 29 | run: pnpm run test 30 | 31 | test-dts: 32 | runs-on: ubuntu-latest 33 | steps: 34 | - uses: actions/checkout@v2 35 | 36 | - name: Install pnpm 37 | uses: pnpm/action-setup@v2.0.1 38 | with: 39 | version: 6.15.1 40 | 41 | - name: Set node version to 16 42 | uses: actions/setup-node@v2 43 | with: 44 | node-version: 16 45 | cache: 'pnpm' 46 | 47 | - run: pnpm install 48 | 49 | - name: Run type declaration tests 50 | run: pnpm run test-dts 51 | 52 | size: 53 | runs-on: ubuntu-latest 54 | env: 55 | CI_JOB_NUMBER: 1 56 | steps: 57 | - uses: actions/checkout@v2 58 | 59 | - name: Install pnpm 60 | uses: pnpm/action-setup@v2.0.1 61 | with: 62 | version: 6.15.1 63 | 64 | - name: Set node version to 16 65 | uses: actions/setup-node@v2 66 | with: 67 | node-version: 16 68 | cache: 'pnpm' 69 | 70 | - run: pnpm install 71 | - run: pnpm run size 72 | 73 | # - name: Check build size 74 | # uses: posva/size-check-action@v1.1.2 75 | # with: 76 | # github_token: ${{ secrets.GITHUB_TOKEN }} 77 | # build_script: size 78 | # files: packages/vue/dist/vue.global.prod.js packages/runtime-dom/dist/runtime-dom.global.prod.js packages/size-check/dist/index.js 79 | -------------------------------------------------------------------------------- /.github/workflows/release-tag.yml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | tags: 4 | - 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10 5 | 6 | name: Create Release 7 | 8 | jobs: 9 | build: 10 | name: Create Release 11 | runs-on: ubuntu-latest 12 | steps: 13 | - name: Checkout code 14 | uses: actions/checkout@master 15 | - name: Create Release for Tag 16 | id: release_tag 17 | uses: yyx990803/release-tag@master 18 | env: 19 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 20 | with: 21 | tag_name: ${{ github.ref }} 22 | body: | 23 | Please refer to [CHANGELOG.md](https://github.com/vuejs/vue-next/blob/master/CHANGELOG.md) for details. 24 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | dist 2 | .DS_Store 3 | node_modules 4 | coverage 5 | temp 6 | explorations 7 | TODOs.md 8 | *.log 9 | .idea 10 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | semi: false 2 | singleQuote: true 3 | printWidth: 80 4 | trailingComma: 'none' 5 | arrowParens: 'avoid' 6 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "Jest", 9 | "type": "node", 10 | "request": "launch", 11 | "program": "${workspaceFolder}/node_modules/.bin/jest", 12 | "stopOnEntry": false, 13 | "args": ["${fileBasename}", "--runInBand", "--detectOpenHandles"], 14 | "cwd": "${workspaceFolder}", 15 | "preLaunchTask": null, 16 | "runtimeExecutable": null, 17 | "runtimeArgs": ["--nolazy"], 18 | "env": { 19 | "NODE_ENV": "development" 20 | }, 21 | "console": "integratedTerminal", 22 | "sourceMaps": true, 23 | "windows": { 24 | "program": "${workspaceFolder}/node_modules/jest/bin/jest", 25 | } 26 | } 27 | ] 28 | } 29 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use the project's typescript version 3 | "typescript.tsdk": "node_modules/typescript/lib", 4 | 5 | "cSpell.enabledLanguageIds": ["markdown", "plaintext", "text", "yml"], 6 | 7 | // Use prettier to format typescript, javascript and JSON files 8 | "[typescript]": { 9 | "editor.defaultFormatter": "esbenp.prettier-vscode" 10 | }, 11 | "[javascript]": { 12 | "editor.defaultFormatter": "esbenp.prettier-vscode" 13 | }, 14 | "[json]": { 15 | "editor.defaultFormatter": "esbenp.prettier-vscode" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2018-present, Yuxi (Evan) You 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Vue3源码共读 2 | 3 | 小伙伴们好,这是村长在B站组织的[Vue3源码共读活动](https://space.bilibili.com/480140591/channel/collectiondetail?sid=114925)产出的项目。项目中会对主要源码做注释,为了更好学习,最好还是去B站听听配套的视频。 4 | 5 | 6 | 7 | 麻烦小伙伴们动动小手: 8 | 9 | - 给项目点个Star ✨ 10 | - 给村长B站视频点个3️⃣连 11 | - 给小伙伴们分享一下 12 | 13 | 14 | 15 | ## 关注村长 16 | 17 | 关注村长公众号「**村长学前端**」,输入“加群”跟大佬们讨论学习~ 18 | 19 | ![](./code.jpg) 20 | 21 | 羊村欢迎你! 22 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Reporting a Vulnerability 2 | 3 | To report a vulnerability, please email security@vuejs.org. 4 | 5 | While the discovery of new vulnerabilities is rare, we also recommend always using the latest versions of Vue and its official companion libraries to ensure your application remains as secure as possible. 6 | 7 | Please note that we do not consider XSS via template expressions a valid attack vector, because it can only happen if the user intentionally uses untrusted content as template compilation source. This is similar to knowingly pasting untrusted scripts into a browser console. We explicitly warn users against using untrusted content as template compilation source in our documentation. 8 | -------------------------------------------------------------------------------- /api-extractor.json: -------------------------------------------------------------------------------- 1 | // this the shared base config for all packages. 2 | { 3 | "$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json", 4 | 5 | "apiReport": { 6 | "enabled": true, 7 | "reportFolder": "/temp/" 8 | }, 9 | 10 | "docModel": { 11 | "enabled": true 12 | }, 13 | 14 | "dtsRollup": { 15 | "enabled": true 16 | }, 17 | 18 | "tsdocMetadata": { 19 | "enabled": false 20 | }, 21 | 22 | "messages": { 23 | "compilerMessageReporting": { 24 | "default": { 25 | "logLevel": "warning" 26 | } 27 | }, 28 | 29 | "extractorMessageReporting": { 30 | "default": { 31 | "logLevel": "warning", 32 | "addToApiReportFile": true 33 | }, 34 | 35 | "ae-missing-release-tag": { 36 | "logLevel": "none" 37 | } 38 | }, 39 | 40 | "tsdocMessageReporting": { 41 | "default": { 42 | "logLevel": "warning" 43 | }, 44 | 45 | "tsdoc-undefined-tag": { 46 | "logLevel": "none" 47 | }, 48 | 49 | "tsdoc-escape-greater-than": { 50 | "logLevel": "none" 51 | }, 52 | 53 | "tsdoc-malformed-inline-tag": { 54 | "logLevel": "none" 55 | }, 56 | 57 | "tsdoc-escape-right-brace": { 58 | "logLevel": "none" 59 | }, 60 | 61 | "tsdoc-unnecessary-backslash": { 62 | "logLevel": "none" 63 | } 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /code.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/57code/vue3-study/6430ac20dfc46e8bd8c88047f11fce67f08631ee/code.jpg -------------------------------------------------------------------------------- /netlify.toml: -------------------------------------------------------------------------------- 1 | [build.environment] 2 | NODE_VERSION = "16" 3 | NPM_FLAGS = "--version" # prevent Netlify npm install 4 | -------------------------------------------------------------------------------- /packages/compiler-core/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2018-present, Yuxi (Evan) You 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /packages/compiler-core/README.md: -------------------------------------------------------------------------------- 1 | # @vue/compiler-core 2 | -------------------------------------------------------------------------------- /packages/compiler-core/__tests__/transforms/__snapshots__/transformExpressions.spec.ts.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`compiler: expression transform bindingMetadata inline mode 1`] = ` 4 | "(_ctx, _cache) => { 5 | return (_openBlock(), _createElementBlock(\\"div\\", null, _toDisplayString(__props.props) + \\" \\" + _toDisplayString(_unref(setup)) + \\" \\" + _toDisplayString(setupConst) + \\" \\" + _toDisplayString(_ctx.data) + \\" \\" + _toDisplayString(_ctx.options), 1 /* TEXT */)) 6 | }" 7 | `; 8 | 9 | exports[`compiler: expression transform bindingMetadata non-inline mode 1`] = ` 10 | "const { toDisplayString: _toDisplayString, openBlock: _openBlock, createElementBlock: _createElementBlock } = Vue 11 | 12 | return function render(_ctx, _cache, $props, $setup, $data, $options) { 13 | return (_openBlock(), _createElementBlock(\\"div\\", null, _toDisplayString($props.props) + \\" \\" + _toDisplayString($setup.setup) + \\" \\" + _toDisplayString($data.data) + \\" \\" + _toDisplayString($options.options), 1 /* TEXT */)) 14 | }" 15 | `; 16 | -------------------------------------------------------------------------------- /packages/compiler-core/__tests__/transforms/noopDirectiveTransform.spec.ts: -------------------------------------------------------------------------------- 1 | import { 2 | baseParse as parse, 3 | transform, 4 | ElementNode, 5 | noopDirectiveTransform, 6 | VNodeCall 7 | } from '../../src' 8 | import { transformElement } from '../../src/transforms/transformElement' 9 | 10 | describe('compiler: noop directive transform', () => { 11 | test('should add no props to DOM', () => { 12 | const ast = parse(`
`) 13 | transform(ast, { 14 | nodeTransforms: [transformElement], 15 | directiveTransforms: { 16 | noop: noopDirectiveTransform 17 | } 18 | }) 19 | const node = ast.children[0] as ElementNode 20 | // As v-noop adds no properties the codegen should be identical to 21 | // rendering a div with no props or reactive data (so just the tag as the arg) 22 | expect((node.codegenNode as VNodeCall).props).toBeUndefined() 23 | }) 24 | }) 25 | -------------------------------------------------------------------------------- /packages/compiler-core/__tests__/transforms/vMemo.spec.ts: -------------------------------------------------------------------------------- 1 | import { baseCompile } from '../../src' 2 | 3 | describe('compiler: v-memo transform', () => { 4 | function compile(content: string) { 5 | return baseCompile(`
${content}
`, { 6 | mode: 'module', 7 | prefixIdentifiers: true 8 | }).code 9 | } 10 | 11 | test('on root element', () => { 12 | expect( 13 | baseCompile(`
`, { 14 | mode: 'module', 15 | prefixIdentifiers: true 16 | }).code 17 | ).toMatchSnapshot() 18 | }) 19 | 20 | test('on normal element', () => { 21 | expect(compile(`
`)).toMatchSnapshot() 22 | }) 23 | 24 | test('on component', () => { 25 | expect(compile(``)).toMatchSnapshot() 26 | }) 27 | 28 | test('on v-if', () => { 29 | expect( 30 | compile( 31 | `
foobar
32 | ` 33 | ) 34 | ).toMatchSnapshot() 35 | }) 36 | 37 | test('on v-for', () => { 38 | expect( 39 | compile( 40 | `
41 | foobar 42 |
` 43 | ) 44 | ).toMatchSnapshot() 45 | }) 46 | 47 | test('on template v-for', () => { 48 | expect( 49 | compile( 50 | `` 53 | ) 54 | ).toMatchSnapshot() 55 | }) 56 | }) 57 | -------------------------------------------------------------------------------- /packages/compiler-core/api-extractor.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../api-extractor.json", 3 | "mainEntryPointFilePath": "./dist/packages//src/index.d.ts", 4 | "dtsRollup": { 5 | "publicTrimmedFilePath": "./dist/.d.ts" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /packages/compiler-core/index.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | if (process.env.NODE_ENV === 'production') { 4 | module.exports = require('./dist/compiler-core.cjs.prod.js') 5 | } else { 6 | module.exports = require('./dist/compiler-core.cjs.js') 7 | } 8 | -------------------------------------------------------------------------------- /packages/compiler-core/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@vue/compiler-core", 3 | "version": "3.2.26", 4 | "description": "@vue/compiler-core", 5 | "main": "index.js", 6 | "module": "dist/compiler-core.esm-bundler.js", 7 | "types": "dist/compiler-core.d.ts", 8 | "files": [ 9 | "index.js", 10 | "dist" 11 | ], 12 | "buildOptions": { 13 | "name": "VueCompilerCore", 14 | "compat": true, 15 | "formats": [ 16 | "esm-bundler", 17 | "cjs" 18 | ] 19 | }, 20 | "repository": { 21 | "type": "git", 22 | "url": "git+https://github.com/vuejs/vue-next.git", 23 | "directory": "packages/compiler-core" 24 | }, 25 | "keywords": [ 26 | "vue" 27 | ], 28 | "author": "Evan You", 29 | "license": "MIT", 30 | "bugs": { 31 | "url": "https://github.com/vuejs/vue-next/issues" 32 | }, 33 | "homepage": "https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme", 34 | "dependencies": { 35 | "@vue/shared": "3.2.26", 36 | "@babel/parser": "^7.16.4", 37 | "estree-walker": "^2.0.2", 38 | "source-map": "^0.6.1" 39 | }, 40 | "devDependencies": { 41 | "@babel/types": "^7.16.0" 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /packages/compiler-core/src/transforms/noopDirectiveTransform.ts: -------------------------------------------------------------------------------- 1 | import { DirectiveTransform } from '../transform' 2 | 3 | export const noopDirectiveTransform: DirectiveTransform = () => ({ props: [] }) 4 | -------------------------------------------------------------------------------- /packages/compiler-core/src/transforms/vMemo.ts: -------------------------------------------------------------------------------- 1 | import { NodeTransform } from '../transform' 2 | import { findDir, makeBlock } from '../utils' 3 | import { 4 | createCallExpression, 5 | createFunctionExpression, 6 | ElementTypes, 7 | MemoExpression, 8 | NodeTypes, 9 | PlainElementNode 10 | } from '../ast' 11 | import { WITH_MEMO } from '../runtimeHelpers' 12 | 13 | const seen = new WeakSet() 14 | 15 | export const transformMemo: NodeTransform = (node, context) => { 16 | if (node.type === NodeTypes.ELEMENT) { 17 | const dir = findDir(node, 'memo') 18 | if (!dir || seen.has(node)) { 19 | return 20 | } 21 | seen.add(node) 22 | return () => { 23 | const codegenNode = 24 | node.codegenNode || 25 | (context.currentNode as PlainElementNode).codegenNode 26 | if (codegenNode && codegenNode.type === NodeTypes.VNODE_CALL) { 27 | // non-component sub tree should be turned into a block 28 | if (node.tagType !== ElementTypes.COMPONENT) { 29 | makeBlock(codegenNode, context) 30 | } 31 | node.codegenNode = createCallExpression(context.helper(WITH_MEMO), [ 32 | dir.exp!, 33 | createFunctionExpression(undefined, codegenNode), 34 | `_cache`, 35 | String(context.cached++) 36 | ]) as MemoExpression 37 | } 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /packages/compiler-core/src/transforms/vOnce.ts: -------------------------------------------------------------------------------- 1 | import { NodeTransform } from '../transform' 2 | import { findDir } from '../utils' 3 | import { ElementNode, ForNode, IfNode, NodeTypes } from '../ast' 4 | import { SET_BLOCK_TRACKING } from '../runtimeHelpers' 5 | 6 | const seen = new WeakSet() 7 | 8 | export const transformOnce: NodeTransform = (node, context) => { 9 | if (node.type === NodeTypes.ELEMENT && findDir(node, 'once', true)) { 10 | if (seen.has(node) || context.inVOnce) { 11 | return 12 | } 13 | seen.add(node) 14 | context.inVOnce = true 15 | context.helper(SET_BLOCK_TRACKING) 16 | return () => { 17 | context.inVOnce = false 18 | const cur = context.currentNode as ElementNode | IfNode | ForNode 19 | if (cur.codegenNode) { 20 | cur.codegenNode = context.cache(cur.codegenNode, true /* isVNode */) 21 | } 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /packages/compiler-dom/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2018-present, Yuxi (Evan) You 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /packages/compiler-dom/README.md: -------------------------------------------------------------------------------- 1 | # @vue/compiler-dom -------------------------------------------------------------------------------- /packages/compiler-dom/__tests__/__snapshots__/index.spec.ts.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`compile should contain standard transforms 1`] = ` 4 | "const _Vue = Vue 5 | 6 | return function render(_ctx, _cache) { 7 | with (_ctx) { 8 | const { toDisplayString: _toDisplayString, createElementVNode: _createElementVNode, normalizeStyle: _normalizeStyle, Fragment: _Fragment, openBlock: _openBlock, createElementBlock: _createElementBlock } = _Vue 9 | 10 | return (_openBlock(), _createElementBlock(_Fragment, null, [ 11 | _createElementVNode(\\"div\\", { 12 | textContent: _toDisplayString(text) 13 | }, null, 8 /* PROPS */, [\\"textContent\\"]), 14 | _createElementVNode(\\"div\\", { innerHTML: html }, null, 8 /* PROPS */, [\\"innerHTML\\"]), 15 | _createElementVNode(\\"div\\", null, \\"test\\"), 16 | _createElementVNode(\\"div\\", { style: {\\"color\\":\\"red\\"} }, \\"red\\"), 17 | _createElementVNode(\\"div\\", { 18 | style: _normalizeStyle({color: 'green'}) 19 | }, null, 4 /* STYLE */) 20 | ], 64 /* STABLE_FRAGMENT */)) 21 | } 22 | }" 23 | `; 24 | -------------------------------------------------------------------------------- /packages/compiler-dom/__tests__/decoderHtmlBrowser.spec.ts: -------------------------------------------------------------------------------- 1 | import { decodeHtmlBrowser } from '../src/decodeHtmlBrowser' 2 | 3 | describe('decodeHtmlBrowser', () => { 4 | it('should decode HTML correctly', () => { 5 | expect(decodeHtmlBrowser(' abc 123 ')).toBe(' abc 123 ') 6 | 7 | expect(decodeHtmlBrowser('&')).toBe('&') 8 | expect(decodeHtmlBrowser('&')).toBe('&') 9 | expect(decodeHtmlBrowser('&amp;')).toBe('&') 10 | 11 | expect(decodeHtmlBrowser('<')).toBe('<') 12 | expect(decodeHtmlBrowser('<')).toBe('<') 13 | expect(decodeHtmlBrowser('&lt;')).toBe('<') 14 | 15 | expect(decodeHtmlBrowser('>')).toBe('>') 16 | expect(decodeHtmlBrowser('>')).toBe('>') 17 | expect(decodeHtmlBrowser('&gt;')).toBe('>') 18 | 19 | expect(decodeHtmlBrowser(' ')).toBe('\u00a0') 20 | expect(decodeHtmlBrowser('"')).toBe('"') 21 | expect(decodeHtmlBrowser(''')).toBe("'") 22 | 23 | expect(decodeHtmlBrowser('É')).toBe('\u00c9') 24 | expect(decodeHtmlBrowser('É')).toBe('\u00c9') 25 | expect(decodeHtmlBrowser('É')).toBe('\u00c9') 26 | 27 | // #3001 html tags inside attribute values 28 | expect(decodeHtmlBrowser('Text', true)).toBe( 29 | 'Text' 30 | ) 31 | expect(decodeHtmlBrowser('&', true)).toBe( 32 | '&' 33 | ) 34 | expect( 35 | decodeHtmlBrowser( 36 | '<strong>&</strong>', 37 | true 38 | ) 39 | ).toBe('&') 40 | }) 41 | }) 42 | -------------------------------------------------------------------------------- /packages/compiler-dom/__tests__/index.spec.ts: -------------------------------------------------------------------------------- 1 | import { compile } from '../src' 2 | 3 | describe('compile', () => { 4 | it('should contain standard transforms', () => { 5 | const { code } = compile(`
6 |
7 |
test
8 |
red
9 |
`) 10 | 11 | expect(code).toMatchSnapshot() 12 | }) 13 | }) 14 | -------------------------------------------------------------------------------- /packages/compiler-dom/__tests__/transforms/__snapshots__/stringifyStatic.spec.ts.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`stringify static html should bail on bindings that are hoisted but not stringifiable 1`] = ` 4 | "const { createElementVNode: _createElementVNode, openBlock: _openBlock, createElementBlock: _createElementBlock } = Vue 5 | 6 | const _hoisted_1 = /*#__PURE__*/_createElementVNode(\\"div\\", null, [ 7 | /*#__PURE__*/_createElementVNode(\\"span\\", { class: \\"foo\\" }, \\"foo\\"), 8 | /*#__PURE__*/_createElementVNode(\\"span\\", { class: \\"foo\\" }, \\"foo\\"), 9 | /*#__PURE__*/_createElementVNode(\\"span\\", { class: \\"foo\\" }, \\"foo\\"), 10 | /*#__PURE__*/_createElementVNode(\\"span\\", { class: \\"foo\\" }, \\"foo\\"), 11 | /*#__PURE__*/_createElementVNode(\\"span\\", { class: \\"foo\\" }, \\"foo\\"), 12 | /*#__PURE__*/_createElementVNode(\\"img\\", { src: _imports_0_ }) 13 | ], -1 /* HOISTED */) 14 | const _hoisted_2 = [ 15 | _hoisted_1 16 | ] 17 | 18 | return function render(_ctx, _cache) { 19 | return (_openBlock(), _createElementBlock(\\"div\\", null, _hoisted_2)) 20 | }" 21 | `; 22 | 23 | exports[`stringify static html should work with bindings that are non-static but stringifiable 1`] = ` 24 | "const { createElementVNode: _createElementVNode, createStaticVNode: _createStaticVNode, openBlock: _openBlock, createElementBlock: _createElementBlock } = Vue 25 | 26 | const _hoisted_1 = /*#__PURE__*/_createStaticVNode(\\"
foofoofoofoofoo
\\", 1) 27 | const _hoisted_2 = [ 28 | _hoisted_1 29 | ] 30 | 31 | return function render(_ctx, _cache) { 32 | return (_openBlock(), _createElementBlock(\\"div\\", null, _hoisted_2)) 33 | }" 34 | `; 35 | -------------------------------------------------------------------------------- /packages/compiler-dom/__tests__/transforms/__snapshots__/vShow.spec.ts.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`compiler: v-show transform simple expression 1`] = ` 4 | "const _Vue = Vue 5 | 6 | return function render(_ctx, _cache) { 7 | with (_ctx) { 8 | const { vShow: _vShow, withDirectives: _withDirectives, openBlock: _openBlock, createElementBlock: _createElementBlock } = _Vue 9 | 10 | return _withDirectives((_openBlock(), _createElementBlock(\\"div\\", null, null, 512 /* NEED_PATCH */)), [ 11 | [_vShow, a] 12 | ]) 13 | } 14 | }" 15 | `; 16 | -------------------------------------------------------------------------------- /packages/compiler-dom/__tests__/transforms/__snapshots__/warnTransitionChildren.spec.ts.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`the v-if/else-if/else branchs in Transition should ignore comments 1`] = ` 4 | "const _Vue = Vue 5 | 6 | return function render(_ctx, _cache) { 7 | with (_ctx) { 8 | const { openBlock: _openBlock, createElementBlock: _createElementBlock, createCommentVNode: _createCommentVNode, createElementVNode: _createElementVNode, Fragment: _Fragment, Transition: _Transition, withCtx: _withCtx, createBlock: _createBlock } = _Vue 9 | 10 | return (_openBlock(), _createBlock(_Transition, null, { 11 | default: _withCtx(() => [ 12 | a 13 | ? (_openBlock(), _createElementBlock(\\"div\\", { key: 0 }, \\"hey\\")) 14 | : b 15 | ? (_openBlock(), _createElementBlock(\\"div\\", { key: 1 }, \\"hey\\")) 16 | : (_openBlock(), _createElementBlock(\\"div\\", { key: 2 }, [ 17 | c 18 | ? (_openBlock(), _createElementBlock(\\"p\\", { key: 0 })) 19 | : (_openBlock(), _createElementBlock(_Fragment, { key: 1 }, [ 20 | _createCommentVNode(\\" this should not be ignored \\"), 21 | _createElementVNode(\\"p\\") 22 | ], 2112 /* STABLE_FRAGMENT, DEV_ROOT_FRAGMENT */)) 23 | ])) 24 | ]), 25 | _: 1 /* STABLE */ 26 | })) 27 | } 28 | }" 29 | `; 30 | -------------------------------------------------------------------------------- /packages/compiler-dom/__tests__/transforms/ignoreSideEffectTags.spec.ts: -------------------------------------------------------------------------------- 1 | import { compile, CompilerError } from '../../src' 2 | 3 | describe('compiler: ignore side effect tags', () => { 4 | it('should ignore script', () => { 5 | let err: CompilerError | undefined 6 | const { code } = compile(``, { 7 | onError(e) { 8 | err = e 9 | } 10 | }) 11 | expect(code).not.toMatch('script') 12 | expect(err).toBeDefined() 13 | expect(err!.message).toMatch(`Tags with side effect`) 14 | }) 15 | 16 | it('should ignore style', () => { 17 | let err: CompilerError | undefined 18 | const { code } = compile(``, { 19 | onError(e) { 20 | err = e 21 | } 22 | }) 23 | expect(code).not.toMatch('style') 24 | expect(err).toBeDefined() 25 | expect(err!.message).toMatch(`Tags with side effect`) 26 | }) 27 | }) 28 | -------------------------------------------------------------------------------- /packages/compiler-dom/__tests__/transforms/vShow.spec.ts: -------------------------------------------------------------------------------- 1 | import { 2 | baseParse as parse, 3 | transform, 4 | generate, 5 | CompilerOptions 6 | } from '@vue/compiler-core' 7 | import { transformElement } from '../../../compiler-core/src/transforms/transformElement' 8 | import { transformShow } from '../../src/transforms/vShow' 9 | import { DOMErrorCodes } from '../../src/errors' 10 | 11 | function transformWithShow(template: string, options: CompilerOptions = {}) { 12 | const ast = parse(template) 13 | transform(ast, { 14 | nodeTransforms: [transformElement], 15 | directiveTransforms: { 16 | show: transformShow 17 | }, 18 | ...options 19 | }) 20 | return ast 21 | } 22 | 23 | describe('compiler: v-show transform', () => { 24 | test('simple expression', () => { 25 | const ast = transformWithShow(`
`) 26 | 27 | expect(generate(ast).code).toMatchSnapshot() 28 | }) 29 | 30 | test('should raise error if has no expression', () => { 31 | const onError = jest.fn() 32 | transformWithShow(`
`, { onError }) 33 | 34 | expect(onError).toHaveBeenCalledTimes(1) 35 | expect(onError).toHaveBeenCalledWith( 36 | expect.objectContaining({ 37 | code: DOMErrorCodes.X_V_SHOW_NO_EXPRESSION 38 | }) 39 | ) 40 | }) 41 | }) 42 | -------------------------------------------------------------------------------- /packages/compiler-dom/api-extractor.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../api-extractor.json", 3 | "mainEntryPointFilePath": "./dist/packages//src/index.d.ts", 4 | "dtsRollup": { 5 | "publicTrimmedFilePath": "./dist/.d.ts" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /packages/compiler-dom/index.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | if (process.env.NODE_ENV === 'production') { 4 | module.exports = require('./dist/compiler-dom.cjs.prod.js') 5 | } else { 6 | module.exports = require('./dist/compiler-dom.cjs.js') 7 | } 8 | -------------------------------------------------------------------------------- /packages/compiler-dom/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@vue/compiler-dom", 3 | "version": "3.2.26", 4 | "description": "@vue/compiler-dom", 5 | "main": "index.js", 6 | "module": "dist/compiler-dom.esm-bundler.js", 7 | "types": "dist/compiler-dom.d.ts", 8 | "unpkg": "dist/compiler-dom.global.js", 9 | "jsdelivr": "dist/compiler-dom.global.js", 10 | "files": [ 11 | "index.js", 12 | "dist" 13 | ], 14 | "sideEffects": false, 15 | "buildOptions": { 16 | "name": "VueCompilerDOM", 17 | "compat": true, 18 | "formats": [ 19 | "esm-bundler", 20 | "esm-browser", 21 | "cjs", 22 | "global" 23 | ] 24 | }, 25 | "repository": { 26 | "type": "git", 27 | "url": "git+https://github.com/vuejs/vue-next.git", 28 | "directory": "packages/compiler-dom" 29 | }, 30 | "keywords": [ 31 | "vue" 32 | ], 33 | "author": "Evan You", 34 | "license": "MIT", 35 | "bugs": { 36 | "url": "https://github.com/vuejs/vue-next/issues" 37 | }, 38 | "homepage": "https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme", 39 | "dependencies": { 40 | "@vue/shared": "3.2.26", 41 | "@vue/compiler-core": "3.2.26" 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /packages/compiler-dom/src/decodeHtmlBrowser.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-restricted-globals */ 2 | 3 | let decoder: HTMLDivElement 4 | 5 | export function decodeHtmlBrowser(raw: string, asAttr = false): string { 6 | if (!decoder) { 7 | decoder = document.createElement('div') 8 | } 9 | if (asAttr) { 10 | decoder.innerHTML = `
` 11 | return decoder.children[0].getAttribute('foo') as string 12 | } else { 13 | decoder.innerHTML = raw 14 | return decoder.textContent as string 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /packages/compiler-dom/src/runtimeHelpers.ts: -------------------------------------------------------------------------------- 1 | import { registerRuntimeHelpers } from '@vue/compiler-core' 2 | 3 | export const V_MODEL_RADIO = Symbol(__DEV__ ? `vModelRadio` : ``) 4 | export const V_MODEL_CHECKBOX = Symbol(__DEV__ ? `vModelCheckbox` : ``) 5 | export const V_MODEL_TEXT = Symbol(__DEV__ ? `vModelText` : ``) 6 | export const V_MODEL_SELECT = Symbol(__DEV__ ? `vModelSelect` : ``) 7 | export const V_MODEL_DYNAMIC = Symbol(__DEV__ ? `vModelDynamic` : ``) 8 | 9 | export const V_ON_WITH_MODIFIERS = Symbol(__DEV__ ? `vOnModifiersGuard` : ``) 10 | export const V_ON_WITH_KEYS = Symbol(__DEV__ ? `vOnKeysGuard` : ``) 11 | 12 | export const V_SHOW = Symbol(__DEV__ ? `vShow` : ``) 13 | 14 | export const TRANSITION = Symbol(__DEV__ ? `Transition` : ``) 15 | export const TRANSITION_GROUP = Symbol(__DEV__ ? `TransitionGroup` : ``) 16 | 17 | registerRuntimeHelpers({ 18 | [V_MODEL_RADIO]: `vModelRadio`, 19 | [V_MODEL_CHECKBOX]: `vModelCheckbox`, 20 | [V_MODEL_TEXT]: `vModelText`, 21 | [V_MODEL_SELECT]: `vModelSelect`, 22 | [V_MODEL_DYNAMIC]: `vModelDynamic`, 23 | [V_ON_WITH_MODIFIERS]: `withModifiers`, 24 | [V_ON_WITH_KEYS]: `withKeys`, 25 | [V_SHOW]: `vShow`, 26 | [TRANSITION]: `Transition`, 27 | [TRANSITION_GROUP]: `TransitionGroup` 28 | }) 29 | -------------------------------------------------------------------------------- /packages/compiler-dom/src/transforms/ignoreSideEffectTags.ts: -------------------------------------------------------------------------------- 1 | import { NodeTransform, NodeTypes, ElementTypes } from '@vue/compiler-core' 2 | import { DOMErrorCodes, createDOMCompilerError } from '../errors' 3 | 4 | export const ignoreSideEffectTags: NodeTransform = (node, context) => { 5 | if ( 6 | node.type === NodeTypes.ELEMENT && 7 | node.tagType === ElementTypes.ELEMENT && 8 | (node.tag === 'script' || node.tag === 'style') 9 | ) { 10 | context.onError( 11 | createDOMCompilerError(DOMErrorCodes.X_IGNORED_SIDE_EFFECT_TAG, node.loc) 12 | ) 13 | context.removeNode() 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /packages/compiler-dom/src/transforms/transformStyle.ts: -------------------------------------------------------------------------------- 1 | import { 2 | NodeTransform, 3 | NodeTypes, 4 | createSimpleExpression, 5 | SimpleExpressionNode, 6 | SourceLocation, 7 | ConstantTypes 8 | } from '@vue/compiler-core' 9 | import { parseStringStyle } from '@vue/shared' 10 | 11 | // Parse inline CSS strings for static style attributes into an object. 12 | // This is a NodeTransform since it works on the static `style` attribute and 13 | // converts it into a dynamic equivalent: 14 | // style="color: red" -> :style='{ "color": "red" }' 15 | // It is then processed by `transformElement` and included in the generated 16 | // props. 17 | export const transformStyle: NodeTransform = node => { 18 | if (node.type === NodeTypes.ELEMENT) { 19 | node.props.forEach((p, i) => { 20 | if (p.type === NodeTypes.ATTRIBUTE && p.name === 'style' && p.value) { 21 | // replace p with an expression node 22 | node.props[i] = { 23 | type: NodeTypes.DIRECTIVE, 24 | name: `bind`, 25 | arg: createSimpleExpression(`style`, true, p.loc), 26 | exp: parseInlineCSS(p.value.content, p.loc), 27 | modifiers: [], 28 | loc: p.loc 29 | } 30 | } 31 | }) 32 | } 33 | } 34 | 35 | const parseInlineCSS = ( 36 | cssText: string, 37 | loc: SourceLocation 38 | ): SimpleExpressionNode => { 39 | const normalized = parseStringStyle(cssText) 40 | return createSimpleExpression( 41 | JSON.stringify(normalized), 42 | false, 43 | loc, 44 | ConstantTypes.CAN_STRINGIFY 45 | ) 46 | } 47 | -------------------------------------------------------------------------------- /packages/compiler-dom/src/transforms/vHtml.ts: -------------------------------------------------------------------------------- 1 | import { 2 | DirectiveTransform, 3 | createObjectProperty, 4 | createSimpleExpression 5 | } from '@vue/compiler-core' 6 | import { createDOMCompilerError, DOMErrorCodes } from '../errors' 7 | 8 | export const transformVHtml: DirectiveTransform = (dir, node, context) => { 9 | const { exp, loc } = dir 10 | if (!exp) { 11 | context.onError( 12 | createDOMCompilerError(DOMErrorCodes.X_V_HTML_NO_EXPRESSION, loc) 13 | ) 14 | } 15 | if (node.children.length) { 16 | context.onError( 17 | createDOMCompilerError(DOMErrorCodes.X_V_HTML_WITH_CHILDREN, loc) 18 | ) 19 | node.children.length = 0 20 | } 21 | return { 22 | props: [ 23 | createObjectProperty( 24 | createSimpleExpression(`innerHTML`, true, loc), 25 | exp || createSimpleExpression('', true) 26 | ) 27 | ] 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /packages/compiler-dom/src/transforms/vShow.ts: -------------------------------------------------------------------------------- 1 | import { DirectiveTransform } from '@vue/compiler-core' 2 | import { createDOMCompilerError, DOMErrorCodes } from '../errors' 3 | import { V_SHOW } from '../runtimeHelpers' 4 | 5 | export const transformShow: DirectiveTransform = (dir, node, context) => { 6 | const { exp, loc } = dir 7 | if (!exp) { 8 | context.onError( 9 | createDOMCompilerError(DOMErrorCodes.X_V_SHOW_NO_EXPRESSION, loc) 10 | ) 11 | } 12 | 13 | return { 14 | props: [], 15 | needRuntime: context.helper(V_SHOW) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /packages/compiler-dom/src/transforms/vText.ts: -------------------------------------------------------------------------------- 1 | import { 2 | DirectiveTransform, 3 | createObjectProperty, 4 | createSimpleExpression, 5 | TO_DISPLAY_STRING, 6 | createCallExpression 7 | } from '@vue/compiler-core' 8 | import { createDOMCompilerError, DOMErrorCodes } from '../errors' 9 | 10 | export const transformVText: DirectiveTransform = (dir, node, context) => { 11 | const { exp, loc } = dir 12 | if (!exp) { 13 | context.onError( 14 | createDOMCompilerError(DOMErrorCodes.X_V_TEXT_NO_EXPRESSION, loc) 15 | ) 16 | } 17 | if (node.children.length) { 18 | context.onError( 19 | createDOMCompilerError(DOMErrorCodes.X_V_TEXT_WITH_CHILDREN, loc) 20 | ) 21 | node.children.length = 0 22 | } 23 | return { 24 | props: [ 25 | createObjectProperty( 26 | createSimpleExpression(`textContent`, true), 27 | exp 28 | ? createCallExpression( 29 | context.helperString(TO_DISPLAY_STRING), 30 | [exp], 31 | loc 32 | ) 33 | : createSimpleExpression('', true) 34 | ) 35 | ] 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /packages/compiler-dom/src/transforms/warnTransitionChildren.ts: -------------------------------------------------------------------------------- 1 | import { 2 | NodeTransform, 3 | NodeTypes, 4 | ElementTypes, 5 | ComponentNode, 6 | IfBranchNode 7 | } from '@vue/compiler-core' 8 | import { TRANSITION } from '../runtimeHelpers' 9 | import { createDOMCompilerError, DOMErrorCodes } from '../errors' 10 | 11 | export const warnTransitionChildren: NodeTransform = (node, context) => { 12 | if ( 13 | node.type === NodeTypes.ELEMENT && 14 | node.tagType === ElementTypes.COMPONENT 15 | ) { 16 | const component = context.isBuiltInComponent(node.tag) 17 | if (component === TRANSITION) { 18 | return () => { 19 | if (node.children.length && hasMultipleChildren(node)) { 20 | context.onError( 21 | createDOMCompilerError( 22 | DOMErrorCodes.X_TRANSITION_INVALID_CHILDREN, 23 | { 24 | start: node.children[0].loc.start, 25 | end: node.children[node.children.length - 1].loc.end, 26 | source: '' 27 | } 28 | ) 29 | ) 30 | } 31 | } 32 | } 33 | } 34 | } 35 | 36 | function hasMultipleChildren(node: ComponentNode | IfBranchNode): boolean { 37 | // #1352 filter out potential comment nodes. 38 | const children = (node.children = node.children.filter( 39 | c => 40 | c.type !== NodeTypes.COMMENT && 41 | !(c.type === NodeTypes.TEXT && !c.content.trim()) 42 | )) 43 | const child = children[0] 44 | return ( 45 | children.length !== 1 || 46 | child.type === NodeTypes.FOR || 47 | (child.type === NodeTypes.IF && child.branches.some(hasMultipleChildren)) 48 | ) 49 | } 50 | -------------------------------------------------------------------------------- /packages/compiler-sfc/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2018-present, Yuxi (Evan) You 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /packages/compiler-sfc/__tests__/__snapshots__/compileTemplate.spec.ts.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`source map 1`] = ` 4 | Object { 5 | "mappings": ";;;wBACE,oBAA8B;IAAzB,oBAAmB,4BAAbA,WAAM", 6 | "names": Array [ 7 | "render", 8 | ], 9 | "sources": Array [ 10 | "example.vue", 11 | ], 12 | "sourcesContent": Array [ 13 | " 14 |

{{ render }}

15 | ", 16 | ], 17 | "version": 3, 18 | } 19 | `; 20 | 21 | exports[`template errors 1`] = ` 22 | Array [ 23 | [SyntaxError: Error parsing JavaScript expression: Unexpected token (1:3)], 24 | [SyntaxError: v-bind is missing expression.], 25 | [SyntaxError: v-model can only be used on , 7 |
8 |
9 | 10 | 27 | 28 | 63 | -------------------------------------------------------------------------------- /packages/vue/examples/composition/markdown.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 | 7 |
8 |
9 | 10 | 27 | 28 | 63 | -------------------------------------------------------------------------------- /packages/vue/index.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | if (process.env.NODE_ENV === 'production') { 4 | module.exports = require('./dist/vue.cjs.prod.js') 5 | } else { 6 | module.exports = require('./dist/vue.cjs.js') 7 | } 8 | -------------------------------------------------------------------------------- /packages/vue/index.mjs: -------------------------------------------------------------------------------- 1 | export * from './index.js' -------------------------------------------------------------------------------- /packages/vue/macros-global.d.ts: -------------------------------------------------------------------------------- 1 | import { 2 | $ as _$, 3 | $$ as _$$, 4 | $ref as _$ref, 5 | $shallowRef as _$shallowRef, 6 | $computed as _$computed, 7 | $customRef as _$customRef, 8 | $toRef as _$toRef 9 | } from './macros' 10 | 11 | declare global { 12 | const $: typeof _$ 13 | const $$: typeof _$$ 14 | const $ref: typeof _$ref 15 | const $shallowRef: typeof _$shallowRef 16 | const $computed: typeof _$computed 17 | const $customRef: typeof _$customRef 18 | const $toRef: typeof _$toRef 19 | } 20 | -------------------------------------------------------------------------------- /packages/vue/ref-macros.d.ts: -------------------------------------------------------------------------------- 1 | // TODO deprecated file - to be removed when out of experimental 2 | import './macros-global' 3 | -------------------------------------------------------------------------------- /packages/vue/server-renderer/index.d.ts: -------------------------------------------------------------------------------- 1 | export * from '@vue/server-renderer' 2 | -------------------------------------------------------------------------------- /packages/vue/server-renderer/index.js: -------------------------------------------------------------------------------- 1 | module.exports = require('@vue/server-renderer') 2 | -------------------------------------------------------------------------------- /packages/vue/server-renderer/index.mjs: -------------------------------------------------------------------------------- 1 | export * from '@vue/server-renderer' -------------------------------------------------------------------------------- /packages/vue/server-renderer/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "main": "index.js", 3 | "module": "index.mjs", 4 | "types": "index.d.ts" 5 | } -------------------------------------------------------------------------------- /packages/vue/src/dev.ts: -------------------------------------------------------------------------------- 1 | import { initCustomFormatter } from '@vue/runtime-dom' 2 | 3 | export function initDev() { 4 | if (__BROWSER__) { 5 | if (!__ESM_BUNDLER__) { 6 | console.info( 7 | `You are running a development build of Vue.\n` + 8 | `Make sure to use the production build (*.prod.js) when deploying for production.` 9 | ) 10 | } 11 | 12 | initCustomFormatter() 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /packages/vue/src/runtime.ts: -------------------------------------------------------------------------------- 1 | // This entry exports the runtime only, and is built as 2 | // `dist/vue.esm-bundler.js` which is used by default for bundlers. 3 | import { initDev } from './dev' 4 | import { warn } from '@vue/runtime-dom' 5 | 6 | if (__DEV__) { 7 | initDev() 8 | } 9 | 10 | export * from '@vue/runtime-dom' 11 | 12 | export const compile = () => { 13 | if (__DEV__) { 14 | warn( 15 | `Runtime compilation is not supported in this build of Vue.` + 16 | (__ESM_BUNDLER__ 17 | ? ` Configure your bundler to alias "vue" to "vue/dist/vue.esm-bundler.js".` 18 | : __ESM_BROWSER__ 19 | ? ` Use "vue.esm-browser.js" instead.` 20 | : __GLOBAL__ 21 | ? ` Use "vue.global.js" instead.` 22 | : ``) /* should not happen */ 23 | ) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /pnpm-workspace.yaml: -------------------------------------------------------------------------------- 1 | packages: 2 | - 'packages/*' 3 | -------------------------------------------------------------------------------- /scripts/dev.js: -------------------------------------------------------------------------------- 1 | /* 2 | Run Rollup in watch mode for development. 3 | 4 | To specific the package to watch, simply pass its name and the desired build 5 | formats to watch (defaults to "global"): 6 | 7 | ``` 8 | # name supports fuzzy match. will watch all packages with name containing "dom" 9 | nr dev dom 10 | 11 | # specify the format to output 12 | nr dev core --formats cjs 13 | 14 | # Can also drop all __DEV__ blocks with: 15 | __DEV__=false nr dev 16 | ``` 17 | */ 18 | 19 | // 执行命令行工具的库 20 | const execa = require('execa') 21 | const { fuzzyMatchTarget } = require('./utils') 22 | // 获取命令行参数 23 | const args = require('minimist')(process.argv.slice(2)) 24 | // 设置打包目标,默认什么也不传会打包vue 25 | const target = args._.length ? fuzzyMatchTarget(args._)[0] : 'vue' 26 | // 设置打包格式 --formats xxx -f xxx 27 | const formats = args.formats || args.f 28 | // 设置映射文件 --sourcemap -s 29 | const sourceMap = args.sourcemap || args.s 30 | const commit = execa.sync('git', ['rev-parse', 'HEAD']).stdout.slice(0, 7) 31 | 32 | // 执行rollup 33 | execa( 34 | 'rollup', 35 | [ 36 | '-wc', 37 | '--environment', 38 | [ 39 | `COMMIT:${commit}`, 40 | `TARGET:${target}`, 41 | `FORMATS:${formats || 'global'}`, 42 | sourceMap ? `SOURCE_MAP:true` : `` 43 | ] 44 | .filter(Boolean) 45 | .join(',') 46 | ], 47 | { 48 | stdio: 'inherit' 49 | } 50 | ) 51 | -------------------------------------------------------------------------------- /scripts/filter-e2e.js: -------------------------------------------------------------------------------- 1 | const e2eTests = ['/Transition', '/TransitionGroup', '/examples/'] 2 | 3 | module.exports = list => { 4 | return { 5 | filtered: list 6 | .filter(t => e2eTests.some(tt => t.includes(tt))) 7 | .map(test => ({ test })) 8 | } 9 | } 10 | 11 | module.exports.e2eTests = e2eTests 12 | -------------------------------------------------------------------------------- /scripts/filter-unit.js: -------------------------------------------------------------------------------- 1 | const { e2eTests } = require('./filter-e2e') 2 | 3 | module.exports = list => { 4 | return { 5 | filtered: list 6 | .filter(t => !e2eTests.some(tt => t.includes(tt))) 7 | .map(test => ({ test })) 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /scripts/preinstall.js: -------------------------------------------------------------------------------- 1 | if (!/pnpm/.test(process.env.npm_execpath || '')) { 2 | console.warn( 3 | `\u001b[33mThis repository requires using pnpm as the package manager ` + 4 | ` for scripts to work properly.\u001b[39m\n` 5 | ) 6 | process.exit(1) 7 | } 8 | -------------------------------------------------------------------------------- /scripts/utils.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs') 2 | const chalk = require('chalk') 3 | 4 | const targets = (exports.targets = fs.readdirSync('packages').filter(f => { 5 | if (!fs.statSync(`packages/${f}`).isDirectory()) { 6 | return false 7 | } 8 | const pkg = require(`../packages/${f}/package.json`) 9 | if (pkg.private && !pkg.buildOptions) { 10 | return false 11 | } 12 | return true 13 | })) 14 | 15 | exports.fuzzyMatchTarget = (partialTargets, includeAllMatching) => { 16 | const matched = [] 17 | partialTargets.forEach(partialTarget => { 18 | for (const target of targets) { 19 | if (target.match(partialTarget)) { 20 | matched.push(target) 21 | if (!includeAllMatching) { 22 | break 23 | } 24 | } 25 | } 26 | }) 27 | if (matched.length) { 28 | return matched 29 | } else { 30 | console.log() 31 | console.error( 32 | ` ${chalk.bgRed.white(' ERROR ')} ${chalk.red( 33 | `Target ${chalk.underline(partialTargets)} not found!` 34 | )}` 35 | ) 36 | console.log() 37 | 38 | process.exit(1) 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /scripts/verifyCommit.js: -------------------------------------------------------------------------------- 1 | // Invoked on the commit-msg git hook by yorkie. 2 | 3 | const chalk = require('chalk') 4 | const msgPath = process.env.GIT_PARAMS 5 | const msg = require('fs') 6 | .readFileSync(msgPath, 'utf-8') 7 | .trim() 8 | 9 | const commitRE = /^(revert: )?(feat|fix|docs|dx|style|refactor|perf|test|workflow|build|ci|chore|types|wip|release)(\(.+\))?: .{1,50}/ 10 | 11 | if (!commitRE.test(msg)) { 12 | console.log() 13 | console.error( 14 | ` ${chalk.bgRed.white(' ERROR ')} ${chalk.red( 15 | `invalid commit message format.` 16 | )}\n\n` + 17 | chalk.red( 18 | ` Proper commit message format is required for automated changelog generation. Examples:\n\n` 19 | ) + 20 | ` ${chalk.green(`feat(compiler): add 'comments' option`)}\n` + 21 | ` ${chalk.green( 22 | `fix(v-model): handle events on blur (close #28)` 23 | )}\n\n` + 24 | chalk.red(` See .github/commit-convention.md for more details.\n`) 25 | ) 26 | process.exit(1) 27 | } 28 | -------------------------------------------------------------------------------- /test-dts/README.md: -------------------------------------------------------------------------------- 1 | # Test-ts 2 | 3 | Tests Typescript types to ensure the types remain as expected. 4 | 5 | ## Configuration 6 | 7 | ### tsconfig.json 8 | 9 | Config used to test against the package source 10 | 11 | ### tsconfig.build.json 12 | 13 | Replaces the `vue` and `@vue/*` dependencies with the built Typescript to ensure the published types are correct. 14 | -------------------------------------------------------------------------------- /test-dts/componentTypeExtensions.test-d.tsx: -------------------------------------------------------------------------------- 1 | import { defineComponent, expectError, expectType } from './index' 2 | 3 | declare module '@vue/runtime-core' { 4 | interface ComponentCustomOptions { 5 | test?(n: number): void 6 | } 7 | 8 | interface ComponentCustomProperties { 9 | state: 'stopped' | 'running' 10 | } 11 | 12 | interface ComponentCustomProps { 13 | custom?: number 14 | } 15 | } 16 | 17 | export const Custom = defineComponent({ 18 | props: { 19 | bar: String, 20 | baz: { 21 | type: Number, 22 | required: true 23 | } 24 | }, 25 | 26 | data: () => ({ counter: 0 }), 27 | 28 | test(n) { 29 | expectType(n) 30 | }, 31 | 32 | methods: { 33 | aMethod() { 34 | // @ts-expect-error 35 | expectError(this.notExisting) 36 | this.counter++ 37 | this.state = 'running' 38 | // @ts-expect-error 39 | expectError((this.state = 'not valid')) 40 | } 41 | } 42 | }) 43 | 44 | expectType() 45 | expectType() 46 | expectType() 47 | 48 | // @ts-expect-error 49 | expectType() 50 | // @ts-expect-error 51 | expectError() 52 | // @ts-expect-error 53 | expectError() 54 | // @ts-expect-error 55 | expectError() 56 | // @ts-expect-error 57 | expectError() 58 | -------------------------------------------------------------------------------- /test-dts/functionalComponent.test-d.tsx: -------------------------------------------------------------------------------- 1 | import { 2 | h, 3 | Text, 4 | FunctionalComponent, 5 | expectError, 6 | expectType, 7 | Component 8 | } from './index' 9 | 10 | // simple function signature 11 | const Foo = (props: { foo: number }) => h(Text, null, props.foo) 12 | 13 | // TSX 14 | expectType() 15 | expectType() 16 | expectType() 17 | // @ts-expect-error 18 | expectError() 19 | // @ts-expect-error 20 | expectError() 21 | // @ts-expect-error 22 | expectError() 23 | 24 | // Explicit signature with props + emits 25 | const Bar: FunctionalComponent< 26 | { foo: number }, 27 | { update: (value: number) => void } 28 | > = (props, { emit }) => { 29 | expectType(props.foo) 30 | 31 | emit('update', 123) 32 | // @ts-expect-error 33 | expectError(emit('nope')) 34 | // @ts-expect-error 35 | expectError(emit('update')) 36 | // @ts-expect-error 37 | expectError(emit('update', 'nope')) 38 | } 39 | 40 | // assigning runtime options 41 | Bar.props = { 42 | foo: Number 43 | } 44 | // @ts-expect-error 45 | expectError((Bar.props = { foo: String })) 46 | 47 | Bar.emits = { 48 | update: value => value > 1 49 | } 50 | // @ts-expect-error 51 | expectError((Bar.emits = { baz: () => void 0 })) 52 | 53 | // TSX 54 | expectType() 55 | // @ts-expect-error 56 | expectError() 57 | // @ts-expect-error 58 | expectError() 59 | // @ts-expect-error 60 | expectError() 61 | 62 | const Baz: FunctionalComponent<{}, string[]> = (props, { emit }) => { 63 | expectType<{}>(props) 64 | expectType<(event: string) => void>(emit) 65 | } 66 | 67 | expectType(Baz) 68 | 69 | const Qux: FunctionalComponent<{}, ['foo', 'bar']> = (props, { emit }) => { 70 | emit('foo') 71 | emit('foo', 1, 2) 72 | emit('bar') 73 | emit('bar', 1, 2) 74 | } 75 | 76 | expectType(Qux) 77 | -------------------------------------------------------------------------------- /test-dts/index.d.ts: -------------------------------------------------------------------------------- 1 | // This directory contains a number of d.ts assertions 2 | // use \@ts-expect-error where errors are expected. 3 | 4 | export * from '@vue/runtime-dom' 5 | 6 | export function describe(_name: string, _fn: () => void): void 7 | 8 | export function expectType(value: T): void 9 | export function expectError(value: T): void 10 | export function expectAssignable(value: T2): void 11 | 12 | export type IsUnion = (T extends any 13 | ? (U extends T ? false : true) 14 | : never) extends false 15 | ? false 16 | : true 17 | 18 | export type IsAny = 0 extends (1 & T) ? true : false 19 | -------------------------------------------------------------------------------- /test-dts/inject.test-d.ts: -------------------------------------------------------------------------------- 1 | import { provide, inject, InjectionKey, expectType } from './index' 2 | 3 | const key: InjectionKey = Symbol() 4 | 5 | provide(key, 1) 6 | // @ts-expect-error 7 | provide(key, 'foo') 8 | 9 | expectType(inject(key)) 10 | expectType(inject(key, 1)) 11 | expectType(inject(key, () => 1, true /* treatDefaultAsFactory */)) 12 | 13 | expectType<() => number>(inject('foo', () => 1)) 14 | expectType<() => number>(inject('foo', () => 1, false)) 15 | expectType(inject('foo', () => 1, true)) 16 | -------------------------------------------------------------------------------- /test-dts/reactivity.test-d.ts: -------------------------------------------------------------------------------- 1 | import { ref, readonly, describe, expectError, expectType, Ref } from './index' 2 | 3 | describe('should support DeepReadonly', () => { 4 | const r = readonly({ obj: { k: 'v' } }) 5 | // @ts-expect-error 6 | expectError((r.obj = {})) 7 | // @ts-expect-error 8 | expectError((r.obj.k = 'x')) 9 | }) 10 | 11 | // #4180 12 | describe('readonly ref', () => { 13 | const r = readonly(ref({ count: 1 })) 14 | expectType(r) 15 | }) 16 | -------------------------------------------------------------------------------- /test-dts/tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "noEmit": true, 4 | "jsx": "preserve", 5 | "module": "esnext", 6 | "strict": true, 7 | "moduleResolution": "node", 8 | "lib": ["esnext", "dom"] 9 | }, 10 | "include": ["./*"] 11 | } 12 | -------------------------------------------------------------------------------- /test-dts/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "noEmit": true, 5 | "declaration": true 6 | }, 7 | "exclude": ["../packages/*/__tests__", "../packages/template-explorer"] 8 | } 9 | -------------------------------------------------------------------------------- /test-dts/tsx.test-d.tsx: -------------------------------------------------------------------------------- 1 | // TSX w/ defineComponent is tested in defineComponent.test-d.tsx 2 | import { 3 | KeepAlive, 4 | Suspense, 5 | Fragment, 6 | Teleport, 7 | expectError, 8 | expectType, 9 | VNode 10 | } from './index' 11 | 12 | expectType(
) 13 | expectType(
) 14 | expectType(
) 15 | expectType() 16 | 17 | // @ts-expect-error style css property validation 18 | expectError(
) 19 | 20 | // allow array styles and nested array styles 21 | expectType(
) 22 | expectType( 23 |
24 | ) 25 | 26 | // @ts-expect-error unknown prop 27 | expectError(
) 28 | 29 | // allow key/ref on arbitrary element 30 | expectType(
) 31 | expectType(
) 32 | 33 | expectType( 34 | { 36 | // infer correct event type 37 | expectType(e.target) 38 | }} 39 | /> 40 | ) 41 | 42 | // built-in types 43 | expectType() 44 | expectType() 45 | 46 | expectType() 47 | expectType() 48 | 49 | // @ts-expect-error 50 | expectError() 51 | // @ts-expect-error 52 | expectError() 53 | 54 | // KeepAlive 55 | expectType() 56 | expectType() 57 | // @ts-expect-error 58 | expectError() 59 | 60 | // Suspense 61 | expectType() 62 | expectType() 63 | expectType( 64 | {}} onFallback={() => {}} onPending={() => {}} /> 65 | ) 66 | // @ts-expect-error 67 | expectError() 68 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": ".", 4 | "outDir": "dist", 5 | "sourceMap": false, 6 | "target": "es2016", 7 | "useDefineForClassFields": false, 8 | "module": "esnext", 9 | "moduleResolution": "node", 10 | "allowJs": false, 11 | "strict": true, 12 | "noUnusedLocals": true, 13 | "experimentalDecorators": true, 14 | "resolveJsonModule": true, 15 | "esModuleInterop": true, 16 | "removeComments": false, 17 | "jsx": "preserve", 18 | "lib": ["esnext", "dom"], 19 | "types": ["jest", "puppeteer", "node"], 20 | "rootDir": ".", 21 | "paths": { 22 | "@vue/compat": ["packages/vue-compat/src"], 23 | "@vue/*": ["packages/*/src"], 24 | "vue": ["packages/vue/src"] 25 | } 26 | }, 27 | "include": [ 28 | "packages/global.d.ts", 29 | "packages/*/src", 30 | "packages/runtime-dom/types/jsx.d.ts", 31 | "packages/*/__tests__", 32 | "test-dts" 33 | ] 34 | } 35 | --------------------------------------------------------------------------------