Skip to content

Commit

Permalink
feat: transform kirbyup.import with Vite plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
johannschopplich committed Oct 6, 2021
1 parent 0e74ac3 commit 2307b67
Show file tree
Hide file tree
Showing 8 changed files with 124 additions and 37 deletions.
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ The fastest and leanest way to bundle your Kirby Panel plugins. No configuration

- 🍂 Lightweight, robust and tested
- ⚡️ Fast compilation with Vite/esbuild
- 🧭 [`~/` Path resolve alias](#path-resolve-alias)
- \*️⃣ [Auto-import blocks](#auto-import-blocks) and fields
- 🔍 Watch mode
- \*️⃣ `kirbyup.import` to [auto-import blocks & fields](#auto-import-blocks-and-fields)
- 🧭 [`~/` path resolve alias](#path-resolve-alias)
- 🎒 [PostCSS transforms](#postcss-transforms) for RTL support & more
- 🔌 [Supports env variables](#env-variables)
- 🔍 Watch mode

## Requirements

Expand Down Expand Up @@ -113,9 +113,9 @@ You can use the alias:
import someUtility from '~/utils'
```

### Auto-Import Blocks
### Auto-Import Blocks and Fields

If you find yourself in the situation of needing to import multiple blocks or fields into your Panel plugin, you can use the kirbyup `autoImport` function to ease the process.
If you find yourself in the situation of needing to import multiple **blocks** or **fields** into your Panel plugin, you can use the kirbyup `kirbyup.import` function to ease the process.

Before:

Expand All @@ -136,10 +136,10 @@ window.panel.plugin('kirbyup/example', {
After:

```js
import { autoImport } from 'kirbyup/plugin'
import { kirbyup } from 'kirbyup/plugin'

window.panel.plugin('kirbyup/example', {
blocks: autoImport(import.meta.globEager('./components/blocks/*.vue'))
blocks: kirbyup.import('./components/blocks/*.vue')
})
```

Expand Down
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"require": "./dist/index.js"
},
"./plugin": {
"import": "./dist/plugin.mjs"
"import": "./dist/client/plugin.js"
}
},
"main": "dist/index.js",
Expand Down Expand Up @@ -43,8 +43,8 @@
},
"homepage": "https://github.com/johannschopplich/kirbyup#readme",
"scripts": {
"build": "tsup src/cli.ts src/index.ts --clean --dts && npm run plugin",
"plugin": "esbuild src/plugin.ts --format=esm --outfile=dist/plugin.mjs && tsc src/plugin.ts --declaration --emitDeclarationOnly --outDir dist",
"build": "tsup src/cli.ts src/index.ts --clean --dts && npm run build:client",
"build:client": "esbuild src/client/plugin.ts --format=esm --outdir=dist/client && tsc src/client/plugin.ts --declaration --emitDeclarationOnly --outDir dist/client",
"test": "jest",
"format": "prettier --write \"src/**/*.ts\"",
"changelog": "conventional-changelog -p angular -i CHANGELOG.md -s",
Expand Down
33 changes: 33 additions & 0 deletions src/client/plugin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* Exports are ESM and not part of the kirbyup CLI,
* but importable when writing a Kirby Panel plugin
*/

/** Single entry of Vite's `import.meta.globEager` function */
type Module = Record<string, any>

const getComponentName = (path: string) =>
path
.split('/')
.pop()!
.replace(/\.vue$/, '')
.toLowerCase()

/*
* Set of Utils for Kirby Plugins
*/
export const kirbyup = Object.freeze({
/**
* Auto-import Kirby Panel components, will be transformed by
* kirbyup's auto import plugin for Vite
*
* @example
* kirbyup.import('./components/blocks/*.vue')
*/
import(modules: Record<string, Module>) {
return Object.entries(modules).reduce((acc: Module, [path, component]) => {
acc[getComponentName(path)] = component.default
return acc
}, {})
}
})
3 changes: 2 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { existsSync } from 'fs'
import colors from 'colorette'
import { build as viteBuild } from 'vite'
import { createVuePlugin } from 'vite-plugin-vue2'
import kirbyupAutoImportPlugin from './plugins/autoImport'
import postcssLogical from 'postcss-logical'
import postcssDirPseudoClass from 'postcss-dir-pseudo-class'
import { handleError, PrettyError } from './errors'
Expand All @@ -21,7 +22,7 @@ export async function runViteBuild(options: NormalizedOptions) {
try {
result = await viteBuild({
mode,
plugins: [createVuePlugin()],
plugins: [createVuePlugin(), kirbyupAutoImportPlugin()],
build: {
lib: {
entry: resolve(currentDir, options.entry),
Expand Down
26 changes: 0 additions & 26 deletions src/plugin.ts

This file was deleted.

53 changes: 53 additions & 0 deletions src/plugins/autoImport.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import MagicString from 'magic-string'
import { multilineCommentsRE, singlelineCommentsRE } from './utils'
import type { Plugin, ResolvedConfig } from 'vite'

/**
* Transform `kirbyup.import(<path>)` to
* `kirbyup.import(import.meta.globEager(<path>))`
*/
export default function kirbyupAutoImportPlugin(): Plugin {
let config: ResolvedConfig

return {
name: 'kirbyup:auto-import',

configResolved(resolvedConfig) {
config = resolvedConfig
},

async transform(code, id) {
if (code.includes('kirbyup.import')) {
const kirbyupImportRE =
/\bkirbyup\.import\s*\(\s*('[^']+'|"[^"]+"|`[^`]+`)\s*\)/g
const noCommentsCode = code
.replace(multilineCommentsRE, (m) => ' '.repeat(m.length))
.replace(singlelineCommentsRE, (m) => ' '.repeat(m.length))
let s: MagicString | null = null
let match: RegExpExecArray | null

while ((match = kirbyupImportRE.exec(noCommentsCode))) {
const { 0: exp, 1: rawPath, index } = match

if (!s) s = new MagicString(code)

const path = rawPath.slice(1, -1)
s.overwrite(
index,
index + exp.length,
`kirbyup.import(import.meta.globEager("${path}"))`
)
}

if (s) {
return {
code: s.toString(),
map: config.build.sourcemap ? s.generateMap({ hires: true }) : null
}
}
}

return null
}
}
}
2 changes: 2 additions & 0 deletions src/plugins/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export const multilineCommentsRE = /\/\*(.|[\r\n])*?\*\//gm
export const singlelineCommentsRE = /\/\/.*/g
24 changes: 24 additions & 0 deletions tests/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -153,3 +153,27 @@ it('builds panel plugins', async () => {
]
`)
})

it('imports components automatically', async () => {
const { output, outFiles } = await run({
'src/input.js': `
import { kirbyup } from '${process.cwd()}/dist/client/plugin.js'
window.panel.plugin('kirbyup/example', {
blocks: kirbyup.import('./components/blocks/*.vue')
})
`,
'src/components/blocks/Foo.vue': `<template><k-header>Bar</k-header></template>`
})

expect(output).toMatchInlineSnapshot(`
"!function(){\\"use strict\\";function e(e,t,n,o,r,i,s,a){var c,l=\\"function\\"==typeof e?e.options:e;if(t&&(l.render=t,l.staticRenderFns=n,l._compiled=!0),o&&(l.functional=!0),i&&(l._scopeId=\\"data-v-\\"+i),s?(c=function(e){(e=e||this.$vnode&&this.$vnode.ssrContext||this.parent&&this.parent.$vnode&&this.parent.$vnode.ssrContext)||\\"undefined\\"==typeof __VUE_SSR_CONTEXT__||(e=__VUE_SSR_CONTEXT__),r&&r.call(this,e),e&&e._registeredComponents&&e._registeredComponents.add(s)},l._ssrRegister=c):r&&(c=a?function(){r.call(this,(l.functional?this.parent:this).$root.$options.shadowRoot)}:r),c)if(l.functional){l._injectStyles=c;var u=l.render;l.render=function(e,t){return c.call(t),u(e,t)}}else{var p=l.beforeCreate;l.beforeCreate=p?[].concat(p,c):[c]}return{exports:e,options:l}}const t={};var n=e({},(function(){var e=this,t=e.$createElement;return(e._self._c||t)(\\"k-header\\",[e._v(\\"Bar\\")])}),[],!1,o,null,null,null);function o(e){for(let n in t)this[n]=t[n]}var r=function(){return n.exports}(),i=Object.freeze({__proto__:null,[Symbol.toStringTag]:\\"Module\\",default:r});const s=Object.freeze({import:e=>Object.entries(e).reduce(((e,[t,n])=>(e[(e=>e.split(\\"/\\").pop().replace(/\\\\.vue$/,\\"\\").toLowerCase())(t)]=n.default,e)),{})});window.panel.plugin(\\"kirbyup/example\\",{blocks:s.import({\\"./components/blocks/Foo.vue\\":i})})}();
"
`)

expect(outFiles).toMatchInlineSnapshot(`
Array [
"index.js",
]
`)
})

0 comments on commit 2307b67

Please sign in to comment.