preface

As a front-end developer, you’ve been exposed to packaging tools like WebPack, Rollup, Parcel, and others that have greatly improved the development experience for front-end developers.

However, as we start building larger and larger applications, the amount of JavaScript code we need to process grows exponentially. Large projects with thousands of modules are quite common. We started hitting performance bottlenecks — tools developed in JavaScript often took a long time (even minutes!). To start the development server, even with HMR, it takes a few seconds for the effect of the file changes to be reflected in the browser. Over and over again, slow feedback can have a huge impact on a developer’s productivity and happiness.

Vite is to solve the above problems!

This paper will be divided into two parts:

  • ViteConcept and design ideas
  • Vite vs CRA
  • useVite + ReactThe development ofToDoList

The body of the

ViteConcept and design ideas

Think with questions:

  1. What is packing?

Use tools to grab, process, and concatenate our source code modules into files that can run in a browser.

  1. What are some of the common front-end build packaging tools we’re familiar with? :

Webpack, Rollup, Pracel, gulp

  1. What’s the problem with these traditional packaging tools?
  • Slow service startup: When cold starting the development server, the packager-based startup must first grab and build yoursThe whole applicationBefore the service can be provided.

  • Slow update: Based when the packer starts, it is inefficient to rebuild the entire package. The reason is obvious: because the update speed willIt goes straight down as the application volume increases.
  1. ViteHow to solve the above problems?
  • ViteBy differentiating the modules in the application fromRely on 和 The source codeTwo classes, improved development server startup time.
    • Dependencies: Vite will be usedesbuildPrebuild dependencies.EsbuildWritten in Go, and 10-100 times faster than prepacker-built dependencies written in JavaScript.
    • Source code: usually JSX, CSS or Vue SFC, etc., will often be edited, need to convert, based on routing split.
  • Vite 以 Native ESMWay to provide source code. This essentially lets the browser take over part of the packaging: Vite simply transforms the source code when the browser requests it and makes it available on demand. Code is dynamically imported according to the situation, which is only processed if it is actually used on the current screen.

  • inVite,HMRIs in the nativeESMOn the execution. When you edit a file,ViteYou just need to precisely inactivate the chain between the edited module and its nearest HMR boundary most of the time just the module itself), allowing the HMR to keep up to date quickly regardless of the size of the application.
  • ViteAt the same time useHTTPHeader to speed up the reload of the entire page (again letting the browser do more for us) : requests from the source module are based on304 Not ModifiedNegotiation cache, while dependent module requests pass throughCache-Control: max-age=31536000,immutableThey are strongly cached so that they do not need to be requested again once they are cached.

Finally, Vite consists of two parts:

  • A development service that serves the development environment and usesESM+HMR
  • A set of build instructions for the production environment, usedRolluppackaging

Vite vs CRA

Why don’t you just say yes? How about some statistics to prove it? Then use Vite and create-react-app to build and package, and record the time for comparison:

Create an empty react project with create-react-app:

Start the time

npx create-react-app my-app
cd my-app
npm start
Copy the code

Execute the command above, until the page is opened, stop the timer and record the build time

Create an empty React project using Vite (although Vite is much more written, React support is even better than Vue) :

Use NPM:

$ npm init vite@latest
Copy the code

Using Yarn:

$ yarn create vite
Copy the code

Use the PNPM:

$ pnpm create vite
Copy the code

Start the time

* Vanilla is equivalent to native JS that does not use frames, the others should all be frames, select React and type the following command

  cd vite-react
  yarn
  yarn dev
Copy the code

Execute the above command and stop the timer until the page is opened

Then do the packaging separately, go to package.json, view the packaging command, and execute:

yarn build
Copy the code

Log the time separately and check the size of the packaged products: Vite generated projects, packaged products in the Dist directory, CRA in the build;

Table record comparison:

Vite CRA
Initialization time 48s 1min 17s
Packaging time 3s 11s
Product size 156kb 565kb

Conclusion:

The above is only in the non-business code project test, as the business code level increases, the time comparison will be more obvious.

Now that the data talk is over, that’s a relief.

But we’re going to use some actual code to avoid that.

useVite + ReactThe development ofToDoList

To review how Vite created a React project:

Personal habits, authors use Yarn:

$ yarn create vite
Copy the code

The framework selects React, variant depends on whether TS is enabled for the individual:

These also vary from person to person, depending on the size of the project:

Next up is some general React development;

main.tsx:

import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
import 'antd/dist/antd.css';
import './index.css'

ReactDOM.render(<App />.document.getElementById("root"));

