vuejs / vue-cli

🛠️ webpack-based tooling for Vue.js Development
https://cli.vuejs.org/
MIT License
29.76k stars 6.33k forks source link

TypeScript support for config file (vue.config.ts) #2138

Open biluochun opened 6 years ago

biluochun commented 6 years ago

What problem does this feature solve?

Type tracking when configured.

What does the proposed API look like?

can config width: vue.config.ts or vue.config.js:

  const VueConf = require('@vue/conf');
  VueConf({
    // baseUrl/assetsDir/devServer/... conf in here
  });
yyx990803 commented 6 years ago

Yeah could be nice to have.

Also /cc @octref

Is there anyway for VSCode to have special type checking / autocomplete for vue.config.js, like for tsconfig.json?

yyx990803 commented 6 years ago

I think we could have something like webpack does:

// vue.config.ts

import { Config } from '@vue/cli-service'

const config: Config = {
  // ...
}

export default config

If anyone want to work on this that'd be great. /cc @ktsn @HerringtonDarkholme

octref commented 6 years ago

special type checking / autocomplete for vue.config.js

JS/TS have different story for type checking / autocomplete than JSON. They are actually closer to what we have in Vetur — finding out the default export and wrap that in a typed function call.

We have plan on our roadmap to support linting / autocomplete for webpack and I believe when it's done it can be easily used to support vue.config.ts.

ktsn commented 6 years ago

I'll work on the vue.config.ts support. 👍

beeequeue commented 5 years ago

Any updates on this?

kbtz commented 5 years ago

We might as well enable JS type checking on vue.config.js.

On tsconfig.json enable JS type checking and make sure the config file is included somehow. Mine looks like this:

{
    "compilerOptions": {
        // ...
        "checkJs": true,
    },
    "include": [
        // ...
        "vue.config.js"
    ],
    // ...
}

Then import ProjectOptions with this specific syntax:

/**
 * @typedef { import("@vue/cli-service").ProjectOptions } Options
 */

Importing the definitions other ways didn't worked for me. Also on vscode I'm not getting any type checking errors, only code completions.

Here's a working example with code completion working in vscode even inside chainWebpack:

// vue.config.js
/**
 * @typedef { import("@vue/cli-service").ProjectOptions } Options
 */

const { ProvidePlugin } = require('webpack')
const { resolve, join } = require('path')

/** @param args {string[]} */
const path = (...args) => resolve(join(__dirname, ...args))

/** @type {Options} */
const options = {
    devServer: {
        host: 'bp.viz',
        port: 80,
    },
    chainWebpack: config => {
        config.merge({
            resolve: {
                modules: ['node_modules', path('src')],
            },
            devtool: 'source-map',
        })

        config.plugin('provide').use(ProvidePlugin, [
            {
                Component: ['vue-property-decorator', 'Component'],
                Base: ['./src/components/Base', 'Base'],
            },
        ])
    },
}

module.exports = options
beeequeue commented 5 years ago

Can confirm this works! I had to install @types/webpack-chain to make sure I got the proper types for chainWebpack as well.

My vue.config.js:

/**
 * @type { ProjectOptions }
 */
module.exports = {
  css: {
    sourceMap: true,
  },
  configureWebpack: {
    target: 'electron-renderer',
  },
  lintOnSave: false,
  chainWebpack: config => {
    const svgRules = config.module.rule('svg')

    // Remove default svg loader
    svgRules.uses.clear()

    // Instead use raw-loader
    svgRules.use('raw-loader').loader('raw-loader')
  },
}
yoyoys commented 5 years ago

Here's my vue.config.js config

/**
 * @typedef { import("@vue/cli-service").ProjectOptions } Options
 * @typedef { import("webpack-chain") ChainWebpack }
 */

/**
 * @type { Options }
 */
module.exports = {
  ....
  ....
  /** @type {ChainWebpack} */
  chainWebpack: config => {
    ....
    ....
  }
}
Zonciu commented 5 years ago

It works without checkJs. Just install @types/webpack-chain to devDependency and add comments:

/**
 *  @typedef { import("@vue/cli-service").ProjectOptions } Options
 *  @type { Options }
 */
module.exports = {
...
}
avxkim commented 5 years ago

What's the status of vue.config.ts support?

150148313 commented 5 years ago

