From 2a664984b750981d35917c9e51b66a6c3975b053 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Tue, 13 Sep 2016 10:39:18 +0200 Subject: [PATCH] happy coding --- .gitignore | 1 + .vscode/launch.json | 18 +++ .vscode/settings.json | 4 + generators/app/index.js | 169 +++++++++++++++++++++++++ generators/app/templates/eslintrc.json | 23 ++++ generators/app/templates/jsconfig.json | 7 + package.json | 25 ++++ tsconfig.json | 11 ++ 8 files changed, 258 insertions(+) create mode 100644 .gitignore create mode 100644 .vscode/launch.json create mode 100644 .vscode/settings.json create mode 100644 generators/app/index.js create mode 100644 generators/app/templates/eslintrc.json create mode 100644 generators/app/templates/jsconfig.json create mode 100644 package.json create mode 100644 tsconfig.json diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3c3629e --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +node_modules diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..2363259 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,18 @@ +{ + "version": "0.2.0", + "configurations": [ + + { + "name": "Attach", + "type": "node", + "request": "attach", + "port": 5858, + "address": "localhost", + "restart": false, + "sourceMaps": false, + "outDir": null, + "localRoot": "${workspaceRoot}", + "remoteRoot": null + } + ] +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..510be30 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,4 @@ +// Place your settings in this file to overwrite default and user settings. +{ + "typescript.tsdk": "node_modules/typescript/lib" +} \ No newline at end of file diff --git a/generators/app/index.js b/generators/app/index.js new file mode 100644 index 0000000..b746dfb --- /dev/null +++ b/generators/app/index.js @@ -0,0 +1,169 @@ +'use strict'; + +const generators = require('yeoman-generator'); +const fs = require('fs'); +const cp = require('child_process'); +const yosay = require('yosay'); + +module.exports = generators.Base.extend({ + + constructor: function () { + generators.Base.apply(this, arguments); + + this.argument('codeExec', { type: String, defaults: 'code', optional: true }); + this.ctx = Object.create(null); + }, + + // --- init ------------ + + _checkConfigJson() { + // check/fetch jsconfig.json + this.ctx.jsConfigJson = this.fs.readJSON(this.destinationPath('jsconfig.json')) + this.ctx.tsConfigJson = this.fs.readJSON(this.destinationPath('tsconfig.json')) + }, + + _checkTypesDependencies() { + // check/fetch package.json + + const pack = this.fs.readJSON(this.destinationPath('package.json')) + if (pack) { + const dependencies = new Set(); + const typeDependencies = new Set(); + + const visit = (properties) => { + if (properties) { + for (let name in properties) { + if (name.indexOf('@types') === -1) { + dependencies.add(name); + } else { + typeDependencies.add(name); + } + } + } + } + + visit(pack.dependencies); + visit(pack.devDependencies); + visit(pack.optionalDependencies); + + pack.optionalDependencies = pack.optionalDependencies || {}; + + for (const dep of dependencies) { + const typeDep = `@types/${dep}`; + if (!typeDependencies.has(typeDep)) { + pack.optionalDependencies[typeDep] = '*'; + this.ctx.newPackageJson = pack; + } + } + } + }, + _checkInstalledExtensions() { + // code-extensions + return new Promise(resolve => { + cp.exec(`${this.codeExec} --list-extensions`, (err, stdout, stderr) => { + if (!err) { + this.ctx.installedExtensions = new Set(stdout.trim().split(/[\r\n]/)); + } + resolve(); + }); + }); + }, + + initializing() { + + this.log(yosay('Welcome to the JavaScript project generator!')); + + return Promise.all([ + this._checkConfigJson(), + this._checkTypesDependencies(), + this._checkInstalledExtensions(), + ]); + }, + + prompting() { + const prompts = [ + { + when: () => !this.ctx.jsConfigJson && !this.ctx.tsConfigJson, + type: 'confirm', + name: 'createJsConfig', + message: 'Create \'jsconfig.json\' file?', + }, + { + when: () => this.ctx.tsConfigJson && (!this.ctx.tsConfigJson.compilerOptions || !this.ctx.tsConfigJson.compilerOptions.allowJs), + type: 'confirm', + name: 'setAllowJs', + message: 'Should I adjust \'tsconfig.json\' to allow for JavaScript files (strongly recommended)?', + }, + { + when: answers => !answers.setAllowJs && this.ctx.tsConfigJson && (!this.ctx.tsConfigJson.compilerOptions || !this.ctx.tsConfigJson.compilerOptions.allowJs), + type: 'confirm', + name: 'setAllowJs', + message: 'Sure about that? The presence of a \'tsconfig.json\'-file shadows a \'jsconfig.json\'-file and without the \'allowJs\'-flag there will be no support for JavaScript. Should I add the \'allowJs\'-flag?', + }, + { + when: () => this.ctx.newPackageJson, + type: 'confirm', + name: 'acquireTypes', + message: 'Install type-definition files (.d.ts) and adjust \'package.json\'?' + }, + { + when: () => this.ctx.installedExtensions && !this.ctx.installedExtensions.has('eg2.vscode-npm-script'), + type: 'confirm', + name: 'installNpmScriptRunner', + message: 'Install \'npm script runner\'-extension?' + }, + { + when: () => this.ctx.installedExtensions && !this.ctx.installedExtensions.has('dbaeumer.vscode-eslint'), + type: 'confirm', + name: 'installEsLint', + message: 'Install \'eslint\'-extension?' + } + ]; + + return this.prompt(prompts).then(answers => { + this.answers = answers; + }); + }, + + writing() { + if (this.answers.createJsConfig) { + // write jsconfig + this.fs.copy(this.templatePath('jsconfig.json'), this.destinationPath('jsconfig.json')); + + } else if (this.answers.setAllowJs) { + // update tsconfig + if (!this.ctx.tsConfigJson.compilerOptions) { + this.ctx.tsConfigJson.compilerOptions = { allowJs: true }; + } else { + this.ctx.tsConfigJson.compilerOptions.allowJs = true; + } + fs.writeFileSync(this.destinationPath('tsconfig.json'), JSON.stringify(this.ctx.tsConfigJson, undefined, 4)); + } + + // update package.json + if (this.answers.acquireTypes) { + fs.writeFileSync(this.destinationPath('package.json'), JSON.stringify(this.ctx.newPackageJson, undefined, 4)); + // this.fs.writeJSON(this.destinationPath('package.json'), this.ctx.newPackageJson, undefined, 4); + } + + // add .eslintrc file + if (this.answers.installEsLint) { + this.fs.copy(this.templatePath('eslintrc.json'), this.destinationPath('.eslintrc')); + } + }, + + install() { + + if (this.answers.acquireTypes) { + this.installDependencies({ bower: false }); + } + + if (this.answers.installNpmScriptRunner) { + this.spawnCommand(this.codeExec, ['--install-extension', 'eg2.vscode-npm-script']); + } + + if (this.answers.installEsLint) { + this.spawnCommand(this.codeExec, ['--install-extension', 'dbaeumer.vscode-eslint']); + } + } +}); \ No newline at end of file diff --git a/generators/app/templates/eslintrc.json b/generators/app/templates/eslintrc.json new file mode 100644 index 0000000..7db5754 --- /dev/null +++ b/generators/app/templates/eslintrc.json @@ -0,0 +1,23 @@ +{ + "env": { + "browser": true, + "commonjs": true, + "es6": true, + "node": true + }, + "parserOptions": { + "ecmaFeatures": { + "jsx": true + }, + "sourceType": "module" + }, + "rules": { + "no-const-assign": "warn", + "no-this-before-super": "warn", + "no-undef": "warn", + "no-unreachable": "warn", + "no-unused-vars": "warn", + "constructor-super": "warn", + "valid-typeof": "warn" + } +} \ No newline at end of file diff --git a/generators/app/templates/jsconfig.json b/generators/app/templates/jsconfig.json new file mode 100644 index 0000000..b854fab --- /dev/null +++ b/generators/app/templates/jsconfig.json @@ -0,0 +1,7 @@ +{ + "compilerOptions": { + "target": "es6", + "module": "commonjs", + "allowSyntheticDefaultImports": true + } +} \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..7169c86 --- /dev/null +++ b/package.json @@ -0,0 +1,25 @@ +{ + "name": "generator-code-javascript", + "version": "0.1.0", + "description": "Generator for JavaScript projects", + "files": [ + "generators/app" + ], + "keywords": [ + "yeoman-generator", + "javascript", + "vscode" + ], + "dependencies": { + "yeoman-generator": "^0.24.1", + "yosay": "^1.2.0" + }, + "devDependencies": { + "typescript": "^2.1.0-dev.20160912" + }, + "optionalDependencies": { + "@types/yeoman-generator": "*", + "@types/yosay": "*", + "@types/typescript": "*" + } +} \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..cc0f371 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "target": "es6", + "module": "commonjs", + "allowJs": true, + "lib": [ + "es2015", + "es2015.collection" + ] + } +} \ No newline at end of file