From 9cb3d132afc59875b9b6fbb100cd103383d81ed4 Mon Sep 17 00:00:00 2001 From: Sam Hulick Date: Wed, 10 Jan 2018 01:39:32 -0600 Subject: [PATCH 01/11] Changes to allow creating TS project --- meta.js | 59 ++++++++++++++++++++--------- template/build/vue-loader.conf.js | 13 +++++-- template/build/webpack.base.conf.js | 21 ++++++++++ template/package.json | 5 +++ template/tsconfig.json | 34 +++++++++++++++++ template/tslint.json | 23 +++++++++++ 6 files changed, 133 insertions(+), 22 deletions(-) create mode 100644 template/tsconfig.json create mode 100644 template/tslint.json diff --git a/meta.js b/meta.js index 0dc63e651b..364bd4559d 100644 --- a/meta.js +++ b/meta.js @@ -1,29 +1,29 @@ -const path = require('path') -const fs = require('fs') +const path = require('path'); +const fs = require('fs'); const { sortDependencies, installDependencies, runLintFix, printMessage, -} = require('./utils') -const pkg = require('./package.json') +} = require('./utils'); +const pkg = require('./package.json'); -const templateVersion = pkg.version +const templateVersion = pkg.version; module.exports = { helpers: { if_or(v1, v2, options) { if (v1 || v2) { - return options.fn(this) + return options.fn(this); } - return options.inverse(this) + return options.inverse(this); }, template_version() { - return templateVersion + return templateVersion; }, }, - + prompts: { name: { type: 'string', @@ -57,6 +57,11 @@ module.exports = { }, ], }, + typescript: { + type: 'confirm', + message: 'Use TypeScript as default language?', + default: false, + }, router: { type: 'confirm', message: 'Install vue-router?', @@ -153,27 +158,45 @@ module.exports = { 'test/unit/setup.js': "unit && runner === 'jest'", 'test/e2e/**/*': 'e2e', 'src/router/**/*': 'router', + 'tsconfig.json': 'typescript', + 'vue-shims.d.ts': 'typescript', }, complete: function(data, { chalk }) { - const green = chalk.green + const green = chalk.green; - sortDependencies(data, green) + sortDependencies(data, green); - const cwd = path.join(process.cwd(), data.inPlace ? '' : data.destDirName) + const cwd = path.join(process.cwd(), data.inPlace ? '' : data.destDirName); if (data.autoInstall) { installDependencies(cwd, data.autoInstall, green) .then(() => { - return runLintFix(cwd, data, green) + return runLintFix(cwd, data, green); }) .then(() => { - printMessage(data, green) + printMessage(data, green); }) .catch(e => { - console.log(chalk.red('Error:'), e) - }) + console.log(chalk.red('Error:'), e); + }); } else { - printMessage(data, chalk) + printMessage(data, chalk); + } + }, + metalsmith: function(metalsmith, opts, helpers) { + function renameJsSourcesToTs(files, metalsmith, done) { + // If typescript is enabled rename any .js files in src/ folder to .ts extension + if (metalsmith.metadata().typescript) { + Object.keys(files).forEach(filename => { + if (/^(src|test\\unit\\specs).*\.js$/.test(filename)) { + const renamed = filename.replace(/\.js$/, '.ts'); + files[renamed] = files[filename]; + delete files[filename]; + } + }); + } + done(null, files); } + metalsmith.use(renameJsSourcesToTs); }, -} +}; diff --git a/template/build/vue-loader.conf.js b/template/build/vue-loader.conf.js index 33ed58bc0a..66e92f5bac 100644 --- a/template/build/vue-loader.conf.js +++ b/template/build/vue-loader.conf.js @@ -7,10 +7,15 @@ const sourceMapEnabled = isProduction : config.dev.cssSourceMap module.exports = { - loaders: utils.cssLoaders({ - sourceMap: sourceMapEnabled, - extract: isProduction - }), + loaders: { + ...utils.cssLoaders({ + sourceMap: sourceMapEnabled, + extract: isProduction + }), + {{#typescript}} + ts: 'ts-loader!tslint-loader', + {{/typescript}} + }, cssSourceMap: sourceMapEnabled, cacheBusting: config.dev.cacheBusting, transformToRequire: { diff --git a/template/build/webpack.base.conf.js b/template/build/webpack.base.conf.js index 391160c571..47a95271c8 100644 --- a/template/build/webpack.base.conf.js +++ b/template/build/webpack.base.conf.js @@ -45,6 +45,27 @@ module.exports = { {{#lint}} ...(config.dev.useEslint ? [createLintingRule()] : []), {{/lint}} + {{#typescript}} + { + test: /\.ts$/, + loader: 'ts-loader', + exclude: /node_modules/, + options: { + appendTsSuffixTo: [/\.vue$/], + }, + }, + { + test: /\.ts$/, + loader: 'tslint-loader', + enforce: 'pre', + include: [resolve('src'), resolve('test')], + options: { + configFile: 'tslint.json', + tsConfigFile: 'tsconfig.json', + typeCheck: true, + }, + }, + {{/typescript}} { test: /\.vue$/, loader: 'vue-loader', diff --git a/template/package.json b/template/package.json index db5f9564d2..bcaa2b9e62 100644 --- a/template/package.json +++ b/template/package.json @@ -82,6 +82,11 @@ "nightwatch": "^0.9.12", "selenium-server": "^3.0.1", {{/e2e}} + {{#typescript}} + "tslint": "^5.8.0", + "tslint-loader": "^3.5.3", + "typescript": "^2.6.2", + {{/typescript}} "autoprefixer": "^7.1.2", "babel-core": "^6.22.1", "babel-helper-vue-jsx-merge-props": "^2.0.3", diff --git a/template/tsconfig.json b/template/tsconfig.json new file mode 100644 index 0000000000..7222982858 --- /dev/null +++ b/template/tsconfig.json @@ -0,0 +1,34 @@ +{ + "include": [ + "src/**/*.ts", + "src/**/*.vue" + ], + "exclude": [ + "node_modules" + ], + "compilerOptions": { + // this aligns with Vue's browser support + "target": "es5", + // this enables stricter inference for data properties on `this` + "strict": true, + // if using webpack 2+ or rollup, to leverage tree shaking: + "module": "es2015", + "moduleResolution": "node", + "lib": [ + "es2016", + "dom" + ], + "sourceMap": true, + "noImplicitReturns": true, + "noImplicitAny": false, + "experimentalDecorators": true, + "emitDecoratorMetadata": true, + "noUnusedLocals": false, + "baseUrl": ".", + "paths": { + "@/*": [ + "src/*" + ] + } + } +} diff --git a/template/tslint.json b/template/tslint.json new file mode 100644 index 0000000000..9b8d974262 --- /dev/null +++ b/template/tslint.json @@ -0,0 +1,23 @@ +{ + "defaultSeverity": "error", + "extends": ["tslint:recommended"], + "jsRules": {}, + "rules": { + "indent": [true, "spaces", 2], + "interface-name": false, + "newline-before-return": true, + "no-consecutive-blank-lines": false, + "no-console": { "severity": "warning" }, + "no-debugger": { "severity": "warning" }, + "no-empty": { "severity": "warning", "options": "allow-empty-catch" }, + "no-irregular-whitespace": true, + "no-unused-variable": { "severity": "warning" }, + "object-literal-sort-keys": [true], + "ordered-imports": false, + "prefer-switch": true, + "space-within-parens": true, + "quotemark": [true, "single"], + "variable-name": true + }, + "rulesDirectory": [] +} From f2aa1fb49ccf13b0eae31779812f3b34a71cc195 Mon Sep 17 00:00:00 2001 From: Sam Hulick Date: Wed, 10 Jan 2018 01:44:47 -0600 Subject: [PATCH 02/11] Added shim --- meta.js | 3 ++- template/src/sfc.d.ts | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 template/src/sfc.d.ts diff --git a/meta.js b/meta.js index 364bd4559d..062b5be111 100644 --- a/meta.js +++ b/meta.js @@ -159,7 +159,8 @@ module.exports = { 'test/e2e/**/*': 'e2e', 'src/router/**/*': 'router', 'tsconfig.json': 'typescript', - 'vue-shims.d.ts': 'typescript', + 'tslint.json': 'typescript', + 'src/sfc.d.ts': 'typescript', }, complete: function(data, { chalk }) { const green = chalk.green; diff --git a/template/src/sfc.d.ts b/template/src/sfc.d.ts new file mode 100644 index 0000000000..8f6f410263 --- /dev/null +++ b/template/src/sfc.d.ts @@ -0,0 +1,4 @@ +declare module '*.vue' { + import Vue from 'vue'; + export default Vue; +} From 99318b34d68c9b3050a4d45a2717681303fc3304 Mon Sep 17 00:00:00 2001 From: Sam Hulick Date: Wed, 10 Jan 2018 02:03:47 -0600 Subject: [PATCH 03/11] Final touches --- template/src/App.vue | 9 +++++---- template/src/components/HelloWorld.vue | 8 +++++--- template/src/main.js | 2 +- template/src/router/index.js | 6 +++--- template/test/unit/jest.conf.js | 9 ++++++--- template/test/unit/specs/HelloWorld.spec.js | 4 +++- 6 files changed, 23 insertions(+), 15 deletions(-) diff --git a/template/src/App.vue b/template/src/App.vue index 03d5e7247d..7999c93cb3 100644 --- a/template/src/App.vue +++ b/template/src/App.vue @@ -9,17 +9,18 @@ -