Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: external support aliases #27

Merged
merged 2 commits into from
Oct 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions __tests__/fixtures/cdn-plugin/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!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>
<script type="module" src="./main.js"></script>
</body>
</html>
15 changes: 15 additions & 0 deletions __tests__/fixtures/cdn-plugin/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/* eslint-disable */
import { createApp, createVNode, defineComponent } from 'vue'

const App = defineComponent({
name: 'Application',
setup() {
return () => createVNode('div', null, 'hello world')
}
})

createApp(App).mount('#app')

export * from 'vue'
const version = 'cdn-plugin-test-version'
export { version }
8 changes: 8 additions & 0 deletions __tests__/fixtures/external-plugin/button.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { createVNode, defineComponent } from 'vue'

export default defineComponent({
name: 'Button',
setup(_, { slots }) {
return () => createVNode('button', null, slots)
}
})
11 changes: 11 additions & 0 deletions __tests__/fixtures/external-plugin/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import _Button from './button'

function withInstall(component) {
component.install = (app) => {
app.component(component.name, component)
}
}

const Button = withInstall(_Button)

export { Button }
46 changes: 46 additions & 0 deletions __tests__/plugin.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import path from 'path'
import test from 'ava'
import { build } from 'vite'
import { cdn, external } from '../dist'

const defaultWd = __dirname

const fixturePath = path.join(defaultWd, 'fixtures')

test('exteranl plugin', async (t) => {
const bundle = await build({
plugins: [external({ include: /\.(mjs|js|ts|vue|jsx|tsx)(\?.*|)$/, modules: [{ name: 'vue', global: 'Vue' }] })],
logLevel: 'silent',
build: {
lib: {
entry: path.join(fixturePath, 'external-plugin', 'main.js'),
formats: ['es']
},
write: false
}
})

const { code } = bundle[0].output[0]
const global = /Vue(.)\w+/g
const [s, s1] = code.match(global)
t.is(s, 'Vue.defineComponent')
t.is(s1, 'Vue.createVNode')
})

test('cdn plugin', async (t) => {
const bundle = await build({
plugins: [cdn({ modules: [{ name: 'vue' }] })],
logLevel: 'silent',
root: path.join(fixturePath, 'cdn-plugin'),
build: {
write: false
}
})
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignored
const { output } = bundle
const chunk = output[0]
const html = output[1]
t.is(/Vue/.test(chunk.code), true)
t.is(/https:\/\/cdn\.jsdelivr\.net\/npm\/vue/.test(html.source), true)
})
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
},
"devDependencies": {
"@esbuild-kit/cjs-loader": "^2.4.2",
"@nolyfill/es-aggregate-error": "^1.0.20",
"@rollup/plugin-json": "^6.0.0",
"@types/babel__core": "^7.20.1",
"@types/debug": "^4.1.8",
Expand All @@ -74,8 +75,7 @@
"tsup": "^7.1.0",
"typescript": "^4.8.3",
"vite": "^3.1.3",
"vue": "^3.3.4",
"@nolyfill/es-aggregate-error": "^1.0.20"
"vue": "^3.3.4"
},
"dependencies": {
"@babel/core": "^7.22.5",
Expand Down
3 changes: 1 addition & 2 deletions src/code-gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export class CodeGen {
this.aliasesToDependencies = new Map()
this.dependencies.forEach(({ name, aliases }) => {
this.aliasesToDependencies.set(name, name)
if (len(aliases)) {
if (Array.isArray(aliases) && len(aliases)) {
aliases.forEach((aliase) => this.aliasesToDependencies.set(aliase, name))
}
})
Expand Down Expand Up @@ -316,7 +316,6 @@ export async function tryScanGlobalName(code: string) {
const ast = await babelParse(code, { babelrc: false, configFile: false })
const { body } = ast.program
if (!len(body)) return
// It's enough to extract only the first node
const node = body[0]
// iife only return the first
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
Expand Down
6 changes: 3 additions & 3 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { createFilter } from '@rollup/pluginutils'
import type { Plugin } from 'vite'
import _debug from 'debug'
import { createScanner, getPackageExports } from './scanner'
import { createScanner, getPackageExports, serializationExportsFields } from './scanner'
import { createInjectScript } from './inject'
import { createCodeGenerator } from './code-gen'
import { isSupportThreads, transformCJSRequire } from './shared'
Expand Down Expand Up @@ -102,7 +102,7 @@ function external(opts: ExternalPluginOptions = {}): Plugin {
const defaultWd = process.cwd()
const dependencies = await Promise.all(modules.map(async (module) => {
const exports = await getPackageExports(module, defaultWd)
return { bindings: exports, ...module }
return { bindings: exports, ...module, aliases: serializationExportsFields(module.name, module.aliases) }
})) as ModuleInfo[]
const deps = new Map(dependencies.map(dep => [dep.name, dep]))
debug('scanning done', deps)
Expand Down Expand Up @@ -131,4 +131,4 @@ export { cdn, external }

export default cdn

export type { InjectVisitor, TrackModule, CDNPluginOptions, ExternalPluginOptions } from './interface'
export type { InjectVisitor, TrackModule, CDNPluginOptions, ExternalPluginOptions, ExternalModule } from './interface'
6 changes: 5 additions & 1 deletion src/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ export interface IModule extends TrackModule {
resolve?: string | ResolverFunction
}

export type ExternalModule = Required<Module> & {
aliases?: Array<string>
}

export interface Serialization {
url?: Set<string>
type?: string
Expand Down Expand Up @@ -97,7 +101,7 @@ export type CDNPluginOptions = Pretty<{
}>

export type ExternalPluginOptions = Pretty<{
modules?: Array<Required<Module>>
modules?: Array<ExternalModule>
include?: FilterPattern
exclude?: FilterPattern
}>
2 changes: 1 addition & 1 deletion src/scanner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ function createWorkerThreads(scannerModule: ScannerModule, defaultWd: string) {
}


function serializationExportsFields(moduleName: string, aliases = []) {
export function serializationExportsFields(moduleName: string, aliases = []) {
return aliases.filter(v => v !== '.').map(v => path.posix.join(moduleName, v))
}

Expand Down
Loading