From cd5fa51eee373687e77d5c40b06dabfe8ba7bb9f Mon Sep 17 00:00:00 2001 From: Eli Perelman Date: Fri, 1 Dec 2017 10:18:27 -0600 Subject: [PATCH] Refactor create-project to support testing the cli and middleware integration (#488) * Refactor create-project to support testing the cli and middleware integration * Make create-project output more helpful and descriptive * Revise create-project tests to utilize new Vue preset and Neutrino extensions * Run create-project tests serially to output to CI stdout more frequently :( * Scaffold all middleware consistently in the root of the destination project --- .travis.yml | 3 + package.json | 23 +- .../bin/create-neutrino-project.js | 18 +- .../create-project/commands/init/index.js | 197 +++++++----- .../create-project/commands/init/questions.js | 167 +++-------- .../{eslintrc.js => airbnb-base/.eslintrc.js} | 0 .../init/templates/airbnb/.eslintrc.js | 5 + .../jest.js => jest/test/simple_test.js} | 0 .../karma.js => karma/test/simple_test.js} | 0 .../init/templates/library/src/index.js | 2 +- .../mocha.js => mocha/test/simple_test.js} | 0 .../commands/init/templates/node/src/app.js | 2 +- .../commands/init/templates/node/src/index.js | 6 +- .../templates/preact/src/{App.js => App.jsx} | 8 +- .../init/templates/preact/src/index.js | 16 - .../init/templates/preact/src/index.jsx | 16 + .../src/components/HelloWorld/index.js | 39 --- .../src/components/HelloWorld/index.jsx | 43 +++ .../src/{stories.js => stories.jsx} | 2 +- .../templates/react/src/{App.js => App.jsx} | 8 +- .../react/src/{index.js => index.jsx} | 4 +- .../init/templates/standardjs/.eslintrc.js | 5 + .../commands/init/templates/vue/src/App.vue | 2 +- .../commands/init/templates/vue/src/index.js | 2 +- .../commands/init/templates/web/src/index.js | 4 +- .../create-project/commands/init/utils.js | 136 +++++---- packages/create-project/package.json | 5 + packages/create-project/test/cli_test.js | 158 ++++++++++ packages/karma/index.js | 18 +- packages/library/index.js | 6 +- packages/mocha/src/index.js | 2 +- packages/node/index.js | 3 + packages/react-components/index.js | 9 +- packages/vue/index.js | 32 +- packages/vue/package.json | 13 +- packages/web/index.js | 6 +- yarn.lock | 283 ++++++++++++++++-- 37 files changed, 841 insertions(+), 402 deletions(-) rename packages/create-project/commands/init/templates/{eslintrc.js => airbnb-base/.eslintrc.js} (100%) create mode 100644 packages/create-project/commands/init/templates/airbnb/.eslintrc.js rename packages/create-project/commands/init/templates/{test/jest.js => jest/test/simple_test.js} (100%) rename packages/create-project/commands/init/templates/{test/karma.js => karma/test/simple_test.js} (100%) rename packages/create-project/commands/init/templates/{test/mocha.js => mocha/test/simple_test.js} (100%) rename packages/create-project/commands/init/templates/preact/src/{App.js => App.jsx} (52%) delete mode 100644 packages/create-project/commands/init/templates/preact/src/index.js create mode 100644 packages/create-project/commands/init/templates/preact/src/index.jsx delete mode 100644 packages/create-project/commands/init/templates/react-components/src/components/HelloWorld/index.js create mode 100644 packages/create-project/commands/init/templates/react-components/src/components/HelloWorld/index.jsx rename packages/create-project/commands/init/templates/react-components/src/{stories.js => stories.jsx} (88%) rename packages/create-project/commands/init/templates/react/src/{App.js => App.jsx} (53%) rename packages/create-project/commands/init/templates/react/src/{index.js => index.jsx} (82%) create mode 100644 packages/create-project/commands/init/templates/standardjs/.eslintrc.js create mode 100644 packages/create-project/test/cli_test.js diff --git a/.travis.yml b/.travis.yml index a259ba1a1..bca7a930a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,13 +10,16 @@ node_js: - '6' - '7' - '8' +- '9' before_install: # Use newer yarn than that pre-installed in the Travis image. - curl -sSfL https://yarnpkg.com/install.sh | bash - export PATH="$HOME/.yarn/bin:$PATH" install: - yarn install --frozen-lockfile +- yarn link:all script: - yarn validate:eslintrc - yarn lint +- yarn build - yarn test diff --git a/package.json b/package.json index f1f2095ff..d84c0c40a 100644 --- a/package.json +++ b/package.json @@ -14,22 +14,25 @@ "packages/*" ], "scripts": { - "validate:eslintrc:root": "eslint --no-eslintrc --print-config . -c ./.eslintrc.js > /dev/null", - "validate:eslintrc:eslint": "eslint --no-eslintrc --print-config . -c ./packages/eslint/eslintrc.js > /dev/null", - "validate:eslintrc:airbnb": "eslint --no-eslintrc --print-config . -c ./packages/airbnb/eslintrc.js > /dev/null", - "validate:eslintrc:airbnb-base": "eslint --no-eslintrc --print-config . -c ./packages/airbnb-base/eslintrc.js > /dev/null", - "validate:eslintrc:standardjs": "eslint --no-eslintrc --print-config . -c ./packages/standardjs/eslintrc.js > /dev/null", - "validate:eslintrc": "yarn validate:eslintrc:eslint && yarn validate:eslintrc:airbnb-base && yarn validate:eslintrc:airbnb && yarn validate:eslintrc:standardjs && yarn validate:eslintrc:root", - "link:all": "lerna exec yarn link", - "lint": "node packages/neutrino/bin/neutrino lint", + "build": "lerna run build", "changelog": "auto-changelog --remote upstream --commit-limit false", + "cnp": "NODE_ENV=test packages/create-project/bin/create-neutrino-project.js $(yarn random)", "docs:build": "gitbook build && cp CNAME _book", "docs:deploy": "yarn docs:build && gh-pages --dist _book --remote upstream", "docs:serve": "gitbook serve", + "link:all": "lerna exec yarn link", + "lint": "node packages/neutrino/bin/neutrino lint", "precommit": "lint-staged", - "release": "lerna publish --force-publish=*", - "release:preview": "lerna publish --force-publish=* --skip-git --skip-npm", + "random": "node -e \"process.stdout.write(require('crypto').randomBytes(8).toString('hex'))\"", + "release": "yarn build && lerna publish --force-publish=*", + "release:preview": "yarn build && lerna publish --force-publish=* --skip-git --skip-npm", "test": "nyc --reporter lcov ava packages/*/test", + "validate:eslintrc:root": "eslint --no-eslintrc --print-config . -c ./.eslintrc.js > /dev/null", + "validate:eslintrc:eslint": "eslint --no-eslintrc --print-config . -c ./packages/eslint/eslintrc.js > /dev/null", + "validate:eslintrc:airbnb": "eslint --no-eslintrc --print-config . -c ./packages/airbnb/eslintrc.js > /dev/null", + "validate:eslintrc:airbnb-base": "eslint --no-eslintrc --print-config . -c ./packages/airbnb-base/eslintrc.js > /dev/null", + "validate:eslintrc:standardjs": "eslint --no-eslintrc --print-config . -c ./packages/standardjs/eslintrc.js > /dev/null", + "validate:eslintrc": "yarn validate:eslintrc:eslint && yarn validate:eslintrc:airbnb-base && yarn validate:eslintrc:airbnb && yarn validate:eslintrc:standardjs && yarn validate:eslintrc:root", "version": "yarn changelog --package && git add CHANGELOG.md" }, "devDependencies": { diff --git a/packages/create-project/bin/create-neutrino-project.js b/packages/create-project/bin/create-neutrino-project.js index d5203558f..6ecacc86e 100755 --- a/packages/create-project/bin/create-neutrino-project.js +++ b/packages/create-project/bin/create-neutrino-project.js @@ -1,18 +1,24 @@ #!/usr/bin/env node -const yeoman = require('yeoman-environment'); const yargs = require('yargs'); -const path = require('path'); +const { createEnv } = require('yeoman-environment'); +const { basename, isAbsolute, join, resolve } = require('path'); -const env = yeoman.createEnv(); +const env = createEnv(); const done = exitCode => process.exit(exitCode || 0); -const dir = path.resolve(__dirname, '../commands/init'); +const dir = resolve(__dirname, '../commands/init'); -env.register(require.resolve(dir), 'create-neutrino-project:init'); +env.register(require.resolve(dir), 'create-neutrino-project'); const cli = yargs.command('') .demandCommand(1, 'Only is required') .help() .argv; +const directory = isAbsolute(cli._[0]) ? cli._[0] : join(process.cwd(), cli._[0]); +const name = basename(directory); -env.run('create-neutrino-project:init', { directory: cli._[0] }, done); +env.run('create-neutrino-project', { + directory, + name, + stdio: process.env.NODE_ENV === 'test' ? 'ignore' : 'inherit' +}, done); diff --git a/packages/create-project/commands/init/index.js b/packages/create-project/commands/init/index.js index e724cd9f2..787a650ea 100644 --- a/packages/create-project/commands/init/index.js +++ b/packages/create-project/commands/init/index.js @@ -1,11 +1,12 @@ const { ensureDirSync, readJsonSync, writeJsonSync } = require('fs-extra'); -const path = require('path'); +const { basename, join, relative } = require('path'); const chalk = require('chalk'); const stringify = require('javascript-stringify'); const merge = require('deepmerge'); +const { contains, partition } = require('ramda'); const Generator = require('yeoman-generator'); const questions = require('./questions'); -const { projects, isYarn } = require('./utils'); +const { projects, packages, isYarn } = require('./utils'); /* eslint-disable no-underscore-dangle */ module.exports = class Project extends Generator { @@ -18,30 +19,32 @@ module.exports = class Project extends Generator { `; } - _makeRcFile(data) { - const rc = { use: [] }; + _getProjectMiddleware() { + const { projectType, project } = this.data; - if (data.linter) { - rc.use.push(data.linter); - } - - if (data.projectType === 'application' && data.project !== '@neutrinojs/node') { - rc.use.push([data.project, { + if (projectType === 'application' && project !== packages.NODE) { + return [project, { html: { - title: this.options.directory + title: this.options.name } - }]); - } else if (data.projectType === 'library') { - rc.use.push([data.project, { - name: this.options.directory - }]); - } else { - rc.use.push(data.project); + }]; + } else if (projectType === 'library') { + return [project, { + name: this.options.name + }]; } - if (data.testRunner) { - rc.use.push(data.testRunner); - } + return project; + } + + _getNeutrinorcContent() { + const rc = { + use: [ + this.data.linter, + this._getProjectMiddleware(), + this.data.testRunner + ].filter(Boolean) + }; return `module.exports = ${stringify(rc, null, 2)};\n`; } @@ -60,113 +63,155 @@ module.exports = class Project extends Generator { } else if (deps.devDependencies.length) { return { devDependencies: deps.devDependencies }; } + return {}; } _initialPackageJson() { - const done = this.async(); const installer = isYarn ? 'yarn' : 'npm'; - const scripts = { build: 'neutrino build' }; + const scripts = { build: `${packages.NEUTRINO} build` }; if (this.data.projectType !== 'library') { - scripts.start = 'neutrino start'; + scripts.start = `${packages.NEUTRINO} start`; } if (this.data.linter) { - scripts.lint = 'neutrino lint'; + scripts.lint = `${packages.NEUTRINO} lint`; } if (this.data.testRunner) { - scripts.test = 'neutrino test'; + scripts.test = `${packages.NEUTRINO} test`; } ensureDirSync(this.options.directory); - const command = this.spawnCommand(installer, ['init', '--yes'], { - cwd: path.resolve(this.options.directory), - stdio: 'ignore' + this.spawnCommandSync(installer, ['init', '--yes'], { + cwd: this.options.directory, + stdio: this.options.stdio }); - command.on('close', () => { - const jsonPath = path.join(this.options.directory, 'package.json'); - const json = readJsonSync(`./${jsonPath}`); - const packageJson = Object.assign(json, { scripts }); - - writeJsonSync(jsonPath, packageJson, { spaces: 2 }); + const jsonPath = join(this.options.directory, 'package.json'); + const json = readJsonSync(jsonPath); + const packageJson = Object.assign(json, { scripts }); - return done(); - }); + writeJsonSync(jsonPath, packageJson, { spaces: 2 }); + this.log(` ${chalk.green('create')} ${join(basename(this.options.directory), 'package.json')}`); } prompting() { const done = this.async(); - console.log(chalk.cyan.bold(this._logo())); - console.log(chalk.magenta.bold('Welcome to Neutrino!')); - console.log(chalk.cyan('To help you create your new project, I am going to ask you a few questions. :)\n')); + this.log(chalk.cyan.bold(this._logo())); + this.log(chalk.white.bold('Welcome to Neutrino! šŸ‘‹')); + this.log(chalk.cyan('To help you create your new project, I am going to ask you a few questions.\n')); this .prompt(questions()) .then(answers => this.data = answers) - .then(() => done()); + .then(() => { + this.log(`\nšŸ‘Œ ${chalk.white.bold('Looks like I have all the info I need. Give me a moment while I create your project!')}\n`); + done(); + }); } writing() { - const destinationPath = this.destinationPath(this.options.directory); - const templateDir = this.data.project.replace('@neutrinojs/', ''); + const templates = [this.data.project, this.data.testRunner, this.data.linter].filter(Boolean); this._initialPackageJson(); - this.fs.copyTpl( - this.templatePath(`${templateDir}/src/**/*`), - path.join(destinationPath, 'src'), - { data: this.options } + this.fs.write( + join(this.options.directory, '.neutrinorc.js'), + this._getNeutrinorcContent() ); - this.fs.write(path.join(destinationPath, '.neutrinorc.js'), this._makeRcFile(this.data)); - - if (this.data.testRunner) { - const testDestinationDir = path.join(destinationPath, 'test'); - - ensureDirSync(testDestinationDir); - this.fs.copy( - this.templatePath(path.join('test', `${this.data.testRunner.replace('@neutrinojs/', '')}.js`)), - path.join(testDestinationDir, 'simple_test.js') - ); - } - - if (this.data.linter) { - this.fs.copy( - this.templatePath('eslintrc.js'), - path.join(destinationPath, '.eslintrc.js') + templates.forEach(template => { + const templateDir = template.replace('@neutrinojs/', ''); + + this.fs.copyTpl( + this.templatePath(`${templateDir}/**`), + this.options.directory, + { data: this.options }, + {}, + { globOptions: { dot: true } } ); - } + }); } install() { - const installer = isYarn ? 'yarn' : 'npm'; - const argument = isYarn ? 'add' : 'install'; - const development = isYarn ? '--dev' : '--save-dev'; + const packageManager = isYarn ? 'yarn' : 'npm'; + const install = isYarn ? 'add' : 'install'; + const devFlag = isYarn ? '--dev' : '--save-dev'; const { dependencies, devDependencies } = this._getDependencies(); - this.log(`\n${chalk.green('success')} Saved package.json`); - process.chdir(this.options.directory); + this.log(''); if (dependencies) { - this.log(`\n${chalk.green('Installing dependencies:')} ${chalk.yellow(dependencies.join(', '))}`); - this.spawnCommandSync(installer, [argument, ...dependencies], { stdio: 'inherit' }); + this.log(`${chalk.green('ā³ Installing dependencies:')} ${chalk.yellow(dependencies.join(', '))}`); + this.spawnCommandSync(packageManager, [install, ...dependencies], { + cwd: this.options.directory, + stdio: this.options.stdio, + env: process.env + }); } if (devDependencies) { - this.log(`\n${chalk.green('Installing dev-dependencies:')} ${chalk.yellow(devDependencies.join(', '))}`); - this.spawnCommandSync(installer, [argument, development, ...devDependencies], { stdio: 'inherit' }); + if (process.env.NODE_ENV === 'test') { + const [local, remote] = partition(contains(packages.NEUTRINO), devDependencies); + + if (remote.length) { + this.log(`${chalk.green('ā³ Installing remote devDependencies:')} ${chalk.yellow(remote.join(', '))}`); + this.spawnCommandSync(packageManager, [install, devFlag, ...remote], { + stdio: this.options.stdio, + env: process.env, + cwd: this.options.directory + }); + } + + if (local.length) { + this.log(`${chalk.green('ā³ Linking local devDependencies:')} ${chalk.yellow(local.join(', '))}`); + this.spawnCommandSync('yarn', ['link', ...local], { + stdio: this.options.stdio, + env: process.env, + cwd: this.options.directory + }); + } + } else { + this.log(`${chalk.green('ā³ Installing devDependencies:')} ${chalk.yellow(devDependencies.join(', '))}`); + this.spawnCommandSync(packageManager, [install, devFlag, ...devDependencies], { + stdio: this.options.stdio, + env: process.env, + cwd: this.options.directory + }); + } } if (this.data.linter) { - this.spawnCommandSync('neutrino', ['lint', '--fix'], { stdio: 'ignore' }); + this.log(`${chalk.green('ā³ Performing one-time lint')}`); + this.spawnCommandSync(packages.NEUTRINO, ['lint', '--fix'], { + stdio: this.options.stdio === 'inherit' ? 'ignore' : this.options.stdio, + cwd: this.options.directory + }); } } end() { - this.log(`\n${chalk.green('Success!')} Created ${chalk.cyan(this.options.directory)} at ${chalk.yellow(process.cwd())}`); - this.log(`To get started, change your current working directory to: ${chalk.cyan(this.options.directory)}`); + this.log(`\n${chalk.green('Hooray, I successfully created your project!')}`); + this.log(`\nI have added a few ${isYarn ? 'yarn' : 'npm'} scripts to help you get started:`); + this.log(` ā€¢ To build your project run: ${chalk.cyan.bold(`${isYarn ? 'yarn' : 'npm run'} build`)}`); + + if (this.data.projectType !== 'library') { + this.log(` ā€¢ To start your project locally run: ${chalk.cyan.bold(`${isYarn ? 'yarn' : 'npm'} start`)}`); + } + + if (this.data.testRunner) { + this.log(` ā€¢ To execute tests run: ${chalk.cyan.bold(`${isYarn ? 'yarn' : 'npm'} test`)}`); + } + + if (this.data.linter) { + this.log(` ā€¢ To lint your project manually run: ${chalk.cyan.bold(`${isYarn ? 'yarn' : 'npm run'} lint`)}`); + this.log(` You can also fix some linting problems with: ${chalk.cyan.bold(`${isYarn ? 'yarn' : 'npm run'} lint --fix`)}`); + } + + this.log('\nNow change your directory to the following to get started:'); + this.log(` ${chalk.cyan(relative(process.cwd(), this.options.directory))}`); + this.log(`\nā¤ļø ${chalk.white.bold('Neutrino')}`); } }; diff --git a/packages/create-project/commands/init/questions.js b/packages/create-project/commands/init/questions.js index 4dbbad934..7d2c895aa 100644 --- a/packages/create-project/commands/init/questions.js +++ b/packages/create-project/commands/init/questions.js @@ -1,160 +1,77 @@ +const { packages } = require('./utils'); + +const NONE = { name: 'None', value: false }; +const APPLICATION = { name: 'A web or Node.js application', value: 'application' }; +const LIBRARY = { name: 'A library', value: 'library' }; +const COMPONENTS = { name: 'Components', value: 'components' }; +const REACT = { name: 'React', value: packages.REACT }; +const PREACT = { name: 'Preact', value: packages.PREACT }; +const VUE = { name: 'Vue', value: packages.VUE }; +const WEB = { name: 'Some other web app, e.g. Angular, jQuery, or plain JS', value: packages.WEB }; +const NODE = { name: 'Node.js', value: packages.NODE }; +const WEB_NODE_LIBRARY = { name: 'Web and/or Node.js', value: packages.WEB_NODE_LIBRARY }; +const REACT_COMPONENTS = { name: 'React Components', value: packages.REACT_COMPONENTS }; +const JEST = { name: 'Jest', value: packages.JEST }; +const KARMA = { name: 'Karma', value: packages.KARMA }; +const MOCHA = { name: 'Mocha', value: packages.MOCHA }; +const AIRBNB = { name: 'Airbnb style rules', value: packages.AIRBNB }; +const AIRBNB_BASE = { name: 'Airbnb style rules', value: packages.AIRBNB_BASE }; +const STANDARDJS = { name: 'StandardJS rules', value: packages.STANDARDJS }; + module.exports = () => [ { name: 'projectType', type: 'list', - message: 'First up, what would you like to create?', - choices: [ - { - name: 'A web or Node.js application', - value: 'application', - checked: true - }, - { - name: 'A library', - value: 'library', - checked: false - }, - { - name: 'Components', - value: 'components', - checked: false - } - ], - store: true + message: 'šŸ¤” First up, what would you like to create?', + choices: [APPLICATION, LIBRARY, COMPONENTS] }, { name: 'project', type: 'list', - message: 'Great! Next, what kind of application would you like to create?', + message: 'šŸ¤” Next, what kind of application would you like to create?', when: data => data.projectType === 'application', - choices: [ - { - name: 'React', - value: '@neutrinojs/react', - checked: true - }, - { - name: 'Preact', - value: '@neutrinojs/preact', - checked: false - }, - { - - name: 'Vue', - value: '@neutrinojs/vue', - checked: false - }, - { - - name: 'Some other web app, e.g. Angular, jQuery, or plain JS', - value: '@neutrinojs/web', - checked: false - }, - { - name: 'Node.js', - value: '@neutrinojs/node', - checked: false - } - ] + choices: [REACT, PREACT, VUE, NODE, WEB] }, { name: 'project', type: 'list', - message: 'Great! Next, what kind of library would you like to create?', + message: 'šŸ¤” Next, what kind of library would you like to create?', when: data => data.projectType === 'library', - choices: [{ - name: 'Web and/or Node.js', - value: '@neutrinojs/library', - checked: true - }] + choices: [WEB_NODE_LIBRARY] }, { name: 'project', type: 'list', - message: 'Great! Next, what kind of components would you like to create?', + message: 'šŸ¤” Next, what kind of components would you like to create?', when: data => data.projectType === 'components', - choices: [ - { - name: 'React Components', - value: '@neutrinojs/react-components', - checked: true - } - ] + choices: [REACT_COMPONENTS] + }, + { + name: 'testRunner', + type: 'list', + message: 'šŸ¤” Would you like to add a test runner to your project?', + when: data => !data.project.includes('node'), + choices: [JEST, KARMA, MOCHA, NONE] }, { name: 'testRunner', type: 'list', - message: 'Would you like to add a test runner to your project?', - choices: [ - { - name: 'Jest', - value: '@neutrinojs/jest', - checked: true - }, - { - name: 'Karma', - value: '@neutrinojs/karma', - checked: false - }, - { - name: 'Mocha', - value: '@neutrinojs/mocha', - checked: false - }, - { - name: 'None', - value: false, - checked: false - } - ], - store: true + message: 'šŸ¤” Would you like to add a test runner to your project?', + when: data => data.project.includes('node'), + choices: [JEST, MOCHA, NONE] }, { name: 'linter', type: 'list', - message: 'Would you like to add linting to your project?', + message: 'šŸ¤” Would you like to add linting to your project?', when: data => data.project.includes('react'), - choices: [ - { - name: 'Airbnb style rules', - value: '@neutrinojs/airbnb', - checked: true - }, - { - name: 'StandardJS rules', - value: '@neutrinojs/standardjs', - checked: false - }, - { - name: 'None', - value: false, - checked: false - } - ], - store: true + choices: [AIRBNB, STANDARDJS, NONE] }, { name: 'linter', type: 'list', - message: 'Would you like to add linting to your project?', + message: 'šŸ¤” Would you like to add linting to your project?', when: data => !data.project.includes('react'), - choices: [ - { - name: 'Airbnb style rules', - value: '@neutrinojs/airbnb-base', - checked: true - }, - { - name: 'StandardJS rules', - value: '@neutrinojs/standardjs', - checked: false - }, - { - name: 'None', - value: false, - checked: false - } - ], - store: true + choices: [AIRBNB_BASE, STANDARDJS, NONE] } ]; diff --git a/packages/create-project/commands/init/templates/eslintrc.js b/packages/create-project/commands/init/templates/airbnb-base/.eslintrc.js similarity index 100% rename from packages/create-project/commands/init/templates/eslintrc.js rename to packages/create-project/commands/init/templates/airbnb-base/.eslintrc.js diff --git a/packages/create-project/commands/init/templates/airbnb/.eslintrc.js b/packages/create-project/commands/init/templates/airbnb/.eslintrc.js new file mode 100644 index 000000000..17e3aed72 --- /dev/null +++ b/packages/create-project/commands/init/templates/airbnb/.eslintrc.js @@ -0,0 +1,5 @@ +const { Neutrino } = require('neutrino'); + +module.exports = Neutrino() + .use('.neutrinorc.js') + .call('eslintrc'); diff --git a/packages/create-project/commands/init/templates/test/jest.js b/packages/create-project/commands/init/templates/jest/test/simple_test.js similarity index 100% rename from packages/create-project/commands/init/templates/test/jest.js rename to packages/create-project/commands/init/templates/jest/test/simple_test.js diff --git a/packages/create-project/commands/init/templates/test/karma.js b/packages/create-project/commands/init/templates/karma/test/simple_test.js similarity index 100% rename from packages/create-project/commands/init/templates/test/karma.js rename to packages/create-project/commands/init/templates/karma/test/simple_test.js diff --git a/packages/create-project/commands/init/templates/library/src/index.js b/packages/create-project/commands/init/templates/library/src/index.js index 0da089224..286805e5f 100644 --- a/packages/create-project/commands/init/templates/library/src/index.js +++ b/packages/create-project/commands/init/templates/library/src/index.js @@ -1 +1 @@ -export default () => console.log('Welcome to <%= data.directory %>'); +export default () => 'Welcome to <%= data.name %>'; diff --git a/packages/create-project/commands/init/templates/test/mocha.js b/packages/create-project/commands/init/templates/mocha/test/simple_test.js similarity index 100% rename from packages/create-project/commands/init/templates/test/mocha.js rename to packages/create-project/commands/init/templates/mocha/test/simple_test.js diff --git a/packages/create-project/commands/init/templates/node/src/app.js b/packages/create-project/commands/init/templates/node/src/app.js index cd2d067cc..7e74976d3 100644 --- a/packages/create-project/commands/init/templates/node/src/app.js +++ b/packages/create-project/commands/init/templates/node/src/app.js @@ -1,5 +1,5 @@ const app = () => ( - '

Welcome to <%= data.directory %>

' + '

Welcome to <%= data.name %>

' ); export default app; diff --git a/packages/create-project/commands/init/templates/node/src/index.js b/packages/create-project/commands/init/templates/node/src/index.js index 3be941487..a51e723da 100644 --- a/packages/create-project/commands/init/templates/node/src/index.js +++ b/packages/create-project/commands/init/templates/node/src/index.js @@ -3,9 +3,9 @@ import app from './app'; const port = process.env.PORT || 3000; +createServer((request, response) => response.end(app())) + .listen(port, () => process.stdout.write(`Running on :${port}\n`)); + if (module.hot) { module.hot.accept('./app'); } - -createServer((request, response) => response.end(app())) - .listen(port, () => console.log(`Running on :${port}`)); diff --git a/packages/create-project/commands/init/templates/preact/src/App.js b/packages/create-project/commands/init/templates/preact/src/App.jsx similarity index 52% rename from packages/create-project/commands/init/templates/preact/src/App.js rename to packages/create-project/commands/init/templates/preact/src/App.jsx index dd1662572..b3880f93d 100644 --- a/packages/create-project/commands/init/templates/preact/src/App.js +++ b/packages/create-project/commands/init/templates/preact/src/App.jsx @@ -1,11 +1,15 @@ -import { h, Component } from 'preact'; +import { Component } from 'preact'; import './App.css'; export default class App extends Component { + state = { + name: '<%= data.name %>' + }; + render() { return (
-

{'Welcome to <%= data.directory %>'}

+

Welcome to {this.state.name}

); } diff --git a/packages/create-project/commands/init/templates/preact/src/index.js b/packages/create-project/commands/init/templates/preact/src/index.js deleted file mode 100644 index 96064fe39..000000000 --- a/packages/create-project/commands/init/templates/preact/src/index.js +++ /dev/null @@ -1,16 +0,0 @@ -import { h, render } from 'preact'; - -let root; - -const load = () => { - const App = require('./App').default; - - root = render(, document.getElementById('root'), root); -}; - -// This is needed for Hot Module Replacement -if (module.hot) { - module.hot.accept('./App', () => requestAnimationFrame(load)); -} - -load(); diff --git a/packages/create-project/commands/init/templates/preact/src/index.jsx b/packages/create-project/commands/init/templates/preact/src/index.jsx new file mode 100644 index 000000000..1df740623 --- /dev/null +++ b/packages/create-project/commands/init/templates/preact/src/index.jsx @@ -0,0 +1,16 @@ +import { render } from 'preact'; + +let mount; +const root = document.getElementById('root'); +const load = async () => { + const { default: App } = await import('./App'); + + mount = render(, root, mount); +}; + +// This is needed for Hot Module Replacement +if (module.hot) { + module.hot.accept('./App', () => requestAnimationFrame(load)); +} + +load(); diff --git a/packages/create-project/commands/init/templates/react-components/src/components/HelloWorld/index.js b/packages/create-project/commands/init/templates/react-components/src/components/HelloWorld/index.js deleted file mode 100644 index 458a17656..000000000 --- a/packages/create-project/commands/init/templates/react-components/src/components/HelloWorld/index.js +++ /dev/null @@ -1,39 +0,0 @@ -import React from 'react'; - -export default class HelloWorld extends React.PureComponent { - static defaultProps = { - initialColor: '#000' - }; - - constructor(props) { - super(props); - - this.state = { - color: this.props.initialColor - }; - } - - componentWillReceiveProps({ initialColor }) { - if (initialColor !== this.props.initialColor) { - this.setState({ color: initialColor }); - } - } - - generateColor() { - return `#${(0x1000000 + (Math.random()) * 0xffffff).toString(16).substr(1, 6)}`; - } - - handleClick = () => { - this.setState({ - color: this.generateColor() - }); - }; - - render() { - return ( -

