Migrate from create react app to vite

Time:2022-1-14

With the release of vue3, we have brought a new packaging tool vite. As a member of the front end, we naturally have to experience it. Because react is often used in work, projects are basically created throughcreate-react-app(CRA). So how do I migrate to vite when I create a react project through CRA? The following will show you how to migrate a react project from CRA to vite:

Initial settings

Open a react project created through CRA

First install vite:

// npm
npm install vite

// yarn
yarn add vite

Then update NPM scripts:

"scripts": {
-    "start": "react-scripts start",
-    "build": "react-scripts build",
+    "start": "vite",
+    "build": "vite build",
     "test": "react-scripts test",

Next, it needs to be modifiedpublic/index.htmlThe reason is stated in the official document

take./publicDirectoryindex.htmlMove to the root directory, add a script tag, and Src points to the entry file. If there is any%PUBLIC_URL%/, change it to/。 The reason is stated in the official document above. Here are my changes

diff --git a/public/index.html b/index.html
similarity index 88%
rename from public/index.html
rename to index.html
index aa069f2..dd43c8b 100644
--- a/public/index.html
+++ b/index.html
@@ -2,19 +2,19 @@
 <html lang="en">
   <head>
     <meta charset="utf-8" />
-    <link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
+    <link rel="icon" href="/favicon.ico" />
     <meta name="viewport" content="width=device-width, initial-scale=1" />
     <meta name="theme-color" content="#000000" />
     <meta
       name="description"
       content="Web site created using create-react-app"
     />
-    <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
+    <link rel="apple-touch-icon" href="/logo192.png" />
     <!--
       manifest.json provides metadata used when your web app is installed on a
       user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
     -->
-    <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
+    <link rel="manifest" href="/manifest.json" />
     <!--
       Notice the use of %PUBLIC_URL% in the tags above.
       It will be replaced with the URL of the `public` folder during the build.
@@ -29,6 +29,7 @@
   <body>
     <noscript>You need to enable JavaScript to run this app.</noscript>
     <div id="root"></div>
+    <script type="module"></script>
     <!--
       This HTML file is a template.
       If you open it directly in the browser, you will see an empty page.

Typescript support

So far, my project has not been able to run. Mainly vite doesn’t understandtsconfig.jsoninincludeProperty is imported using an absolute path. The solution is to install avite-tsconfig-pathsTo support the path mapping of typescript.

// npm
npm install vite-tsconfig-paths

// yarn
yarn add vite-tsconfig-paths

After the installation is complete, add thevite.config.ts

import { defineConfig } from "vite";
import tsConfigPaths from "vite-tsconfig-paths";

export default defineConfig({
  build: {
    outDir: "build"
  },
  plugins: [tsConfigPaths()]
});

Here, our output directory is set tobuildInstead of the defaultdist, in order to be consistent with CRA.

Now our project can run through vite.

Jest support

Because we are ready to remove from the projectreact-scriptsSo we need to figure out how not to passreact-scripts testTo run the jest test.

We need to rely onts-jest, add dependency

// npm
npm install ts-jest

// yarn
yarn add ts-jest

Then againjest.config.jsAdd ints-jestPreset:

module.exports = {
  preset: "ts-jest",
  setupFilesAfterEnv: ["<rootDir>src/setupTests.ts"],
  moduleDirectories: ["node_modules", "src"],
  moduleNameMapper: {
    "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/tests/__mocks__/fileMock.js",
    "\\.(css|less|scss|sass)$":"<rootDir>/tests/__mocks__/styleMock.js"
  }
}

Note that the react project can import files such as CSS / PNG, but jest will treat them as JS imports, which will lead to test failure. Therefore, we need to deal with this situation, that ismoduleNameMapperFor what you have done, refer to jest to deal with static resources.

staytests/__mocks__/Add under directoryfileMock.jsandstyleMock.js

// fileMock.js
module.exports="test-file-stub"
// styleMock.js
module.exports = {}

Update package json

"scripts": {
    "start": "vite",
    "build": "vite build",
-   "test": "react-scripts test",
+   "test": "jest",

Close out work

Now that we have built the react project through vite, the dependencies related to CRA can also be removed. I only need to remove react scripts, which actually needs to be determined according to our own project

// npm
npm uninstall react-scripts

// yarn
yarn remove react-scripts

summary

On the whole, we have done some work. In the development environment, it is much faster to start the whole through vite.

It has been explained why vite is used and why vite is selected in the official document.

However, vite is still a very new tool, which means that there are not many solutions, the ecology is not mature enough, and there are many potential pits, etc.

As a learning tool, I think you can choose any tool, but in practical work, you still need to choose more stable and ecologically rich tools.