一、内容简介
目前大家常用的webpack打包ts主要为两种方案:
ts-loader:将ts转为js,再使用babel将js转为低版本js;
@babel/preset-typescript:它是直接移除TypeScript,转为JS,这使得它的编译速度飞快,并且只需要管理Babel一个编译器就行了。
二、方案对比
首先我们需要安装 webpack、webpack-cli、typescript 随便写一点ts,用于打包测试:
// index.ts
class Student {
name: string
age: Number
constructor(name: string, age: Number) {
this.name = name
this.age = age
}
greet() {
console.log(`Hello, my name is ${this.name}`)
}
}
const testPromise = (): Promise => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve('1')
}, 1000)
})
}
const studentA = new Student('a', 20)
studentA.greet()
testPromise().then(data => {
console.log('data', data)
})
复制代码
1.使用方法法对比
1)ts-loader:
先安装ts-loader: npm install ts-loader --save-dev 在项目中配置webpack.config.js:
const path = require('path')
module.exports = {
mode: 'development',
entry: './index.ts',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, './dist')
},
resolve: {
extensions: [".ts", ".tsx", ".js"]
},
module: {
rules: [
{
test: /\.tsx?$/,
exclude: /node_modules/,
loader: 'ts-loader'
}
]
},
plugins: []
}
复制代码
然后需要设置tsconfig.json:
{
"compilerOptions": {
"module": "commonjs",
"sourceMap": true,
"target": "es5",
"lib": [
"es5",
"dom",
"es2015.promise"
]
}
}
复制代码
lib根据具体代码和应用场景还可以配置其他参数:
接下来打包后可以看到打包代码:
实际const、箭头函数之类的已经转成了es5,而 promise可能在低版本浏览器不兼容,那么设置babel将一些不兼容的语法转为es5:
npm install core-js
npm install --save-dev babel-loader @babel/core @babel/cli @babel/preset-env
npm install --save @babel/polyfill
复制代码
设置.babelrc;
{
"presets": [
[
"@babel/preset-env",
{
"corejs": "3",
"useBuiltIns": "usage"
}
]
]
}
复制代码
在webpack.config.js中设置babel-loader处理js
module: {
rules: [
{
test: /\.tsx?$/,
exclude: /node_modules/,
loader: ['babel-loader', 'ts-loader']
}
]
},
复制代码
再进行打包:
可以看到promse这类的方法已经有了定义,这样不会造成低版本不兼容的问题了,当然如果你已经设置了 高版本的浏览器,这部分代码也不会被打包进来,因为高版本浏览器已经可以直接使用promise。
2)@babel/preset-typescript:
和上面相关bebel的插件基本相同
npm install core-js
npm install --save-dev babel-loader @babel/core @babel/cli @babel/preset-env
npm install --save @babel/polyfill
npm install --save-dev @babel/preset-typescript
复制代码
就多了@babel/preset-typescript webpack.config.js中直接使用了babel-loader:
const path = require('path')
module.exports = {
mode: 'development',
entry: './index.ts',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, './dist')
},
module: {
rules: [
{
test: /\.tsx?$/,
exclude: /node_modules/,
loader: ['babel-loader']
}
]
},
plugins: []
}
复制代码
.babelrc中也只多了@babel/preset-typescript
{
"presets": [
[
"@babel/preset-env",
{
"corejs": "3",
"useBuiltIns": "usage"
}
],
"@babel/preset-typescript"
]
}
复制代码
执行打包,发现bundle.js也是打包了promise。
这里使用@babel/preset-typescript的时候专门删了tsconfig.js,发现依然可以打包成功,但是ts-loader是一定要设置tsconfig.js的,因为我只是做了一下测试,所以删除了,实际项目中还是要设置tsconfig.js。
2.打包时间比较
两种方案中ts代码完全相同:
ts-loader打包时间:
大概 1000ms
@babel/preset-typescript打包时间:
大概500ms 感觉打包速度上提升还是很明显的,打包的大小是大致一样。
三、总结
通过上面的两种方案对比,我是更喜欢@babel/preset-typescript,相比较两种方案:
@babel/preset-typescript配置更简单,而且打包速度更快一点;
而ts-loader在配置过程中还是遇到了很多坑的,比如tsconfig.json中lib没有设置导致报错,而在转es5实际也是用babel处理es6的方案解决,这样直接使用@babel/preset-typescript感觉会更加清晰。