- Hello World! (click me) -

- ); - } -} diff --git a/packages/create-project/commands/init/templates/react-components/src/components/HelloWorld/index.jsx b/packages/create-project/commands/init/templates/react-components/src/components/HelloWorld/index.jsx new file mode 100644 index 000000000..c70ba7241 --- /dev/null +++ b/packages/create-project/commands/init/templates/react-components/src/components/HelloWorld/index.jsx @@ -0,0 +1,43 @@ +import { PureComponent } from 'react'; // eslint-disable-line import/no-extraneous-dependencies +import { string } from 'prop-types'; // eslint-disable-line import/no-extraneous-dependencies + +const generateColor = () => `#${ + (0x1000000 + ((Math.random()) * 0xffffff)) + .toString(16) + .substr(1, 6) +}`; + +export default class HelloWorld extends PureComponent { + static defaultProps = { + initialColor: '#000' + }; + + static propTypes = { + initialColor: string + }; + + state = { + color: this.props.initialColor + }; + + componentWillReceiveProps({ initialColor }) { + if (initialColor !== this.props.initialColor) { + this.setState({ color: initialColor }); + } + } + + handleClick = () => { + this.setState({ + color: generateColor() + }); + }; + + render() { + return ( +
+

Hello World!

+ +
+ ); + } +} diff --git a/packages/create-project/commands/init/templates/react-components/src/stories.js b/packages/create-project/commands/init/templates/react-components/src/stories.jsx similarity index 88% rename from packages/create-project/commands/init/templates/react-components/src/stories.js rename to packages/create-project/commands/init/templates/react-components/src/stories.jsx index 7164621b7..137b8ad7f 100644 --- a/packages/create-project/commands/init/templates/react-components/src/stories.js +++ b/packages/create-project/commands/init/templates/react-components/src/stories.jsx @@ -1,4 +1,4 @@ -import React from 'react'; +/* eslint-disable import/no-extraneous-dependencies */ import { render } from 'react-dom'; import { Stories, Story, Props } from '@neutrinojs/react-components/lib'; import HelloWorld from './components/HelloWorld'; diff --git a/packages/create-project/commands/init/templates/react/src/App.js b/packages/create-project/commands/init/templates/react/src/App.jsx similarity index 53% rename from packages/create-project/commands/init/templates/react/src/App.js rename to packages/create-project/commands/init/templates/react/src/App.jsx index 8dbf130c0..b74b39646 100644 --- a/packages/create-project/commands/init/templates/react/src/App.js +++ b/packages/create-project/commands/init/templates/react/src/App.jsx @@ -1,11 +1,15 @@ -import React, { Component } from 'react'; +import { Component } from 'react'; import './App.css'; export default class App extends Component { + state = { + name: '<%= data.name %>' + }; + render() { return (
-

{'Welcome to <%= data.directory %>'}

+

Welcome to {this.state.name}

); } diff --git a/packages/create-project/commands/init/templates/react/src/index.js b/packages/create-project/commands/init/templates/react/src/index.jsx similarity index 82% rename from packages/create-project/commands/init/templates/react/src/index.js rename to packages/create-project/commands/init/templates/react/src/index.jsx index e5733f5c4..90065383c 100644 --- a/packages/create-project/commands/init/templates/react/src/index.js +++ b/packages/create-project/commands/init/templates/react/src/index.jsx @@ -1,13 +1,13 @@ -import React from 'react'; import { render } from 'react-dom'; import { AppContainer } from 'react-hot-loader'; import App from './App'; +const root = document.getElementById('root'); const load = () => render(( -), document.getElementById('root')); +), root); // This is needed for Hot Module Replacement if (module.hot) { diff --git a/packages/create-project/commands/init/templates/standardjs/.eslintrc.js b/packages/create-project/commands/init/templates/standardjs/.eslintrc.js new file mode 100644 index 000000000..17e3aed72 --- /dev/null +++ b/packages/create-project/commands/init/templates/standardjs/.eslintrc.js @@ -0,0 +1,5 @@ +const { Neutrino } = require('neutrino'); + +module.exports = Neutrino() + .use('.neutrinorc.js') + .call('eslintrc'); diff --git a/packages/create-project/commands/init/templates/vue/src/App.vue b/packages/create-project/commands/init/templates/vue/src/App.vue index ddc995d8e..157755d02 100644 --- a/packages/create-project/commands/init/templates/vue/src/App.vue +++ b/packages/create-project/commands/init/templates/vue/src/App.vue @@ -9,7 +9,7 @@ diff --git a/packages/create-project/commands/init/templates/vue/src/index.js b/packages/create-project/commands/init/templates/vue/src/index.js index 0850ce880..eea53e53e 100644 --- a/packages/create-project/commands/init/templates/vue/src/index.js +++ b/packages/create-project/commands/init/templates/vue/src/index.js @@ -1,7 +1,7 @@ import Vue from 'vue'; import App from './App.vue'; -new Vue({ +export default new Vue({ el: '#root', render: (h) => h(App), }); diff --git a/packages/create-project/commands/init/templates/web/src/index.js b/packages/create-project/commands/init/templates/web/src/index.js index dc281ad4b..2c4d8789a 100644 --- a/packages/create-project/commands/init/templates/web/src/index.js +++ b/packages/create-project/commands/init/templates/web/src/index.js @@ -1,6 +1,6 @@ -const rootEl = document.getElementById('root'); +const root = document.getElementById('root'); -rootEl.innerHTML = '

