-
Notifications
You must be signed in to change notification settings - Fork 44
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(local-cli): implement build, develop and serve commands
- Loading branch information
1 parent
520c1d7
commit 6378026
Showing
9 changed files
with
366 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
'use strict'; | ||
|
||
var hopsBuild = require('hops-build'); | ||
|
||
module.exports = function buildCommand (callback) { | ||
return { | ||
command: 'build', | ||
describe: 'Builds the browser and server JS bundles', | ||
builder: { | ||
static: { | ||
alias: 's', | ||
default: false, | ||
describe: 'Statically build locations', | ||
type: 'boolean' | ||
}, | ||
clean: { | ||
alias: 'c', | ||
default: true, | ||
describe: 'Clean up artifacts in build / cache directories before building', | ||
type: 'boolean' | ||
} | ||
}, | ||
handler: function buildHandler (argv) { | ||
hopsBuild.runBuild(argv, callback); | ||
} | ||
}; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
'use strict'; | ||
|
||
var hopsBuild = require('hops-build'); | ||
|
||
module.exports = function developCommand (callback) { | ||
return { | ||
command: 'develop', | ||
describe: 'Starts a webpack-dev-server to enable local development with ' + | ||
'hot code reloading', | ||
builder: { | ||
clean: { | ||
alias: 'c', | ||
default: true, | ||
describe: 'Clean up artifacts in build / cache directories before building', | ||
type: 'boolean' | ||
} | ||
}, | ||
handler: function developHandler (argv) { | ||
hopsBuild.runServer(argv, callback); | ||
} | ||
}; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
'use strict'; | ||
|
||
var hopsExpress = require('hops-express'); | ||
|
||
module.exports = function serveCommand (callback) { | ||
return { | ||
command: 'serve', | ||
describe: 'Starts a production-ready Node.js server to serve your ' + | ||
'application', | ||
builder: {}, | ||
handler: function serveHandler () { | ||
hopsExpress.startServer(callback); | ||
} | ||
}; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
#!/usr/bin/env node | ||
'use strict'; | ||
|
||
var init = require('./init'); | ||
var run = require('./run'); | ||
|
||
module.exports = { | ||
init: init, | ||
run: run | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
'use strict'; | ||
|
||
var pm = require('./lib/package-manager'); | ||
|
||
function init (appRoot, appName, options) { | ||
var useYarn = !!(pm.isGlobalCliUsingYarn() || pm.getYarnVersionIfAvailable()); | ||
|
||
var prodDependencies = [ | ||
'hops-express', | ||
'hops-react', | ||
'hops-redux', | ||
'react', | ||
'react-dom', | ||
'react-helmet', | ||
'react-redux', | ||
'react-router', | ||
'react-router-dom', | ||
'redux', | ||
'redux-thunk' | ||
]; | ||
var devDependencies = [ | ||
'hops-build', | ||
'jest', | ||
'jest-preset-hops', | ||
'react-test-renderer' | ||
]; | ||
pm.installPackages(prodDependencies, { yarn: useYarn }); | ||
pm.installPackages(devDependencies, { yarn: useYarn, dev: true }); | ||
|
||
// fetch template from github/npm and copy files into app folder | ||
} | ||
module.exports = init; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
'use strict'; | ||
|
||
var fs = require('fs'); | ||
var path = require('path'); | ||
var execSync = require('child_process').execSync; | ||
|
||
function execIgnoreStdError (command, options) { | ||
var commandToRun = process.platform.indexOf('win') === 0 | ||
? command + ' 2> NUL' | ||
: command + ' 2> /dev/null'; | ||
|
||
if (options.verbose) { | ||
console.log('Executing:', commandToRun); | ||
} | ||
var result = (options.execSync || execSync)(commandToRun); | ||
return result.toString('utf-8').trim(); | ||
} | ||
|
||
function getYarnVersionIfAvailable (options) { | ||
try { | ||
return execIgnoreStdError('yarn --version', options); | ||
} catch (error) { | ||
return null; | ||
} | ||
} | ||
module.exports.getYarnVersionIfAvailable = getYarnVersionIfAvailable; | ||
|
||
function getNpmVersionIfAvailable (options) { | ||
try { | ||
return execIgnoreStdError('npm --version', options); | ||
} catch (error) { | ||
return null; | ||
} | ||
} | ||
module.exports.getNpmVersionIfAvailable = getNpmVersionIfAvailable; | ||
|
||
function isGlobalCliUsingYarn (projectPath, options) { | ||
return fs.existsSync(path.join(projectPath, 'yarn.lock')); | ||
} | ||
module.exports.isGlobalCliUsingYarn = isGlobalCliUsingYarn; | ||
|
||
function installPackages (packages, options) { | ||
var command = null; | ||
if (options.installCommand) { | ||
command = options.installCommand.split(' '); | ||
} else { | ||
if (options.yarn) { | ||
command = [ | ||
'yarn', | ||
'add', | ||
'--exact' | ||
]; | ||
if (options.dev) { | ||
command.push('--dev'); | ||
} | ||
} else { | ||
command = [ | ||
'npm', | ||
'install', | ||
'--save-exact' | ||
]; | ||
if (options.dev) { | ||
command.push('--save-dev'); | ||
} else { | ||
command.push('--save'); | ||
} | ||
} | ||
if (options.verbose) { | ||
command.add('--verbose'); | ||
} | ||
} | ||
Array.prototype.push.apply(command, packages); | ||
|
||
try { | ||
if (options.verbose) { | ||
console.log('Executing:', command.join(' ')); | ||
} | ||
(options.execSync || execSync)(command.join(' '), { stdio: 'inherit' }); | ||
return true; | ||
} catch (error) { | ||
console.error(error.message); | ||
if (options.verbose) { | ||
console.error(error); | ||
console.error('Command: "', command.join(' '), 'has failed.'); | ||
} | ||
} | ||
return false; | ||
} | ||
module.exports.installPackages = installPackages; | ||
|
||
function isPackageInstalled (name) { | ||
try { | ||
require.resolve(name); | ||
return true; | ||
} catch (error) { | ||
return false; | ||
} | ||
} | ||
module.exports.isPackageInstalled = isPackageInstalled; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
{ | ||
"name": "hops-local-cli", | ||
"version": "6.2.8", | ||
"description": "CLI tool to build, run and develop Hops based projects", | ||
"keywords": [ | ||
"hops", | ||
"cli" | ||
], | ||
"license": "MIT", | ||
"bin": { | ||
"hops": "run.js" | ||
}, | ||
"main": "index.js", | ||
"files": [ | ||
"index.js", | ||
"init.js", | ||
"run.js", | ||
"commands", | ||
"lib" | ||
], | ||
"scripts": { | ||
"test": "echo \"Error: run tests in xing/hops repo\" && exit 1" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/xing/hops.git" | ||
}, | ||
"dependencies": { | ||
"yargs": "^9.0.1" | ||
}, | ||
"optionalDependencies": { | ||
"hops-build": "6.2.8", | ||
"hops-express": "6.2.8" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
# Hops CLI | ||
|
||
hops-cli provides a small set of commands to manage your hops project. Installing hops-cli is the minimum requirement for being able to start working with Hops. | ||
|
||
# Installation | ||
## Minimum installation for any project | ||
We assume that you already created a folder for your project and initialized it with `npm init -y`. Go to the root folder of your project and install hops-cli. This installs hops-config and hops-server as dependencies as well: | ||
``` bash | ||
npm install --save hops-cli | ||
``` | ||
|
||
That's it - at least this is sufficient to get you started with a very basic setup. | ||
|
||
## Additional setup for a React project | ||
In case you are going to implement a project with React, you need to install further packages: | ||
``` bash | ||
npm install --save react react-dom react-helmet react-router react-router-dom hops-react | ||
``` | ||
|
||
# Usage | ||
## Available commands | ||
The following commands are provided by hops-cli: | ||
|
||
- `hops build` - initiates a project build | ||
- `hops develop` - starts a Webpack development server | ||
- `hops serve` - initiates a project build, stores the build artifacts in the file system and starts a production (Express) server | ||
- `hops start` - if NODE_ENV is set to production, this runs `hops serve`. Otherwise, `hops develop` gets executed | ||
|
||
Please note that hops-cli is not meant to be called directly, but rather to be added to your project's package.json file and then called indirectly by using npm or yarn (see below). | ||
|
||
## Configure package.json | ||
To actually use the hops-cli commands, you have to add them to the scripts section of your project's package.json. Hops is designed to leverage npm/yarn features, so it does not make much sense to call the hops executable directly. | ||
|
||
``` JSON | ||
"scripts": { | ||
"build": "hops build", | ||
"develop": "hops develop", | ||
"serve": "hops serve", | ||
"start": "hops start" | ||
}, | ||
"config": { | ||
"hops": {} | ||
} | ||
``` | ||
|
||
However, for simple projects, it should be sufficient to just add `"start": "hops start"` here. | ||
|
||
To learn what configuration options are supported, please see the [`hops-config` docs](https://github.com/xing/hops/tree/master/packages/config#hops-config). | ||
|
||
## Static mode | ||
hops-cli can be used as a static site generator, too. To enable static mode, pass `--static` or `-s` to the above commands and configure a `locations` array to your package.json file. | ||
|
||
``` JSON | ||
"scripts": { | ||
"start": "hops start --static" | ||
}, | ||
"config": { | ||
"hops": { | ||
"locations": ["/"] | ||
} | ||
} | ||
``` | ||
|
||
## Use via npm | ||
After that, you can execute them via npm like so: | ||
|
||
``` bash | ||
npm run build | ||
npm run develop | ||
npm run serve | ||
npm start | ||
npm start --production | ||
``` | ||
|
||
## Very basic example app | ||
To try out the [minimum installation described above](#minimum-installation-for-any-project), create an index.js file in the root folder of your project and put the following code in there: | ||
|
||
``` js | ||
export default function (req, res, next) { | ||
if (req) { | ||
console.log('server'); | ||
if (req.path === '/') { | ||
res.set('Content-Type', 'text/html'); | ||
res.send('<script src="/main.js"></script>'); | ||
} else { | ||
next(); | ||
} | ||
} else { | ||
console.log('browser'); | ||
} | ||
} | ||
|
||
``` | ||
|
||
Don't forget to [configure the scripts section](#configure-packagejson) of your package.json. And you're done! |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
#!/usr/bin/env node | ||
'use strict'; | ||
|
||
var yargs = require('yargs'); | ||
|
||
var pm = require('./lib/package-manager'); | ||
var packageManifest = require('./package.json'); | ||
|
||
module.exports = function run (argv, callback) { | ||
var args = yargs | ||
.version(packageManifest.version) | ||
.usage('Usage: $0 <command> [options]') | ||
.help('help') | ||
.alias('h', 'help') | ||
.demandCommand(); | ||
|
||
if (pm.isPackageInstalled('hops-build')) { | ||
args.command(require('./commands/build')(callback)); | ||
args.command(require('./commands/develop')(callback)); | ||
} | ||
|
||
if (pm.isPackageInstalled('hops-express')) { | ||
args.command(require('./commands/serve')(callback)); | ||
} | ||
|
||
args.parse(argv); | ||
}; | ||
|
||
if (require.main === module) { | ||
module.exports(process.argv.slice(2)); | ||
} |