1, the content is personal translation From Vue 3.0 Beta version of the document in chapter 2, not necessarily accurate, welcome to exchange (others have read hundreds of times, say no one to see) 3, the level is limited, at any time eunuch

· Destructive features of the migration guide from Vue 2 to Vue 3 (I, Global API)

Global API Treeshaking

2. X syntax

If you’ve ever needed to manually manipulate the DOM in a Vue, you’ve probably seen the following pattern:

import Vue from 'vue'

Vue.nextTick(() = > {
  // DOM related operations
})
Copy the code

Or when you’re unit testing an asynchronous component, you might have written something like this:

import { shallowMount } from '@vue/test-utils'
import { MyComponent } from './MyComponent.vue'

test('an async feature'.async() = > {const wrapper = shallowMount(MyComponent)

  // Perform some DOM related tasks

  await wrapper.vm.$nextTick()

  // Run your assertion
})
Copy the code

Vue.nexttick () is a global API that is exposed directly from the Vue object, but $nextTick() is simply a wrapper around vue.nexttick () that binds the this callback to the current instance for convenience.

But if you never need to manipulate the DOM manually, or you don’t need to use or test asynchronous components in your application, or for some reason you prefer to use the old window.setTimeout() to handle problems, The associated source code for nextTick() becomes “dead code,” code that is written but never used. This kind of useless code is really not a good thing, especially in a client-side environment where space costs money.

Packaging tools like Webpack support tree-shaking (the term for streamlining useless code). Unfortunately, global apis like vue.nexttick () are not tree-shaking because of the way they were written in Vue. Ultimately, packaged code will include these apis, whether you use them or not.

3. X syntax

In Vue 3, we refactored the global and internal apis with tree-shaking in mind. As a result, the global apis now require named references via native ES Module references. The above code fragment needs to be rewritten like this:

import { nextTick } from 'vue'

nextTick(() = > {
  // DOM related operations
})
Copy the code

and

import { shallowMount } from '@vue/test-utils'
import { MyComponent } from './MyComponent.vue'
import { nextTick } from 'vue'

test('an async feature'.async() = > {const wrapper = shallowMount(MyComponent)

  // Perform some DOM related tasks

  await nextTick()

  // Run your assertion
})
Copy the code

Vue.nexttick () : undefined is not a function

With this change, unused global apis in Vue applications are streamlined for optimal file sizes when packaged using tree-shaking enabled packaging tools.

Affected apis

The following global apis in Vue 2.x are affected by this change:

  • Vue.nextTick
  • Vue.observable(beVue.reactiveReplaced)
  • Vue.version
  • Vue.compile(Available in full version only)
  • Vue.set(Compatible version only)
  • Vue.delete(Compatible version only)

Built-in tools

In addition to the public API, many built-in components and tools now have named exports as well, allowing the compiler to output code only when the imported methods are used. For example, take the following template:

<transition>
  <div v-show="ok">hello</div>
</transition>
Copy the code

The above code will compile like this:

import { h, Transition, withDirectives, vShow } from 'vue'

export function render() {
  return h(Transition, [withDirectives(h('div'.'hello'), [[vShow, this.ok]])])
}
Copy the code

This means that the Transition component is imported only when the application actually uses it. In other words, if the application does not use the
component, then the final package will have no code related to this method.

With global tree-shaking, users only “pay” for the methods they actually use. Even better, we know that these optional features won’t add any extra bulk to the package if we don’t use them, so we don’t have to worry about the size of the frame in the future.

important

The above changes only apply to versions of ES Modules built with a packaging tool that supports tree-shaking, That is, the version UMD builds will still contain all of these methods, while exposing Vue’s global variable environment (and the compiler will generate the appropriate output so that these apis can be accessed in the global environment rather than imported).

Usage in plug-ins

If your plugin relies on the global API in Vue 2.x, for example:

const plugin = {
  install: Vue= > {
    Vue.nextTick(() = > {
      // ...}}})Copy the code

In Vue 3 you have to explicitly import these things manually:

import { nextTick } from 'vue'

const plugin = {
  install: app= > {
    nextTick(() = > {
      // ...}}})Copy the code

If you use a packaging tool like Webpack, it may package the Vue source code into your plugin, which is usually not something you want to see. A common way to avoid this is to configure the packaging tool to exclude Vue from the packaging results. Like webpack, you can configure externals:

// webpack.config.js
module.exports = {
  / *... * /
  externals: {
    vue: 'Vue'}}Copy the code

This configuration tells WebPack to treat Vue as an external library and not package it together.

If your package of choice happens to be Rollup, you can get the same effect with little extra work. By default, Rollup will treat modules with a certain ID (we used ‘vue’) as external dependencies and will not include them in the final package. Treating vue as external dependency may trigger a warning during compilation: “Treating vue as external dependency”

// rollup.config.js
export default {
  / *... * /
  external: ['vue']}Copy the code