在浏览器支持 ES 模块之前,开发者没有以模块化的方式开发 JavaScript 的原生机制。这也是 “打包” 这个概念出现的原因:使用工具抓取、处理和链接我们的源码模块到文件中,使其可以运行在浏览器中。
时过境迁,我们见证了许多诸如 webpack、Rollup 和 Parcel 等工具的诞生,这些工具极大地改善了前端开发者的开发体验。
然而,当我们开始构建越来越大型的应用时,需要处理的 JavaScript 代码量也呈指数级增长。大型项目包含数千个模块的情况并不少见。我们开始遇到性能瓶颈 —— 使用 JavaScript 开发的工具通常需要很长时间(甚至是几分钟!)才能启动开发服务器,即使使用 HMR,文件修改后的效果也需要几秒钟才能在浏览器中反映出来。如此循环往复,迟钝的反馈会极大地影响开发者的开发效率和幸福感。
Vite 旨在利用生态系统中的新进展解决上述问题:浏览器开始原生支持 ES 模块,越来越多 JavaScript 工具使用编译型语言编写。
Vite 安装如下
npm init @vitejs/app my-vue-app --template vue
# npm 7+, 需要额外的双横线:
npm init @vitejs/app my-vue-app -- --template vue
# yarn
yarn create @vitejs/app my-vue-app --template vue
npm install
npm run dev
打包 配置如下
//config.js
module.exports = {
js: {
hysStatic: "1.6.8",
vue: "3.0.11",
vueRouter: "4.0.6",
weixin: "1.2.0",
gio: "2.1.35"
},
css: {
hysStatic: "1.5.2"
}
}
// .env.production
NODE_ENV=production
VITE_APP_ENV=prod
VITE_APP_STATIC_PATH=https://xx.www.org
// vite.config.js
import { defineConfig, loadEnv } from "vite"
import vue from "@vitejs/plugin-vue"
import html from "vite-plugin-html"
import externalGlobals from "rollup-plugin-external-globals"
const path = require("path")
const {
js: { vue: VueV, vueRouter, weixin, hysStatic: hysStaticJs },
css: { hysStatic: hysStaticCss }
} = require("./config")
export default ({ mode }) => {
const { VITE_APP_STATIC_PATH, VITE_APP_IMG_PATH } = loadEnv(
mode,
process.cwd()
)
console.log(mode, VITE_APP_STATIC_PATH)
let externalObj = {}
let injectScript = `<script crossorigin="anonymous" type="text/javascript" src="${VITE_APP_STATIC_PATH}/h5-static/weixin@${weixin}/index.js"></script>`
if (mode == "develop" || mode == "test" || mode == "release") {
externalObj = {
vue: "Vue",
"vue-router": "VueRouter"
}
injectScript = `
<script crossorigin="anonymous" type="text/javascript" src="${VITE_APP_STATIC_PATH}/h5-static/vue@${VueV}/vue.runtime.prod.js"></script>
<script crossorigin="anonymous" type="text/javascript" src="${VITE_APP_STATIC_PATH}/h5-static/vue-router@${vueRouter}/vue-router.prod.js"></script>
<script crossorigin="anonymous" type="text/javascript" src="${VITE_APP_STATIC_PATH}/h5-static/weixin@${weixin}/index.js"></script>
} else if (mode == "production") {
externalObj = {
vue: "Vue",
"vue-router": "VueRouter",
"@hysfront/static": "hysStatic"
} injectScript = `
<script crossorigin="anonymous" type="text/javascript" src="${VITE_APP_STATIC_PATH}/h5-static/??vue@${VueV}/vue.runtime.prod.js,vue-router@${vueRouter}/vue-router.prod.js,weixin@${weixin}/index.js"></script>
`
}
const injectGio = `<script crossorigin="anonymous" async defer type="text/javascript" src="${VITE_APP_STATIC_PATH}/h5-static/gio@2.1.35/index.js"></script>`
return defineConfig({
plugins: [
vue(),
externalGlobals(externalObj),
html({
inject: {
injectData: {
injectLink: `
<link rel="dns-prefetch" href="${VITE_APP_STATIC_PATH}"/>
<link rel="dns-prefetch" href="${VITE_APP_IMG_PATH}"/>
<link href="${VITE_APP_STATIC_PATH}/h5-static/img/favicon.ico" rel="Shortcut Icon" type="image/x-icon" />
`,
injectScript,
injectGio,
injectCss: `<link rel="stylesheet" type="text/css" href="${VITE_APP_STATIC_PATH}/h5-static/css/hys-static@${hysStaticCss}/index.css"/>`
}
},
minify: true
})
],
base: mode == "production" ? VITE_APP_STATIC_PATH + "/" : "/",
resolve: {
alias: {
"@": path.resolve(__dirname, "src")
}
},
build: {
polyfillDynamicImport: true,
brotliSize: false,
cssCodeSplit: true,
assetsDir: "home-static",
assetsInlineLimit: 10
},
server: {
port: "8080",
proxy: {
"^/api": {
target: "http://api.xxx.com",
changeOrigin: true
}
}
}
})
}