Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dev with ts-node #4

Merged
merged 13 commits into from Nov 28, 2020
4 changes: 2 additions & 2 deletions README.md
Expand Up @@ -39,7 +39,7 @@ Other providers (Netlify, Vercel, etc.) offer free tier generally.
3. Import `vitedge/plugin.js` in your `vite.config.js`. [Example here](./example/vite.config.js).
4. Import and call Vitedge from your app's entry point providing your main `App.vue` and your page routes. Vitedge will create the router and attach the app to the DOM for you according to the running environment. [Example here](./example/src/main.js).
5. Add page props or API handlers in [functions directory](./example/functions).
6. Develop locally with Vite's blazing fast HMR running `vite --open`.
6. Develop locally with Vite's blazing fast HMR running `vitedge dev --open` (pass any Vite CLI option). When using TypeScript, make sure `typescript` and `ts-node` are installed as devDependencies.
7. Build using `vitedge build` command, import `vitedge/worker` in your [worker entry point](./example/worker-site/index.js) and add a custom [Webpack config](./example/worker-site/webpack.config.js).

## TODOS - Raw ideas
Expand All @@ -53,7 +53,7 @@ Other providers (Netlify, Vercel, etc.) offer free tier generally.
- [ ] Auth utilities (passing JWT in requests)
- [ ] List of pages that should be prerrendered automatically after deployment
- [x] Compatibility with Node runtime for other providers (Vercel/...)
- [ ] Detect imported files in HTML and push them with HTTP2
- [ ] Detect imported files in HTML and push them with HTTP/2
- [ ] Sitemap utility (handler in `<root>/functions/sitemap.js`?)
- [ ] React/Preact compatibility.

Expand Down
27 changes: 23 additions & 4 deletions core/bin/cli.js
Expand Up @@ -3,6 +3,7 @@
import path from 'path'
import { promises as fs } from 'fs'
import { createRequire } from 'module'
import cp from 'child_process'

const [, , command, ...args] = process.argv

Expand All @@ -14,10 +15,17 @@ const patchVite = async () => {
try {
await fs.writeFile(
viteConfigLoader,
(await fs.readFile(viteConfigLoader, 'utf8')).replace(
/\srequire\(resolvedPath\)/,
' await import(resolvedPath); config = config.default || config'
)
(await fs.readFile(viteConfigLoader, 'utf8'))
// Use native ESM to import config file instead of Rollup
.replace(
/\srequire\(resolvedPath\)/,
' await import(resolvedPath); config = config.default || config'
)
// Ignore TS check to keep using native ESM with ts-node instead of Rollup
.replace(
/if\s+\(!isTS\)/i,
'if (!isTS || process[Symbol.for("ts-node.register.instance")])'
)
)
} catch (error) {
console.warn('Vitedge could not patch Vite:', error.message)
Expand All @@ -29,6 +37,17 @@ const patchVite = async () => {
const { default: build } = await import('vitedge/build/index.js')
await build()
process.exit()
} else if (command === 'dev') {
args.unshift('node_modules/.bin/vite')

const { default: config } = await import('vitedge/config.cjs')
if (config.isTS) {
args.unshift('--loader', 'ts-node/esm')
}

cp.spawn('node', args, {
stdio: [process.stdin, process.stdout, process.stderr],
})
} else if (command === 'patch') {
await patchVite()
process.exit()
Expand Down
2 changes: 1 addition & 1 deletion core/build/index.js
@@ -1,5 +1,5 @@
import path from 'path'
import buildSSR from 'vite-ssr/build/index.js'
import buildSSR from 'vite-ssr/build.js'
import buildFunctions from './functions.js'

import config from '../config.cjs'
Expand Down
15 changes: 2 additions & 13 deletions core/config.cjs
@@ -1,18 +1,7 @@
const fs = require('fs')
const path = require('path')

const viteConfigName = 'vite.config.js'

let rootDir = process.cwd()
if (!fs.existsSync(path.resolve(rootDir, viteConfigName))) {
rootDir = path.resolve(process.cwd(), '..')
if (!fs.existsSync(path.resolve(rootDir, viteConfigName))) {
throw new Error(`Could not find ${viteConfigName}`)
}
}
const { getProjectInfo } = require('vite-ssr/config')

module.exports = {
rootDir,
...getProjectInfo(),
outDir: 'dist',
clientOutDir: 'client',
ssrOutDir: 'ssr',
Expand Down
2 changes: 1 addition & 1 deletion core/package.json
Expand Up @@ -37,6 +37,6 @@
"@rollup/plugin-virtual": "^2.0.3",
"fast-glob": "^3.2.4",
"rollup": "^2.33.1",
"vite-ssr": "^0.0.6"
"vite-ssr": "^0.0.7"
}
}
15 changes: 12 additions & 3 deletions core/plugin.js
Expand Up @@ -12,11 +12,20 @@ export default {
server, // raw http server instance
watcher, // chokidar file watcher instance
}) => {
const cacheBust = new Map()
watcher.on('change', (fullPath) => {
if (fullPath.replace(root, '').startsWith('/functions/')) {
const filePath = fullPath.replace(/\.[jt]sx?$/i, '')
cacheBust.set(filePath, (cacheBust.get(filePath) || 0) + 1)
}
})

async function handleFunctionRequest(ctx, functionPath) {
try {
const filePath = root + '/functions' + functionPath + '.js'
const cacheBust = `?cacheBust=${Math.random().toString(36).substr(2)}`
let endpointMeta = await import(filePath + cacheBust)
const filePath = root + '/functions' + functionPath
let endpointMeta = await import(
filePath + '.js' + `?cacheBust=${cacheBust.get(filePath) || 0}`
)

if (endpointMeta) {
endpointMeta = endpointMeta.default || endpointMeta
Expand Down
7 changes: 1 addition & 6 deletions core/webpack.cjs
Expand Up @@ -7,12 +7,7 @@ module.exports = {
resolve: {
mainFields: ['main', 'module'],
alias: {
__vitedge_router__: path.resolve(
rootDir,
outDir,
ssrOutDir,
'_assets/src/main.js'
),
__vitedge_router__: path.resolve(rootDir, outDir, ssrOutDir),
__vitedge_functions__: path.resolve(rootDir, outDir, fnsOutFile),
},
},
Expand Down