mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-23 14:15:13 +00:00
refactor(ts): better DX for typescript support (#5079)
Breaking change : `build.useForkTsChecker` renamed to `build.typescript.typeCheck`
This commit is contained in:
parent
821676511b
commit
920f444b6e
@ -9,6 +9,7 @@ coverage
|
||||
## cofeescript
|
||||
examples/coffeescript/pages/index.vue
|
||||
examples/pug-stylus-coffee/
|
||||
examples/typescript-eslint/
|
||||
# Packages
|
||||
|
||||
# vue-app
|
||||
|
@ -1,21 +1,8 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const { resolve } = require('path')
|
||||
|
||||
// Globally indicate we are running in ts mode
|
||||
process.env.NUXT_TS = 'true'
|
||||
|
||||
const nuxtCommands = ['dev', 'build', 'generate', 'start']
|
||||
const rootDir = (process.argv[2] && !nuxtCommands.includes(process.argv[2])) ? process.argv[2] : process.cwd()
|
||||
const tsConfigPath = resolve(rootDir, 'tsconfig.json')
|
||||
|
||||
const suffix = require('../package.json').name.includes('-edge') ? '-edge' : ''
|
||||
|
||||
const errorHandler = (error) => {
|
||||
require('consola').fatal(error)
|
||||
process.exit(2)
|
||||
}
|
||||
|
||||
require('@nuxt/typescript' + suffix).setup(tsConfigPath).then(() => {
|
||||
require('@nuxt/cli' + suffix).run().catch(errorHandler)
|
||||
}).catch(errorHandler)
|
||||
require('@nuxt/cli' + suffix).run()
|
||||
.catch((error) => {
|
||||
require('consola').fatal(error)
|
||||
process.exit(2)
|
||||
})
|
||||
|
@ -1,8 +1,8 @@
|
||||
module.exports = {
|
||||
apps: [
|
||||
{
|
||||
name: 'pm2-nuxt-ts',
|
||||
script: './node_modules/.bin/nuxt-ts',
|
||||
name: 'pm2-nuxt-typescript',
|
||||
script: './node_modules/.bin/nuxt',
|
||||
args: 'start',
|
||||
instances: 2,
|
||||
exec_mode: 'cluster',
|
||||
|
@ -2,17 +2,16 @@
|
||||
"version": "1.0.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"nuxt-ts": "latest",
|
||||
"nuxt": "latest",
|
||||
"vue-property-decorator": "^7.3.0"
|
||||
},
|
||||
"scripts": {
|
||||
"dev": "nuxt-ts",
|
||||
"build": "nuxt-ts build",
|
||||
"start": "nuxt-ts start",
|
||||
"generate": "nuxt-ts generate",
|
||||
"lint": "tslint --project ."
|
||||
"dev": "nuxt",
|
||||
"build": "nuxt build",
|
||||
"start": "nuxt start",
|
||||
"generate": "nuxt generate"
|
||||
},
|
||||
"devDependencies": {
|
||||
"tslint-config-standard": "^8.0.1"
|
||||
"@nuxt/typescript": "latest"
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1 @@
|
||||
{
|
||||
"extends": "@nuxt/typescript",
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"types": [
|
||||
"@types/node",
|
||||
"@nuxt/vue-app"
|
||||
]
|
||||
}
|
||||
}
|
||||
{}
|
||||
|
@ -1,9 +0,0 @@
|
||||
{
|
||||
"defaultSeverity": "error",
|
||||
"extends": [
|
||||
"tslint-config-standard"
|
||||
],
|
||||
"rules": {
|
||||
"prefer-const": true
|
||||
}
|
||||
}
|
9
examples/typescript-eslint/.eslintrc.js
Normal file
9
examples/typescript-eslint/.eslintrc.js
Normal file
@ -0,0 +1,9 @@
|
||||
module.exports = {
|
||||
plugins: ['@typescript-eslint'],
|
||||
parserOptions: {
|
||||
parser: '@typescript-eslint/parser'
|
||||
},
|
||||
extends: [
|
||||
'@nuxtjs'
|
||||
]
|
||||
}
|
15
examples/typescript-eslint/.gitignore
vendored
Normal file
15
examples/typescript-eslint/.gitignore
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
# Dependencies
|
||||
node_modules
|
||||
|
||||
# Logs
|
||||
*.log*
|
||||
|
||||
# IDE
|
||||
.idea
|
||||
.vscode
|
||||
|
||||
# Nuxt build
|
||||
.nuxt
|
||||
|
||||
# Nuxt generate
|
||||
dist
|
33
examples/typescript-eslint/README.md
Normal file
33
examples/typescript-eslint/README.md
Normal file
@ -0,0 +1,33 @@
|
||||
# Nuxt with TypeScript & ESLint example
|
||||
|
||||
Use `yarn lint` or `npm run lint` to lint your TypeScript project !
|
||||
|
||||
## Why ESLint and not TSLint ?
|
||||
|
||||
See https://eslint.org/blog/2019/01/future-typescript-eslint
|
||||
|
||||
##
|
||||
|
||||
## VSCode settings
|
||||
|
||||
If you're using VSCode, we recommend using these settings :
|
||||
|
||||
```json
|
||||
"eslint.autoFixOnSave": true,
|
||||
"eslint.validate": [
|
||||
{
|
||||
"language": "javascript",
|
||||
"autoFix": true
|
||||
},
|
||||
{
|
||||
"language": "typescript",
|
||||
"autoFix": true
|
||||
},
|
||||
{
|
||||
"language": "vue",
|
||||
"autoFix": true
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
It will lint your `.js`, `.ts` & `.vue` files whenever you're saving them.
|
1
examples/typescript-eslint/nuxt.config.ts
Normal file
1
examples/typescript-eslint/nuxt.config.ts
Normal file
@ -0,0 +1 @@
|
||||
export default {}
|
30
examples/typescript-eslint/package.json
Normal file
30
examples/typescript-eslint/package.json
Normal file
@ -0,0 +1,30 @@
|
||||
{
|
||||
"version": "1.0.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"nuxt": "latest",
|
||||
"vue-property-decorator": "^7.3.0"
|
||||
},
|
||||
"scripts": {
|
||||
"dev": "nuxt",
|
||||
"build": "nuxt build",
|
||||
"start": "nuxt start",
|
||||
"generate": "nuxt generate",
|
||||
"lint": "eslint --ext .ts,.js,.vue --ignore-path .gitignore .",
|
||||
"lint:fix": "yarn lint --fix",
|
||||
"post-update": "yarn upgrade --latest"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@nuxt/typescript": "latest",
|
||||
"@nuxtjs/eslint-config": "latest",
|
||||
"@typescript-eslint/eslint-plugin": "^1.4.2",
|
||||
"eslint": "^5.14.1",
|
||||
"eslint-config-standard": "^12.0.0",
|
||||
"eslint-plugin-import": "^2.16.0",
|
||||
"eslint-plugin-jest": "^22.3.0",
|
||||
"eslint-plugin-node": "^8.0.1",
|
||||
"eslint-plugin-promise": "^4.0.1",
|
||||
"eslint-plugin-standard": "^4.0.0",
|
||||
"eslint-plugin-vue": "^5.2.2"
|
||||
}
|
||||
}
|
14
examples/typescript-eslint/pages/index.vue
Normal file
14
examples/typescript-eslint/pages/index.vue
Normal file
@ -0,0 +1,14 @@
|
||||
<template>
|
||||
<div>
|
||||
<h1>{{ title }}</h1>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { Component, Vue } from 'vue-property-decorator'
|
||||
|
||||
@Component
|
||||
export default class Home extends Vue {
|
||||
title = 'TypeScript + ESLint example'
|
||||
}
|
||||
</script>
|
1
examples/typescript-eslint/tsconfig.json
Normal file
1
examples/typescript-eslint/tsconfig.json
Normal file
@ -0,0 +1 @@
|
||||
{}
|
@ -3,20 +3,18 @@
|
||||
"private": true,
|
||||
"version": "1.0.0",
|
||||
"scripts": {
|
||||
"dev": "nuxt-ts",
|
||||
"build": "nuxt-ts build",
|
||||
"start": "nuxt-ts start",
|
||||
"generate": "nuxt-ts generate",
|
||||
"lint": "tslint --project .",
|
||||
"lint:fix": "tslint --project . --fix",
|
||||
"dev": "nuxt",
|
||||
"build": "nuxt build",
|
||||
"start": "nuxt start",
|
||||
"generate": "nuxt generate",
|
||||
"post-update": "yarn upgrade --latest",
|
||||
"watch:css": "tcm components -w"
|
||||
},
|
||||
"dependencies": {
|
||||
"nuxt-ts": "latest"
|
||||
"nuxt": "latest"
|
||||
},
|
||||
"devDependencies": {
|
||||
"tslint-config-standard": "^8.0.1",
|
||||
"@nuxt/typescript": "latest",
|
||||
"typed-css-modules": "^0.3.7"
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,6 @@
|
||||
{
|
||||
"extends": "@nuxt/typescript",
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"noImplicitThis": true,
|
||||
"types": ["@types/node", "@nuxt/vue-app"]
|
||||
"jsx": "preserve",
|
||||
"noImplicitThis": true
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +0,0 @@
|
||||
{
|
||||
"defaultSeverity": "error",
|
||||
"extends": ["tslint-config-standard"],
|
||||
"rules": {
|
||||
"prefer-const": true
|
||||
}
|
||||
}
|
@ -3,20 +3,19 @@
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"axios": "^0.18.0",
|
||||
"nuxt-ts": "latest",
|
||||
"nuxt": "latest",
|
||||
"tachyons": "^4.11.1",
|
||||
"vue-property-decorator": "^7.3.0",
|
||||
"vuex-class": "^0.3.1"
|
||||
},
|
||||
"scripts": {
|
||||
"dev": "nuxt-ts",
|
||||
"build": "nuxt-ts build",
|
||||
"start": "nuxt-ts start",
|
||||
"generate": "nuxt-ts generate",
|
||||
"lint": "tslint --project .",
|
||||
"dev": "nuxt",
|
||||
"build": "nuxt build",
|
||||
"start": "nuxt start",
|
||||
"generate": "nuxt generate",
|
||||
"post-update": "yarn upgrade --latest"
|
||||
},
|
||||
"devDependencies": {
|
||||
"tslint-config-standard": "^8.0.1"
|
||||
"@nuxt/typescript": "latest"
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1 @@
|
||||
{
|
||||
"extends": "@nuxt/typescript",
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"noImplicitAny": false,
|
||||
"types": [
|
||||
"@types/node",
|
||||
"@nuxt/vue-app"
|
||||
]
|
||||
}
|
||||
}
|
||||
{}
|
||||
|
@ -1,9 +0,0 @@
|
||||
{
|
||||
"defaultSeverity": "error",
|
||||
"extends": [
|
||||
"tslint-config-standard"
|
||||
],
|
||||
"rules": {
|
||||
"prefer-const": true
|
||||
}
|
||||
}
|
@ -2,18 +2,17 @@
|
||||
"version": "1.0.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"nuxt-ts": "latest",
|
||||
"nuxt": "latest",
|
||||
"vue-property-decorator": "^7.3.0"
|
||||
},
|
||||
"scripts": {
|
||||
"dev": "nuxt-ts",
|
||||
"build": "nuxt-ts build",
|
||||
"start": "nuxt-ts start",
|
||||
"generate": "nuxt-ts generate",
|
||||
"lint": "tslint --project .",
|
||||
"dev": "nuxt",
|
||||
"build": "nuxt build",
|
||||
"start": "nuxt start",
|
||||
"generate": "nuxt generate",
|
||||
"post-update": "yarn upgrade --latest"
|
||||
},
|
||||
"devDependencies": {
|
||||
"tslint-config-standard": "^8.0.1"
|
||||
"@nuxt/typescript": "latest"
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1 @@
|
||||
{
|
||||
"extends": "@nuxt/typescript",
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"types": [
|
||||
"@types/node",
|
||||
"@nuxt/vue-app"
|
||||
]
|
||||
}
|
||||
}
|
||||
{}
|
||||
|
@ -1,9 +0,0 @@
|
||||
{
|
||||
"defaultSeverity": "error",
|
||||
"extends": [
|
||||
"tslint-config-standard"
|
||||
],
|
||||
"rules": {
|
||||
"prefer-const": true
|
||||
}
|
||||
}
|
@ -1,9 +1,12 @@
|
||||
|
||||
import path from 'path'
|
||||
import consola from 'consola'
|
||||
import minimist from 'minimist'
|
||||
import { name, version } from '../package.json'
|
||||
import { loadNuxtConfig, forceExit } from './utils'
|
||||
import { indent, foldLines, colorize } from './utils/formatting'
|
||||
import { startSpaces, optionSpaces, forceExitTimeout } from './utils/constants'
|
||||
import { detectAndSetupTypeScriptSupport } from './utils/typescript'
|
||||
import * as imports from './imports'
|
||||
|
||||
export default class NuxtCommand {
|
||||
@ -73,7 +76,10 @@ export default class NuxtCommand {
|
||||
return this._parsedArgv
|
||||
}
|
||||
|
||||
async getNuxtConfig(extraOptions) {
|
||||
async getNuxtConfig(extraOptions = {}) {
|
||||
const rootDir = path.resolve(this.argv._[0] || '.')
|
||||
extraOptions._typescript = await detectAndSetupTypeScriptSupport(rootDir, { transpileOnly: this.cmd.name === 'start' })
|
||||
|
||||
const config = await loadNuxtConfig(this.argv)
|
||||
const options = Object.assign(config, extraOptions)
|
||||
|
||||
|
@ -1,5 +1,4 @@
|
||||
import path from 'path'
|
||||
import { existsSync } from 'fs'
|
||||
import consola from 'consola'
|
||||
import esm from 'esm'
|
||||
import exit from 'exit'
|
||||
@ -11,14 +10,14 @@ import prettyBytes from 'pretty-bytes'
|
||||
import env from 'std-env'
|
||||
import { successBox, warningBox } from './formatting'
|
||||
|
||||
export const requireModule = process.env.NUXT_TS ? require : esm(module, {
|
||||
const esmOptions = {
|
||||
cache: false,
|
||||
cjs: {
|
||||
cache: true,
|
||||
vars: true,
|
||||
namedExports: true
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export const eventsMapping = {
|
||||
add: { icon: '+', color: 'green', action: 'Created' },
|
||||
@ -26,18 +25,23 @@ export const eventsMapping = {
|
||||
unlink: { icon: '-', color: 'red', action: 'Removed' }
|
||||
}
|
||||
|
||||
const getRootDir = argv => path.resolve(argv._[0] || '.')
|
||||
const getNuxtConfigFile = argv => path.resolve(getRootDir(argv), argv['config-file'])
|
||||
|
||||
export async function loadNuxtConfig(argv) {
|
||||
const rootDir = getRootDir(argv)
|
||||
const nuxtConfigFile = getNuxtConfigFile(argv)
|
||||
|
||||
const rootDir = path.resolve(argv._[0] || '.')
|
||||
let nuxtConfigFile
|
||||
let options = {}
|
||||
|
||||
if (existsSync(nuxtConfigFile)) {
|
||||
delete require.cache[nuxtConfigFile]
|
||||
options = requireModule(nuxtConfigFile) || {}
|
||||
try {
|
||||
nuxtConfigFile = require.resolve(path.resolve(rootDir, argv['config-file']))
|
||||
} catch (e) {
|
||||
if (e.code !== 'MODULE_NOT_FOUND') {
|
||||
throw (e)
|
||||
} else if (argv['config-file'] !== defaultNuxtConfigFile) {
|
||||
consola.fatal('Could not load config file: ' + argv['config-file'])
|
||||
}
|
||||
}
|
||||
|
||||
if (nuxtConfigFile) {
|
||||
options = (nuxtConfigFile.endsWith('.ts') ? require(nuxtConfigFile) : esm(module, esmOptions)(nuxtConfigFile)) || {}
|
||||
if (options.default) {
|
||||
options = options.default
|
||||
}
|
||||
@ -56,9 +60,8 @@ export async function loadNuxtConfig(argv) {
|
||||
|
||||
// Keep _nuxtConfigFile for watching
|
||||
options._nuxtConfigFile = nuxtConfigFile
|
||||
} else if (argv['config-file'] !== defaultNuxtConfigFile) {
|
||||
consola.fatal('Could not load config file: ' + argv['config-file'])
|
||||
}
|
||||
|
||||
if (typeof options.rootDir !== 'string') {
|
||||
options.rootDir = rootDir
|
||||
}
|
||||
|
38
packages/cli/src/utils/typescript.js
Normal file
38
packages/cli/src/utils/typescript.js
Normal file
@ -0,0 +1,38 @@
|
||||
import path from 'path'
|
||||
import { existsSync } from 'fs'
|
||||
import chalk from 'chalk'
|
||||
import consola from 'consola'
|
||||
import { warningBox } from './formatting'
|
||||
|
||||
const dependencyNotFoundMessage =
|
||||
`Please install @nuxt/typescript and rerun the command
|
||||
|
||||
${chalk.bold('Using yarn')}
|
||||
yarn add -D @nuxt/typescript
|
||||
|
||||
${chalk.bold('Using npm')}
|
||||
npm install -D @nuxt/typescript`
|
||||
|
||||
export async function detectAndSetupTypeScriptSupport(rootDir, options = {}) {
|
||||
const tsConfigPath = path.resolve(rootDir, 'tsconfig.json')
|
||||
|
||||
if (!existsSync(tsConfigPath)) {
|
||||
return false
|
||||
}
|
||||
|
||||
consola.info(`${chalk.bold.blue('tsconfig.json')} found, enabling TypeScript runtime support`)
|
||||
|
||||
try {
|
||||
const { setup } = require('@nuxt/typescript')
|
||||
await setup(tsConfigPath, options)
|
||||
} catch (e) {
|
||||
if (e.code === 'MODULE_NOT_FOUND') {
|
||||
process.stdout.write(warningBox(dependencyNotFoundMessage, chalk.yellow('An external official dependency is needed to enable TS support')))
|
||||
process.exit(1)
|
||||
} else {
|
||||
throw (e)
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
@ -14,7 +14,7 @@ exports[`cli/command builds help text 1`] = `
|
||||
--universal, -u Launch in Universal
|
||||
mode (default)
|
||||
--config-file, -c Path to Nuxt.js
|
||||
config file (default: nuxt.config.js)
|
||||
config file (default: nuxt.config)
|
||||
--modern, -m Build/Start app for
|
||||
modern browsers, e.g. server, client and
|
||||
false
|
||||
|
@ -54,7 +54,9 @@ export default () => ({
|
||||
},
|
||||
vueStyle: {}
|
||||
},
|
||||
useForkTsChecker: process.env.NUXT_TS === 'true',
|
||||
typescript: {
|
||||
typeCheck: true
|
||||
},
|
||||
styleResources: {},
|
||||
plugins: [],
|
||||
terser: {},
|
||||
|
@ -10,7 +10,7 @@ import router from './router'
|
||||
import server from './server'
|
||||
import cli from './cli'
|
||||
|
||||
export const defaultNuxtConfigFile = `nuxt.config${process.env.NUXT_TS === 'true' ? '.ts' : '.js'}`
|
||||
export const defaultNuxtConfigFile = 'nuxt.config'
|
||||
|
||||
export function getDefaultNuxtConfig(options = {}) {
|
||||
if (!options.env) {
|
||||
|
@ -84,7 +84,7 @@ export function getNuxtConfig(_options) {
|
||||
|
||||
// Default value for _nuxtConfigFile
|
||||
if (!options._nuxtConfigFile) {
|
||||
options._nuxtConfigFile = path.resolve(options.rootDir, defaultNuxtConfigFile)
|
||||
options._nuxtConfigFile = path.resolve(options.rootDir, `${defaultNuxtConfigFile}.js`)
|
||||
}
|
||||
|
||||
// Watch for _nuxtConfigFile changes
|
||||
|
@ -131,7 +131,9 @@ Object {
|
||||
"templates": Array [],
|
||||
"terser": Object {},
|
||||
"transpile": Array [],
|
||||
"useForkTsChecker": false,
|
||||
"typescript": Object {
|
||||
"typeCheck": true,
|
||||
},
|
||||
"watch": Array [],
|
||||
},
|
||||
"buildDir": "/var/nuxt/test/.nuxt",
|
||||
|
@ -121,7 +121,9 @@ Object {
|
||||
"templates": Array [],
|
||||
"terser": Object {},
|
||||
"transpile": Array [],
|
||||
"useForkTsChecker": false,
|
||||
"typescript": Object {
|
||||
"typeCheck": true,
|
||||
},
|
||||
"watch": Array [],
|
||||
},
|
||||
"buildDir": ".nuxt",
|
||||
@ -450,7 +452,9 @@ Object {
|
||||
"templates": Array [],
|
||||
"terser": Object {},
|
||||
"transpile": Array [],
|
||||
"useForkTsChecker": false,
|
||||
"typescript": Object {
|
||||
"typeCheck": true,
|
||||
},
|
||||
"watch": Array [],
|
||||
},
|
||||
"buildDir": ".nuxt",
|
||||
|
@ -4,8 +4,7 @@
|
||||
"repository": "nuxt/nuxt.js",
|
||||
"license": "MIT",
|
||||
"files": [
|
||||
"dist",
|
||||
"tsconfig.json"
|
||||
"dist"
|
||||
],
|
||||
"main": "dist/typescript.js",
|
||||
"dependencies": {
|
||||
@ -22,15 +21,11 @@
|
||||
"@types/webpack-bundle-analyzer": "^2.13.1",
|
||||
"@types/webpack-dev-middleware": "^2.0.2",
|
||||
"@types/webpack-hot-middleware": "^2.16.5",
|
||||
"chalk": "^2.4.2",
|
||||
"consola": "^2.5.6",
|
||||
"enquirer": "^2.3.0",
|
||||
"fork-ts-checker-webpack-plugin": "^1.0.0",
|
||||
"fs-extra": "^7.0.1",
|
||||
"std-env": "^2.2.1",
|
||||
"lodash": "^4.17.11",
|
||||
"ts-loader": "^5.3.3",
|
||||
"ts-node": "^8.0.3",
|
||||
"tslint": "^5.14.0",
|
||||
"typescript": "^3.3.3333"
|
||||
},
|
||||
"publishConfig": {
|
||||
|
@ -1,53 +1,57 @@
|
||||
import chalk from 'chalk'
|
||||
import consola from 'consola'
|
||||
import env from 'std-env'
|
||||
import { prompt } from 'enquirer'
|
||||
import { existsSync, writeJSON } from 'fs-extra'
|
||||
import { readJSON, writeJSON } from 'fs-extra'
|
||||
import { register } from 'ts-node'
|
||||
import defaultsDeep from 'lodash/defaultsDeep'
|
||||
|
||||
async function generateTsConfig(tsConfigPath) {
|
||||
const configToExtend = '@nuxt/typescript'
|
||||
await writeJSON(tsConfigPath, {
|
||||
extends: configToExtend,
|
||||
compilerOptions: {
|
||||
baseUrl: '.',
|
||||
types: [
|
||||
'@types/node',
|
||||
'@nuxt/vue-app'
|
||||
export const defaultTsJsonConfig = {
|
||||
compilerOptions: {
|
||||
target: 'esnext',
|
||||
module: 'esnext',
|
||||
moduleResolution: 'node',
|
||||
lib: [
|
||||
'esnext',
|
||||
'esnext.asynciterable',
|
||||
'dom'
|
||||
],
|
||||
esModuleInterop: true,
|
||||
experimentalDecorators: true,
|
||||
allowJs: true,
|
||||
sourceMap: true,
|
||||
strict: true,
|
||||
noImplicitAny: false,
|
||||
noEmit: true,
|
||||
baseUrl: '.',
|
||||
paths: {
|
||||
'~/*': [
|
||||
'./*'
|
||||
],
|
||||
'@/*': [
|
||||
'./*'
|
||||
]
|
||||
}
|
||||
}, { spaces: 2 })
|
||||
consola.info(`Extending ${chalk.bold.blue(`node_modules/${configToExtend}/tsconfig.json`)}`)
|
||||
consola.success(`Generated successfully at ${chalk.bold.green(tsConfigPath)}`)
|
||||
},
|
||||
types: [
|
||||
'@types/node',
|
||||
'@nuxt/vue-app'
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
let _setup = false
|
||||
|
||||
export async function setup(tsConfigPath) {
|
||||
export async function setup(tsConfigPath, options = {}) {
|
||||
if (_setup) {
|
||||
return
|
||||
}
|
||||
_setup = true
|
||||
|
||||
if (!existsSync(tsConfigPath)) {
|
||||
const { confirmGeneration } = await prompt({
|
||||
type: 'confirm',
|
||||
name: 'confirmGeneration',
|
||||
message: `${chalk.bold.blue(tsConfigPath)} is missing, generate it ?`,
|
||||
initial: true,
|
||||
skip: env.minimal
|
||||
})
|
||||
const config = await readJSON(tsConfigPath)
|
||||
await writeJSON(tsConfigPath, defaultsDeep(config, defaultTsJsonConfig), { spaces: 2 })
|
||||
|
||||
if (confirmGeneration) {
|
||||
await generateTsConfig(tsConfigPath)
|
||||
}
|
||||
}
|
||||
// https://github.com/TypeStrong/ts-node
|
||||
register({
|
||||
project: tsConfigPath,
|
||||
compilerOptions: {
|
||||
module: 'commonjs'
|
||||
},
|
||||
transpileOnly: process.argv[2] === 'start'
|
||||
...options
|
||||
})
|
||||
}
|
||||
|
@ -1,12 +1,9 @@
|
||||
import { resolve } from 'path'
|
||||
import { exists, mkdirp, readJSON, remove } from 'fs-extra'
|
||||
import { mkdirp, readJSON, remove, writeJSON } from 'fs-extra'
|
||||
import { register } from 'ts-node'
|
||||
import { setup as setupTypeScript } from '@nuxt/typescript'
|
||||
import { defaultTsJsonConfig, setup as setupTypeScript } from '@nuxt/typescript'
|
||||
|
||||
jest.mock('ts-node')
|
||||
jest.mock('enquirer', () => ({
|
||||
prompt: jest.fn(() => ({ confirmGeneration: true }))
|
||||
}))
|
||||
|
||||
describe('typescript setup', () => {
|
||||
const rootDir = 'tmp'
|
||||
@ -15,21 +12,12 @@ describe('typescript setup', () => {
|
||||
beforeAll(async () => {
|
||||
// We're assuming that rootDir provided to setupTypeScript is existing so we create the tested one
|
||||
await mkdirp(rootDir)
|
||||
await writeJSON(tsConfigPath, {})
|
||||
await setupTypeScript(tsConfigPath)
|
||||
})
|
||||
|
||||
test('tsconfig.json has been generated if missing', async () => {
|
||||
expect(await exists(tsConfigPath)).toBe(true)
|
||||
expect(await readJSON(tsConfigPath)).toEqual({
|
||||
extends: '@nuxt/typescript',
|
||||
compilerOptions: {
|
||||
baseUrl: '.',
|
||||
types: [
|
||||
'@types/node',
|
||||
'@nuxt/vue-app'
|
||||
]
|
||||
}
|
||||
})
|
||||
test('tsconfig.json has been updated with defaults', async () => {
|
||||
expect(await readJSON(tsConfigPath)).toEqual(defaultTsJsonConfig)
|
||||
})
|
||||
|
||||
test('ts-node has been registered once', async () => {
|
||||
@ -41,13 +29,12 @@ describe('typescript setup', () => {
|
||||
project: tsConfigPath,
|
||||
compilerOptions: {
|
||||
module: 'commonjs'
|
||||
},
|
||||
transpileOnly: false
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
afterAll(async () => {
|
||||
// Clean workspace by removing the temporary folder (and the generated tsconfig.json at the same time)
|
||||
await remove(tsConfigPath)
|
||||
await remove(rootDir)
|
||||
})
|
||||
})
|
||||
|
@ -1,30 +0,0 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "esnext",
|
||||
"module": "esnext",
|
||||
"moduleResolution": "node",
|
||||
"lib": [
|
||||
"esnext",
|
||||
"esnext.asynciterable",
|
||||
"dom"
|
||||
],
|
||||
"esModuleInterop": true,
|
||||
"experimentalDecorators": true,
|
||||
"jsx": "preserve",
|
||||
"sourceMap": true,
|
||||
"strict": true,
|
||||
"noImplicitAny": true,
|
||||
"noEmit": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"~/*": [
|
||||
"./*"
|
||||
],
|
||||
"@/*": [
|
||||
"./*"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
@ -1,5 +1,4 @@
|
||||
import path from 'path'
|
||||
import fs from 'fs'
|
||||
import querystring from 'querystring'
|
||||
import consola from 'consola'
|
||||
import webpack from 'webpack'
|
||||
@ -77,7 +76,7 @@ export default class WebpackClientConfig extends WebpackBaseConfig {
|
||||
|
||||
plugins() {
|
||||
const plugins = super.plugins()
|
||||
const { buildOptions, options: { appTemplatePath, buildDir, rootDir, modern } } = this.buildContext
|
||||
const { buildOptions, options: { appTemplatePath, buildDir, modern, rootDir, _typescript } } = this.buildContext
|
||||
|
||||
// Generate output HTML for SSR
|
||||
if (buildOptions.ssr) {
|
||||
@ -140,21 +139,16 @@ export default class WebpackClientConfig extends WebpackBaseConfig {
|
||||
|
||||
// TypeScript type checker
|
||||
// Only performs once per client compilation and only if `ts-loader` checker is not used (transpileOnly: true)
|
||||
if (!this.isModern && this.loaders.ts.transpileOnly && buildOptions.useForkTsChecker) {
|
||||
const forkTsCheckerResolvedPath = this.buildContext.nuxt.resolver.resolveModule('fork-ts-checker-webpack-plugin')
|
||||
if (forkTsCheckerResolvedPath) {
|
||||
const ForkTsCheckerWebpackPlugin = require(forkTsCheckerResolvedPath)
|
||||
plugins.push(new ForkTsCheckerWebpackPlugin(Object.assign({
|
||||
vue: true,
|
||||
tsconfig: path.resolve(rootDir, 'tsconfig.json'),
|
||||
// https://github.com/Realytics/fork-ts-checker-webpack-plugin#options - tslint: boolean | string - So we set it false if file not found
|
||||
tslint: (tslintPath => fs.existsSync(tslintPath) && tslintPath)(path.resolve(rootDir, 'tslint.json')),
|
||||
formatter: 'codeframe',
|
||||
logger: consola
|
||||
}, buildOptions.useForkTsChecker)))
|
||||
} else {
|
||||
consola.warn('You need to install `fork-ts-checker-webpack-plugin` as devDependency to enable TypeScript type checking !')
|
||||
}
|
||||
if (_typescript && buildOptions.typescript && buildOptions.typescript.typeCheck && !this.isModern && this.loaders.ts.transpileOnly) {
|
||||
// We assume that "_typescript" being truthy means @nuxt/typescript is installed <=> fork-ts-checker-webpack-plugin is installed
|
||||
const ForkTsCheckerWebpackPlugin = require(this.buildContext.nuxt.resolver.resolveModule('fork-ts-checker-webpack-plugin'))
|
||||
plugins.push(new ForkTsCheckerWebpackPlugin(Object.assign({
|
||||
vue: true,
|
||||
tsconfig: path.resolve(rootDir, 'tsconfig.json'),
|
||||
tslint: false, // We recommend using ESLint so we set this option to `false` by default
|
||||
formatter: 'codeframe',
|
||||
logger: consola
|
||||
}, buildOptions.typescript.typeCheck)))
|
||||
}
|
||||
|
||||
return plugins
|
||||
|
26
test/fixtures/typescript/tsconfig.json
vendored
26
test/fixtures/typescript/tsconfig.json
vendored
@ -1,8 +1,30 @@
|
||||
{
|
||||
"extends": "@nuxt/typescript",
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"target": "esnext",
|
||||
"module": "esnext",
|
||||
"moduleResolution": "node",
|
||||
"lib": [
|
||||
"esnext",
|
||||
"esnext.asynciterable",
|
||||
"dom"
|
||||
],
|
||||
"esModuleInterop": true,
|
||||
"experimentalDecorators": true,
|
||||
"allowJs": true,
|
||||
"jsx": "preserve",
|
||||
"sourceMap": true,
|
||||
"strict": true,
|
||||
"noImplicitAny": false,
|
||||
"noEmit": true,
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"~/*": [
|
||||
"./*"
|
||||
],
|
||||
"@/*": [
|
||||
"./*"
|
||||
]
|
||||
},
|
||||
"types": [
|
||||
"@types/node",
|
||||
"@nuxt/vue-app"
|
||||
|
@ -8,7 +8,7 @@ describe('typescript modern', () => {
|
||||
|
||||
beforeAll(async () => {
|
||||
const options = await loadFixture('typescript')
|
||||
nuxt = new Nuxt(Object.assign(options, { modern: true, build: { useForkTsChecker: true } }))
|
||||
nuxt = new Nuxt(Object.assign(options, { modern: true, _typescript: true }))
|
||||
await new Builder(nuxt, BundleBuilder).build()
|
||||
})
|
||||
|
||||
|
@ -2184,7 +2184,7 @@ ansi-align@^3.0.0:
|
||||
dependencies:
|
||||
string-width "^3.0.0"
|
||||
|
||||
ansi-colors@^3.0.0, ansi-colors@^3.2.1:
|
||||
ansi-colors@^3.0.0:
|
||||
version "3.2.4"
|
||||
resolved "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz#e3a3da4bfbae6c86a9c285625de124a234026fbf"
|
||||
integrity sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA==
|
||||
@ -4284,13 +4284,6 @@ enhanced-resolve@^4.0.0, enhanced-resolve@^4.1.0:
|
||||
memory-fs "^0.4.0"
|
||||
tapable "^1.0.0"
|
||||
|
||||
enquirer@^2.3.0:
|
||||
version "2.3.0"
|
||||
resolved "https://registry.npmjs.org/enquirer/-/enquirer-2.3.0.tgz#c362c9d84984ebe854def63caaf12983a16af552"
|
||||
integrity sha512-RNGUbRVlfnjmpxV+Ed+7CGu0rg3MK7MmlW+DW0v7V2zdAUBC1s4BxCRiIAozbYB2UJ+q4D+8tW9UFb11kF72/g==
|
||||
dependencies:
|
||||
ansi-colors "^3.2.1"
|
||||
|
||||
entities@^1.1.1, entities@~1.1.1:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56"
|
||||
|
Loading…
Reference in New Issue
Block a user