Copy the code

App.tsx:

import { useState } from "react";

import ToDoItem from ".. /components/ToDoItem";
import ToDoContainer from '.. /components/ToDoContainer'
import { TodoItemType } from ".. /constans";

function App() {

  const [todos,setTodos] = useState<TodoItemType[]|[]>([])

  const handleSubmit = (todoItem: any) = >{
    console.log(todoItem)
    setTodos([
      ...todos,
      todoItem
    ])
  }

  const handleOpreta =(todoItem:TodoItemType) = >{
    const newTodos = todos.filter(todo= >todoItem.id ! == todo.id) newTodos.push(todoItem)console.log(newTodos)
    setTodos(newTodos)
  }

  return (
    <div className="todo-app">
      <h2 className="todo-title">Charge list</h2>
      <ToDoItem onSubmit={handleSubmit} />
      <ToDoContainer onOpreta={handleOpreta} todos={todos}/>
    </div>
  );
}

export default App;

Copy the code

/components/ToDoContainer/index.tsx:

import { List, Radio } from "antd";
import { STATUS, TodoItemType } from ".. /.. /constans";
import { CheckOutlined, CloseCircleOutlined } from "@ant-design/icons";
import { useState } from "react";

const ToDoContainer = (props: { todos? : TodoItemType[] |undefined;
  onOpreta: (arg: TodoItemType) => void;
}) = > {
  const { todos = [], onOpreta } = props;
  const [optionsValue, setOptionsValue] = useState(STATUS.IS_CREATE);

  const options = [
    { label: "All".value: ' ' },
    { label: "Agent".value: STATUS.IS_CREATE },
    { label: "Have to do".value: STATUS.IS_DONE },
    { label: "Deleted".value: STATUS.IS_DELETE },
  ];

  const handleChangeRadio = (e: any) = > {
    console.log(e.target.value);
    setOptionsValue(e.target.value);
  };

  const handleOpreta = (opretaType: string, todo: TodoItemType) = > {
    switch (opretaType) {
      case "is-delete": onOpreta && onOpreta({ ... todo,status: STATUS.IS_DELETE,
          });
        break;
      case "is-done": onOpreta && onOpreta({ ... todo,status: STATUS.IS_DONE,
          });
        break;
      default:
        break; }};return (
    <div>
      <Radio.Group
        options={options}
        onChange={handleChangeRadio}
        value={optionsValue}
        optionType="button"
        buttonStyle="solid"
      />
      <List
        className="todo"
        dataSource={todos}
        renderItem={(todo)= >
          optionsValue === todo.status && (
            <List.Item className="todo-list-item-container">
              {todo.content}
              <div>
                <CloseCircleOutlined
                  onClick={()= > handleOpreta("is-delete", todo)}
                />
                <CheckOutlined onClick={()= > handleOpreta("is-done", todo)} />
              </div>
            </List.Item>
          )
        }
      />
    </div>
  );
};

export default ToDoContainer;

Copy the code

/components/ToDoItem/index.tsx:

import { Button, Input } from "antd";
import { useState } from "react";
import { STATUS } from ".. /.. /constans";

const ToDoItem = (props: { onSubmit: (todoItem: any) = >void }) = > {
  const { onSubmit } = props;
  const [todoItem, setToDoItem] = useState({
    id: Math.random(),
    content: "".status: STATUS.IS_CREATE,
  });

  const handleSubmit = (e: any) = >{ onSubmit && onSubmit({ ... todoItem,id: Math.random() });
  };

  const handleInpurChange = (e: any) = >{ setToDoItem({ ... todoItem,content: e.target.value,
    });
  };

  return (
    <div className="todo-item-input">
      <Input
        value={todoItem.content}
        onPressEnter={handleSubmit}
        onChange={handleInpurChange}
      />
      <Button size="large" type="primary" onClick={handleSubmit}>submit</Button>
    </div>
  );
};

export default ToDoItem;

Copy the code

/constans/index.ts:

export interface TodoItemType{
    id:number.content:string.status:number
}

export const STATUS = {
    /** * all */
    
    /** * agent */
    IS_CREATE:0./** ** resolved */
    IS_DONE:1./** * delete */
    IS_DELETE:2
}
Copy the code

The code is not perfect, you can improve on me. We recommend a free online deployment site: app.netlify.com/. You can log on to github directly

Execute the package command:

yarn build
Copy the code

The domain name will appear in this position:

conclusion

That’s all about Vite quick start, welcome to the big guys.

The weather turns cool, we drink more hot water, pay more attention to warm rest.