I. Brief introduction

At present, we commonly used Webpack TS mainly for two schemes:

  1. Ts-loader: convert TS to JS, and then use Babel to convert JS to lower version JS;
  2. Babel /preset-typescript: This removes typescript directly and changes to JS, which makes it fast and only needs to manage Babel as a compiler.

Ii. Comparison of schemes

First we need to install webpack, webpack-CLI, typescript and write some ts for packing test:

// 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<string> => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve('1')
    }, 1000)
  })
}

const studentA = new Student('a', 20)
studentA.greet()
testPromise().then(data => {
  console.log('data', data)
})
Copy the code

1. Comparison of methods

1) ts – loader:

Ts-loader: NPM install ts-loader –save-dev

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: []
}
Copy the code

Then you need to set tsconfig.json:

{
  "compilerOptions": {
    "module": "commonjs"."sourceMap": true."target": "es5"."lib": [
      "es5"."dom"."es2015.promise"]}}Copy the code

Lib can also be configured with additional parameters depending on the code and application scenario:

npm install core-js
npm install --save-dev babel-loader @babel/core @babel/cli @babel/preset-env
npm install --save @babel/polyfill
Copy the code

Settings. Babelrc;

{
  "presets": [["@babel/preset-env",
      {
        "corejs": "3"."useBuiltIns": "usage"}}]]Copy the code

Set up babel-loader to handle JS in webpack.config.js

module: {
    rules: [
      {
        test: /\.tsx? $/, exclude: /node_modules/, loader: ['babel-loader'.'ts-loader']]}},Copy the code

Then pack:

2) @ Babel/preset – typescript:

Basically the same as the bebel plugin above

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
Copy the code

@babel/preset-typescript webpack.config.js uses babel-loader directly:

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: []
}
Copy the code

There is also only @babel/preset-typescript in. Babelrc

{
  "presets": [["@babel/preset-env",
      {
        "corejs": "3"."useBuiltIns": "usage"}]."@babel/preset-typescript"]}Copy the code

Perform the packaging and discover that bundle.js also packages the promise. Tsconfig. js can still be packed successfully, but ts-loader must set tsconfig.js, because I just do a test, so I delete it. In the actual project, tsconfig.js will still be set.

2. Comparison of packing time

The TS code is exactly the same in both scenarios:

@babel/preset-typescript packaging time:

3. Compare NPM packages with TS packages

If we need to use TS to develop NPM packages for development tools, I would prefer ts-Loader:

Let’s create two new projects and write some random test code:

1) ts – loader:

Ts-build-loader is an NPM package developed using TS-loader:

ts-build-loader:  src/index.ts

export function addFn(a: number, b: number): number {
  return a + b
}
Copy the code

In tsconfig.json you need to configure to generate the project declaration file:

{
  "compilerOptions": {
    "module": "commonjs"."sourceMap": true."target": "es5"."declaration": true, // the.d.ts file will be generated"outDir": "./dist"."lib": [
      "es5"."dom"."es2015.promise"]},"exclude": [
    "./dist"]}Copy the code

At this point, we can execute NPM run build to see the packaged code:


2) @ Babel/preset – typescript:

Ts-build-babel for NPM packages developed using @babel/preset-typescript:

ts-build-babel:  src/index.ts

export function subFn(a: number, b: number): number {
  return a - b
}
Copy the code

Execute NPM run build:

tsconfig.json
declaration

Finally, we set main to the packaged JS in package.json for both projects:

Test-ts-npm: test-ts-loader: test-ts-npm: test-ts-npm: test-ts-npm: test-ts-npm: test-ts-npm: test-ts-npm: test-ts-npm: test-ts-npm: test-ts-npm: test-ts-npm NPM link TS-build-loader, NPM link ts-build-babel

Simply install ts in your project and create an index.ts file to test the two utility classes you wrote earlier:

test-ts-npm:  index.ts

import { addFn } from 'ts-build-loader'
import { subFn } from 'ts-build-babel'

let n = addFn(1, 1)

let m = subFn(1, 1)

console.log(n)
console.log(m)
Copy the code

Ts: TSC index.ts: TSC index.ts: TSC index.ts: TSC index.ts: TSC index.ts: TSC index.ts

ts-loader

  • 1. No error message is reported in the introduction:

ts-loader

  • 2. Smarter error: When we intentionally miswrite a parameter:

ts-loader

Finally, a few questions remain:

    1. @babel/preset-typescriptWhether the declaration file of the project can be generated through setting;
    1. In fact, the packaged code can be clearly seen: usets-loaderThe amount of packaged code is much larger than@babel/preset-typescriptPackaged code, has not found a reasonable explanation and treatment method

I hope that if you know, you can comment below. If I find relevant information, I will improve and supplement it in the first time.

Third, summary

Through the comparison of the two schemes above:

If the project is business-logical, consider using @babel/preset-typescript, which is easier to configure and a bit faster to pack. For example, lib is not set in tsconfig.json, and an error is reported. In es5, Babel is used to process ES6, so that @babel/preset-typescript feels clearer.

If it is used as a development related toolkit or component library, it is more recommended to use TS-Loader, which can automatically generate project declaration files after packaging, and can be introduced into other projects for a more friendly development experience.