Skip to content

Commit

Permalink
Use command-line arguments to configure nwb new; added jsNext config
Browse files Browse the repository at this point in the history
The ES6 modules build is now optional - jsNext defaults to true.

Closes #27
  • Loading branch information
insin committed Dec 20, 2015
1 parent b7fefc8 commit 65c6bc6
Show file tree
Hide file tree
Showing 16 changed files with 295 additions and 103 deletions.
9 changes: 9 additions & 0 deletions CHANGES.md
@@ -1,8 +1,17 @@
**Added:**

- Command-line arguments can now be used to configure settings for `nwb new`.

**Fixed:**

- Demo apps weren't generating sourcemaps when bundling.
- Use a non-zero exit code when displaying usage or otherwise exiting due to missing arguments [[#23](https://github.com/insin/nwb/issues/23)]

**Changed:**

- The ES6 modules build for npm modules is now optional, controlled by a `jsNext` setting in `nwb.config.js`, defaulting to `true`.
- nwb 0.6 will default `jsNext` to `true` and log a warning when it's missing from a config file - this behaviour will be removed in nwb 0.7.

# 0.5.0 / 2015-12-15

**Added:**
Expand Down
10 changes: 7 additions & 3 deletions README.md
Expand Up @@ -52,8 +52,9 @@ Create a new React component module and start hot reloading its demo app:

```
$ nwb new react-component react-thing
? Do you want nwb to create a UMD build for this module? Yes
? Do you want to create a UMD build for npm? Yes
? Which global variable should the UMD build export? ReactThing
? Do you want to create an ES6 modules build for npm? Yes
nwb: created /path/to/react-thing
nwb: installing dependencies
...
Expand All @@ -64,7 +65,7 @@ nwb: dev server listening at http://localhost:3000
...
```

Create a new web module and run tests on every change as you develop it:
Create a new web module without being asked any questions and run tests on every change as you develop it:

```
$ nwb new web-module get-form-data -f
Expand Down Expand Up @@ -100,7 +101,10 @@ Project creation commands:
new react-app <name> create a React app
new react-component <name> create a React component with a demo app
new web-module <name> create a web module
-f force creation, don't ask any questions
-f, --force force creation, no questions
-g, --global global variable for npm UMD build
--no-jsnext disable npm ES6 modules build
--no-umd disable npm UMD module build
Development commands:
build clean and build
Expand Down
14 changes: 11 additions & 3 deletions docs/Commands.md
Expand Up @@ -10,23 +10,31 @@ Creates a skeleton for a React app with the given name.

```
nwb new react-component <component-name>
? Do you want nwb to create a UMD build for this module?
? Do you want to create a UMD build for npm?
? Which global variable should the UMD build export?
? Do you want to create an ES6 modules build for npm?
```

Creates a skeleton for a React component with the given name, with an optional UMD build exporting a specified global variable.

```
nwb new web-module <module-name>
? Do you want nwb to create a UMD build for this module?
? Do you want to create a UMD build for npm?
? Which global variable should the UMD build export?
? Do you want to create an ES6 modules build for npm?
```

Creates a skeleton for a web module with the given name, with an optional UMD build exporting a specified global variable.

**Flags:**

* `-f` - force creation of the new project without asking any questions, using whichever default settings are necessary as a result.
* `-f, --force` - force creation of the new project without asking any questions, using whichever default settings are necessary as a result.

**React component and web module flags:**

* `-g, --global` - provide a global variable to be exported by the UMD build, implicitly enabling the UMD build.
* `--no-jsnext` - disable the npm ES6 modules build.
* `--no-umd` - disable the npm UMD build.

### `serve` - serve a React app

Expand Down
8 changes: 7 additions & 1 deletion docs/Configuration.md
Expand Up @@ -52,11 +52,17 @@ module.exports = {
}
```

#### jsNext: `Boolean`

Determines whether or not nwb will create an ES6 modules build for tree-shaking module bundlers when you run `nwb build` for a React component or web module.

Defaults to `true`.

#### `umd`: `Boolean`

Determines whether or not nwb will create a UMD build when you run `nwb build` for a React component or web module.

Defaults to `true` when you are prompted to onfigure this by `nwb new`.
Defaults to `true` when you are prompted to onfigure this by `nwb new`, or if you provide a UMD global variable as a command-line argument.

#### `externals`: `Object` (only for UMD builds)

Expand Down
8 changes: 7 additions & 1 deletion src/cli.js
Expand Up @@ -28,7 +28,10 @@ export default function(argv, cb) {
new react-app <name> create a React app
new react-component <name> create a React component with a demo app
new web-module <name> create a web module
-f force creation, don't ask any questions
-f, --force force creation, no questions
-g, --global global variable for npm UMD build
--no-jsnext disable npm ES6 modules build
--no-umd disable npm UMD module build
Development commands:
build clean and build
Expand Down Expand Up @@ -66,5 +69,8 @@ export default function(argv, cb) {
}

let commandModule = require(commandModulePath)
if (commandModule.default) {
commandModule = commandModule.default
}
commandModule(args, cb)
}
10 changes: 6 additions & 4 deletions src/commands/build-module.js
Expand Up @@ -31,10 +31,12 @@ export default function(args) {
console.log('nwb: build-module (es5)')
exec('babel', babelArgs, {cwd})

babelArgs[2] = es6
babelArgs = [...babelArgs, '--blacklist=es6.modules']
console.log('nwb: build-module (es6)')
exec('babel', babelArgs, {cwd})
if (userConfig.jsNext) {
babelArgs[2] = es6
babelArgs = [...babelArgs, '--blacklist=es6.modules']
console.log('nwb: build-module (es6)')
exec('babel', babelArgs, {cwd})
}

temp.cleanupSync()
}
53 changes: 43 additions & 10 deletions src/commands/new.js
Expand Up @@ -14,23 +14,47 @@ import pkg from '../../package.json'

let nwbVersion = `~${pkg.version}`

function getWebModulePrefs(args, done) {
if (args.f) {
return done({umd: false, globalVariable: ''})
export function getWebModulePrefs(args, done) {
// Determine defaults based on arguments
let umd = true
if (args.umd === false) {
umd = false
}
else if (args.g || args.global) {
umd = true
}
else if (args.f || args.force) {
umd = false
}
let globalVariable = args.g || args.global || ''
let jsNext = true
if (args.jsnext === false) {
jsNext = false
}

if (args.f || args.force) {
return done({umd, globalVariable, jsNext})
}

inquirer.prompt([
{
type: 'confirm',
name: 'umd',
message: 'Do you want nwb to create a UMD build for this module?',
default: true
message: 'Do you want to create a UMD build for npm?',
default: umd
},
{
when: ({umd}) => umd,
type: 'input',
name: 'globalVariable',
message: 'Which global variable should the UMD build export?',
default: ''
default: globalVariable
},
{
type: 'confirm',
name: 'jsNext',
message: 'Do you want to create an ES6 modules build for npm?',
default: jsNext
}
], done)
}
Expand All @@ -44,6 +68,11 @@ function installReact(targetDir) {
})
}

export function npmModuleVars(vars) {
vars.jsNextMain = vars.jsNext ? '\n "jsnext:main": "es6/index.js",' : ''
return vars
}

let projectCreators = {
[REACT_APP](args, name, targetDir, cb) {
let templateDir = path.join(__dirname, `../../templates/${REACT_APP}`)
Expand All @@ -58,9 +87,11 @@ let projectCreators = {
},

[REACT_COMPONENT](args, name, targetDir, cb) {
getWebModulePrefs(args, ({umd, globalVariable}) => {
getWebModulePrefs(args, ({umd, globalVariable, jsNext}) => {
let templateDir = path.join(__dirname, `../../templates/${REACT_COMPONENT}`)
let templateVars = {umd, globalVariable, name, nwbVersion, reactVersion}
let templateVars = npmModuleVars(
{umd, globalVariable, jsNext, name, nwbVersion, reactVersion}
)
copyTemplateDir(templateDir, targetDir, templateVars, err => {
if (err) return cb(err)
console.log(`nwb: created ${targetDir}`)
Expand All @@ -72,9 +103,11 @@ let projectCreators = {
},

[WEB_MODULE](args, name, targetDir, cb) {
getWebModulePrefs(args, ({umd, globalVariable}) => {
getWebModulePrefs(args, ({umd, globalVariable, jsNext}) => {
let templateDir = path.join(__dirname, `../../templates/${WEB_MODULE}`)
let templateVars = {umd, globalVariable, name, nwbVersion}
let templateVars = npmModuleVars(
{umd, globalVariable, jsNext, name, nwbVersion}
)
copyTemplateDir(templateDir, targetDir, templateVars, err => {
if (err) return cb(err)
console.log(`nwb: created ${targetDir}`)
Expand Down
18 changes: 17 additions & 1 deletion src/getUserConfig.js
Expand Up @@ -2,10 +2,13 @@ import path from 'path'

import glob from 'glob'

import {PROJECT_TYPES} from './constants'
import {PROJECT_TYPES, REACT_COMPONENT, WEB_MODULE} from './constants'
import debug from './debug'
import {UserError} from './errors'

// TODO Remove in 0.7
let warnedJSNext = false

export default function getUserConfig(args = {}) {
// Try to load default user config, or user a config file path we were given
let userConfig = {}
Expand Down Expand Up @@ -50,6 +53,19 @@ export default function getUserConfig(args = {}) {
}
}

// TODO Remove in 0.7
if ((userConfig.type === REACT_COMPONENT || userConfig.type === WEB_MODULE) &&
!('jsNext' in userConfig)) {
if (!warnedJSNext) {
console.warn([
'nwb: there was no jsNext setting in your nwb config file - this will default to true in nwb 0.6',
`nwb: set jsNext: true in ${path.basename(userConfigPath)} if you want to keep using the ES6 modules build`
].join('\n'))
warnedJSNext = true
}
userConfig.jsNext = true
}

debug('final user config: %o', userConfig)

return userConfig
Expand Down
3 changes: 1 addition & 2 deletions templates/react-component/_package.json
Expand Up @@ -2,8 +2,7 @@
"name": "{{name}}",
"version": "1.0.0",
"description": "{{name}} React component",
"main": "lib/index.js",
"jsnext:main": "es6/index.js",
"main": "lib/index.js",{{jsNextMain}}
"files": [
"css",
"es6",
Expand Down
7 changes: 6 additions & 1 deletion templates/react-component/nwb.config.js
Expand Up @@ -12,5 +12,10 @@ module.exports = {
// build.
externals: {
'react': 'React'
}
},

// Should nwb create a build with untranspiled ES6 modules for tree-shaking
// module bundlers? If you change your mind later, add or remove this line in
// package.json: "jsnext:main": "es6/index.js"
jsNext: {{jsNext}}
}
3 changes: 1 addition & 2 deletions templates/web-module/_package.json
Expand Up @@ -2,8 +2,7 @@
"name": "{{name}}",
"version": "1.0.0",
"description": "Describe {{name}} here",
"main": "lib/index.js",
"jsnext:main": "es6/index.js",
"main": "lib/index.js",{{jsNextMain}}
"files": [
"es6",
"lib",
Expand Down
7 changes: 6 additions & 1 deletion templates/web-module/nwb.config.js
Expand Up @@ -9,5 +9,10 @@ module.exports = {
// A mapping from the npm package names of this module's peerDependencies - if
// it has any - to the global variables they're expected to be available as
// for use by the UMD build, e.g. {'react': 'React'}
externals: {}
externals: {},

// Should nwb create a build with untranspiled ES6 modules for tree-shaking
// module bundlers? If you change your mind later, add or remove this line in
// package.json: "jsnext:main": "es6/index.js"
jsNext: {{jsNext}}
}
62 changes: 62 additions & 0 deletions tests/commands-new-test.js
@@ -0,0 +1,62 @@
import expect from 'expect'
import parseArgs from 'minimist'

let {getWebModulePrefs} = require('../src/commands/new')

let moduleArgs = (args, cb) => {
args.push('-f')
getWebModulePrefs(parseArgs(args), cb)
}

describe('nwb new', () => {
describe('command-line arguments', () => {
it('set umd=false by default', done => {
moduleArgs([], settings => {
expect(settings).toEqual({
globalVariable: '',
jsNext: true,
umd: false
})
done()
})
})
it('implicitly set umd=true with a --global variable', done => {
moduleArgs(['--global=Test'], settings => {
expect(settings).toEqual({
globalVariable: 'Test',
jsNext: true,
umd: true
})
done()
})
})
it('implicitly set umd=true with a -g variable', done => {
moduleArgs(['-g', 'Test'], settings => {
expect(settings).toEqual({
globalVariable: 'Test',
jsNext: true,
umd: true
})
done()
})
})
it('set umd=false with --no-umd', done => {
moduleArgs(['--no-umd'], settings => {
expect(settings.umd).toBe(false)
done()
})
})
it('set umd=false with --umd=false', done => {
moduleArgs(['--no-umd'], settings => {
expect(settings.umd).toBe(false)
done()
})
})
it('set jsNext=false with --no-jsnext', done => {
moduleArgs(['--no-jsnext'], settings => {
expect(settings.jsNext).toBe(false)
done()
})
})
})
})

0 comments on commit 65c6bc6

Please sign in to comment.