Skip to content

Commit

Permalink
feat: working poc
Browse files Browse the repository at this point in the history
  • Loading branch information
pi0 committed Feb 9, 2022
1 parent b9cdcbd commit 6f5c475
Show file tree
Hide file tree
Showing 26 changed files with 162 additions and 130 deletions.
28 changes: 26 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,30 @@
# 🚀 Nitopack
# Nitopack

> Next Generation Web Framework
> Next Generation Web Tooling
## 🚀 Quick Start

1️⃣ Create `api/test.ts`:

```ts [api/test.ts]
export default () => 'Nitro is amazing!'
```

2️⃣ Start development server with HMR using `npx nitropack dev` command:

> Your API is ready at http://localhost:3000/api/test
3️⃣ You can now build your production ready server:

```bash
npx nitropack build
````

4️⃣ Output is in `.output` directory and ready to be deployed on almost any VPS with no dependencies. You can locally try it too:

```bash
node .output/server/index.mjs
```

## 💻 Development

Expand Down
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"name": "nitropack",
"version": "0.0.0",
"description": "Next Generation Web Tooling",
"license": "MIT",
"type": "module",
"exports": {
Expand All @@ -20,6 +21,7 @@
"build": "unbuild",
"dev": "yarn nitro dev playground",
"dev:build": "yarn nitro build playground",
"dev:start": "node playground/.output/server/index.mjs",
"lint": "eslint --ext .ts,.mjs,.cjs .",
"nitro": "jiti ./src/cli.ts",
"prepack": "yarn build"
Expand Down
1 change: 1 addition & 0 deletions playground/api/test.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default () => 'API Works!'
1 change: 0 additions & 1 deletion playground/server/api/test.ts

This file was deleted.

5 changes: 0 additions & 5 deletions playground/server/middleware/test.ts

This file was deleted.

6 changes: 3 additions & 3 deletions src/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ async function writeTypes (nitro: Nitro) {
}

async function _build (nitro: Nitro) {
nitro.scannedMiddleware = await scanMiddleware(nitro.options.serverDir)
nitro.scannedMiddleware = await scanMiddleware(nitro.options.srcDir)
await writeTypes(nitro)

consola.start('Building server...')
Expand Down Expand Up @@ -153,6 +153,7 @@ function startRollupWatcher (nitro: Nitro) {
case 'END':
nitro.hooks.callHook('nitro:compiled', nitro)
consola.success('Nitro built', start ? `in ${Date.now() - start} ms` : '')
nitro.hooks.callHook('nitro:dev:reload')
return

// Encountered an error while bundling
Expand All @@ -166,8 +167,7 @@ function startRollupWatcher (nitro: Nitro) {

async function _watch (nitro: Nitro) {
let watcher = startRollupWatcher(nitro)

nitro.scannedMiddleware = await scanMiddleware(nitro.options.serverDir,
nitro.scannedMiddleware = await scanMiddleware(nitro.options.srcDir,
(middleware, event) => {
nitro.scannedMiddleware = middleware
if (['add', 'addDir'].includes(event)) {
Expand Down
5 changes: 2 additions & 3 deletions src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ async function main () {
const rootDir = resolve(args._[1] || '.')

if (command === 'dev') {
const nitro = createNitro({
const nitro = await createNitro({
rootDir,
dev: true,
preset: 'dev'
Expand All @@ -21,12 +21,11 @@ async function main () {
await server.listen({})
await prepare(nitro)
await build(nitro)
await server.reload()
return
}

if (command === 'build') {
const nitro = createNitro({
const nitro = await createNitro({
rootDir,
dev: false,
preset: 'server'
Expand Down
94 changes: 6 additions & 88 deletions src/nitro.ts
Original file line number Diff line number Diff line change
@@ -1,67 +1,12 @@
import { resolve } from 'pathe'
import defu from 'defu'
import { createHooks } from 'hookable'
import { tryImport, resolvePath, detectTarget } from './utils'
import * as PRESETS from './presets'
import type { Nitro, NitroOptions, NitroConfig } from './types'
// import { mergeHooks } from 'hookable'
import { pkgDir, runtimeDir } from './dirs'
import type { NitroConfig, Nitro } from './types'
import { resolvePath } from './utils'
import { loadOptions } from './options'

const nitroDefaults: NitroConfig = {
alias: {
'#nitro': runtimeDir
},
unenv: {},
analyze: false,
experiments: {},
moduleSideEffects: ['unenv/runtime/polyfill/'],
middleware: [],
modulesDir: [],
ignore: [],
hooks: {},
output: {
dir: '{{ rootDir }}/.output',
serverDir: '{{ output.dir }}/server',
publicDir: '{{ output.dir }}/public'
},
storage: { mounts: {} },
commands: {},
assets: {
// inline: !config.dev,
dirs: {}
},
publicDir: 'public',
serverDir: 'server',
routerBase: '/',
publicPath: '/',
runtimeConfig: {
public: {
app: {
baseURL: '/',
cdnURL: undefined,
buildAssetsDir: '_dist'
}
},
private: {}
}
}

export function createNitro (config: NitroConfig = {}): Nitro {
// Apply nitro defaults
config = defu(config, nitroDefaults)

// Apply preset defaults
config.extends = config.preset = process.env.NITRO_PRESET || config.extends || config.preset || detectTarget() || 'server'
config = extendConfig(config)

// Normalize options
const options = config as NitroOptions
options.rootDir = resolve(options.rootDir || '.')
for (const key of ['srcDir', 'publicDir', 'serverDir', 'generateDir', 'buildDir']) {
options[key] = resolve(options.rootDir, options[key])
}
options.modulesDir.push(resolve(options.rootDir, 'node_modules'))
options.modulesDir.push(resolve(pkgDir, 'node_modules'))
export async function createNitro (config: NitroConfig = {}): Promise<Nitro> {
// Resolve options
const options = await loadOptions(config)

// Create context
const nitro: Nitro = {
Expand Down Expand Up @@ -102,30 +47,3 @@ export function createNitro (config: NitroConfig = {}): Nitro {

return nitro
}

function extendConfig (config: NitroConfig): NitroConfig {
if (!config.extends) {
return config
}

let _extends = config.extends
if (typeof config.extends === 'string') {
type Preset = NitroConfig['preset']
_extends = (PRESETS as Record<string, Preset>)[config.extends] || tryImport(config.rootDir, config.extends) || {}
if (!_extends) {
throw new Error('Cannot resolve config: ' + config.extends)
}
_extends = (_extends as any).default || _extends
}
if (typeof _extends === 'function') {
_extends = _extends(config)
}

// TODO: Merge hooks
const preset = extendConfig(_extends as NitroConfig)
return defu(config, preset)
}

export function defineNitroPreset (preset: NitroConfig['extends']) {
return preset
}
89 changes: 89 additions & 0 deletions src/options.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import defu from 'defu'
import { resolve } from 'pathe'
import type { NitroConfig, NitroOptions } from './types'
import { runtimeDir, pkgDir } from './dirs'
import * as PRESETS from './presets'
import { tryImport, detectTarget } from './utils'

const defaultNitroConfig = () => ({
alias: {
'#nitro': runtimeDir
},
unenv: {},
analyze: false,
experiments: {},
moduleSideEffects: ['unenv/runtime/polyfill/'],
middleware: [],
modulesDir: [],
ignore: [],
hooks: {},
output: {
dir: '{{ rootDir }}/.output',
serverDir: '{{ output.dir }}/server',
publicDir: '{{ output.dir }}/public'
},
storage: { mounts: {} },
commands: {},
assets: {
// inline: !config.dev,
dirs: {}
},
publicDir: 'public',
srcDir: undefined,
routerBase: '/',
publicPath: '/',
runtimeConfig: {
public: {
app: {
baseURL: '/',
cdnURL: undefined,
buildAssetsDir: '_dist'
}
},
private: {}
}
}) as NitroConfig

export function loadOptions (config: NitroConfig = {}): NitroOptions {
// Apply nitro defaults
config = defu(config, defaultNitroConfig())

// Apply preset defaults
config.extends = config.preset = process.env.NITRO_PRESET || config.extends || config.preset || detectTarget() || 'server'
config = extendConfig(config)

// Normalize options
const options = config as NitroOptions
options.rootDir = resolve(options.rootDir || '.')
options.srcDir = resolve(options.srcDir || options.rootDir)
for (const key of ['srcDir', 'publicDir', 'generateDir', 'buildDir']) {
options[key] = resolve(options.rootDir, options[key])
}
options.modulesDir.push(resolve(options.rootDir, 'node_modules'))
options.modulesDir.push(resolve(pkgDir, 'node_modules'))

return options
}

function extendConfig (config: NitroConfig): NitroConfig {
if (!config.extends) {
return config
}

let _extends = config.extends
if (typeof config.extends === 'string') {
type Preset = NitroConfig['preset']
_extends = (PRESETS as Record<string, Preset>)[config.extends] || tryImport(config.rootDir, config.extends) || {}
if (!_extends) {
throw new Error('Cannot resolve config: ' + config.extends)
}
_extends = (_extends as any).default || _extends
}
if (typeof _extends === 'function') {
_extends = _extends(config)
}

// TODO: Merge hooks
const preset = extendConfig(_extends as NitroConfig)
return defu(config, preset)
}
5 changes: 5 additions & 0 deletions src/preset.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import type { NitroConfig } from './types'

export function defineNitroPreset (preset: NitroConfig['extends']) {
return preset
}
2 changes: 1 addition & 1 deletion src/presets/azure.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import fse from 'fs-extra'
import { globby } from 'globby'
import { join, resolve } from 'pathe'
import { writeFile } from '../utils'
import { defineNitroPreset } from '../nitro'
import { defineNitroPreset } from '../preset'
import type { Nitro } from '../types'

export const azure = defineNitroPreset({
Expand Down
4 changes: 2 additions & 2 deletions src/presets/azure_functions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { createWriteStream } from 'fs'
import archiver from 'archiver'
import { join, resolve } from 'pathe'
import { writeFile } from '../utils'
import { defineNitroPreset } from '../nitro'
import { defineNitroPreset } from '../preset'
import type { Nitro } from '../types'

// eslint-disable-next-line
Expand Down Expand Up @@ -68,7 +68,7 @@ async function writeRoutes (nitro: Nitro) {
]
}

await writeFile(resolve(nitro.options.serverDir, 'function.json'), JSON.stringify(functionDefinition))
await writeFile(resolve(nitro.options.srcDir, 'function.json'), JSON.stringify(functionDefinition))
await writeFile(resolve(nitro.options.output.dir, 'host.json'), JSON.stringify(host))
await zipDirectory(nitro.options.output.dir, join(nitro.options.output.dir, 'deploy.zip'))
}
2 changes: 1 addition & 1 deletion src/presets/browser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { resolve } from 'pathe'
import consola from 'consola'
import { joinURL } from 'ufo'
import { prettyPath } from '../utils'
import { defineNitroPreset } from '../nitro'
import { defineNitroPreset } from '../preset'

export const browser = defineNitroPreset((_input) => {
// TODO
Expand Down
4 changes: 2 additions & 2 deletions src/presets/cli.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { defineNitroPreset } from '../nitro'
import { defineNitroPreset } from '../preset'

export const cli = defineNitroPreset({
extends: 'node',
entry: '#nitro/entries/cli',
commands: {
preview: 'Run with node {{ options.serverDir }} [route]'
preview: 'Run with node {{ options.srcDir }} [route]'
}
})
2 changes: 1 addition & 1 deletion src/presets/cloudflare.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { resolve } from 'pathe'
import { writeFile } from '../utils'
import { defineNitroPreset } from '../nitro'
import { defineNitroPreset } from '../preset'
import type { Nitro } from '../types'

export const cloudflare = defineNitroPreset({
Expand Down
4 changes: 2 additions & 2 deletions src/presets/dev.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { defineNitroPreset } from '../nitro'
import { defineNitroPreset } from '../preset'

export const dev = defineNitroPreset({
extends: 'node',
entry: '#nitro/entries/dev',
output: {
serverDir: '{{ options.buildDir }}/nitro'
serverDir: '{{ buildDir }}/nitro'
},
externals: { trace: false },
inlineDynamicImports: true, // externals plugin limitation
Expand Down
Loading

0 comments on commit 6f5c475

Please sign in to comment.