mirror of
https://github.com/nuxt/nuxt.git
synced 2025-01-18 09:25:54 +00:00
feat(nitro): assets driver (#511)
This commit is contained in:
parent
e363ed5853
commit
820a9d0b57
@ -64,7 +64,7 @@
|
||||
"table": "^6.7.1",
|
||||
"ufo": "^0.7.9",
|
||||
"unenv": "^0.3.3",
|
||||
"unstorage": "^0.2.3",
|
||||
"unstorage": "^0.2.5",
|
||||
"upath": "^2.0.1",
|
||||
"vue": "3.2.10",
|
||||
"vue-bundle-renderer": "^0.3.0",
|
||||
|
@ -1,9 +1,9 @@
|
||||
import { promises as fsp } from 'fs'
|
||||
import type { Plugin } from 'rollup'
|
||||
import createEtag from 'etag'
|
||||
import mime from 'mime'
|
||||
import { resolve } from 'upath'
|
||||
import globby from 'globby'
|
||||
import type { Plugin } from 'rollup'
|
||||
import virtual from './virtual'
|
||||
|
||||
export interface AssetOptions {
|
||||
@ -16,60 +16,26 @@ export interface AssetOptions {
|
||||
}
|
||||
}
|
||||
|
||||
interface Asset {
|
||||
fsPath: string,
|
||||
meta: {
|
||||
type?: string,
|
||||
etag?: string,
|
||||
mtime?: string
|
||||
}
|
||||
}
|
||||
|
||||
export function assets (opts: AssetOptions): Plugin {
|
||||
type Asset = {
|
||||
fsPath: string,
|
||||
meta: {
|
||||
type?: string,
|
||||
etag?: string,
|
||||
mtime?: string
|
||||
}
|
||||
}
|
||||
|
||||
const assetUtils = `
|
||||
export function readAsset (id) {
|
||||
return getAsset(id).read()
|
||||
}
|
||||
|
||||
export function statAsset (id) {
|
||||
return getAsset(id).meta
|
||||
}
|
||||
`
|
||||
|
||||
if (!opts.inline) {
|
||||
return virtual({
|
||||
'#assets': `
|
||||
import { statSync, promises as fsp } from 'fs'
|
||||
import { resolve } from 'path'
|
||||
|
||||
const dirs = ${JSON.stringify(opts.dirs)}
|
||||
|
||||
${assetUtils}
|
||||
|
||||
export function getAsset (id) {
|
||||
for (const dirname in dirs) {
|
||||
if (id.startsWith(dirname + '/')) {
|
||||
const dirOpts = dirs[dirname]
|
||||
const path = resolve(dirOpts.dir, id.substr(dirname.length + 1))
|
||||
let stat = statSync(path)
|
||||
const asset = {
|
||||
read: () => fsp.readFile(path, 'utf-8'),
|
||||
meta: {
|
||||
mtime: stat.mtime
|
||||
}
|
||||
}
|
||||
return asset
|
||||
}
|
||||
}
|
||||
throw new Error('Asset dir not found: ' + id)
|
||||
}
|
||||
`
|
||||
})
|
||||
// Development: Use filesystem
|
||||
return virtual({ '#assets': getAssetsDev(opts.dirs) })
|
||||
}
|
||||
|
||||
// Production: Bundle assets
|
||||
return virtual({
|
||||
'#assets': {
|
||||
async load () {
|
||||
// Scan all assets
|
||||
const assets: Record<string, Asset> = {}
|
||||
for (const assetdir in opts.dirs) {
|
||||
const dirOpts = opts.dirs[assetdir]
|
||||
@ -88,17 +54,55 @@ export function getAsset (id) {
|
||||
}
|
||||
}
|
||||
}
|
||||
const inlineAssets = `const assets = {\n${Object.keys(assets).map(id =>
|
||||
` ['${id}']: {\n read: () => import('${assets[id].fsPath}').then(r => r.default || r),\n meta: ${JSON.stringify(assets[id].meta)}\n }`
|
||||
).join(',\n')}\n}`
|
||||
return `${inlineAssets}\n${assetUtils}
|
||||
export function getAsset (id) {
|
||||
if (!assets[id]) {
|
||||
throw new Error('Asset not found : ' + id)
|
||||
}
|
||||
return assets[id]
|
||||
}`
|
||||
return getAssetProd(assets)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function getAssetsDev (dirs) {
|
||||
return `
|
||||
import { createStorage } from 'unstorage'
|
||||
import fsDriver from 'unstorage/drivers/fs'
|
||||
|
||||
const dirs = ${JSON.stringify(dirs)}
|
||||
|
||||
export const assets = createStorage()
|
||||
|
||||
for (const [dirname, dirOpts] of Object.entries(dirs)) {
|
||||
assets.mount(dirname, fsDriver({ base: dirOpts.dir }))
|
||||
}
|
||||
`
|
||||
}
|
||||
|
||||
function normalizeKey (key) {
|
||||
return key.replace(/[/\\\\]/g, ':').replace(/^:|:$/g, '')
|
||||
}
|
||||
|
||||
function getAssetProd (assets: Record<string, Asset>) {
|
||||
return `
|
||||
const _assets = {\n${Object.entries(assets).map(([id, asset]) =>
|
||||
` ['${normalizeKey(id)}']: {\n import: () => import('${asset.fsPath}').then(r => r.default || r),\n meta: ${JSON.stringify(asset.meta)}\n }`
|
||||
).join(',\n')}\n}
|
||||
|
||||
${normalizeKey.toString()}
|
||||
|
||||
export const assets = {
|
||||
getKeys() {
|
||||
return Object.keys(_assets)
|
||||
},
|
||||
hasItem (id) {
|
||||
id = normalizeKey(id)
|
||||
return id in _assets
|
||||
},
|
||||
getItem (id) {
|
||||
id = normalizeKey(id)
|
||||
return _assets[id] ? _assets[id].import() : null
|
||||
},
|
||||
getMeta (id) {
|
||||
id = normalizeKey(id)
|
||||
return _assets[id] ? _assets[id].meta : {}
|
||||
}
|
||||
}
|
||||
`
|
||||
}
|
||||
|
@ -32,10 +32,14 @@ export function storage (opts: StorageOptions) {
|
||||
return virtual({
|
||||
'#storage': `
|
||||
import { createStorage } from 'unstorage'
|
||||
import { assets } from '#assets'
|
||||
|
||||
${driverImports.map(i => `import ${getImportName(i)} from '${i}'`).join('\n')}
|
||||
|
||||
export const storage = createStorage({})
|
||||
|
||||
storage.mount('/assets', assets)
|
||||
|
||||
${mounts.map(m => `storage.mount('${m.path}', ${getImportName(m.driver)}(${JSON.stringify(m.opts)}))`).join('\n')}
|
||||
`
|
||||
})
|
||||
|
10
packages/nitro/types/shims.d.ts
vendored
10
packages/nitro/types/shims.d.ts
vendored
@ -1,7 +1,6 @@
|
||||
import type { $Fetch } from 'ohmyfetch'
|
||||
import type { Storage } from 'unstorage'
|
||||
|
||||
declare global {
|
||||
import type { $Fetch } from 'ohmyfetch'
|
||||
|
||||
// eslint-disable-next-line no-var
|
||||
var $fetch: $Fetch
|
||||
namespace NodeJS {
|
||||
@ -12,6 +11,7 @@ declare global {
|
||||
}
|
||||
|
||||
declare module '#storage' {
|
||||
import type { Storage } from 'unstorage'
|
||||
export const storage: Storage
|
||||
}
|
||||
|
||||
@ -19,5 +19,7 @@ declare module '#assets' {
|
||||
export interface AssetMeta { type?: string, etag?: string, mtime?: string }
|
||||
export function readAsset<T=any>(id: string): Promise<T>
|
||||
export function statAsset(id: string): Promise<AssetMeta>
|
||||
export function getAsset<T=any>(id: string): { read: () => Promise<T>, meta: AssetMeta }
|
||||
export function getKeys() : Promise<string[]>
|
||||
}
|
||||
|
||||
export default {}
|
||||
|
67
yarn.lock
67
yarn.lock
@ -1523,7 +1523,7 @@ __metadata:
|
||||
ufo: ^0.7.9
|
||||
unbuild: ^0.4.2
|
||||
unenv: ^0.3.3
|
||||
unstorage: ^0.2.3
|
||||
unstorage: ^0.2.5
|
||||
upath: ^2.0.1
|
||||
vue: 3.2.10
|
||||
vue-bundle-renderer: ^0.3.0
|
||||
@ -4532,7 +4532,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"chokidar@npm:3.5.2, chokidar@npm:^3.5.1, chokidar@npm:^3.5.2":
|
||||
"chokidar@npm:3.5.2, chokidar@npm:^3.5.2":
|
||||
version: 3.5.2
|
||||
resolution: "chokidar@npm:3.5.2"
|
||||
dependencies:
|
||||
@ -7732,9 +7732,9 @@ fsevents@~2.3.2:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"ioredis@npm:^4.27.3":
|
||||
version: 4.27.7
|
||||
resolution: "ioredis@npm:4.27.7"
|
||||
"ioredis@npm:^4.27.9":
|
||||
version: 4.27.9
|
||||
resolution: "ioredis@npm:4.27.9"
|
||||
dependencies:
|
||||
cluster-key-slot: ^1.1.0
|
||||
debug: ^4.3.1
|
||||
@ -7747,7 +7747,7 @@ fsevents@~2.3.2:
|
||||
redis-errors: ^1.2.0
|
||||
redis-parser: ^3.0.0
|
||||
standard-as-callback: ^2.1.0
|
||||
checksum: 42c2f242b3c91202578415dc39fbc9e9ecff58f19acbd91b654cbe12877181e18dbeb6c12b3e71225a7cc928cc4e34f536953375978093c7c1a6f7417a9dfd84
|
||||
checksum: 0472f20366759fe17c71c42105869dbaba99ad54e3fc14428cd6e1d28f8767ff1aea03bfc0228b29bf6030d7ae1ac856941ab6698c850a9b27fd8a17328e7f9f
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@ -9990,17 +9990,6 @@ fsevents@~2.3.2:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"ohmyfetch@npm:^0.2.0":
|
||||
version: 0.2.0
|
||||
resolution: "ohmyfetch@npm:0.2.0"
|
||||
dependencies:
|
||||
destr: ^1.1.0
|
||||
node-fetch: ^2.6.1
|
||||
ufo: ^0.6.10
|
||||
checksum: 58afffe238610d2b8829d1f90949cdc776a0d531cd4b9f88f7d0c4ab82550179b810e9b0e0197212216a1722e630149421b4e2b710fa92ed72fa739c28f935cb
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"ohmyfetch@npm:^0.3.1":
|
||||
version: 0.3.1
|
||||
resolution: "ohmyfetch@npm:0.3.1"
|
||||
@ -13418,14 +13407,7 @@ fsevents@~2.3.2:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"ufo@npm:^0.6.10":
|
||||
version: 0.6.11
|
||||
resolution: "ufo@npm:0.6.11"
|
||||
checksum: cf73c7f3e62413237cb8b763b2ae39ec9b83a630644a9ceac721c6394c62d562f1d7deb117e7b0c35f5a29a4c88b5e67a8c1ebf0d41543b8acc4c44e5dd607df
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"ufo@npm:^0.7.5, ufo@npm:^0.7.9":
|
||||
"ufo@npm:^0.7.9":
|
||||
version: 0.7.9
|
||||
resolution: "ufo@npm:0.7.9"
|
||||
checksum: 8a141889382dfe9fe42af625316ea0bc60e287ed81275befa699d3c099af44232720ea7b72d5ea738e4766e79adb8dc901bd7f788f9c2057d0ec2389d9f06df5
|
||||
@ -13603,21 +13585,21 @@ fsevents@~2.3.2:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"unstorage@npm:^0.2.3":
|
||||
version: 0.2.3
|
||||
resolution: "unstorage@npm:0.2.3"
|
||||
"unstorage@npm:^0.2.5":
|
||||
version: 0.2.5
|
||||
resolution: "unstorage@npm:0.2.5"
|
||||
dependencies:
|
||||
anymatch: ^3.1.1
|
||||
chokidar: ^3.5.1
|
||||
chokidar: ^3.5.2
|
||||
destr: ^1.1.0
|
||||
h3: ^0.2.10
|
||||
ioredis: ^4.27.3
|
||||
ioredis: ^4.27.9
|
||||
listhen: ^0.2.4
|
||||
mri: ^1.1.6
|
||||
ohmyfetch: ^0.2.0
|
||||
ufo: ^0.7.5
|
||||
ws: ^7.4.5
|
||||
checksum: 88996f454624a8da10c140f28441376ceee84047bff7aad7c9df7b8bfd8f4768042ce97c63713bad1c5d42c66c1fad367c7e9727b7241260ec75e04350f5b785
|
||||
ohmyfetch: ^0.3.1
|
||||
ufo: ^0.7.9
|
||||
ws: ^8.2.1
|
||||
checksum: 214042a12eaf4ac9b17ee35058681330f57c7d9570f0e30cb46fd96b9d0952ff73296e6bf43c40162d7f4f86df29b249d2d1df7db0d7c1d9d98b72c2a0b50ed8
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@ -14327,7 +14309,7 @@ fsevents@~2.3.2:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"ws@npm:^7.3.1, ws@npm:^7.4.5, ws@npm:^7.4.6":
|
||||
"ws@npm:^7.3.1, ws@npm:^7.4.6":
|
||||
version: 7.5.3
|
||||
resolution: "ws@npm:7.5.3"
|
||||
peerDependencies:
|
||||
@ -14342,6 +14324,21 @@ fsevents@~2.3.2:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"ws@npm:^8.2.1":
|
||||
version: 8.2.1
|
||||
resolution: "ws@npm:8.2.1"
|
||||
peerDependencies:
|
||||
bufferutil: ^4.0.1
|
||||
utf-8-validate: ^5.0.2
|
||||
peerDependenciesMeta:
|
||||
bufferutil:
|
||||
optional: true
|
||||
utf-8-validate:
|
||||
optional: true
|
||||
checksum: 22906903c7952790a911627f99e3419d8f251a6a540d9ba4f334a7e0865d7ea7026d8ad23829c3c0f2843a9f15bdb91c646e7f8853a5a5ba25a57dea2cf7d416
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"xml-name-validator@npm:^3.0.0":
|
||||
version: 3.0.0
|
||||
resolution: "xml-name-validator@npm:3.0.0"
|
||||
|
Loading…
Reference in New Issue
Block a user