学习搭建Vue的TypeScript环境

实现目标:搭建 Vue 的 TS 版编程环境,并学习下 Vue 的类组件使用

一、配置 webpack

首先通过:

npm init

来创建依赖文件:package.json

接下来安装 webpack,因为 webpack 属于开发环境下的依赖,所以安装在 devDependencies 里面。

npm install -D webpack webpack-cli webpack-dev-server

接下来整理和创建文件,文件结构为:


├─ package.json
│  webpack.config.js
│  
├─public
│      index.html
│      
└─src
        main.js

先说下怎么获取这个文档树的,windows下打开 CMD:

tree /f > filetree.txt

tree 只能获取到文件夹,/f 能获取到具体文件,然后通过 > filetree.txt 写入文件。如果有 node_modules 的影响,我们可以忽略这个文件夹,这时的借助 git 来实现:

-I命令允许你使用正则匹配来排除掉你不想看到的文件夹
tree -I "node_modules"
也可以使用|同时排除掉多个文件夹:
tree -I "node_modules|cache|test_*"
有时候文件夹层级很深,我们只关心前两级的文件,可以使用如下-L :
tree -L 2

这时来看看各个文件的内容:
webpack.config.js:

module.exports = {
    
    /* 
        mode:"production" | "development" | "none" 
        production:enable many optimizations for production builds
        development:enabled useful tools for development
        none: no defaults,没有默认,必须设置为production或development
        Chosen mode tells webpack to use its built-in optimizations accordingly
    */
    //--mode=development会将 process.env.NODE_ENV 的值设为 development。并启动相应的插件
    mode:"development",

    /* 基础目录,用于从配置中解析入口起点(entry point)和 loader */
    // context: path.resolve(__dirname, "app")

    /* 应用程序的起点入口。从这个起点开始,应用程序启动执行。
    */
    entry:"./src/main.js",

    output:{
        filename:"bundle.js",
        // 
        publicPath:"virtual"
    },
    module:{
        rules:[

        ]
    },
    resolve:{
        extensions:[".js",".vue",".css",".json"]
    },
    devServer:{
        open: true,
        /* When open is enabled, the dev server will open the browser.
        使用默认浏览器打开服务
        open: true
        Usage via the CLI//命令行中使用
        webpack-dev-server --open
        If no browser is provided (as shown above), your default browser will be used. To specify a different browser, just pass its name:
        //指定浏览器
        webpack-dev-server --open 'Google Chrome */


        /* 指定打开浏览器时要浏览的页面。
        Specify a page to navigate to when opening the browser. 
        默认浏览的页面是webpack.config.js所在目录的index.html文件
        */
        openPage: './public/index.html'
    },
    plugins:[

    ]
}

index.html:




    
    
    Vue中使用TypeScript


    


main.js:

alert(process.env.NODE_ENV);//development

欧克了,现在来启动服务:

启动服务, --progress可以将运行进度输出到控制台。
npx webpack-dev-server --progress

二、启动 JS 版 Vue

安装 Vue:

npm i -S vue

在 index.html 增加一个一行:

这时更改main.js文件:

import Vue from "vue";

new Vue({
    el:"#app",
    render:function(h){
        return h("h1","TypeScript!")
    }
})
image

打开网址查看,没有问题。但是如果把 main.js 改成这样:

import Vue from "vue";

