使用TypeScript + Vue + Webpack

本文共--字 阅读约--分钟 | 浏览: -- Last Updated: 2021-02-26

Vue的主入口

// main.ts 
import Vue from 'vue'
import App from './App.vue'

new Vue({
  el: '#app',
  render: h => h(App)
});

App的主页:

<!-- App.vue -->
<template>
  <h1>{{ msg }}</h1>
</template>

<!-- 用于指明代码的语法是TypeScript  -->
<script lang="ts">
  import Vue from "vue";
  // 通过 Vue.extend 启用 TypeScript 类型推断
  export default Vue.extend({
    data() {
      return {
        msg: 'Hello, Webpack',
      }
    },
  });
</script>

<style scoped>
  h1 {
    color: red;
  }
</style>

从 vue2.5 之后,vue 对 ts 有更好的支持。根据官方文档,vue 结合 typescript ,有两种书写方式:

<!-- App.vue -->
<template>
  <h1 @click="onClic">{{ msg }}</h1>

  <h1 >{{ oldMsg }}</h1>
</template>

<!-- 用于指明代码的语法是TypeScript  -->
<script lang="ts">
  import { Vue, Componentfrom 'vue-class-component';

  @Component({
    data() {
      return {
        oldMsg: '可以在这里这样使用原来的写法',
      }
    },
    methods: {
      onOldClick() {
        console.log(this.oldMsg)
      }
    },
    created() {
      console.log('created')
    }
  })
  export default class MyComponent extends Vue {
    msg: string = 'Hello!';

    onClick(): void {
      console.log(this.msg)
    }

    mounted() {
      console.log('mounted')
    }

    // 还有很多修饰符可以用
    // @Emit @Watch @Props @Inject @Provider ...
  }
</script>

<style scoped>
  h1 {
    color: red;
  }
</style>

关于Vue的声明文件:由于Type Script 不认识以.vue结尾的文件,所以为了让其支持import App from './App.vue'这样的导入语句,还需要定义声明文件vue-shims.d.ts 定义.vue文件的类型,告诉 Type Script编译器.vue文件其实是一个new Vue()

// vue-shims.d.ts
declare module "*.vue" {
  import Vue from "vue";
  export default Vue;
}

tsconfig.json的配置:

{
  "compilerOptions": {
    // 构建出 ES5 版本的 JavaScript,与 Vue 的浏览器支持保持一致
    "target": "es5",
    // 开启严格模式,这可以对 `this` 上的数据属性进行更严格的推断
    "strict": true,
    // 输出的 JavaScript 采用 es2015 模块化,使 Tree Shaking 生效
    "module": "es2015",
    "moduleResolution": "node"
  }
}

Webpack的配置文件

// webpack.config.js
const path = require('path');

module.exports = {
  // 执行入口文件
  entry: './main.ts',
  output: {
    // 把所有依赖的模块合并输出到一个 bundle.js 文件
    filename: 'bundle.js',
    // 输出文件都放到 dist 目录下
    path: path.resolve(__dirname, './dist'),
  },
  resolve: {
    extensions: ['.ts', '.js', '.vue', '.json'],
  },
  module: {
    rules: [
      // 加载 .vue 文件
      {
        test: /\.vue$/,
        use: ['vue-loader'],
        exclude: /node_modules/,
      },
      // 加载 .ts 文件
      {
        test: /\.ts$/,
        loader: 'ts-loader',
        exclude: /node_modules/,
        options: {
          // 让 tsc 把 vue 文件当成一个 TypeScript 模块去处理,
          // 以解决 moudle not found 的问题,tsc 本身不会处理 .vue 结尾的文件
          appendTsSuffixTo: [/\.vue$/],
        }
      },
    ]
  },
  devtool: 'source-map' // 输出 source-map 方便直接调试 ES6 源码
};

主页面: index.html

<html>
  <head>
    <meta charset="UTF-8">
  </head>
  <body>
    <div id="app"></div>
    <!--导入 webpack 输出的 JS 文件-->
    <script src="./dist/bundle.js"></script>
  </body>
</html>