Skip to content

Commit

Permalink
feat: export inject-script plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
hemengke1997 committed Sep 14, 2023
1 parent fa3a590 commit e6f96ac
Show file tree
Hide file tree
Showing 26 changed files with 591 additions and 560 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
node_modules
dist
.idea
.idea
.Ds_store
72 changes: 37 additions & 35 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,51 +4,63 @@

**中文** | [English](./README.md)

**在vite的运行时或构建时打包指定目录下的typescript文件,供独立使用**
**在vite的运行时或构建时打包指定目录下的typescript文件,供开发者独立使用**

> 如果你希望项目中所有脚本都使用typescript编写,那么你应该试试此插件
## 应用场景

- 独立的第三方脚本,如 `sentry``google analytics`百度统计等
- 独立的第三方脚本,如 `sentry``google analytics``百度统计`
- 希望在页面完全加载前就执行的脚本,如 `modern-flexible`
- 初始化全局函数

## 功能

- 运行时和构建时,把指定文件夹中的`typescript`文件编译为`javascript`浏览器可直接使用
- 输出带有`hash`的js文件,无需担心缓存
- 运行时和构建时,把指定文件夹中的`typescript`文件编译为`javascript`供浏览器直接使用
- 输出带有 `hash` 的js文件,无需担心缓存
- 自定义编译选项,指定目标浏览器范围,无需担心兼容性
- 支持vite环境变量
- 支持`HMR`
- 支持 `HMR`
- 生产可用

## Install
## 安装

```bash
pnpm add vite-plugin-public-typescript -D
```

## Preview

<img src="./screenshots/ts.gif" />

## 用法

```typescript
import { defineConfig } from 'vite'
import { publicTypescript } from 'vite-plugin-public-typescript'
import { publicTypescript, injectScripts } from 'vite-plugin-public-typescript'
import manifest from './public-typescript/manifest.json'

export default defineConfig({
plugins: [publicTypescript()],
plugins: [
publicTypescript({
inputDir: 'public-typescript',
manifestName: 'manifest',
hash: true,
outputDir: '/out',
destination: 'memory',
}),
injectScripts([
{
attrs: {
src: manifest.script,
},
injectTo: 'head',
},
])
]
})
```


### SPA

