Vuejs design and implementation

Chapter two, the design elements of the framework core

2.1 Improve user development experience

2.1.1 Good error message

  • A good framework is measured by its development experience.
  • When we create a Vuejs application and try to mount it to a non-existentDOMNode, you will receive an error message.[Vue warn]: Failed to mount app: mount target selector '#not exit' returned null.This message tells us why the mount failed: Vuejs is based on the selector we providedThe DOM of the response could not be foundElement (returns null). So that we can quickly locate the problem.

2.1.2 Good console use

  • When using vue3’s ref variable, we can see in the console that the console content is a proxy variable.
  • And to see the value visually, we can open it upChromeDeveloper tools checkConsole => Enable custom formatters, so you can see more intuitive output.

2.2 Control the volume of framework code

2.2.1 through__DEV__To control packaging errors

  • Rollup to the project build, pass__DEV__Constant for plugin-like configuration. (It functions like the DefinePlugin plugin in WebPack.)
  • The Vuejs build is used forWhen developing the resources of the environment,__DEV__constant-settrue, the above output warning message is equivalent to:
if(true && !res){
  warn(
  	`Failed to mount app: mount target selector ${container} returned null`)}Copy the code
  • When Vuejs builds resources for a production environment, it puts__DEV__Constant set tofalse, the above code output warning message is equivalent to
if(false && !res){
  warn(
  	`Failed to mount app: mount target selector "${container} returned null}"`)}Copy the code

As you can see above, if the __DEV__ constant is replaced with false, this code will never run and will be removed when building the resource.

2.3 Frameworks should be tree-shaking well

  • Concept: tree-shaking is eliminating code that will never execute.
  • In rollup tree-shaking, code that is not executed does not appear in the package.
  • Side effects concept: If a function call has side effects, it cannot be removed. What are side effects? The side effect is that when a function is called, it has external effects, such as modifying global variables.
  • When you tell Rollup to pack, rest assured, this code will have no side effects and you can remove it. Add comments/*#__PURE__*/Note that rollup.js is also told that a call to a function has no side effects.

2.4 What build artifacts should the framework produce

  • First we want users to be able to use it directly in HTML pages<script>Vuejs, in which case you need to output a resource called IIFE format.
  • By modifying thepackage.jsonIn themoduleTo control the resource instead of the main field pointing toPriority of resources.
  • with-browserThe words ESM resources are given directly<script type='module'>The use of. then-browserand-bundlerThe difference is when the build is used for<script>Tag resources when. If it is a development environment__DEV__Set totrue. The production environment, then__DEV__Constant set tofalse, thus can beThe Tree - Shaking removed.
  • But we can’t just take it__DEV__Set to true or false, usually required(process.env.NODE_ENV ! == 'production')replace__DEV__ constantsIn order to enable users to determine the target environment for building resources in the WebPack configuration.
  • Server-side rendering, we will supportrequire()Introduction,rolluppackagedformatChanged to ‘CJS’

2.5 Feature Switch

  • We can take advantage of features that the user has turned offThree-ShakingThe mechanism keeps it out of the final resource.
  • This mechanism brings flexibility to the framework design, allowing new features to be added to the framework through feature switches without worrying about resource volume. Also, when the framework is upgraded, we can support legacy apis through feature switches so that new users can choose not to use legacy apis, minimizing the amount of resources that end up packaged.
  • in__VUE_OPTIONS_API__Is a property switch that allows the user to pre-define the value of a constant to control whether the following code is required:
// Users can do this using webpack.definePlugin
/ / webpack DefinePlugin configuration

new webpack.DefinePlugin({
  __VUE_OPTIONS_API__: JSON.stringify(true) // Enable features
})

// Then the user can choose whether to enable __VUE_OPTIONS_API
Copy the code

2.6 Error Handling

  • Error handling is an important part of the framework development process. The quality of the framework’s error handling mechanism directly determines the robustness of the user application, and also determines the mental burden of the user’s error development.

  • In the Vue3 framework, the registerErrorHandler function is provided, which the user can use to register an error handler and then pass the error to the user registered error handler after catching it inside the callWithErrorHandling function.

import utils from 'utils.js'
// Register the error handler
utils.registerErrorHandler((e) = > {
  console.log(e)
})

utils.foo(() = > {/ *... * /})
utils.bar(() = > {/ *... * /})
Copy the code
  • In the Vue3 source code, you can search for itcallWithErrorHandlingFunction. Alternatively, we can register uniform error handlers:
import App from 'App.vue'
const app = create(app)
app.config.errorHandler = () = > {
  // Error handler
}
Copy the code

2.7 Good TypeScript type support

  • The TS (JS) superset introduced in Vue3 to regulate the entire type system of a project.
function foo(val:any){
  return val
}
Copy the code
  • The above code simply returns the return argument, which can be of any type, but the return value of the function is of type TS, which cannot be deduced. So we need to change the code:
function foo<T extends any> (value: T) :T {
  return val
}
Copy the code
  • According to the code modification, we can pass T generic to let TS help us deduce the type of return result of the function.
  • It is not easy to complete the types of TS, check out the Vuejs source coderuntime-core/src/apiDefineComponent.tsFile. There are only three lines of code in this file that actually runs in the browser.

END

Personal blog summary address: github.com/codehzy/blo…