Skip to content

Commit

Permalink
feat: new public asset handling
Browse files Browse the repository at this point in the history
  • Loading branch information
pi0 committed Apr 1, 2022
1 parent 4d7c6ac commit 305c498
Show file tree
Hide file tree
Showing 24 changed files with 264 additions and 203 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
"fs-extra": "^10.0.1",
"globby": "^13.1.1",
"gzip-size": "^7.0.0",
"h3": "^0.5.3",
"h3": "^0.5.4",
"hasha": "^5.2.2",
"hookable": "^5.1.1",
"http-proxy": "^1.18.1",
Expand Down
17 changes: 5 additions & 12 deletions src/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,21 +22,15 @@ export async function prepare (nitro: Nitro) {
}

async function cleanupDir (dir: string) {
// consola.info('Cleaning up', prettyPath(dir))
await fse.emptyDir(dir)
}

export async function copyPublicAssets (nitro: Nitro) {
nitro.logger.start('Generating public...')

const clientDist = resolve(nitro.options.buildDir, 'dist/client')
if (await isDirectory(clientDist)) {
await fse.copy(clientDist, join(nitro.options.output.publicDir, nitro.options.publicPath))
}
if (await isDirectory(nitro.options.publicDir)) {
await fse.copy(nitro.options.publicDir, nitro.options.output.publicDir)
for (const asset of nitro.options.publicAssets) {
if (await isDirectory(asset.dir)) {
await fse.copy(asset.dir, join(nitro.options.output.publicDir, asset.baseURL))
}
}

nitro.logger.success('Generated public ' + prettyPath(nitro.options.output.publicDir))
}

Expand Down Expand Up @@ -170,8 +164,7 @@ function startRollupWatcher (nitro: Nitro) {

// Encountered an error while bundling
case 'ERROR':
nitro.logger.error('Rollup error: ' + event.error)
// nitro.logger.error(event.error)
nitro.logger.error('Rollup error: ', event.error)
}
})
return watcher
Expand Down
53 changes: 33 additions & 20 deletions src/nitro.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { existsSync } from 'fs'
import { resolve } from 'pathe'
import { createHooks } from 'hookable'
import { createUnimport } from 'unimport'
import consola from 'consola'
import type { NitroConfig, Nitro } from './types'
import { resolvePath } from './utils'
import { loadOptions } from './options'

