vite本身不直接注入脚本,而是通过vite-plugin-html在构建时静态注入、import()在运行时动态加载、vite-plugin-monkey工程化打包userscript三种方式支持安全高效的动态脚本注入。

Vite 本身不直接“注入脚本”到页面运行时,它是一个构建工具和开发服务器,动态脚本注入是开发者根据场景主动实现的行为。Vite 的作用是安全、高效地支持这类注入逻辑的开发与构建,尤其在生产环境能保障路径正确、代码分割、类型安全和条件控制。
下面从实际落地角度说明 Vite 是如何配合完成动态脚本注入构建的:
动态注入脚本的常见场景
- 在 HTML 模板中按环境插入分析脚本(如 GA、埋点)
- 权限路由驱动的组件按需加载
- 第三方 SDK(如地图、支付)延迟加载或条件加载
- 用户脚本(Userscript)工程化开发(如油猴插件)
构建阶段:用 vite-plugin-html 注入变量与脚本
适合在 index.html 中静态决定是否插入某段 <script></script>,比如只在生产环境加监控脚本:
-
安装插件:
npm install vite-plugin-html --save-dev
-
配置
vite.config.js:import { defineConfig } from 'vite' import { createHtmlPlugin } from 'vite-plugin-html' export default defineConfig({ plugins: [ createHtmlPlugin({ inject: { data: { isProd: process.env.NODE_ENV === 'production', cdnUrl: process.env.CDN_URL || '' } } }) ] }) -
修改
index.html(使用 EJS 语法):<script src="<%=%20cdnUrl%20%>/analytics.js" defer></script>
构建后,Vite 会把 isProd 替换为 true 或 false,HTML 中只保留最终需要的 <script></script> 标签,不会残留判断逻辑。
运行时:用 import() 动态加载模块
这是真正的“动态注入”——脚本在浏览器中按需请求、解析并执行:
-
基础用法(无依赖):
const loadAnalytics = async () => { try { const { init } = await import('./utils/analytics.js') init() } catch (err) { console.warn('Analytics not loaded:', err) } } // 比如在用户进入某页后触发 if (shouldLoadAnalytics()) loadAnalytics() -
加载远程 ES 模块(CDN):
const loadChart = async () => { const Chart = await import('https://cdn.jsdelivr.net/npm/chart.js@4/dist/chart.umd.js') new Chart(ctx, { /* config */ }) }
Vite 在开发时会代理该请求,在生产构建中会自动处理为独立 chunk,并生成带哈希的文件名,确保缓存与更新可控。
用户脚本(Tampermonkey 类)工程化注入
若目标是向任意网页注入逻辑(即 Userscript),推荐使用 vite-plugin-monkey:
- 它自动将
main.ts打包为符合油猴规范的.user.js文件 - 支持
@require、@connect、@resource等元信息自动生成 - 开发时热更新注入,无需手动刷新目标页
- 可直接调用
GM_*API 并获得 TypeScript 类型提示
示例配置:
// vite.config.ts
import monkey from 'vite-plugin-monkey'
export default defineConfig({
plugins: [
monkey({
entry: 'src/main.ts',
userscript: {
namespace: 'your-name',
author: 'you',
match: ['*://example.com/*']
}
})
]
})
构建后输出一个标准 .user.js,复制粘贴进油猴即可生效,所有 import 和逻辑都已打包注入。
注意事项与避坑点
-
import()返回 Promise,必须用await或.then(),不能直接赋值给src - 不要混用
document.write()或eval(),Vite 不处理这类字符串执行,也不安全 - 生产环境避免硬编码 CDN 地址,应通过构建变量或运行时配置传入
- 动态加载的模块路径必须是相对路径或绝对 URL,不能是拼接字符串(如
import(path + '.js')),否则 Vite 无法预分析和打包 - 如果脚本需全局访问(如挂载到
window),应在模块顶层export default或显式赋值,而非仅执行
基本上就这些。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











