Overview
为什么选Vite: https://cn.vite.dev/guide/why.html
esbuild, Rollup: https://cn.vite.dev/guide/why.html#why-bundle-for-production
Quick start
1. Start a new project
pnpm init
2. installl Vite, Typescript
pnpm add vite typescript -D
3. create index.html under root directory
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><div id="app"></div>
</body>
<script type="module" src="./src/index.ts"></script>
</html>
4. Create src/index.ts, src/counter.ts
// index.ts
import { setupCounter } from "./counter";document.querySelector('#app')!.innerHTML = `<div><button id="counter" type="button"></button></div>
`;
setupCounter(document.querySelector('#counter') as HTMLButtonElement);// counter.ts
export function setupCounter(element: HTMLButtonElement) { let counter = 0;const setCounter = (count: number) => { counter = count;element.innerHTML = `Counter: ${counter}`;}setCounter(0);element.addEventListener('click', () => setCounter(counter + 1));
}
5. Update package.json
"scripts": {"dev":"vite","build":"vite build","preview":"vite preview"},"type": "module",
6. Run pnpm run dev
Then a web applicaiton should be start.
默认配置和一些常识问题
1. Create tsconfig.json
Recommend to include following options, see from https://cn.vite.dev/guide/features.html#typescript-compiler-options
{"compilerOptions": {"target": "ES2020","module": "ESNext","lib": ["DOM", "DOM.Iterable", "ESNext"],"isolatedModules":true,"useDefineForClassFields":true,"skipLibCheck": true,"moduleResolution": "Bundler","esModuleInterop": true,"allowSyntheticDefaultImports": true,"resolveJsonModule": true,"noEmit": true,"allowImportingTsExtensions": true},"include": ["src","vite.config.ts"]
}
2. Create vite.config.ts
Tell the port and open the browser
import { defineConfig, ConfigEnv, UserConfig} from 'vite'export default defineConfig(({command, mode}: ConfigEnv):UserConfig => { console.log(command); console.log(mode); // development, production, useful when you want to run different code based on the commandreturn {server: {port: 3000,open: true, // open the browser (true), or you can tell which html should be the entry, e.g. index1.html}}
})
3. ts声明问题
for example added following code in vite.config.ts
// ...
import path from "path"// ...
Typescript complain that Cannot find module 'path' or its corresponding type declarations.
This is due to it is running in node.env
Run: pnpm add @types/node -D
will resolve the issue
4. node环境ESM问题
without type: "module"
in package.json, if we run node src/test1.js
will throw SyntaxError: Cannot use import statement outside a module
// test1.js
import test2 from "./test2";
test2();//test2.js
export default function test2() { console.log('test2');
}
"type: module": is to resolve this issue.
5. 文件执行环境问题 & 路径查找问题
But running node test1.js
again, you will see Did you mean to import "./test2.js"?
If we change
import { defineConfig, ConfigEnv, UserConfig} from 'vite'
node will help to complete the file path for the module, here we say vite
, node will find it in node_module automatically.
It only happens in node env, not in browser env. In Browser env, you have to give the fulll path.
Add lodash-es, the update test1.js as following:
import { debounce } from "lodash-es" //bare import ESM默认不支持
import test2 from "./test2.js";test2();
debounce(() => console.log("hello"), 1000)();
Then run: node src/test1.js, it works as expect; but if you run it in browser, it throw error:
Uncaught TypeError: Failed to resolve module specifier "lodash-es". Relative references must start with either "/", "./", or "../".
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document index1.html</title>
</head>
<body><div id="app"></div>
</body>
<script type="module" src="./src/test1.js"></script>
</html>
Give the full path then it works in browser env.
// import { debounce } from "lodash-es" //bare import ESM默认不支持
import debounce from '../node_modules/lodash-es/debounce.js'; // 从node_modules中引入
// ...
Code: https://gitee.com/dev-edu/vite/tree/main/03.%E9%BB%98%E8%AE%A4%E9%85%8D%E7%BD%AE%E5%92%8C%E4%B8%80%E4%BA%9B%E5%B8%B8%E8%AF%86%E9%97%AE%E9%A2%98/vite-demo