Skip to content

Typescript capablility #1238

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 11 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 51 additions & 21 deletions meta.js
Original file line number Diff line number Diff line change
@@ -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',
Expand Down Expand Up @@ -57,16 +57,27 @@ module.exports = {
},
],
},
typescript: {
type: 'confirm',
message: 'Use TypeScript as default language?',
default: false,
},
router: {
type: 'confirm',
message: 'Install vue-router?',
},
lint: {
when: '!typescript',
type: 'confirm',
message: 'Use ESLint to lint your code?',
},
tslint: {
when: 'typescript',
type: 'confirm',
message: 'Use TSLint to lint your code?',
},
lintConfig: {
when: 'lint',
when: '!typescript && lint',
type: 'list',
message: 'Pick an ESLint preset',
choices: [
Expand Down Expand Up @@ -141,8 +152,8 @@ module.exports = {
},
},
filters: {
'.eslintrc.js': 'lint',
'.eslintignore': 'lint',
'.eslintrc.js': '!typescript && lint',
'.eslintignore': '!typescript && lint',
'config/test.env.js': 'unit || e2e',
'build/webpack.test.conf.js': "unit && runner === 'karma'",
'test/unit/**/*': 'unit',
Expand All @@ -153,27 +164,46 @@ module.exports = {
'test/unit/setup.js': "unit && runner === 'jest'",
'test/e2e/**/*': 'e2e',
'src/router/**/*': 'router',
'tsconfig.json': 'typescript',
'tslint.json': 'typescript && tslint',
'src/sfc.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);
},
}
};
13 changes: 9 additions & 4 deletions template/build/vue-loader.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -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}}!tslint-loader{{/tslint}}',
{{/typescript}}
},
cssSourceMap: sourceMapEnabled,
cacheBusting: config.dev.cacheBusting,
transformToRequire: {
Expand Down
26 changes: 24 additions & 2 deletions template/build/webpack.base.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ function resolve (dir) {
module.exports = {
context: path.resolve(__dirname, '../'),
entry: {
app: './src/main.js'
app: './src/main.{{#typescript}}ts{{else}}js{{/typescript}}'
},
output: {
path: config.build.assetsRoot,
Expand All @@ -32,7 +32,7 @@ module.exports = {
: config.dev.assetsPublicPath
},
resolve: {
extensions: ['.js', '.vue', '.json'],
extensions: ['.js', {{#typescript}}'.ts', {{/typescript}}'.vue', '.json'],
alias: {
{{#if_eq build "standalone"}}
'vue$': 'vue/dist/vue.esm.js',
Expand All @@ -45,6 +45,28 @@ module.exports = {
{{#lint}}
...(config.dev.useEslint ? [createLintingRule()] : []),
{{/lint}}
{{#typescript}}
{
test: /\.ts$/,
loader: 'ts-loader',
exclude: /node_modules/,
options: {
appendTsSuffixTo: [/\.vue$/],
},
},
{{#tslint}}
{
test: /\.ts$/,
loader: 'tslint-loader',
enforce: 'pre',
include: [resolve('src'), resolve('test')],
options: {
configFile: 'tslint.json',
tsConfigFile: 'tsconfig.json',
typeCheck: true,
},
},
{{/tslint}}{{/typescript}}
{
test: /\.vue$/,
loader: 'vue-loader',
Expand Down
8 changes: 8 additions & 0 deletions template/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,14 @@
"nightwatch": "^0.9.12",
"selenium-server": "^3.0.1",
{{/e2e}}
{{#typescript}}
{{#tslint}}
"tslint": "^5.8.0",
"tslint-loader": "^3.5.3",
{{/tslint}}
"ts-loader": "^3.2.0",
"typescript": "^2.6.2",
{{/typescript}}
"autoprefixer": "^7.1.2",
"babel-core": "^6.22.1",
"babel-helper-vue-jsx-merge-props": "^2.0.3",
Expand Down
9 changes: 5 additions & 4 deletions template/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,18 @@
</div>
</template>

<script>
<script{{#typescript}} lang="ts"{{/typescript}}>
{{#typescript}}import Vue from 'vue'{{/typescript}}
{{#unless router}}
import HelloWorld from './components/HelloWorld'
import HelloWorld from './components/HelloWorld{{#typescript}}.vue{{/typescript}}'

{{/unless}}
export default {
export default {{#typescript}}Vue.extend({{/typescript}}{
name: 'app'{{#router}}{{else}},
components: {
HelloWorld
}{{/router}}
}
}{{#typescript}}){{/typescript}}
</script>

<style>
Expand Down
10 changes: 6 additions & 4 deletions template/src/components/HelloWorld.vue
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,17 @@
</div>
</template>

<script>
export default {
<script{{#typescript}} lang="ts"{{/typescript}}>
{{#typescript}}import Vue from 'vue'

{{/typescript}}export default {{#typescript}}Vue.extend({{/typescript}}{
name: 'HelloWorld',
data () {
data() {
return {
msg: 'Welcome to Your Vue.js App'
}
}
}
}{{#typescript}}){{/typescript}}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
Expand Down
4 changes: 2 additions & 2 deletions template/src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
{{/if_eq}}
import Vue from 'vue'
import App from './App'
import App from './App{{#typescript}}.vue{{/typescript}}'
{{#router}}
import router from './router'
{{/router}}

Vue.config.productionTip = false

/* eslint-disable no-new */
/* {{#typescript}}tslint:disable-next-line{{else}}eslint-disable no-new{{/typescript}} */
new Vue({
el: '#app',
{{#router}}
Expand Down
6 changes: 3 additions & 3 deletions template/src/router/index.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'
import HelloWorld from '@/components/HelloWorld{{#typescript}}.vue{{/typescript}}'

Vue.use(Router)

export default new Router({
routes: [
{
path: '/',
component: HelloWorld,
name: 'HelloWorld',
component: HelloWorld
path: '/',
}
]
})
4 changes: 4 additions & 0 deletions template/src/sfc.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
declare module '*.vue' {
import Vue from 'vue';
export default Vue;
}
9 changes: 6 additions & 3 deletions template/test/unit/jest.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,18 @@ const path = require('path')
module.exports = {
rootDir: path.resolve(__dirname, '../../'),
moduleFileExtensions: [
'js',
'js',{{#typescript}}
'ts',{{/typescript}}
'json',
'vue'
],
],{{#typescript}}
testRegex: "(/__tests__/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$",{{/typescript}}
moduleNameMapper: {
'^@/(.*)$': '<rootDir>/src/$1'
},
transform: {
'^.+\\.js$': '<rootDir>/node_modules/babel-jest',
'^.+\\.js$': '<rootDir>/node_modules/babel-jest',{{#typescript}}
'^.+\\.ts$': 'ts-jest',{{/typescript}}
'.*\\.(vue)$': '<rootDir>/node_modules/vue-jest'
},{{#e2e}}
testPathIgnorePatterns: [
Expand Down
4 changes: 3 additions & 1 deletion template/test/unit/specs/HelloWorld.spec.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import Vue from 'vue'
import HelloWorld from '@/components/HelloWorld'

describe('HelloWorld.vue', () => {
{{#typescript}}{{#if_eq runner "karma"}}import { expect } from 'chai'

{{/if_eq}}{{/typescript}}describe('HelloWorld.vue', () => {
it('should render correct contents', () => {
const Constructor = Vue.extend(HelloWorld)
const vm = new Constructor().$mount()
Expand Down
34 changes: 34 additions & 0 deletions template/tsconfig.json
Original file line number Diff line number Diff line change
@@ -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/*"
]
}
}
}
25 changes: 25 additions & 0 deletions template/tslint.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"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,
"semicolon": false,
"space-within-parens": true,
"quotemark": [true, "single"],
"trailing-comma": false,
"variable-name": true
},
"rulesDirectory": []
}