-
-
Notifications
You must be signed in to change notification settings - Fork 223
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #163 from formkit/nuxt-module
Nuxt module
- Loading branch information
Showing
23 changed files
with
9,682 additions
and
2,592 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,3 +8,4 @@ temp | |
/.aws/credentials | ||
.yalc | ||
.idea | ||
.nuxt |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
shamefully-hoist=true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,228 @@ | ||
import { existsSync, promises as fsp } from "fs" | ||
import { pathToFileURL } from "url" | ||
import { resolve } from "pathe" | ||
import { consola } from "consola" | ||
import type { ModuleMeta, NuxtModule, NuxtConfig } from "@nuxt/schema" | ||
import { findExports } from "mlly" | ||
|
||
interface BuildModuleOptions { | ||
rootDir: string | ||
srcDir?: string | ||
sourcemap?: boolean | ||
stub?: boolean | ||
outDir?: string | ||
} | ||
|
||
interface PrepareModuleOptions { | ||
rootDir: string | ||
srcDir: string | ||
} | ||
|
||
/** | ||
* Original source: https://github.com/nuxt/module-builder/blob/main/src/prepare.ts | ||
* @param options | ||
*/ | ||
async function prepareModule (options: PrepareModuleOptions) { | ||
const { runCommand } = await import('nuxi') | ||
|
||
return runCommand('prepare', [resolve(options.rootDir, 'build/nuxt-playground')], { | ||
overrides: { | ||
typescript: { | ||
builder: 'shared' | ||
}, | ||
imports: { | ||
autoImport: false | ||
}, | ||
modules: [ | ||
resolve(options.rootDir, `${options.srcDir}/module`), | ||
function (_options, nuxt) { | ||
nuxt.hooks.hook('app:templates', (app) => { | ||
for (const template of app.templates) { | ||
template.write = true | ||
} | ||
}) | ||
} | ||
] | ||
} satisfies NuxtConfig | ||
}) | ||
} | ||
|
||
|
||
/** | ||
* Original source: https://github.com/nuxt/module-builder/blob/main/src/build.ts | ||
* @param opts - options | ||
*/ | ||
export async function buildModule(opts: BuildModuleOptions) { | ||
const { build } = await import("unbuild") | ||
|
||
const outDir = opts.outDir || "dist" | ||
const srcDir = opts.srcDir || "src" | ||
|
||
await prepareModule({ rootDir: opts.rootDir, srcDir }) | ||
|
||
await build(opts.rootDir, false, { | ||
clean: false, // auto-animate’s build does its own cleaning | ||
failOnWarn: false, // unbuild will validate the package.json, but we don’t want to fail on warnings | ||
declaration: true, | ||
sourcemap: opts.sourcemap, | ||
stub: opts.stub, | ||
outDir, | ||
entries: [ | ||
{ input: `${srcDir}/module`, outDir: `${outDir}/nuxt` }, | ||
{ input: `${srcDir}/runtime/`, outDir: `${outDir}/nuxt/runtime`, ext: "mjs" }, | ||
], | ||
rollup: { | ||
emitCJS: false, | ||
cjsBridge: false, | ||
dts: { | ||
tsconfig: "./build/nuxt-playground/tsconfig.json", | ||
}, | ||
}, | ||
externals: [ | ||
"@nuxt/schema", | ||
"@nuxt/schema-edge", | ||
"@nuxt/kit", | ||
"@nuxt/kit-edge", | ||
"nuxt", | ||
"nuxt-edge", | ||
"nuxt3", | ||
"vue", | ||
"vue-demi", | ||
], | ||
hooks: { | ||
async "rollup:done"(ctx) { | ||
const outDir = resolve(ctx.options.outDir, 'nuxt') | ||
// Generate CommonJS stub | ||
await writeCJSStub(outDir) | ||
|
||
// Load module meta | ||
const moduleEntryPath = resolve(outDir, "module.mjs") | ||
const moduleFn: NuxtModule<any> = await import( | ||
pathToFileURL(moduleEntryPath).toString() | ||
) | ||
.then((r) => r.default || r) | ||
.catch((err) => { | ||
consola.error(err) | ||
consola.error( | ||
"Cannot load module. Please check dist:", | ||
moduleEntryPath | ||
) | ||
return null | ||
}) | ||
|
||
if (!moduleFn || !moduleFn.getMeta) { | ||
return | ||
} | ||
const moduleMeta = await moduleFn.getMeta() | ||
|
||
// Enhance meta using package.json | ||
if (ctx.pkg) { | ||
if (!moduleMeta.name) { | ||
moduleMeta.name = ctx.pkg.name | ||
} | ||
if (!moduleMeta.version) { | ||
moduleMeta.version = ctx.pkg.version | ||
} | ||
} | ||
|
||
// Write meta | ||
const metaFile = resolve(outDir, "module.json") | ||
await fsp.writeFile( | ||
metaFile, | ||
JSON.stringify(moduleMeta, null, 2), | ||
"utf8" | ||
) | ||
|
||
// Generate types | ||
await writeTypes(outDir, moduleMeta) | ||
}, | ||
}, | ||
}) | ||
} | ||
|
||
async function writeTypes(distDir: string, meta: ModuleMeta) { | ||
const dtsFile = resolve(distDir, "types.d.ts") | ||
const dtsFileMts = resolve(distDir, "types.d.mts") | ||
if (existsSync(dtsFile)) { | ||
return | ||
} | ||
|
||
// Read generated module types | ||
const moduleTypesFile = resolve(distDir, "module.d.ts") | ||
const moduleTypes = await fsp | ||
.readFile(moduleTypesFile, "utf8") | ||
.catch(() => "") | ||
const typeExports = findExports( | ||
// Replace `export { type Foo }` with `export { Foo }` | ||
moduleTypes.replace(/export\s*{.*?}/gs, (match) => | ||
match.replace(/\btype\b/g, "") | ||
) | ||
) | ||
const isStub = moduleTypes.includes("export *") | ||
|
||
const schemaShims = [] | ||
const moduleImports = [] | ||
|
||
const hasTypeExport = (name: string) => | ||
isStub || typeExports.find((exp) => exp.names.includes(name)) | ||
|
||
if (meta.configKey && hasTypeExport("ModuleOptions")) { | ||
moduleImports.push("ModuleOptions") | ||
schemaShims.push( | ||
` interface NuxtConfig { ['${meta.configKey}']?: Partial<ModuleOptions> }` | ||
) | ||
schemaShims.push( | ||
` interface NuxtOptions { ['${meta.configKey}']?: ModuleOptions }` | ||
) | ||
} | ||
if (hasTypeExport("ModuleHooks")) { | ||
moduleImports.push("ModuleHooks") | ||
schemaShims.push(" interface NuxtHooks extends ModuleHooks {}") | ||
} | ||
if (hasTypeExport("ModuleRuntimeConfig")) { | ||
moduleImports.push("ModuleRuntimeConfig") | ||
schemaShims.push(" interface RuntimeConfig extends ModuleRuntimeConfig {}") | ||
} | ||
if (hasTypeExport("ModulePublicRuntimeConfig")) { | ||
moduleImports.push("ModulePublicRuntimeConfig") | ||
schemaShims.push( | ||
" interface PublicRuntimeConfig extends ModulePublicRuntimeConfig {}" | ||
) | ||
} | ||
|
||
const dtsContents = ` | ||
import { ${moduleImports.join(", ")} } from './module' | ||
${ | ||
schemaShims.length | ||
? `declare module '@nuxt/schema' {\n${schemaShims.join("\n")}\n}\n` | ||
: "" | ||
} | ||
${ | ||
schemaShims.length | ||
? `declare module 'nuxt/schema' {\n${schemaShims.join("\n")}\n}\n` | ||
: "" | ||
} | ||
export { ${typeExports[0].names.join(", ")} } from './module' | ||
` | ||
|
||
await fsp.writeFile(dtsFile, dtsContents, "utf8") | ||
if (!existsSync(dtsFileMts)) { | ||
await fsp.writeFile(dtsFileMts, dtsContents, "utf8") | ||
} | ||
} | ||
|
||
async function writeCJSStub(distDir: string) { | ||
const cjsStubFile = resolve(distDir, "module.cjs") | ||
if (existsSync(cjsStubFile)) { | ||
return | ||
} | ||
const cjsStub = `module.exports = function(...args) { | ||
return import('./module.mjs').then(m => m.default.call(this, ...args)) | ||
} | ||
const _meta = module.exports.meta = require('./module.json') | ||
module.exports.getMeta = () => Promise.resolve(_meta) | ||
` | ||
await fsp.writeFile(cjsStubFile, cjsStub, "utf8") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import createJITI from "jiti" | ||
import { fileURLToPath } from "url" | ||
import { dirname, resolve } from "path" | ||
|
||
const __filename = fileURLToPath(import.meta.url) | ||
|
||
const jiti = createJITI(__filename, { | ||
esmResolve: true, | ||
}) | ||
|
||
jiti("./bundle.ts") |
Oops, something went wrong.
6218460
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Successfully deployed to the following URLs:
auto-animate – ./
auto-animate.vercel.app
auto-animate-formkit.vercel.app
auto-animate-git-master-formkit.vercel.app
auto-animate.formkit.com
autoanimate.formkit.com