`SPA` 应用中,我们可以通过 vite 的 `transformIndexHtml` hook 注入 script
你也可以使用 [`vite-plugin-html`](https://github.com/vbenjs/vite-plugin-html),这会使得注入更加简单
`SPA` 应用中,我们可以通过 `injectScripts` 插件往 `index.html` 中注入 script

完整示例请参考:[spa playground](./playground/spa/vite.config.ts)

Expand All @@ -57,30 +69,20 @@ export default defineConfig({
```typescript
import type { HtmlTagDescriptor } from 'vite'
import { defineConfig } from 'vite'
import { publicTypescript } from 'vite-plugin-public-typescript'
import manifest from './publicTypescript/manifest.json'
import { publicTypescript, injectScripts } from 'vite-plugin-public-typescript'
import manifest from './public-typescript/manifest.json'

export default defineConfig({
plugins: [
publicTypescript(),
{
name: 'add-script',
async transformIndexHtml(html) {
const tags: HtmlTagDescriptor[] = [
{
tag: 'script',
attrs: {
src: manifest.spa,
},
injectTo: 'head-prepend',
},
]
return {
html,
tags,
}
},
},
injectScripts([
{
attrs: {
src: manifest.spa,
},
injectTo: 'head-prepend',
}
])
],
})
```
Expand Down Expand Up @@ -109,7 +111,7 @@ export default defineConfig({
#### server.js

```js
import manifest from './publicTypescript/custom-manifest.json' assert { type: 'json' }
import manifest from './public-typescript/custom-manifest.json' assert { type: 'json' }

const html = template
// inject js
Expand Down
119 changes: 119 additions & 0 deletions __test__/basic.spec.todo.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
// import { afterEach, beforeEach, describe, expect, test, vi } from 'vitest'
// import mock from 'mock-fs'
// import fs from 'fs-extra'
// import type { ResolvedConfig, ViteDevServer } from 'vite'
// import { createServer } from 'vite'
// import { ManifestCache } from '../src/helper/ManifestCache'
// import { eq, isEmptyObject } from '../src/helper/utils'
// import { publicTypescript } from '../src'

// declare module 'vitest' {
// export interface TestContext {
// cache: ManifestCache
// vite: ResolvedConfig
// viteDevServer: ViteDevServer
// }
// }

// const manifestPath = 'manifest.json'

// vi.mock('fs-extra', async () => {
// const actual: any = await vi.importActual('fs-extra')
// return {
// readFileSync: vi.fn(),
// writeFile: vi.fn(),
// ...actual,
// }
// })

// function initCache() {
// const cache = new ManifestCache({ watchMode: false, write: false })
// cache.set({
// x: {
// path: 'x.js',
// _code: 'console.log("x")',
// },
// y: {
// path: 'y.js',
// _code: 'console.log("y")',
// },
// })
// return cache
// }

// async function createDevServer() {
// const server = await createServer({
// define: { hahahaha: JSON.stringify('this is haha') },
// plugins: [publicTypescript({ destination: 'file' })],
// server: {
// middlewareMode: true,
// port: 4000,
// host: '127.0.0.1',
// },
// })
// return server
// }

// const globalServer = await createDevServer()

// // beforeAll(() => {
// // vi.spyOn(fs, 'readFileSync').mockImplementation(() => {
// // return '{ "a": "/a.chunk.js" }'
// // })
// // })

// beforeEach((ctx) => {
// ctx.cache = initCache()
// mock({
// 'manifest.json': '{}',
// })
// })

// beforeEach(async (ctx) => {
// ctx.vite = globalServer.config
// ctx.viteDevServer = globalServer
// })

// afterEach(async (ctx) => {
// mock.restore()
// await ctx.viteDevServer.close()
// })

// describe('manifestCache', () => {
// test('should set cache and get cache right', ({ cache }) => {
// expect(cache.getByKey('x')).toStrictEqual({ path: 'x.js', _code: 'console.log("x")' })
// })

// test('should remove cache', ({ cache }) => {
// cache.remove('x')

// expect(cache.getByKey('x')).toBeFalsy()
// })

// test('should get all', ({ cache }) => {
// const v = cache.get()
// expect(Object.keys(v).length === 2).toBe(true)
// })

// test('should set manifestPath', ({ cache }) => {
// cache.setManifestPath(manifestPath)
// expect(cache.getManifestPath()).toBe(manifestPath)
// })

// test('should write manifest', ({ cache }) => {
// cache.setManifestPath(manifestPath)

// {
// const content = JSON.parse(fs.readFileSync(manifestPath, 'utf-8'))
// expect(isEmptyObject(content)).toBe(true)
// }

// cache.writeManifestJSON()

// {
// const content = fs.readFileSync(manifestPath, 'utf-8')
// const c = initCache()
// expect(eq(JSON.parse(content), c.extractPath(c.get()))).toBe(true)
// }
// })
// })
116 changes: 0 additions & 116 deletions __test__/basic.spec.ts

This file was deleted.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,9 @@
"debug": "^4.3.4",
"esbuild": "^0.19.2",
"fs-extra": "^11.1.1",
"magic-string": "^0.30.3",
"on-change": "^4.0.2",
"parse5": "^7.1.2",
"sirv": "^2.0.3",
"tiny-glob": "^0.2.9",
"watcher": "^2.3.0"
Expand Down
2 changes: 1 addition & 1 deletion playground/spa/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"dev": "vite",
"debug": "cross-env DEBUG=vite-plugin-public-typescript* vite",
"build": "vite build",
"debug:build": "cross-env DEBUG=vite-plugin-public-typescript* vite build",
"preview": "vite preview"
},
"dependencies": {
Expand All @@ -20,7 +21,6 @@
"cross-env": "^7.0.3",
"typescript": "^4.9.5",
"vite": "4.4.9",
"vite-plugin-html": "^3.2.0",
"vite-plugin-public-typescript": "workspace:*"
}
}
Loading

0 comments on commit e6f96ac

Please sign in to comment.