Skip to content

Commit

Permalink
feat: add dependency merging
Browse files Browse the repository at this point in the history
  • Loading branch information
krmax44 committed Jul 28, 2019
1 parent afd444e commit 284759f
Show file tree
Hide file tree
Showing 9 changed files with 703 additions and 194 deletions.
26 changes: 26 additions & 0 deletions packages/saber/lib/cli-commands/build.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
const { setNodeEnv, handleError } = require('./utils')

module.exports = function(cli) {
cli
.command(
'build [app]',
'Compile the application and generate static HTML files'
)
.alias('generate')
.option('--skip-compilation', 'Skip the webpack compilation process')
.action((cwd = '.', options) => {
setNodeEnv('production')

if (cli.matchedCommandName === 'generate') {
require('saber-log').log.warn(
`The "generate" command is now deprecated, please use "build" instead.`
)
}

const { skipCompilation } = options
delete options.skipCompilation
return require('..')(Object.assign({ cwd, dev: false }, options))
.build({ skipCompilation })
.catch(handleError)
})
}
31 changes: 31 additions & 0 deletions packages/saber/lib/cli-commands/dev.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
const { setNodeEnv, handleError } = require('./utils')

module.exports = function(cli) {
cli
.command('[app]', 'Run the application in dev mode', {
ignoreOptionDefaultValue: true
})
.alias('dev')
.option('--lazy', 'Enable lazy page compilation')
.option('--port <port>', 'Server port', { default: 3000 })
.option('--host <host>', 'Server host', { default: '0.0.0.0' })
.action((cwd = '.', options) => {
setNodeEnv('development')

const { host, port, lazy } = options
delete options.host
delete options.port
delete options.lazy
return require('..')(Object.assign({ cwd, dev: true }, options), {
server: {
host,
port
},
build: {
lazy
}
})
.serve()
.catch(handleError)
})
}
152 changes: 152 additions & 0 deletions packages/saber/lib/cli-commands/eject.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
const path = require('path')
const { spawnSync } = require('child_process')
const { fs } = require('saber-utils')
const { log } = require('saber-log')
const downloadRepo = require('download-git-repo')
const configLoader = require('../utils/configLoader')
const resolvePackage = require('../utils/resolvePackage')
const { handleError, spawn } = require('./utils')

module.exports = function(cli) {
cli
.command(
'eject [app]',
`Copy the currently used theme's source code to a local folder.`
)
.option(
'--git',
'Pull code from Git, instead of node_modules, and add the theme as a submodule',
{ default: false }
)
.option(
'--merge-dependencies',
"Copy over the theme's dependencies to your project's package.json.",
{ default: true }
)
.option('--path <path>', 'Ejected theme destination', {
default: './theme'
})
.action(async (cwd = '.', options) => {
cwd = path.join(process.cwd(), cwd)
const { git } = options
const mergeDependencies = options['merge-dependencies']

const config =
configLoader.load({ cwd, files: configLoader.CONFIG_FILES }).data || {}
if (!config.theme) {
handleError('No theme specified in config.')
}

const destPath = path.join(cwd, options.path)
const relativeDest = path.relative(cwd, destPath)
if (await fs.pathExists(destPath)) {
handleError(
`The path ${
options.path
} already exists. Please specify a different one using "--path".`
)
}

const themePath = resolvePackage(config.theme, {
prefix: 'saber-theme-',
cwd
})
if (!themePath) {
handleError(
`Theme "${config.theme}" could not be found in your node_modules.`
)
}

const themePackage = configLoader.load({
cwd: themePath,
files: ['package.json']
}).data

if (git) {
const repo = themePackage.repository
if (repo && repo.url) {
const tmp = path.join(cwd, '.saber', 'theme-tmp')

const dl = await new Promise(resolve =>
downloadRepo(repo.url, tmp, {}, resolve)
)

if (dl) {
handleError(dl)
}

try {
await fs.move(
repo.directory ? path.join(tmp, repo.directory) : tmp,
destPath
)

await fs.remove(tmp)
} catch (error) {
handleError(error)
}

log.success('Downloaded theme source via Git.')
} else {
handleError(
'The theme has no git repository specified within its package.json.'
)
}
} else {
try {
await fs.copy(themePath, destPath, {
filter: src => !src.endsWith('/node_modules')
})

log.info('Copied theme from node_modules.')
} catch (error) {
handleError(error)
}
}

if (mergeDependencies) {
const dependencies = themePackage.dependencies || {}
const devDependencies = themePackage.devDependencies || {}

const projectPackage = configLoader.load({
cwd,
files: ['package.json']
}).data

try {
await fs.writeJson(
path.join(cwd, 'package.json'),
{
...projectPackage,
dependencies: {
...projectPackage.dependencies,
...dependencies,
[themePackage.name]: undefined // remove theme from dependencies
},
devDependencies: {
...projectPackage.devDependencies,
...devDependencies,
[themePackage.name]: undefined // remove theme from dev dependencies
}
},
{ spaces: 2 }
)

try {
spawnSync('yarn', ['--version']) // test if yarn is present before allowing it to use the same stdio
await spawn('yarn', [], { stdio: 'inherit' })
} catch (error) {
await spawn('npm i', [], { stdio: 'inherit' })
}

log.success('Merged theme dependencies.')
} catch (error) {
handleError(error)
}
}

log.info(
`Please change "theme" in your Saber config to "./${relativeDest}".`
)
})
}
5 changes: 5 additions & 0 deletions packages/saber/lib/cli-commands/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
const commands = ['dev', 'build', 'serve', 'eject']

module.exports = function(cli) {
commands.forEach(command => require(`./${command}`)(cli))
}
23 changes: 23 additions & 0 deletions packages/saber/lib/cli-commands/serve.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
const { setNodeEnv, handleError } = require('./utils')

module.exports = function(cli) {
cli
.command('serve [app]', 'Serve the output directory')
.option('--host <host>', 'Server host', { default: '0.0.0.0' })
.option('--port <port>', 'Server port', { default: 3000 })
.action((cwd = '.', options) => {
setNodeEnv('production')

const { host, port } = options
delete options.host
delete options.port
return require('..')(Object.assign({ cwd, dev: true }, options), {
server: {
host,
port
}
})
.serveOutDir()
.catch(handleError)
})
}
21 changes: 21 additions & 0 deletions packages/saber/lib/cli-commands/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
const { spawn } = require('child_process')

module.exports = {
setNodeEnv(env) {
if (!process.env.NODE_ENV) {
process.env.NODE_ENV = env
}
},
handleError(err) {
if (typeof err === 'string') err = new Error(err)
require('saber-log').log.error(err.stack)
process.exit(1) // eslint-disable-line
},
spawn(...args) {
return new Promise((resolve, reject) => {
const childProcess = spawn(...args)
childProcess.on('close', resolve)
childProcess.on('error', reject)
})
}
}
Loading

0 comments on commit 284759f

Please sign in to comment.