Skip to content

Commit

Permalink
Add vercel-sapper command to configure a project for Vercel
Browse files Browse the repository at this point in the history
  • Loading branch information
thgh committed Jul 26, 2020
1 parent b7d0a05 commit 0dfa69f
Show file tree
Hide file tree
Showing 3 changed files with 157 additions and 1 deletion.
10 changes: 9 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,15 @@ Vercel builder for Sapper with SSR enabled
* [x] Deploy your Sapper app as a Lambda in 30 seconds.
* [x] Serve all static assets from a CDN.

## Basic usage
## Automatic configuration

Run `npx vercel-sapper` on an existing project.

Or create a new project with `npx vercel-sapper my-project`

_🧪 This feature is experimental, let us know what you think => https://github.com/thgh/vercel-sapper/pull/47_

## Manual configuration

You must make 3 changes to your project to get started:

Expand Down
144 changes: 144 additions & 0 deletions bin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
#!/usr/bin/env node

const fs = require('fs')
const { join } = require('path')

;(async () => {
console.log(
yellow(
'🧪 This feature is experimental, let us know what you think' +
'=> https://github.com/thgh/vercel-sapper/pull/47\n'
)
)
// Fallback to current working directory
const dir = process.argv[2] || '.'

// TODO: Create a new project if the directory is empty
// Create a new project if the directory does not exist
if (!fs.existsSync(dir)) {
await degit(dir)
}

// Configure the project for Vercel
patch(dir)

console.log(green('\nDeploy your Sapper project:\n'))
console.log(' cd', dir)
console.log(' vercel\n')
})()

function degit(dir) {
return new Promise((resolve) => {
console.log(green('degit'), `sveltejs/sapper-template#rollup`)
require('child_process').execFile(
'npx',
['degit', 'sveltejs/sapper-template#rollup', dir],
(err, stdout, stderr) => {
if (err) {
console.error(red('something went wrong with degit'), err)
return
}

stdout && console.log(stdout.trim())
stderr && console.log(stderr.trim())
console.log(green('Created'), `Sapper project in ${dir}`)
resolve()
}
)
})
}

async function patch(dir) {
try {
if (!fs.existsSync(join(dir, 'src/server.js'))) {
throw new Error(
'expected src/server.js to exist, is this really a Sapper project?'
)
}
const server = fs.readFileSync(join(dir, 'src/server.js'), 'utf8')
fs.writeFileSync(join(dir, 'src/server.js'), patchServer(server))
console.log(green('Patched'), 'src/server.js')
} catch (e) {
console.error(red(e.message))
}

try {
if (fs.existsSync(join(dir, 'vercel.json'))) {
throw new Error('vercel.json already exists')
}
fs.writeFileSync(
join(dir, 'vercel.json'),
`{
"version": 2,
"builds": [
{
"src": "package.json",
"use": "vercel-sapper"
}
]
}`
)
console.log(green('Created'), 'vercel.json')
} catch (e) {
console.error(red(e.message))
}

try {
if (fs.existsSync(join(dir, '.vercelignore'))) {
throw new Error('.vercelignore already exists')
}
fs.writeFileSync(
join(dir, '.vercelignore'),
`__sapper__
cypress
node_modules`
)
console.log(green('Created'), '.vercelignore')
} catch (e) {
console.error(red(e.message))
}
}

function patchServer(server) {
if (server.includes('export default')) {
throw new Error('src/server.js was already patched')
}
if (server.includes('module.exports')) {
throw new Error('src/server.js was already patched')
}
if (!server.includes('polka()') && !server.includes('express()')) {
throw new Error('src/server.js should contain polka() or express()')
}

// Simplest case
if (server.includes('\npolka()')) {
return server.replace('\npolka()', '\nexport default polka()')
}
if (server.includes('\nexpress()')) {
return server.replace('\nexpress()', '\nexport default express()')
}

// Server is assigned to variable
if (server.includes('= polka()')) {
return server.replace('= polka()', '= (module.exports = polka())')
}
if (server.includes('= express()')) {
return server.replace('= express()', '= (module.exports = express())')
}

throw new Error(
'src/server.js needs manual patch: https://www.npmjs.com/package/vercel-sapper#manual-configuration'
)
}

function red(text) {
return '\u001b[1m\u001b[31m' + text + '\u001b[39m\u001b[22m'
}

function green(text) {
return '\u001b[1m\u001b[32m' + text + '\u001b[39m\u001b[22m'
}

function yellow(text) {
return '\u001b[1m\u001b[33m' + text + '\u001b[39m\u001b[22m'
}
4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@
"license": "MIT",
"description": "Vercel builder for Sapper with SSR enabled",
"main": "index.js",
"bin": {
"vercel-sapper": "./bin.js"
},
"files": [
"bin.js",
"index.js",
"lib",
"yarn.lock"
Expand Down

0 comments on commit 0dfa69f

Please sign in to comment.