前言
随着TypeScript越来越火,作为一名前端工程师,必须紧跟技术的潮流,最近也学习起了TypeScript,然后通过博客来记录自己的一些学习心得和笔记,同时,这也是本人的第一篇博客,如果有写的不好的地方请大家见谅,如果有错误的地方,也欢迎大家指正; 我们都知道,TypeScript是2012年微软正式发布的一门编程,虽然发布的时间不久,他的热门程度可是不低的,就连前端最火的三大框架都在用TypeScript开发,TypeScrip是JavaScrip的超集,他是在JavaScript语法之上建立的一门语言,同时将其他语言的一些精妙的语法引入了进来,从而把JavaScript带到了一个新的高度,借助TS的扩展语法以及面向对象和静态类型的良好支持,我们可以编写出更健壮更可维护的大型项目;学习TS之前,我们需要先搭建出TS的开发环境,这篇文章,我们将学习如何使用webpack5搭建一个Vue3+TS的项目,方便我们学习TypeScript;
1、新建TS项目
新建一个文件夹,命名如first-typescript,然后初始化工程;
执行命令
git init
npm init-y //忽略所有提问,默认都选Y
根目录下添加.gitignore文件,将node_modules添加进去,避免git没必要的文件追踪;
安装typescript,这里选择全局安装;
npm i typescript -g
引入ts的配置文件;
tsc --init
这个时候文件夹中就会生产一个tsconfig.json文件,打开文件,里面是ts的编译选项及相应的解释;接下来就可以编译ts文件了;
根目录下新建src文件夹,文件夹中新建index.ts文件,简单的写入一下内容;如下:
// index.ts
let hello: string = "Hello TypeScript"
然后编译一下,执行命令;
tsc ./src/index.ts
此时,在文件夹中就会看到一个编译好的js文件,打开文件可以看到以下内容;你会看到let被编译成了var,然后去掉了类型注解;
// index.js
var hello = "Hello TypeScript"
2、搭建开发环境引入ts-loader
以上,一个ts的环境就搭建好了,也可以正常编译ts文件了,接下来我们将使用webpack构建我们的开发环境;
引入相应的包;
npm i webpack webpack-cli webpack-dev-server -D
在根目录下创建一个config文件夹,用来存放我们所有的配置文件,我们知道开发环境和生产环境的配置是不一样的,为了便于维护,我们需要将开发环境和生产环境的配置以及公共配置文件分开,然后通过插件进行合并;
在config文件夹下新建四个配置文件,分别是webpack.base.config.js(公共配置文件)、webpack.dev.config.js(开发环境配置文件)、webpack.pro.config.js(生产环境配置文件)、webpack.config.js(配置文件入口)文件,接下来,我们分别编写各个配置文件的配置;
3、编辑项目配置文件
首先,我们先来编写公共配置文件,因为我们使用了TS,所以要引入相应的loader文件,同时,我们还需要在开发环境中安装下typescript;
执行命令:
npm i typescript ts-loader -D
1)、创建html入口文件
我们还需要一个模板去帮助我们生产网站的首页,同时我们还需要安装html-webpack-plugin插件,然后在配置文件中引入这个插件;
新建html模板文件,在src下新建tpl文件夹,文件夹中新建index.html文件,快速构建html文件并修改;
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
<div id="app"></div>
</body>
</html>
安装html-webpack-plugin
npm i html-webpack-plugin -D
2)、公共配置
webpack.base.config.js
const HtmlWebpackPlugin = require("html-webpack-plugin")
module.exports = {
entry: "./src/index.ts", // 入口文件
output: {
filename: "app.js", // 输出文件名字
},
resolve: {
extensions: [".js", "ts", "tsx"], // 指定文件扩展名
},
module: {
rules: [
{
test: /\.(t|j)s$/, //也可以写成/\.tsx?$/i
exclude: /node_modules/, // 排除node_modules文件夹
use: {
loader: "ts-loader",
},
},
],
},
plugins: [
new HtmlWebpackPlugin({
// 这个插件可以通过一个模板帮助我们生成网站的首页,而且可以帮助我们将输入的模板自动嵌入到指定的文件中
title: "firstTypescript",
template: "./src/tpl/index.html",
}),
],
}
3)、开发环境配置
然后我们配置开发环境信息,在开发环境中我们开启了sourceMap,这里我们选用了官方推荐的eval-cheap-module-source-map;其中cheap表示sourceMap会忽略文中的列信息,因为我们在调试的时候列信息是没用的,module表示会定位到我们的TS源码而不是经过loader转译的JS源码;evalSourceMap表示会将sourceMap会以DataUrl的形式打包到文件中,他的重编译速度是很快的,所以不用担心性能问题;
module.exports = {
devtool: 'eval-cheap-module-source-map'
}
4)、生产环境配置
接下来我们配置生产环境信息,开发环境我们使用了一个插件clean-webpack-plugin,他的作用就是在每次构成成功之后帮助我们清空dist目录,因为每次构建之后为了避免缓存,我们需要在构建的文件中加入hash,这样的话在多次构建之后,就会产生很多无用的文件;
执行命令:
npm i clean-webpack-plugin -D
然后在配置文件中引用;
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
module.exports = {
plugins: [
new CleanWebpackPlugin()
]
}
2)、配置文件入口
最后,我们编写配置文件的入口,首先我们使用了一个插件webpack-merge来合并配置文件,然后引入刚刚编写的配置文件,将配置文件合并;
安装webpack-merge:
npm i webpack-merge -D
然后根据环境来合并相应的配置文件;
const merge = require("webpack-merge")
const baseConfig = require("./webpack.base.config")
const devConfig = require("./webpack.dev.config")
const proConfig = require("./webpack.pro.config")
module.exports = (env, argv) => {
let config = argv.mode === "development" ? devConfig : proConfig
return merge(baseConfig, config)
}
4、修改构建脚本
接下来我们要去修改构建脚本,进入package.json文件,首先更改一下他的入口,将main指定为'./src/index.ts',然后编写项目的启动命令,将其命名为serve,使用webpack-dev-serve插件,然后将当前的环境变量设置为development,然后再指定配置文件;
"scripts": {
"serve": "webpack-dev-serve --mode=development --config ./config/webpack.config.js"
},
然后运行项目:
npm run serve
你会发现项目可以正常运行了,然后我们修改index.ts文件来验证一下,将一开始写的"Hello TypeScript"渲染到页面上;
// index.ts
let hello: string = "Hello TypeScript"
document.querySelectorAll('.app')[0].innerHTML = hello;
完成后保存,然后看到页面上能够正常渲染,说明开发环境构建成功;添加生产环境构建命令,取名为build,构建生产环境我们需要使用webpack命令,同样,我们需要设置环境给你参数为production,然后指定配置文件;
"scripts": {
"serve": "webpack-dev-serve --mode=development --config ./config/webpack.config.js",
"build": "webpack --mode=production --config ./config/webpack.config.js"
},
运行npm run build,构成成功,生产了一个dist目录,里面是我们构建之后的文件;
5、提高构建速度
以上,我们借助ts-loader搭建好了一个TS的开发环境,通过t-loader源码可以看出,ts-loader是使用了官方的tsc,ts-loader和tsc是共享tscconfig.json文件的,此外,ts-loader还有一些自己的配置,他是通过options来传入的,他的配置项可以借助ts-loader官方文档来了解,这里我们介绍一个配置项,叫transpileOnly,它的默认值是false,意思就是告诉ts-loader在做语言转换的时候只做语言转换而不进行类型检查,因为在实际的项目中,你会发现随着项目越来越大,构建时间也越来越长,原因之一就是ts编译器要做很多的事情,不仅要做语言转换,还要做类型检查,开启这个配置项,就可以大幅度的提高构建速度;
那么,我们在开启这个配置项的时候如何进行配置检查呢?这里我们要借助一个插件,fork-ts-checker-webpack-plugin,他可以在一个独立的进程中运行,安装插件并引入;
npm i fork-ts-checker-webpack-plugin -D
在配置文件中引入;
const HtmlWebpackPlugin = require("html-webpack-plugin")
const ForkTsCheckerWebpackPlugin = require("fork-ts-checker-webpack-plugin")
module.exports = {
entry: "./src/index.ts", // 入口文件
output: {
filename: "app.js", // 输出文件名字
},
resolve: {
extensions: [".js", "ts", "tsx"], // 指定文件扩展名
},
module: {
rules: [
{
test: /\.(t|j)s$/, //也可以写成/\.tsx?$/i
exclude: /node_modules/, // 排除node_modules文件夹
use: {
loader: "ts-loader",
options: {
transpileOnly: true,
},
},
},
],
},
plugins: [
new HtmlWebpackPlugin({
// 这个插件可以通过一个模板帮助我们生成网站的首页,而且可以帮助我们将输入的模板自动嵌入到指定的文件中
title: "firstTypescript",
template: "./index.html",
}),
new ForkTsCheckerWebpackPlugin(),
],
}
然后在构建过程中就能进行类型检查;
6、使用babel编译TS
除了ts-loader之外,其实我们还可以使用babel-loader来编译ts文件,和ts-loader相比,babel-loader只会对TS文件进行转义不会进行类型检查,所以他的编译速度是很快的,如果要进行类型检查,可以借助IDE来实现,同时开启ts配置项"noEmit": true,只进行类型检查而不编译文件,同时,Babel会根据不同的兼容环境,按需引入pollyfill,比 TSC 直接引入 core-js 更优雅,因此使用了 Babel 打包的体积也会更小。Babel处理TS需要安装@babel/preset-typescript,然后在配置文件中声明;
引入相关依赖:
npm i babel-loader @babel/core @babel/preset-env @babel/preset-typescript -D
修改webpack.base.config.js文件
const HtmlWebpackPlugin = require("html-webpack-plugin")
module.exports = {
entry: "./src/index.ts", // 入口文件
output: {
filename: "app.js", // 输出文件名字
},
resolve: {
extensions: [".js", "ts", "tsx"], // 指定文件扩展名
},
module: {
rules: [
{
test: /\.(t|j)s$/, //也可以写成/\.tsx?$/i
exclude: /node_modules/, // 排除node_modules文件夹
use: {
loader: "babel-loader",
options: {
cacheDirectory: true,
},
},
},
],
},
plugins: [
new HtmlWebpackPlugin({
// 这个插件可以通过一个模板帮助我们生成网站的首页,而且可以帮助我们将输入的模板自动嵌入到指定的文件中
title: "firstTypescript",
template: "./index.html",
}),
],
}
7、修改babel配置
跟目录下新建babel.config.js文件
module.exports = {
presets: [
"@babel/preset-env",
[
"@babel/preset-typescript",
{
allExtensions: true, //支持所有文件扩展名
},
],
],
}
然后打包项目,发现打包并没有异常,然后允许项目,无异常,这时我们就可以卸载ts-loader了;
8、引入Vue3
最后我们再引入vue3,安装vue3及vue-loader;
npm i vue -S // 2022年2月7号开始,默认安装vue3版本
npm i vue-loader -D
然后在基础配置文件中引入vue-loader;同时,我们还需要引入vue插件,将定义的js, css等规则应用到.vue文件中去;
const HtmlWebpackPlugin = require("html-webpack-plugin")
const { VueLoaderPlugin } = require("vue-loader")
module.exports = {
entry: "./src/index.ts", // 入口文件
output: {
filename: "app.js", // 输出文件名字
},
resolve: {
extensions: [".js", "ts", "tsx"], // 指定文件扩展名
},
module: {
rules: [
{
test: /\.(t|j)s$/, //也可以写成/\.tsx?$/i
exclude: /node_modules/, // 排除node_modules文件夹
use: {
loader: "babel-loader",
options: {
cacheDirectory: true,
},
},
},
{
test: /\.vue$/,
use: 'vue-loader'
},
],
},
plugins: [
new HtmlWebpackPlugin({
// 这个插件可以通过一个模板帮助我们生成网站的首页,而且可以帮助我们将输入的模板自动嵌入到指定的文件中
title: "firstTypescript",
template: "./src/tpl/index.html",
}),
new VueLoaderPlugin(),
],
}
8、编译Vue3
我们在src下新建App.vue文件,写入vue3代码
<template>
<h1>{{ name }}</h1>
</template>
<script lang="ts">
import { defineComponent } from "vue"
export default defineComponent({
setup() {
const name = "vue3 + TypeScript"
return {
name,
}
},
})
</script>
然后修改index.ts文件
import { createApp } from "vue"
import App from "./App.vue"
createApp(App).mount("#app")
你会发现引入App.vue时编辑器会报错,这是因为ts无法解析.vue文件,需要在src新建一个以.d.ts结尾的类型声明文件;新建vue-shims.d.ts,写入以下代码;
declare module "*.vue" {
import type { DefineComponent } from "vue"
const component: DefineComponent<{}, {}, any>
export default component
}
执行打包命令,这个时候我们会发现报错,这是因为解析.vue文件我们需要引入@vue/compiler-sfc这个包;
npm i @vue/compiler-sfc -D
然后执行打包命令,这下,我们就能打包成功了,然后我们运行项目,在浏览器中,我们就能看到项目已经正常运行了;
9、结语
这样,一个基于webpack+vue3+TS的项目就搭建完成了,当然,正式开发的配置远不止这些,像css,img以及代码格式检查工具ESLint这些我们都还没有配置,这里完成的只是一个很基础的配置,分别介绍了如何使用ts-loader和babel-loader搭建TS开发环境以及他们的区别,至于其他的配置,会在后续的文章中,再一一讲述;