Browse Source

Initial commit, moving Neo core into neutrino

plugin-mode
Eli Perelman 8 years ago
parent
commit
59c5c52648
  1. 41
      packages/neutrino/.gitignore
  2. 55
      packages/neutrino/bin/neutrino
  3. 51
      packages/neutrino/commands/build/index.js
  4. 37
      packages/neutrino/commands/init/index.js
  5. 11
      packages/neutrino/commands/start/index.js
  6. 17
      packages/neutrino/commands/test/index.js
  7. 57
      packages/neutrino/package.json
  8. 30
      packages/neutrino/src/get-preset.js

41
packages/neutrino/.gitignore

@ -0,0 +1,41 @@
# Logs
logs
*.log
npm-debug.log*
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
# nyc test coverage
.nyc_output
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# node-waf configuration
.lock-wscript
# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules
jspm_packages
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Optional REPL history
.node_repl_history

55
packages/neutrino/bin/neutrino

@ -0,0 +1,55 @@
#!/usr/bin/env node
'use strict';
const path = require('path');
const Vorpal = require('vorpal');
const commands = require('../package.json').commands;
const cli = new Vorpal();
const register = (command) => {
const cmd = command.command;
const name = cmd.split(' ')[0];
const options = command.options || [];
const dir = path.resolve(__dirname, `../commands/${name}`);
const cliCommand = cli.command(cmd, command.description);
Object
.keys(options)
.map(option => {
if (Array.isArray(options[option])) {
cliCommand.option.apply(cliCommand, [option].concat(options[option]));
} else {
cliCommand.option(option, options[option]);
}
});
cliCommand
.action(function(args) {
const done = (code) => process.exit(code || 0);
if (this.commandObject._events) {
const options = Object
.keys(this.commandObject._events)
.reduce((options, key) => {
options[key] = this.commandObject[key];
return options;
}, {});
args.options = Object.assign(options, args.options);
}
process.env.NODE_ENV = command.environment || 'development';
// Kick off the command
require(dir)(args, done);
});
};
commands.map(register);
cli
.find('exit')
.hidden();
cli.parse.apply(cli, process.argv[2] ? [process.argv] : process.argv.concat(['help']));

51
packages/neutrino/commands/build/index.js

@ -0,0 +1,51 @@
'use strict';
const getPreset = require('../../src/get-preset');
const DevServer = require('webpack-dev-server');
const webpack = require('webpack');
const build = (config, done) => {
webpack(config, (err, stats) => {
if (!err) {
console.log(stats.toString({ colors: true }));
} else {
console.error(err.stack || err);
if (err.details) {
console.error(err.details);
}
}
done();
});
};
const watch = (config, done) => {
const protocol = config.devServer.https ? 'https' : 'http';
const host = config.devServer.host || 'localhost';
const port = config.devServer.port || 5000;
const compiler = webpack(config);
const server = new DevServer(compiler, config.devServer);
process.on('SIGINT', done);
server.listen(port, host, () => console.log(`Listening on ${protocol}://${host}:${port}`));
};
module.exports = (args, done) => {
const config = getPreset(args.options.preset);
if (process.env.NODE_ENV === 'production') {
return build(config, done);
}
// If we can't start a development server, just do a build,
// which is currently the case for Node.js packages since we
// don't have HMR implemented
if (!config.devServer || config.target === 'node') {
console.log('Warning: This preset does not support watch compilation. Falling back to a one-time build.');
return build(config, done);
}
watch(config, done);
};

37
packages/neutrino/commands/init/index.js

@ -0,0 +1,37 @@
'use strict';
const yeoman = require('yeoman-environment');
const crypto = require('crypto');
const npm = require('npm');
const os = require('os');
const path = require('path');
const env = yeoman.createEnv();
module.exports = (args, done) => {
// For initializing a project, the preset is not installed in the project.
// Rather, we install it ourselves into a temp directory and invoke from there.
const tempDir = path.join(os.tmpdir(), crypto.randomBytes(8).toString('hex'));
const packageName = args.packageName;
npm.load({ loglevel: 'silent' }, (err, npm) => {
if (err) {
console.error(err);
return done(1);
}
const pkg = path.join(tempDir, 'node_modules', packageName.startsWith('@') || !packageName.includes(path.sep) ?
packageName :
path.basename(packageName));
npm.commands.install(tempDir, [packageName], (err) => {
if (err) {
console.error(err);
return done(1);
}
env.register(pkg, 'neutrino:init');
env.run('neutrino:init', done);
});
});
};

11
packages/neutrino/commands/start/index.js

@ -0,0 +1,11 @@
'use strict';
const webpack = require('webpack');
const build = require('../build');
module.exports = (args, done) => {
// Right now the main point of having this `start` entry point is to ensure that
// NODE_ENV is development.
// TODO: consolidate build command to accept a --watch flag which correctly handles NODE_ENV
return build(args, done);
};

17
packages/neutrino/commands/test/index.js

@ -0,0 +1,17 @@
'use strict';
const getPreset = require('../../src/get-preset');
const Server = require('karma').Server;
module.exports = (args, done) => {
const config = getPreset(args.options.preset);
const karma = config.karma;
delete config.karma;
delete config.plugins;
karma.webpack = config;
karma.singleRun = !args.options.watch;
karma.autoWatch = args.options.watch;
new Server(karma, done).start();
};

57
packages/neutrino/package.json

@ -0,0 +1,57 @@
{
"name": "neutrino",
"version": "2.0.0",
"description": "Create and build JS applications with managed configurations",
"main": "bin/neutrino",
"bin": {
"neutrino": "./bin/neutrino"
},
"commands": [
{
"command": "init <packageName>",
"description": "Scaffold and initialize a project based on a scaffolding package"
},
{
"command": "start",
"description": "Start a development server on a given port",
"options": {
"-p, --preset [nameOrFile]": "Specify a configuration preset for running the development server",
"--port [port]": [
"Specify a port on which to start the development server",
4000
]
}
},
{
"command": "build",
"description": "Compile the source directory to a built project",
"environment": "production",
"options": {
"-p, --preset [nameOrFile]": "Specify a configuration preset for building the source"
}
},
{
"command": "test",
"description": "Run a set of test suites",
"environment": "test",
"options": {
"-p, --preset [nameOrFile]": "Specify a configuration preset for running tests",
"--watch": "Watch source directory for changes and re-run tests"
}
}
],
"keywords": [],
"author": "Eli Perelman <eli@eliperelman.com>",
"license": "MPL-2.0",
"dependencies": {
"karma": "1.2.0",
"npm": "3.10.6",
"resolve": "1.1.7",
"vorpal": "1.4.1",
"webpack": "1.13.2",
"webpack-dev-server": "1.15.0",
"webpack-hot-middleware": "2.12.2",
"webpack-merge": "0.14.1",
"yeoman-environment": "1.6.3"
}
}

30
packages/neutrino/src/get-preset.js

@ -0,0 +1,30 @@
'use strict';
const path = require('path');
module.exports = (preset) => {
const cwd = process.cwd();
if (!preset) {
const pkg = require(path.join(cwd, 'package.json'));
if (!pkg.config || !pkg.config.preset) {
throw new Error(`This command requires a preset.
Specify one using -p, --preset, or in your package.json as \`config.preset\`.`);
}
preset = pkg.config.preset;
}
// Try requiring the preset as an absolute dependency, and if that fails
// try requiring it as relative to the project
try {
return require(preset);
} catch (err) {
try {
return require(path.join(process.cwd(), preset));
} catch (err) {
return require(path.join(process.cwd(), 'node_modules', preset));
}
}
};
Loading…
Cancel
Save