new Vue({
    el:"#app",
    data:{
        name: "TypeScript!"
    },
    template:"

{{name}}

" })

会看到浏览器报错:

vue.runtime.esm.js:620 [Vue warn]: You are using the runtime-only build of Vue where the
template compiler is not available. Either pre-compile the templates into render functions,
or use the compiler-included build.
[Vue警告]:您正在使用Vue的仅运行时版本,而模板编译器不可用。可以将模板预编译为渲染函数,
也可以使用包含编译器的内部版本。

Vue 官网演示案例:

https://cn.vuejs.org/v2/guide/installation.html#%E6%9C%AF%E8%AF%AD
// 需要编译器
new Vue({
  template: '
{{ hi }}
' }) // 不需要编译器 new Vue({ render (h) { return h('div', this.hi) } })

如果你使用 render(h) 渲染函数就不需要去 webpack 指定完整版了。现在我们去指定下 Vue 的版本,修改 webpack.config.js,需要注意的是:因为运行时版本相比完整版体积要小大约30%,所以应该尽可能使用这个版本。如果你仍然希望使用完整版,则需要在打包工具里配置一个别名:

module.exports = {
  // ...
  resolve: {
    alias: {
      'vue$': 'vue/dist/vue.esm.js' // 用 webpack 1 时需用 'vue/dist/vue.common.js'
    }
  }
}
//https://cn.vuejs.org/v2/guide/installation.html

这个时候在 main.js 同级目录下创建 App.vue 文件,同时更改 main.js 文件的内容为:

import Vue from "vue";
import App from "./App";

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

不过这时候我们还不能使用单文件组件,需要 loader 对应的 loader:
安装依赖:

npm i -D vue-loader vue-template-compiler

注意:

vue-template-compiler 需要独立安装的原因是你可以单独指定其版本。
每个 vue 包的新版本发布时,一个相应版本的 vue-template-compiler 也会随之发布。编译器的版本必须和基本的 vue 包保持同步,这样 vue-loader 就会生成兼容运行时的代码。这意味着你每次升级项目中的 vue 包时,也应该匹配升级 vue-template-compiler。

去 webpack.config.js 配置下loader:

// webpack.config.js
const VueLoaderPlugin = require('vue-loader/lib/plugin')

module.exports = {
  module: {
    rules: [
      // ... 其它规则
      {
        test: /\.vue$/,
        loader: 'vue-loader'
      }
    ]
  },
  plugins: [
    // 请确保引入这个插件!
    new VueLoaderPlugin()
  ]
}

你肯定好奇,vue-Loader 的配置和其它的 loader 怎么不太一样。除了通过一条规则将 vue-loader 应用到所有扩展名为 .vue 的文件上之外,还在 plugins 里使用了 VueLoaderPlugin 插件。这个插件是干啥的?

这个插件是必须的! 它的职责是将你定义过的其它规则复制并应用到 .vue 文件里相应语言的块。例如,如果你有一条匹配 /\.css$/ 的规则,那么它会应用到 .vue 文件里的

安装处理样式的依赖:

npm i -D css-loader vue-style-loader

在去配置下 webpack :

module:{
    rules:[
        {
            test: /\.vue$/,
            loader: 'vue-loader'
        },
        {
            test: /\.css$/,
            use: [
                //顺序不能倒过来
                'vue-style-loader',
                'css-loader'
            ]
        }
    ]
},

完成显示:

image

三、启动 TS 版 Vue

Vue 时自带 xx.d.ts 声明文件的,所以不用我们安装支持 TS 的第三方插件。

接着配置,安装插件并生成 ts.config.json

npm i -D ts-loader typescript
npx tsc --init

修改 webpack.config.js 的配置:

{ 
    test: /\.ts?$/, 
    loader: "ts-loader",
    options: {
        // .vue文件必须加
        appendTsSuffixTo: [/\.vue$/]
    },
    exclude:/node_modules/
}

appendTsSuffixTo的作用?
要与文件名匹配的正则表达式列表。如果文件名与其中一个正则表达式匹配,则会在该文件名后面附加一个.ts或.tsx后缀。这对于*.vue文件格式现在很有用。(将来可能会受益于新的单一文件格式。)

App.vue 文件内容改为:




//下面这种写法也行



main.js 改为 main.ts 内容改成:

import Vue from "vue";
// 不能不加.vue后缀,不加会报错
import App from "./App.vue";

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

这时启动服务会有个问题:

Cannot find module './App.vue'.

不能找到模块,由于 TypeScript 默认并不支持 *.vue 后缀的文件,所以在 vue 项目中引入的时候需要创建一个 vue-shims.d.ts 文件,意思是告诉 TypeScript 以 *.vue 为后缀的文件可以交给 vue 模块来处理 (真正的原因是导入的模块需要一个 Vueconstructor)

而在代码中导入 *.vue 文件的时候,需要写上 .vue 后缀。原因是因为 TypeScript 默认只识别 *.ts 文件,不识别 *.vue 文件。
在 src 目录下新建 vue-shims.d.ts:

declare module '*.vue' {
    import Vue from 'vue';
    export default Vue;
}

四、类组件

上面单文件组件 Vue 的写法固然是没问题,但是不能很好的去使用 ES6 类等语法,所以我们要改成类组件的形式。

安装依赖:

npm i -D vue-class-component

然后去修改下 App.vue 文件:




注意 main.ts 也被修改了:

import Vue from "vue";
// 不能不加.vue,会报错
import App from "./App.vue";

new Vue({
    el:"#app",
    components:{
        App
    },
    template:""
});

又因为我们用到了装饰器,所以的更改下 tsconfig.js 文件,打开装饰器语法:

"experimentalDecorators": true,        /* Enables experimental support for ES7 decorators. */

演示效果:

image

更多官网 API :https://class-component.vuejs.org/

五、Vue 装饰器

上面的案例我们使用了一个装饰器,挺好用的是不是,但是可以只有一个,如果想要更多可以参考官网自定义装饰器来给我们使用,我们当然不使用这种方式,我们使用插件:

npm i -D vue-property-decorator

看看官网提供了多少个装饰器:

There are several decorators and 1 function (Mixin):

@Prop
@PropSync
@Model
@Watch
@Provide
@Inject
@ProvideReactive
@InjectReactive
@Emit
@Ref
@Component (provided by vue-class-component)
Mixins (the helper function named mixins provided by vue-class-component)

注意这个插件是依赖vue-class-component的。

我们来看几个最常用的,现在 App.vue 是 Children.vue 的父亲,main.ts 内容不变,来开始吧:
App.vue





Children.vue




演示效果:

image

更多 API 参考官网:https://www.npmjs.com/package/vue-property-decorator

六、提升编译速度

现在项目编译一次需要时间为:

Time: 6236ms

As your project becomes bigger, compilation time increases linearly. It's because typescript's semantic checker has to inspect all files on every rebuild. The simple solution is to disable it by using the transpileOnly: true option, but doing so leaves you without type checking and will not output declaration files.

随着项目变得越来越大,编译时间线性增加。这是因为在每次重建时,类型脚本的语义检查器必须检查所有文件。简单的解决方案是通过使用transfileOnly:true选项来禁用它,但是这样做会使您没有类型检查,并且不会输出声明文件。

所以我们配置下 webpack.config.js 文件:

{
    test: /\.tsx?$/,
    use: [
        {
            loader: 'ts-loader',
            options: {
                transpileOnly: true
            }
        }
    ]
}

再次编译用时:

Time: 1659ms

快了不是一星半点。但是现在类型检查没了,这则么能够,这时我们使用 fork-ts-checker-webpack-plugin 另外开一个线程来进行类型检查,安装依赖:

npm install -D fork-ts-checker-webpack-plugin
//使用:
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
plugins:[
    new ForkTsCheckerWebpackPlugin()
]

再次编译用时:

//无类型检查编译用时
Time: 1947ms
//加上类型检查用时
Time: 3284ms

就这也快了一半。

2020年2月15日 01点05分

你可能感兴趣的:(学习搭建Vue的TypeScript环境)