(function (exports, require, module, filename, dirname) { import * as path from 'path'; ^

SyntaxError: Unexpected token *

Christilut commented 5 years ago

Would like this too. I'm writing scripts for prerendering that I call in my vue.config.js and I prefer to write everything in TypeScript.

n1kk commented 5 years ago

Any update on this?

Also might be a good idea to add ability to specify path to tsconfig.json since it may need to be different from default one for your project.

Aside of type checking this will make it easier to reuse ts code from your codebase. Currently I'm using ts-node with a custom tsconfig because my projects compiles to esnext but it is not yet supported by default in node, so I need a separate config to override target as well as add node types since this is compilation process that can use nodejs specific modules.

My IDE does a good job on type-checking and auto-completion but I have to import all utils as require("...").name or require("...").default. Having a proper vue.config.ts support would make code so much nicer and cleaner.

phil294 commented 5 years ago

Note: Webpack itself does support various languages for their config files: https://webpack.js.org/configuration/configuration-languages/ This however mostly only includes file extensions and not type hints

zwmmm commented 4 years ago

Support?

GrayStrider commented 4 years ago

Bump, I need to import some things from .ts files, would be really nice to have this feature. What are my other options, if any?

Edit:

require('ts-node').register({
  transpileOnly: true
})

seem to do the trick, but ES6 import/export still doesn't work, so I guess I'll just copy the code over?

n1kk commented 4 years ago

@GrayStrider you can create vue.config.ts and move all your code to it and use import and export in there, and in vue.config.js you can import it, but keep in mind that if your project output is not supported by node you will need to have additional tsconfig.js that has module set to commonjs:

require('ts-node').register({
  project: _PATH_TO_TSCONFIG_WITH_COMMONJS_,
})

module.exports = require("./vue.config.ts").config;

And then your vue.config.ts can look like this

import { ProjectOptions } from "@vue/cli-service"

export const config: ProjectOptions = {
    // ... your vue config here
};

Now you have type checks and code completion in your vue config.

I keep additional tsconfig with node support in my ./scripts folder, then I can also use it to write my projects build/deploy/etc scripts in ts so I could reuse my code in them and run then from cli directly using ts-script shebang.

cheesytim commented 4 years ago

Any changes?

undergroundwires commented 4 years ago

Bump, looking forward to this 🙏 Any updates?

kondaurovDev commented 4 years ago

I've created vue.config.ts, now it looks:

import { ProjectOptions } from "@vue/cli-service"
import * as path from 'path'

const conf: ProjectOptions = {
    publicPath: process.env.BASE_URL || "/",
    chainWebpack: config => {
        config.resolve
        .alias
        .set('@public', path.resolve(__dirname, 'src/module/public/'));
    },
    devServer: {
        proxy: {
            '^/api': {
                target: "http://localhost:8072",
                pathRewrite: {'^/api' : ''}
            }
        }
    },
    configureWebpack: {
        devtool: 'source-map',
    },
    productionSourceMap: false
}

module.exports = conf

Added script to package.json "compile:config": "tsc -m commonjs --esModuleInterop vue.config.ts"

Added vue.config.js to gitignore

Now if i've changed configuration i just need to type: pnpm run compile:config and vue.config.js appears :)

I use pnpm, not yarn or npm

Penguinlay commented 3 years ago

Would love to see vue.config.ts for vue 3.x!

NWYLZW commented 3 years ago

I did it!!!

  1. install ts-node cross-env
  2. edit your package.json
    {
    "scripts": {
    // a little ugly, it can be optimized
    "serve": "cross-env VUE_CLI_SERVICE_CONFIG_PATH=./vue.config.ts ts-node ./node_modules/@vue/cli-service/bin/vue-cli-service.js serve"
    },
    }
  3. run it
jim3692 commented 2 years ago

@n1kk 's solution seems cleaner. I had to add tsconfig-paths as well for my use case.

require('ts-node').register({
    project: _PATH_TO_TSCONFIG_WITH_COMMONJS_,
});
require('tsconfig-paths/register'); // In case you need paths
module.exports = require("./vue.config.ts").config;
markhalliwell commented 2 years ago

Any progress on this?

lmcsu commented 2 years ago

Finally got it working.

vue.config.js:

// eslint-disable-next-line n/no-deprecated-api
const isTsRegistered = require.extensions['.ts'];

if (!isTsRegistered) {
    require('ts-node').register({
        project: './tsconfig.json',
        compilerOptions: {
            module: 'commonjs',
        },
    });
}

module.exports = require('./vue.config.ts').default;

vue.config.ts:

import { defineConfig } from '@vue/cli-service';

export default defineConfig({
   ...