export async function createNitro (config: NitroConfig = {}): Promise<Nitro> {
Expand All @@ -27,35 +27,48 @@ export async function createNitro (config: NitroConfig = {}): Promise<Nitro> {
// Init hooks
nitro.hooks.addHooks(nitro.options.hooks)

// Resolve output dir
options.output.dir = resolvePath(nitro, nitro.options.output.dir)
options.output.publicDir = resolvePath(nitro, nitro.options.output.publicDir)
options.output.serverDir = resolvePath(nitro, nitro.options.output.serverDir)
// Public assets
for (const dir of options.scanDirs) {
const publicDir = resolve(dir, 'public')
consola.log(publicDir)
if (!existsSync(publicDir)) { continue }
if (options.publicAssets.find(asset => asset.dir === publicDir)) {
continue
}
options.publicAssets.push({ dir: publicDir } as any)
}
for (const asset of options.publicAssets) {
asset.baseURL = asset.baseURL || '/'
const isTopLevel = asset.baseURL === '/'
asset.fallthrough = asset.fallthrough ?? isTopLevel
asset.maxAge = asset.maxAge ?? (isTopLevel ? 0 : 60)
}

// Server assets
nitro.options.serverAssets.push({
baseName: 'server',
dir: resolve(nitro.options.srcDir, 'assets')
})

if (nitro.options.autoImport) {
nitro.unimport = createUnimport(nitro.options.autoImport)
}

// Dev-only storage
if (nitro.options.dev) {
if (options.dev) {
const fsMounts = {
root: resolve(nitro.options.rootDir),
src: resolve(nitro.options.srcDir),
build: resolve(nitro.options.buildDir),
cache: resolve(nitro.options.rootDir, 'node_modules/.nitro/cache')
root: resolve(options.rootDir),
src: resolve(options.srcDir),
build: resolve(options.buildDir),
cache: resolve(options.buildDir, 'cache')
}
for (const p in fsMounts) {
nitro.options.storage.mounts[p] = nitro.options.storage.mounts[p] || {
options.storage.mounts[p] = options.storage.mounts[p] || {
driver: 'fs',
driverOptions: { base: fsMounts[p] }
}
}
}

// Assets
nitro.options.assets.dirs.server = {
dir: resolve(nitro.options.srcDir, 'server/assets'), meta: true
}

if (nitro.options.autoImport) {
nitro.unimport = createUnimport(nitro.options.autoImport)
}

return nitro
}
58 changes: 29 additions & 29 deletions src/options.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,29 @@
import { resolve } from 'pathe'
import { loadConfig } from 'c12'
import { klona } from 'klona/full'
import defu from 'defu'
import { withLeadingSlash, withoutTrailingSlash } from 'ufo'
import { resolvePath, detectTarget } from './utils'
import type { NitroConfig, NitroOptions } from './types'
import { runtimeDir, pkgDir } from './dirs'
import * as PRESETS from './presets'
import { detectTarget } from './utils'

const NitroDefaults: NitroConfig = {
// General
dev: false,
preset: undefined,
logLevel: 3,
runtimeConfig: {
public: {
app: {
baseURL: '/',
cdnURL: undefined,
buildAssetsDir: '_dist'
}
},
public: {},
private: {}
},
app: {
baseURL: '/',
cdnURL: undefined,
buildAssetsDir: 'dist'
},

// Dirs
publicDir: 'public',
scanDirs: [],
buildDir: '.nitro',
output: {
Expand All @@ -32,13 +32,11 @@ const NitroDefaults: NitroConfig = {
publicDir: '{{ output.dir }}/public'
},

// Paths
routerBase: '/',
publicPath: '/',

// Featueres
experimental: {},
storage: { mounts: {} },
publicAssets: [],
serverAssets: [],

// Routing
handlers: [],
Expand All @@ -56,7 +54,6 @@ const NitroDefaults: NitroConfig = {
analyze: false,
moduleSideEffects: ['unenv/runtime/polyfill/'],
replace: {},
assets: { dirs: { } },

// Advanced
nodeModulesDirs: [],
Expand Down Expand Up @@ -87,35 +84,38 @@ export async function loadOptions (userConfig: NitroConfig = {}): Promise<NitroO
]
}
})

// Normalize options
const options = klona(config) as NitroOptions
options._config = userConfig

options.rootDir = resolve(options.rootDir || '.')
options.srcDir = resolve(options.srcDir || options.rootDir)
for (const key of ['srcDir', 'publicDir', 'buildDir']) {
options[key] = resolve(options.rootDir, options[key])
}

// Resolve possibly template paths
options.entry = resolvePath(options.entry, options)
options.output.dir = resolvePath(options.output.dir, options)
options.output.publicDir = resolvePath(options.output.publicDir, options)
options.output.serverDir = resolvePath(options.output.serverDir, options)

options.nodeModulesDirs.push(resolve(options.rootDir, 'node_modules'))
options.nodeModulesDirs.push(resolve(pkgDir, 'node_modules'))
options.nodeModulesDirs = Array.from(new Set(options.nodeModulesDirs))

if (!options.scanDirs.length) {
options.scanDirs = [options.srcDir]
}

// Dev-only storage
if (options.dev) {
const fsMounts = {
root: resolve(options.rootDir),
src: resolve(options.srcDir),
build: resolve(options.buildDir),
cache: resolve(options.rootDir, '.cache')
}
for (const p in fsMounts) {
options.storage.mounts[p] = options.storage.mounts[p] || {
driver: 'fs',
driverOptions: { base: fsMounts[p] }
}
options.runtimeConfig = defu(options.runtimeConfig, {
public: {
app: options.app
}
})

for (const asset of options.publicAssets) {
asset.dir = resolve(options.srcDir, asset.dir)
asset.baseURL = withLeadingSlash(withoutTrailingSlash(asset.baseURL || '/'))
}

return options
Expand Down
12 changes: 6 additions & 6 deletions src/presets/browser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,15 +63,15 @@ if ('serviceWorker' in navigator) {

// Temp fix
if (!existsSync(resolve(nitro.options.output.publicDir, 'index.html'))) {
await fsp.writeFile(resolve(nitro.options.publicDir, 'index.html'), html, 'utf8')
await fsp.writeFile(resolve(nitro.options.output.publicDir, 'index.html'), html, 'utf8')
}
if (!existsSync(resolve(nitro.options.publicDir, '200.html'))) {
await fsp.writeFile(resolve(nitro.options.publicDir, '200.html'), html, 'utf8')
if (!existsSync(resolve(nitro.options.output.publicDir, '200.html'))) {
await fsp.writeFile(resolve(nitro.options.output.publicDir, '200.html'), html, 'utf8')
}
if (!existsSync(resolve(nitro.options.publicDir, '404.html'))) {
await fsp.writeFile(resolve(nitro.options.publicDir, '404.html'), html, 'utf8')
if (!existsSync(resolve(nitro.options.output.publicDir, '404.html'))) {
await fsp.writeFile(resolve(nitro.options.output.publicDir, '404.html'), html, 'utf8')
}
nitro.logger.info('Ready to deploy to static hosting:', prettyPath(nitro.options.publicDir as string))
nitro.logger.info('Ready to deploy to static hosting:', prettyPath(nitro.options.output.publicDir as string))
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/presets/dev.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ export const dev = defineNitroPreset({
extends: 'node',
entry: '#nitro/entries/dev',
output: {
serverDir: '{{ buildDir }}/nitro-dev'
serverDir: '{{ buildDir }}/dev'
},
externals: { trace: false },
inlineDynamicImports: true, // externals plugin limitation
Expand Down
2 changes: 1 addition & 1 deletion src/presets/firebase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ async function writeRoutes (nitro: Nitro) {
hosting: [
{
site: '<your_project_id>',
public: relative(nitro.options.rootDir, nitro.options.publicDir),
public: relative(nitro.options.rootDir, nitro.options.output.publicDir),
cleanUrls: true,
rewrites: [
{
Expand Down
30 changes: 17 additions & 13 deletions src/rollup/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,13 @@ import type { Preset } from 'unenv'
import { sanitizeFilePath } from 'mlly'
import unimportPlugin from 'unimport/unplugin'
import type { Nitro } from '../types'
import { resolveAliases, resolvePath } from '../utils'
import { resolveAliases } from '../utils'
import { runtimeDir } from '../dirs'
import { dynamicRequire } from './plugins/dynamic-require'
import { externals } from './plugins/externals'
import { timing } from './plugins/timing'
// import { autoMock } from './plugins/automock'
import { staticAssets, dirnames } from './plugins/static'
import { assets } from './plugins/assets'
import { publicAssets } from './plugins/public-assets'
import { serverAssets } from './plugins/server-assets'
import { handlers } from './plugins/handlers'
import { esbuild } from './plugins/esbuild'
import { raw } from './plugins/raw'
Expand Down Expand Up @@ -57,7 +56,7 @@ export const getRollupConfig = (nitro: Nitro) => {
const runtimeAppDir = join(runtimeDir, 'app')

const rollupConfig: RollupConfig = {
input: resolvePath(nitro, nitro.options.entry),
input: nitro.options.entry,
output: {
dir: nitro.options.output.serverDir,
entryFileNames: 'index.mjs',
Expand Down Expand Up @@ -140,8 +139,6 @@ export const getRollupConfig = (nitro: Nitro) => {
'process.server': 'true',
'process.client': 'false',
'process.dev': String(nitro.options.dev),
'process.env.ROUTER_BASE': JSON.stringify(nitro.options.routerBase),
'process.env.PUBLIC_PATH': JSON.stringify(nitro.options.publicPath),
'process.env.RUNTIME_CONFIG': devalue(nitro.options.runtimeConfig),
'process.env.DEBUG': JSON.stringify(nitro.options.dev),
...nitro.options.replace
Expand All @@ -168,14 +165,21 @@ export const getRollupConfig = (nitro: Nitro) => {
]
}))

// Assets
rollupConfig.plugins.push(assets(nitro.options.assets))
// Server assets
rollupConfig.plugins.push(serverAssets(nitro))

// Static
// TODO: use assets plugin
// Public assets
if (nitro.options.serveStatic) {
rollupConfig.plugins.push(dirnames())
rollupConfig.plugins.push(staticAssets(nitro))
rollupConfig.plugins.push({
name: 'dirnames',
renderChunk (code, chunk) {
return {
code: (chunk.isEntry ? 'globalThis.entryURL = import.meta.url;' : '') + code,
map: null
}
}
})
rollupConfig.plugins.push(publicAssets(nitro))
}

// Storage
Expand Down
Loading

0 comments on commit 305c498

Please sign in to comment.