Welcome to <%= data.directory %>

'; +root.innerHTML = '

Welcome to <%= data.name %>

'; // This is needed for Hot Module Replacement if (module.hot) { diff --git a/packages/create-project/commands/init/utils.js b/packages/create-project/commands/init/utils.js index f3fc1b1ba..8e957e945 100644 --- a/packages/create-project/commands/init/utils.js +++ b/packages/create-project/commands/init/utils.js @@ -1,74 +1,100 @@ +const LINTING = 'linting'; +const PROJECT = 'project'; +const TESTING = 'testing'; +const N = 'neutrino'; +const REACT = '@neutrinojs/react'; +const PREACT = '@neutrinojs/preact'; +const VUE = '@neutrinojs/vue'; +const WEB = '@neutrinojs/web'; +const NODE = '@neutrinojs/node'; +const WEB_NODE_LIBRARY = '@neutrinojs/library'; +const REACT_COMPONENTS = '@neutrinojs/react-components'; +const JEST = '@neutrinojs/jest'; +const KARMA = '@neutrinojs/karma'; +const MOCHA = '@neutrinojs/mocha'; +const AIRBNB = '@neutrinojs/airbnb'; +const AIRBNB_BASE = '@neutrinojs/airbnb-base'; +const STANDARDJS = '@neutrinojs/standardjs'; + const projects = { - '@neutrinojs/airbnb': { - devDependencies: [ - '@neutrinojs/airbnb' - ] + [AIRBNB]: { + type: LINTING, + devDependencies: [AIRBNB] + }, + [AIRBNB_BASE]: { + type: LINTING, + devDependencies: [AIRBNB_BASE] + }, + [WEB_NODE_LIBRARY]: { + type: PROJECT, + devDependencies: [WEB_NODE_LIBRARY, N] }, - '@neutrinojs/airbnb-base': { - devDependencies: [ - '@neutrinojs/airbnb-base' - ] + [NODE]: { + type: PROJECT, + devDependencies: [NODE, N] }, - '@neutrinojs/library': { - devDependencies: [ - '@neutrinojs/library' - ] + [PREACT]: { + type: PROJECT, + dependencies: ['preact', 'preact-compat'], + devDependencies: [PREACT, N] }, - '@neutrinojs/node': { - devDependencies: [ - '@neutrinojs/node' - ] + [REACT]: { + type: PROJECT, + dependencies: ['prop-types', 'react', 'react-dom', 'react-hot-loader'], + devDependencies: [REACT, N] }, - '@neutrinojs/preact': { - dependencies: [ - 'preact', - 'preact-compat' - ], - devDependencies: [ - '@neutrinojs/preact' - ] + [REACT_COMPONENTS]: { + type: PROJECT, + devDependencies: [REACT_COMPONENTS, N, 'prop-types', 'react', 'react-addons-css-transition-group', 'react-dom'] }, - '@neutrinojs/react': { - dependencies: [ - 'react', - 'react-dom', - 'react-hot-loader' - ], - devDependencies: [ - '@neutrinojs/react' - ] + [STANDARDJS]: { + type: LINTING, + devDependencies: [STANDARDJS] }, - '@neutrinojs/react-components': { - devDependencies: [ - '@neutrinojs/react', - 'react', - 'react-dom', - 'react-addons-css-transition-group' - ] + [VUE]: { + type: PROJECT, + dependencies: ['vue'], + devDependencies: [VUE, N] }, - '@neutrinojs/standardjs': { - devDependencies: [ - '@neutrinojs/standardjs' - ] + [WEB]: { + type: PROJECT, + devDependencies: [WEB, N] }, - '@neutrinojs/vue': { - dependencies: [ - 'vue' - ], - devDependencies: [ - '@neutrinojs/vue' - ] + [JEST]: { + type: TESTING, + devDependencies: [JEST] }, - '@neutrinojs/web': { - devDependencies: [ - '@neutrinojs/web' - ] + [KARMA]: { + type: TESTING, + devDependencies: [KARMA] + }, + [MOCHA]: { + type: TESTING, + devDependencies: [MOCHA] } }; +const packages = { + NEUTRINO: N, + REACT, + PREACT, + VUE, + WEB, + NODE, + WEB_NODE_LIBRARY, + REACT_COMPONENTS, + JEST, + KARMA, + MOCHA, + AIRBNB, + AIRBNB_BASE, + STANDARDJS +}; + const isYarn = process.env.npm_config_user_agent && process.env.npm_config_user_agent.includes('yarn'); module.exports = { + packages, projects, isYarn }; diff --git a/packages/create-project/package.json b/packages/create-project/package.json index 0a4a2a31a..54f3ed5ce 100644 --- a/packages/create-project/package.json +++ b/packages/create-project/package.json @@ -31,8 +31,13 @@ "deepmerge": "^1.5.2", "fs-extra": "^4.0.2", "javascript-stringify": "^1.6.0", + "ramda": "^0.25.0", "yargs": "^10.0.3", "yeoman-environment": "^2.0.5", "yeoman-generator": "^2.0.1" + }, + "devDependencies": { + "yeoman-assert": "^3.1.0", + "yeoman-test": "^1.7.0" } } diff --git a/packages/create-project/test/cli_test.js b/packages/create-project/test/cli_test.js new file mode 100644 index 000000000..6cfadf460 --- /dev/null +++ b/packages/create-project/test/cli_test.js @@ -0,0 +1,158 @@ +import test from 'ava'; +import { xprod } from 'ramda'; +import assert from 'yeoman-assert'; +import helpers from 'yeoman-test'; +import { join } from 'path'; +import { spawn } from 'child_process'; +import { packages } from '../commands/init/utils' + +if (process.env.NODE_ENV !== 'test') { + process.env.NODE_ENV = 'test'; +} + +const project = (prompts) => helpers + .run(require.resolve(join(__dirname, '../commands/init'))) + .inTmpDir(function(dir) { + this.withOptions({ directory: dir, name: 'testable', stdio: 'ignore' }); + }) + .withPrompts(prompts) + .toPromise(); +const usable = (dir, files) => assert.file(files.map(f => join(dir, f))); +const spawnP = (cmd, args, options) => new Promise((resolve, reject) => { + const child = spawn(cmd, args, options); + let output = ''; + + child.stdout.on('data', data => output += data.toString()); + child.stderr.on('data', data => output += data.toString()); + child.on('close', (code) => { + code === 0 ? resolve(code) : reject(output); + }); +}); +const buildable = async (t, dir) => { + try { + await spawnP('yarn', ['build'], { cwd: dir, stdio: 'pipe' }); + t.pass(); + } catch (output) { + t.fail(`Failed to build project:\n\n${output}`); + } +}; +const testable = async (t, dir) => { + try { + await spawnP('yarn', ['test'], { cwd: dir, stdio: 'pipe' }); + t.pass(); + } catch (output) { + t.fail(`Failed to test project:\n\n${output}`); + } +}; +const lintable = async (t, dir) => { + try { + await spawnP('yarn', ['lint'], { cwd: dir, stdio: 'pipe' }); + t.pass(); + } catch (output) { + t.fail(`Failed to lint project:\n\n${output}`); + } +}; +const tests = [packages.JEST, packages.KARMA, packages.MOCHA]; +const matrix = { + react: [ + [packages.REACT], + [packages.AIRBNB, packages.STANDARDJS], + tests + ], + preact: [ + [packages.PREACT], + [packages.AIRBNB, packages.STANDARDJS], + tests + ], + node: [ + [packages.NODE], + [packages.AIRBNB_BASE, packages.STANDARDJS], + tests.filter(t => t !== packages.KARMA) + ], + 'react-components': [ + [packages.REACT_COMPONENTS], + [packages.AIRBNB, packages.STANDARDJS], + tests + ], + vue: [ + [packages.VUE], + [packages.AIRBNB_BASE, packages.STANDARDJS], + tests + ], + web: [ + [packages.WEB], + [packages.AIRBNB_BASE, packages.STANDARDJS], + tests + ], +}; + +Object + .keys(matrix) + .forEach((key) => { + const [presets, linters, tests] = matrix[key]; + const [preset] = presets; + + test.serial(preset, async t => { + const dir = await project({ + projectType: 'application', + project: preset, + testRunner: false, + linter: false + }); + + usable(dir, [ + 'package.json', + '.neutrinorc.js' + ]); + + await buildable(t, dir); + }); + + xprod(presets, tests).forEach(([preset, testRunner]) => { + const testName = testRunner ? `${preset} + ${testRunner}` : preset; + + test.serial(testName, async t => { + const dir = await project({ + projectType: 'application', + project: preset, + testRunner, + linter: false + }); + + usable(dir, [ + 'package.json', + '.neutrinorc.js', + 'test/simple_test.js' + ]); + + await Promise.all([ + buildable(t, dir), + testable(t, dir) + ]); + }); + }); + + xprod(presets, linters).forEach(([preset, linter]) => { + const testName = `${preset} + ${linter}`; + + test.serial(testName, async t => { + const dir = await project({ + projectType: 'application', + project: preset, + testRunner: false, + linter + }); + + usable(dir, [ + 'package.json', + '.neutrinorc.js', + '.eslintrc.js' + ]); + + await Promise.all([ + buildable(t, dir), + lintable(t, dir) + ]); + }); + }); + }); diff --git a/packages/karma/index.js b/packages/karma/index.js index 7ac309e24..d5488af7a 100644 --- a/packages/karma/index.js +++ b/packages/karma/index.js @@ -56,11 +56,19 @@ module.exports = (neutrino, opts = {}) => { }); } - neutrino.on('test', ({ files, watch }) => new Promise((resolve, reject) => - new Server(merge.all([ + neutrino.on('test', ({ files, watch }) => new Promise((resolve, reject) => { + const karmaOptions = merge.all([ opts.override ? opts : merge(defaults, opts), - { singleRun: !watch, autoWatch: watch, webpack: omit(['plugins'], neutrino.config.toConfig()) }, + { + singleRun: !watch, + autoWatch: watch, + webpack: omit(['plugins'], neutrino.config.toConfig()) + }, files && files.length ? { files } : {} - ]), exitCode => (exitCode !== 0 ? reject() : resolve())) - .start())); + ]); + + const server = new Server(karmaOptions, exitCode => (exitCode !== 0 ? reject() : resolve())); + + return server.start(); + })); }; diff --git a/packages/library/index.js b/packages/library/index.js index 6d1418bee..b9d266d05 100644 --- a/packages/library/index.js +++ b/packages/library/index.js @@ -9,6 +9,7 @@ const nodeExternals = require('webpack-node-externals'); const { join } = require('path'); const MODULES = join(__dirname, 'node_modules'); +const NEUTRINO_MODULES = join(__dirname, '../../node_modules'); module.exports = (neutrino, opts = {}) => { if (!opts.name) { @@ -59,9 +60,6 @@ module.exports = (neutrino, opts = {}) => { ); } - neutrino.config.resolve.modules.add(MODULES); - neutrino.config.resolveLoader.modules.add(MODULES); - try { const pkg = require(join(neutrino.options.root, 'package.json')); // eslint-disable-line global-require const hasSourceMap = (pkg.dependencies && 'source-map-support' in pkg.dependencies) || @@ -99,6 +97,7 @@ module.exports = (neutrino, opts = {}) => { .add('node_modules') .add(neutrino.options.node_modules) .add(MODULES) + .add(NEUTRINO_MODULES) .end() .extensions .merge(neutrino.options.extensions.map(ext => `.${ext}`)) @@ -108,6 +107,7 @@ module.exports = (neutrino, opts = {}) => { .modules .add(neutrino.options.node_modules) .add(MODULES) + .add(NEUTRINO_MODULES) .end() .end() .node diff --git a/packages/mocha/src/index.js b/packages/mocha/src/index.js index eeb5752ad..a19eeae75 100644 --- a/packages/mocha/src/index.js +++ b/packages/mocha/src/index.js @@ -9,7 +9,7 @@ module.exports = (neutrino, opts = {}) => { const options = merge.all([ { reporter: 'spec', ui: 'tdd', bail: true }, opts, - files.length ? { recursive: true } : {} + files && files.length ? { recursive: true } : {} ]); neutrino.config.when(usingBabel, () => { diff --git a/packages/node/index.js b/packages/node/index.js index 14a107656..d7b94600b 100644 --- a/packages/node/index.js +++ b/packages/node/index.js @@ -15,6 +15,7 @@ const { } = require('ramda'); const MODULES = join(__dirname, 'node_modules'); +const NEUTRINO_MODULES = join(__dirname, '../../node_modules'); const getPackageJson = (root) => { try { return require(join(root, 'package.json')); // eslint-disable-line @@ -96,6 +97,7 @@ module.exports = (neutrino, opts = {}) => { .add('node_modules') .add(neutrino.options.node_modules) .add(MODULES) + .add(NEUTRINO_MODULES) .end() .extensions .merge(neutrino.options.extensions.map(ext => `.${ext}`)) @@ -105,6 +107,7 @@ module.exports = (neutrino, opts = {}) => { .modules .add(neutrino.options.node_modules) .add(MODULES) + .add(NEUTRINO_MODULES) .end() .end() .when(neutrino.options.debug, (config) => { diff --git a/packages/react-components/index.js b/packages/react-components/index.js index 714849833..1f0746029 100644 --- a/packages/react-components/index.js +++ b/packages/react-components/index.js @@ -6,6 +6,7 @@ const { extname, join, basename } = require('path'); const { readdirSync } = require('fs'); const MODULES = join(__dirname, 'node_modules'); +const NEUTRINO_MODULES = join(__dirname, '../../node_modules'); module.exports = (neutrino, options = {}) => { const reactOptions = merge({ @@ -16,8 +17,12 @@ module.exports = (neutrino, options = {}) => { externals: {} }, options); - neutrino.config.resolve.modules.add(MODULES); - neutrino.config.resolveLoader.modules.add(MODULES); + neutrino.config.resolve.modules + .add(MODULES) + .add(NEUTRINO_MODULES); + neutrino.config.resolveLoader.modules + .add(MODULES) + .add(NEUTRINO_MODULES); neutrino.config.when( process.env.NODE_ENV === 'development', diff --git a/packages/vue/index.js b/packages/vue/index.js index 4c43c15c7..839ee5a6a 100644 --- a/packages/vue/index.js +++ b/packages/vue/index.js @@ -5,27 +5,41 @@ const path = require('path'); const MODULES = path.join(__dirname, 'node_modules'); -module.exports = (neutrino, options) => { +module.exports = (neutrino, options = {}) => { neutrino.use(web, options); + const babel = neutrino.config.module.rule('compile').use('babel'); + const html = neutrino.config.module.rule('html').use('html'); + const vueOptions = merge({ + extractCss: options.extract !== false, + loaders: { + js: { + loader: babel.get('loader'), + options: babel.get('options') + }, + html: { + loader: html.get('loader'), + options: babel.get('options') + } + } + }, options.vue || {}); + neutrino.config.module .rule('vue') .test(neutrino.regexFromExtensions(['vue'])) .use('vue') .loader(require.resolve('vue-loader')) - .options(options); + .options(vueOptions); neutrino.config.when(neutrino.config.module.rules.has('lint'), () => { neutrino.use(loaderMerge('lint', 'eslint'), { + baseConfig: { + extends: ['plugin:vue/base'] + }, plugins: ['vue'], - envs: ['node'], + parser: 'vue-eslint-parser', parserOptions: { - ecmaFeatures: { - jsx: true - } - }, - rules: { - 'vue/jsx-uses-vars': 'error' + parser: 'babel-eslint' } }); }); diff --git a/packages/vue/package.json b/packages/vue/package.json index 2025ad741..87ddfe313 100644 --- a/packages/vue/package.json +++ b/packages/vue/package.json @@ -5,12 +5,6 @@ "main": "src/index.js", "author": "Capi Etheriel (https://barraponto.blog.br)", "license": "MPL-2.0", - "peerDependencies": { - "neutrino": "^7.0.0" - }, - "devDependencies": { - "neutrino": "^7.2.1" - }, "keywords": [ "neutrino", "neutrino-preset", @@ -19,13 +13,16 @@ "hot module replacement" ], "dependencies": { - "@neutrinojs/web": "^7.3.2", "@neutrinojs/loader-merge": "^7.3.2", + "@neutrinojs/web": "^7.3.2", "babel-preset-vue": "^1.2.1", "deepmerge": "^1.5.2", - "eslint-plugin-vue": "^2.1.0", + "eslint-plugin-vue": "^4.0.0-beta.0", "stylelint-processor-html": "^1.0.0", "vue-loader": "^13.5.0", "vue-template-compiler": "^2.5.6" + }, + "peerDependencies": { + "neutrino": "^7.0.0" } } diff --git a/packages/web/index.js b/packages/web/index.js index edaa8fac7..bf50d6b9a 100644 --- a/packages/web/index.js +++ b/packages/web/index.js @@ -19,6 +19,7 @@ const ManifestPlugin = require('webpack-manifest-plugin'); const { optimize } = require('webpack'); const MODULES = join(__dirname, 'node_modules'); +const NEUTRINO_MODULES = join(__dirname, '../../node_modules'); module.exports = (neutrino, opts = {}) => { const publicPath = './'; @@ -36,7 +37,8 @@ module.exports = (neutrino, opts = {}) => { publicPath: resolve('/', publicPath) }, style: { - hot: opts.hot !== false + hot: opts.hot !== false, + extract: opts.extract || process.env.NODE_ENV === 'production' && {} }, manifest: opts.html === false ? {} : false, minify: {}, @@ -119,6 +121,7 @@ module.exports = (neutrino, opts = {}) => { .add('node_modules') .add(neutrino.options.node_modules) .add(MODULES) + .add(NEUTRINO_MODULES) .end() .extensions .merge(neutrino.options.extensions.map(ext => `.${ext}`)) @@ -128,6 +131,7 @@ module.exports = (neutrino, opts = {}) => { .modules .add(neutrino.options.node_modules) .add(MODULES) + .add(NEUTRINO_MODULES) .end() .end() .node diff --git a/yarn.lock b/yarn.lock index c9f18f1db..1c23fc9fc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -259,7 +259,7 @@ ansi-align@^2.0.0: dependencies: string-width "^2.0.0" -ansi-escapes@^1.0.0: +ansi-escapes@^1.0.0, ansi-escapes@^1.1.0: version "1.4.0" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e" @@ -502,7 +502,7 @@ async@1.x, async@^1.4.0, async@^1.5.0, async@^1.5.2: version "1.5.2" resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" -async@2.6.0, async@^2.4.1: +async@2.6.0, async@^2.0.0, async@^2.4.1: version "2.6.0" resolved "https://registry.yarnpkg.com/async/-/async-2.6.0.tgz#61a29abb6fcc026fea77e56d1c6ec53a795951f4" dependencies: @@ -2174,6 +2174,12 @@ clap@^1.0.9: dependencies: chalk "^1.1.3" +class-extend@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/class-extend/-/class-extend-0.1.2.tgz#8057a82b00f53f82a5d62c50ef8cffdec6fabc34" + dependencies: + object-assign "^2.0.0" + classnames@^2.2: version "2.2.5" resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.5.tgz#fb3801d453467649ef3603c7d61a02bd129bde6d" @@ -2202,7 +2208,7 @@ cli-boxes@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-1.0.0.tgz#4fa917c3e59c94a004cd61f8ee509da651687143" -cli-cursor@^1.0.2: +cli-cursor@^1.0.1, cli-cursor@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-1.0.2.tgz#64da3f7d56a54412e59794bd62dc35295e8f2987" dependencies: @@ -3124,7 +3130,7 @@ debug-log@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/debug-log/-/debug-log-1.0.1.tgz#2307632d4c04382b8df8a32f70b895046d52745f" -debug@2, debug@2.6.9, debug@^2.2.0, debug@^2.4.1, debug@^2.6.6, debug@^2.6.8: +debug@2, debug@2.6.9, debug@^2.0.0, debug@^2.1.0, debug@^2.2.0, debug@^2.4.1, debug@^2.6.6, debug@^2.6.8: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" dependencies: @@ -3358,7 +3364,11 @@ diff@3.3.1: version "3.3.1" resolved "https://registry.yarnpkg.com/diff/-/diff-3.3.1.tgz#aa8567a6eed03c531fc89d3f711cd0e5259dec75" -diff@^3.2.0, diff@^3.3.1: +diff@^2.1.2: + version "2.2.3" + resolved "https://registry.yarnpkg.com/diff/-/diff-2.2.3.tgz#60eafd0d28ee906e4e8ff0a52c1229521033bf99" + +diff@^3.1.0, diff@^3.2.0, diff@^3.3.1: version "3.4.0" resolved "https://registry.yarnpkg.com/diff/-/diff-3.4.0.tgz#b1d85507daf3964828de54b37d0d73ba67dda56c" @@ -3909,13 +3919,6 @@ eslint-plugin-babel@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/eslint-plugin-babel/-/eslint-plugin-babel-4.1.2.tgz#79202a0e35757dd92780919b2336f1fa2fe53c1e" -eslint-plugin-html@^3.0.0: - version "3.2.2" - resolved "https://registry.yarnpkg.com/eslint-plugin-html/-/eslint-plugin-html-3.2.2.tgz#ef7093621d3a93de3206fd1f92f347ea9a1a4dfa" - dependencies: - htmlparser2 "^3.8.2" - semver "^5.4.1" - eslint-plugin-import@^2.7.0, eslint-plugin-import@^2.8.0: version "2.8.0" resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.8.0.tgz#fa1b6ef31fcb3c501c09859c1b86f1fc5b986894" @@ -3967,7 +3970,7 @@ eslint-plugin-promise@^3.6.0: version "3.6.0" resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-3.6.0.tgz#54b7658c8f454813dc2a870aff8152ec4969ba75" -eslint-plugin-react@^7.0.0, eslint-plugin-react@^7.4.0, eslint-plugin-react@^7.5.1: +eslint-plugin-react@^7.4.0, eslint-plugin-react@^7.5.1: version "7.5.1" resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.5.1.tgz#52e56e8d80c810de158859ef07b880d2f56ee30b" dependencies: @@ -3980,12 +3983,12 @@ eslint-plugin-standard@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/eslint-plugin-standard/-/eslint-plugin-standard-3.0.1.tgz#34d0c915b45edc6f010393c7eef3823b08565cf2" -eslint-plugin-vue@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-vue/-/eslint-plugin-vue-2.1.0.tgz#50ed0b7e9a2389d90e689743a3cc26b502441b69" +eslint-plugin-vue@^4.0.0-beta.0: + version "4.0.0-beta.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-vue/-/eslint-plugin-vue-4.0.0-beta.0.tgz#5f7a5e991994b6e70baddc65ebd840a09ccbdddb" dependencies: - eslint-plugin-html "^3.0.0" - eslint-plugin-react "^7.0.0" + requireindex "^1.1.0" + vue-eslint-parser "^2.0.1-beta.1" eslint-restricted-globals@^0.1.1: version "0.1.1" @@ -4049,7 +4052,7 @@ espower-location-detector@^1.0.0: source-map "^0.5.0" xtend "^4.0.0" -espree@^3.5.2: +espree@^3.5.1, espree@^3.5.2: version "3.5.2" resolved "https://registry.yarnpkg.com/espree/-/espree-3.5.2.tgz#756ada8b979e9dcfcdb30aad8d1a9304a905e1ca" dependencies: @@ -4271,6 +4274,14 @@ extend@^3.0.0, extend@~3.0.0, extend@~3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444" +external-editor@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-1.1.1.tgz#12d7b0db850f7ff7e7081baf4005700060c4600b" + dependencies: + extend "^3.0.0" + spawn-sync "^1.0.15" + tmp "^0.0.29" + external-editor@^2.0.4: version "2.0.5" resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-2.0.5.tgz#52c249a3981b9ba187c7cacf5beb50bf1d91a6bc" @@ -4595,6 +4606,12 @@ form-data@~2.3.1: combined-stream "^1.0.5" mime-types "^2.1.12" +formatio@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/formatio/-/formatio-1.2.0.tgz#f3b2167d9068c4698a8d51f4f760a39a54d818eb" + dependencies: + samsam "1.x" + forwarded@~0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" @@ -4817,6 +4834,13 @@ getpass@^0.1.1: dependencies: assert-plus "^1.0.0" +gh-got@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/gh-got/-/gh-got-5.0.0.tgz#ee95be37106fd8748a96f8d1db4baea89e1bfa8a" + dependencies: + got "^6.2.0" + is-plain-obj "^1.1.0" + gh-got@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/gh-got/-/gh-got-6.0.0.tgz#d74353004c6ec466647520a10bd46f7299d268d0" @@ -4922,6 +4946,12 @@ github-url-from-username-repo@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/github-url-from-username-repo/-/github-url-from-username-repo-1.0.2.tgz#7dd79330d2abe69c10c2cef79714c97215791dfa" +github-username@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/github-username/-/github-username-3.0.0.tgz#0a772219b3130743429f2456d0bdd3db55dce7b1" + dependencies: + gh-got "^5.0.0" + github-username@^4.0.0: version "4.1.0" resolved "https://registry.yarnpkg.com/github-username/-/github-username-4.1.0.tgz#cbe280041883206da4212ae9e4b5f169c30bf417" @@ -4982,6 +5012,16 @@ glob@^5.0.15, glob@^5.0.3: once "^1.3.0" path-is-absolute "^1.0.0" +glob@^6.0.1: + version "6.0.4" + resolved "https://registry.yarnpkg.com/glob/-/glob-6.0.4.tgz#0f08860f6a155127b2fadd4f9ce24b1aab6e4d22" + dependencies: + inflight "^1.0.4" + inherits "2" + minimatch "2 || 3" + once "^1.3.0" + path-is-absolute "^1.0.0" + glob@~7.0.6: version "7.0.6" resolved "https://registry.yarnpkg.com/glob/-/glob-7.0.6.tgz#211bafaf49e525b8cd93260d14ab136152b3f57a" @@ -5014,6 +5054,17 @@ globals@^9.17.0, globals@^9.18.0: version "9.18.0" resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" +globby@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-4.1.0.tgz#080f54549ec1b82a6c60e631fc82e1211dbe95f8" + dependencies: + array-union "^1.0.1" + arrify "^1.0.0" + glob "^6.0.1" + object-assign "^4.0.1" + pify "^2.0.0" + pinkie-promise "^2.0.0" + globby@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/globby/-/globby-5.0.0.tgz#ebd84667ca0dbb330b99bcfc68eac2bc54370e0d" @@ -5067,7 +5118,7 @@ got@^5.0.0: unzip-response "^1.0.2" url-parse-lax "^1.0.0" -got@^6.7.1: +got@^6.2.0, got@^6.7.1: version "6.7.1" resolved "https://registry.yarnpkg.com/got/-/got-6.7.1.tgz#240cd05785a9a18e561dc1b44b41c763ef1e8db0" dependencies: @@ -5110,7 +5161,7 @@ graceful-fs@4.1.11, graceful-fs@^4.0.0, graceful-fs@^4.1.11, graceful-fs@^4.1.2, version "1.0.1" resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725" -grouped-queue@^0.3.3: +grouped-queue@^0.3.0, grouped-queue@^0.3.3: version "0.3.3" resolved "https://registry.yarnpkg.com/grouped-queue/-/grouped-queue-0.3.3.tgz#c167d2a5319c5a0e0964ef6a25b7c2df8996c85c" dependencies: @@ -5436,7 +5487,7 @@ html-webpack-template@^6.1.0: version "6.1.0" resolved "https://registry.yarnpkg.com/html-webpack-template/-/html-webpack-template-6.1.0.tgz#d96ffdab53131adfa672f981988607807966ad97" -htmlparser2@^3.8.2, htmlparser2@^3.9.1: +htmlparser2@^3.9.1: version "3.9.2" resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.9.2.tgz#1bdf87acca0f3f9e53fa4fcceb0f4b4cbb00b338" dependencies: @@ -5750,7 +5801,26 @@ init-package-json@~1.9.4: validate-npm-package-license "^3.0.1" validate-npm-package-name "^3.0.0" -inquirer@^3.0.6, inquirer@^3.2.2, inquirer@^3.3.0: +inquirer@^1.0.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-1.2.3.tgz#4dec6f32f37ef7bb0b2ed3f1d1a5c3f545074918" + dependencies: + ansi-escapes "^1.1.0" + chalk "^1.0.0" + cli-cursor "^1.0.1" + cli-width "^2.0.0" + external-editor "^1.1.0" + figures "^1.3.5" + lodash "^4.3.0" + mute-stream "0.0.6" + pinkie-promise "^2.0.0" + run-async "^2.2.0" + rx "^4.1.0" + string-width "^1.0.1" + strip-ansi "^3.0.0" + through "^2.3.6" + +inquirer@^3.0.1, inquirer@^3.0.6, inquirer@^3.2.2, inquirer@^3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-3.3.0.tgz#9dd2f2ad765dcab1ff0443b491442a20ba227dc9" dependencies: @@ -7290,7 +7360,7 @@ lodash@^3.8.0: version "3.10.1" resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.10.1.tgz#5bf45e8e49ba4189e17d482789dfd15bd140b7b6" -log-symbols@^1.0.2: +log-symbols@^1.0.1, log-symbols@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-1.0.2.tgz#376ff7b58ea3086a0f09facc74617eca501e1a18" dependencies: @@ -7327,6 +7397,10 @@ loglevel@^1.4.1: version "1.5.1" resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.5.1.tgz#189078c94ab9053ee215a0acdbf24244ea0f6502" +lolex@^1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/lolex/-/lolex-1.6.0.tgz#3a9a0283452a47d7439e72731b9e07d7386e49f6" + longest@^1.0.0, longest@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097" @@ -7746,6 +7820,10 @@ multipipe@^0.1.2: dependencies: duplexer2 "0.0.2" +mute-stream@0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.6.tgz#48962b19e169fd1dfc240b3f1e7317627bbc47db" + mute-stream@0.0.7, mute-stream@~0.0.4: version "0.0.7" resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" @@ -7762,6 +7840,10 @@ nan@^2.3.0: version "2.7.0" resolved "https://registry.yarnpkg.com/nan/-/nan-2.7.0.tgz#d95bf721ec877e08db276ed3fc6eb78f9083ad46" +native-promise-only@^0.8.1: + version "0.8.1" + resolved "https://registry.yarnpkg.com/native-promise-only/-/native-promise-only-0.8.1.tgz#20a318c30cb45f71fe7adfbf7b21c99c1472ef11" + natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" @@ -8558,6 +8640,10 @@ os-locale@^2.0.0: lcid "^1.0.0" mem "^1.1.0" +os-shim@^0.1.2: + version "0.1.3" + resolved "https://registry.yarnpkg.com/os-shim/-/os-shim-0.1.3.tgz#6b62c3791cf7909ea35ed46e17658bb417cb3917" + os-tmpdir@^1.0.0, os-tmpdir@^1.0.1, os-tmpdir@~1.0.1, os-tmpdir@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" @@ -8802,6 +8888,12 @@ path-to-regexp@0.1.7: version "0.1.7" resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" +path-to-regexp@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-1.7.0.tgz#59fde0f435badacba103a84e9d3bc64e96b9937d" + dependencies: + isarray "0.0.1" + path-type@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" @@ -8852,7 +8944,7 @@ pinkie-promise@^1.0.0: dependencies: pinkie "^1.0.0" -pinkie-promise@^2.0.0: +pinkie-promise@^2.0.0, pinkie-promise@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" dependencies: @@ -9516,7 +9608,7 @@ read-all-stream@^3.0.0: pinkie-promise "^2.0.0" readable-stream "^2.0.0" -read-chunk@^2.1.0: +read-chunk@^2.0.0, read-chunk@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/read-chunk/-/read-chunk-2.1.0.tgz#6a04c0928005ed9d42e1a6ac5600e19cbc7ff655" dependencies: @@ -9964,6 +10056,10 @@ require-uncached@^1.0.3: caller-path "^0.1.0" resolve-from "^1.0.0" +requireindex@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/requireindex/-/requireindex-1.1.0.tgz#e5404b81557ef75db6e49c5a72004893fe03e162" + requires-port@1.0.x, requires-port@1.x.x: version "1.0.0" resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" @@ -10020,7 +10116,7 @@ right-align@^0.1.1: dependencies: align-text "^0.1.1" -rimraf@2, rimraf@^2.2.6, rimraf@^2.2.8, rimraf@^2.3.3, rimraf@^2.5.1, rimraf@^2.5.2, rimraf@^2.5.4, rimraf@^2.6.0, rimraf@^2.6.1, rimraf@^2.6.2, rimraf@~2.6.1: +rimraf@2, rimraf@^2.2.0, rimraf@^2.2.6, rimraf@^2.2.8, rimraf@^2.3.3, rimraf@^2.4.4, rimraf@^2.5.1, rimraf@^2.5.2, rimraf@^2.5.4, rimraf@^2.6.0, rimraf@^2.6.1, rimraf@^2.6.2, rimraf@~2.6.1: version "2.6.2" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36" dependencies: @@ -10061,6 +10157,10 @@ rx-lite@*, rx-lite@^4.0.8: version "4.0.8" resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-4.0.8.tgz#0b1e11af8bc44836f04a6407e92da42467b79444" +rx@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/rx/-/rx-4.1.0.tgz#a5f13ff79ef3b740fe30aa803fb09f98805d4782" + rxjs@^5.4.2: version "5.5.2" resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-5.5.2.tgz#28d403f0071121967f18ad665563255d54236ac3" @@ -10071,6 +10171,10 @@ safe-buffer@5.1.1, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, s version "5.1.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" +samsam@1.x, samsam@^1.1.3: + version "1.3.0" + resolved "https://registry.yarnpkg.com/samsam/-/samsam-1.3.0.tgz#8d1d9350e25622da30de3e44ba692b5221ab7c50" + sanctuary-type-classes@^6.0.0: version "6.1.0" resolved "https://registry.yarnpkg.com/sanctuary-type-classes/-/sanctuary-type-classes-6.1.0.tgz#6bd67044358c8440d561e6e2556ab88dd8cd8001" @@ -10255,7 +10359,7 @@ shebang-regex@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" -shelljs@^0.7.8: +shelljs@^0.7.0, shelljs@^0.7.8: version "0.7.8" resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.7.8.tgz#decbcf874b0d1e5fb72e14b164a9683048e9acb3" dependencies: @@ -10271,6 +10375,19 @@ signal-exit@^3.0.0, signal-exit@^3.0.1, signal-exit@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" +sinon@^2.3.6: + version "2.4.1" + resolved "https://registry.yarnpkg.com/sinon/-/sinon-2.4.1.tgz#021fd64b54cb77d9d2fb0d43cdedfae7629c3a36" + dependencies: + diff "^3.1.0" + formatio "1.2.0" + lolex "^1.6.0" + native-promise-only "^0.8.1" + path-to-regexp "^1.7.0" + samsam "^1.1.3" + text-encoding "0.6.4" + type-detect "^4.0.0" + slash@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" @@ -10460,6 +10577,13 @@ sparkles@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/sparkles/-/sparkles-1.0.0.tgz#1acbbfb592436d10bbe8f785b7cc6f82815012c3" +spawn-sync@^1.0.15: + version "1.0.15" + resolved "https://registry.yarnpkg.com/spawn-sync/-/spawn-sync-1.0.15.tgz#b00799557eb7fb0c8376c29d44e8a1ea67e57476" + dependencies: + concat-stream "^1.4.7" + os-shim "^0.1.2" + spawn-wrap@=1.3.8: version "1.3.8" resolved "https://registry.yarnpkg.com/spawn-wrap/-/spawn-wrap-1.3.8.tgz#fa2a79b990cbb0bb0018dca6748d88367b19ec31" @@ -10988,6 +11112,10 @@ tether@^1.4: version "1.4.1" resolved "https://registry.yarnpkg.com/tether/-/tether-1.4.1.tgz#78112ef21adf2aea68cd90e72185f43d9ffc44e8" +text-encoding@0.6.4: + version "0.6.4" + resolved "https://registry.yarnpkg.com/text-encoding/-/text-encoding-0.6.4.tgz#e399a982257a276dae428bb92845cb71bdc26d19" + text-extensions@^1.0.0: version "1.7.0" resolved "https://registry.yarnpkg.com/text-extensions/-/text-extensions-1.7.0.tgz#faaaba2625ed746d568a23e4d0aacd9bf08a8b39" @@ -11091,6 +11219,12 @@ tmp@0.0.x, tmp@^0.0.33: dependencies: os-tmpdir "~1.0.2" +tmp@^0.0.29: + version "0.0.29" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.29.tgz#f25125ff0dd9da3ccb0c2dd371ee1288bb9128c0" + dependencies: + os-tmpdir "~1.0.1" + tmpl@1.0.x: version "1.0.4" resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.4.tgz#23640dd7b42d00433911140820e5cf440e521dd1" @@ -11276,6 +11410,10 @@ type-check@~0.3.2: dependencies: prelude-ls "~1.1.2" +type-detect@^4.0.0: + version "4.0.5" + resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.5.tgz#d70e5bc81db6de2a381bcaca0c6e0cbdc7635de2" + type-is@~1.6.15: version "1.6.15" resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.15.tgz#cab10fb4909e441c82842eafe1ad646c81804410" @@ -11394,6 +11532,12 @@ unquote@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/unquote/-/unquote-1.1.0.tgz#98e1fc608b6b854c75afb1b95afc099ba69d942f" +untildify@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/untildify/-/untildify-2.1.0.tgz#17eb2807987f76952e9c0485fc311d06a826a2e0" + dependencies: + os-homedir "^1.0.0" + untildify@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/untildify/-/untildify-3.0.2.tgz#7f1f302055b3fea0f3e81dc78eb36766cb65e3f1" @@ -11492,7 +11636,7 @@ urlgrey@0.4.4: version "0.4.4" resolved "https://registry.yarnpkg.com/urlgrey/-/urlgrey-0.4.4.tgz#892fe95960805e85519f1cd4389f2cb4cbb7652f" -user-home@2.0.0: +user-home@2.0.0, user-home@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/user-home/-/user-home-2.0.0.tgz#9c70bfd8169bc1dcbf48604e0f04b8b49cde9e9f" dependencies: @@ -11673,6 +11817,16 @@ void-elements@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-2.0.1.tgz#c066afb582bb1cb4128d60ea92392e94d5e9dbec" +vue-eslint-parser@^2.0.1-beta.1: + version "2.0.1-beta.2" + resolved "https://registry.yarnpkg.com/vue-eslint-parser/-/vue-eslint-parser-2.0.1-beta.2.tgz#82e5130ac18ae4b0c894a7c831b55ec92478fa2f" + dependencies: + debug "^3.1.0" + eslint-scope "^3.7.1" + espree "^3.5.1" + esquery "^1.0.0" + lodash "^4.17.4" + vue-hot-reload-api@^2.2.0: version "2.2.4" resolved "https://registry.yarnpkg.com/vue-hot-reload-api/-/vue-hot-reload-api-2.2.4.tgz#683bd1d026c0d3b3c937d5875679e9a87ec6cd8f" @@ -12196,7 +12350,28 @@ yeast@0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/yeast/-/yeast-0.1.2.tgz#008e06d8094320c372dbc2f8ed76a0ca6c8ac419" -yeoman-environment@^2.0.3, yeoman-environment@^2.0.5: +yeoman-assert@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/yeoman-assert/-/yeoman-assert-3.1.0.tgz#ad89ab4616d697f98b1a3eb8a1b63e8e315a89e8" + +yeoman-environment@^1.1.0: + version "1.6.6" + resolved "https://registry.yarnpkg.com/yeoman-environment/-/yeoman-environment-1.6.6.tgz#cd85fa67d156060e440d7807d7ef7cf0d2d1d671" + dependencies: + chalk "^1.0.0" + debug "^2.0.0" + diff "^2.1.2" + escape-string-regexp "^1.0.2" + globby "^4.0.0" + grouped-queue "^0.3.0" + inquirer "^1.0.2" + lodash "^4.11.1" + log-symbols "^1.0.1" + mem-fs "^1.1.0" + text-table "^0.2.0" + untildify "^2.0.0" + +yeoman-environment@^2.0.0, yeoman-environment@^2.0.3, yeoman-environment@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/yeoman-environment/-/yeoman-environment-2.0.5.tgz#84f22bafa84088971fe99ea85f654a3a3dd2b693" dependencies: @@ -12214,6 +12389,41 @@ yeoman-environment@^2.0.3, yeoman-environment@^2.0.5: text-table "^0.2.0" untildify "^3.0.2" +yeoman-generator@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/yeoman-generator/-/yeoman-generator-1.1.1.tgz#40c2b4f6cdfbe05e1952fdd72933f0d8925dbdf5" + dependencies: + async "^2.0.0" + chalk "^1.0.0" + class-extend "^0.1.0" + cli-table "^0.3.1" + cross-spawn "^5.0.1" + dargs "^5.1.0" + dateformat "^2.0.0" + debug "^2.1.0" + detect-conflict "^1.0.0" + error "^7.0.2" + find-up "^2.1.0" + github-username "^3.0.0" + glob "^7.0.3" + istextorbinary "^2.1.0" + lodash "^4.11.1" + mem-fs-editor "^3.0.0" + minimist "^1.2.0" + mkdirp "^0.5.0" + path-exists "^3.0.0" + path-is-absolute "^1.0.0" + pretty-bytes "^4.0.2" + read-chunk "^2.0.0" + read-pkg-up "^2.0.0" + rimraf "^2.2.0" + run-async "^2.0.0" + shelljs "^0.7.0" + text-table "^0.2.0" + through2 "^2.0.0" + user-home "^2.0.0" + yeoman-environment "^1.1.0" + yeoman-generator@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/yeoman-generator/-/yeoman-generator-2.0.1.tgz#cc6b35dec1c352f8eded1fbfce47189d6f823813" @@ -12243,3 +12453,16 @@ yeoman-generator@^2.0.1: text-table "^0.2.0" through2 "^2.0.0" yeoman-environment "^2.0.3" + +yeoman-test@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/yeoman-test/-/yeoman-test-1.7.0.tgz#3edbee64591f2597027a5b42b1dc058251adc9fe" + dependencies: + inquirer "^3.0.1" + lodash "^4.3.0" + mkdirp "^0.5.1" + pinkie-promise "^2.0.1" + rimraf "^2.4.4" + sinon "^2.3.6" + yeoman-environment "^2.0.0" + yeoman-generator "^1.1.0"