Recently I’ve been working on TypeScript, a massively hardcoded language that gives JavaScript static typing and compilation. The first pure Node.js project with full TypeScript refactoring is up and running. The second front and back end project is currently being refactored, and the Webpack-based TypeScript paradigm for the front end was mentioned earlier: the TypeScript practice in the React project.

But there’s always something missing:



JavaScript
TypeScript



JavaScript
TypeScript


  • WebpackConfiguration file at packaging time
  • Some simple test cases (using Mocha and CHAI)

Knowing where JavaScript is still being used makes it easy to break it down one by one, starting with the build tool (Webpack), and replace it all with TypeScript.

TypeScript implementation of Webpack

In 8102, happily, Webpack has officially supported TypeScript authoring configuration files, document addresses. Interpreters that support JSX and CoffeeScript in addition to TypeScript are ignored here

Dependent installation

The first step is to install a set of typescript-related dependencies, including the interpreter and the language’s core modules:

npm install -D typescript ts-node
Copy the code

Typescript is the core module of the language, and TS-Node is used to execute. Ts files directly, without compiling.js output files as TSC does.

ts-node helloworld.ts
Copy the code

Because you are using Webpack-related objects in TypeScript, you need to install the corresponding types. The *.d.ts that Webpack corresponds to tell TypeScript what an object is and what methods it provides.

npm i -D @types/webpack
Copy the code

Some commonly usedpLuginThere will be corresponding ones@typesThe file can be easily passednpm info @types/XXXTo check for presence

For niche plugins, you may need to create a d.ts file, such as the qiniu-webpack-plugin we’ve been using, for which there is no @types package, so create an empty file to tell TypeScript what it is:

declare module'qiniu-webpack-plugin' // just a simple definition // If there are other packages, just put them in the same file // there is no requirement on the filename, make sure it ends with d.tsCopy the code

There is no limit on the position of the place, just throw it, it is generally recommended to put ittypesfolder

Finally, some configuration file Settings for.ts file execution. The.ts file used to execute Webpack has some small requirements for tsconfig.json. The target option under compilerOptions must be ES5, which represents the format of the output. And module requires you to select CommonJS.

{
  "compilerOptions": {
    "module": "commonjs"."target": "es5"."esModuleInterop": true}}Copy the code

But in general, the same directories that execute Webpack already have tsconfig.json for actual front-end code compilation, and it’s possible that the parameters of the two configuration files are not the same. It is definitely not desirable to change the actual code configuration parameters because you are using Webpack. So we use a package that changes the configuration file that ts-Node execution depends on: tsconfig-Paths

If process.env.ts_node_project is set it will be used to resolved tsconfig.json This is also mentioned in the Webpack documentation, so it is a compatible way to specify a path at command run time to create a configuration for Webpack packaging without affecting the original configuration.

  1. Rename the above configuration file to something else,WebpackIn the document exampletsconfig-for-webpack-config.jsonI’m going to use it here
  2. And then addnpm scriptThe following
{
  "scripts": {
    "build": "TS_NODE_PROJECT=tsconfig-for-webpack-config.json webpack --config configs.ts"}}Copy the code

Document writing

In terms of configuration files, switching from JavaScript to TypeScript doesn’t really change that much, because Webpack configuration files are mostly written dead text/constants. Many types are automatically generated and can be specified almost without being manually specified. A simple example:

import { Configuration } from 'webpack'

const config: Configuration = {
  mode: process.env.NODE_ENV === 'production' ? 'production' : 'development',}export default config
Copy the code

Configuration is a WebPack-defined interface that regulates the behavior of an object. Holding Command + clicking under VS Code jumps directly to the specific Webpack.d. ts definition file to see the detailed definition information.



TypeScript
d.ts



VS Code
NODE_ENV
process.env.NODE_ENV || 'development'
d.ts
mode
production
developemnt
none
process.env.NODE_ENV



As well as in the process of writing, if there are some custom plugins and so on, it may throw an exception indicating that an object is not a valid plugin object in the process of using. A very simple method is to add as webpack.plugin after the corresponding plugin.

Here,TypeScriptAll that is done is static checking and does not have any impact on the actual code execution, even if the type is forcedasChanges, however, are only compile-time changes that are actually executedJavaScriptThe code is still weakly typed

After doing this, you can run the TypeScript Webpack configuration directly by executing NPM run XXX.

An interesting thing about the exploration

Because TS-Node was already installed in my project root directory, and the front-end project existed as a folder, I didn’t install it again. This brings up a blood-sucking problem.

Json NODE_ENV=dev webpack –config./webpack/dev. Ts Then put this command in NPM scripts:

{
  "scripts": {
    "start": "TS_NODE_PROJECT=XXX.json NODE_ENV=dev webpack --config ./webpack/dev.ts"}}Copy the code

The ts_NODE_PROJECT config file was not applied to the ts_NODE_PROJECT config file. The ts_NODE_PROJECT config file was not applied to the ts_NODE_PROJECT config file. You don’t know what the problem is at first, because there’s nothing wrong with executing it directly from the command line. I wondered if the environment variables were not set properly, used the cross-env plug-in, and even wrote commands to an sh file to execute. However, there was still a problem, and when I was talking to my friends about it in a group, someone asked if you had TS-Node installed globally. After checking, it turns out that yes, global TS-Node is used for command line execution, but local TS-Node is used for NPM scripts. Node_modules is a global package that automatically looks for dependencies in the parent node_modules folder. This problem is solved by installing ts-Node in the client-src folder. Global dependency kills.

Test case modification

Most of the reasons why Webpack is changed to TypeScript are obsessive. But TypeScript reworking of test cases is a highly efficient operation.

Why use TypeScript in test cases

Test cases are written using CHAI (Postman used the same CHAI syntax), which provides a series of semantically chained calls to implement assertions. As mentioned in previous posts, you don’t need to remember all of these commands, just expect(XXX).to.equal(true).

But this whole to.equal(true) thing is ugly, and if you use those semantic chain calls, it’s easy to get unskilled:

Error: XXX.XXX is not a function
Copy the code

Because this does have a threshold problem, you have to write a lot to remember the call rules, various not, includes operations. But with TypeScript, these problems are solved. As mentioned earlier, all TypeScript modules have their own.d.ts files that tell us what the module does and what it provides to use. This means that when test cases are written, assertions can be quickly written using dynamic prompts, without the need for documentation to “translate”.


use

If you have previously written mocha and Chai, basically change the file suffix + install the corresponding @types. You can skip right to this: Start writing test scripts, but if you’re interested in test cases but haven’t used them yet, you can look at the basic steps below.

Install dependencies

  1. TypeScriptRelated installations,npm i -D typescript ts-node
  2. Mocha,chaiRelated installations,npm i -D mocha chai @types/mocha @types/chai
  3. If you need requests that involve some API, you can install additional oneschai-http.npm i -D chai-http @types/chai-http

The dependency of the environment is done, if you are using some additional plug-ins, remember to install the corresponding @types file. If you use a plugin like ESLint, you may be prompted that modules must exist in dependencies instead of devDependencies. This is caused by the import/no-extraneous dependencies rule of ESLint. For this, Our current scheme is to add some exceptions:

import/no-extraneous-dependencies:
  - 2
  - devDependencies:
    - "**/*.test.js"
    - "**/*.spec.js"
    - "**/webpack*"
    - "**/webpack/*"
Copy the code

Files/folders in these directories are not verified. Yes, this is also a problem with Webpack

Start writing test scripts

If you are modifying an existing test script, you can simply change the suffix and add some necessary type declarations without changing the logic at all.

A simple example

// number-comma.ts
export default (num: number | string) = >String(num).replace(/\B(? =(\d{3})+$)/g.', ')

// number-comma.spec.ts
import chai from 'chai'
import numberComma from './number-comma'

const { expect } = chai

/ / test items
describe('number-comma'.(a)= > {
  // Subproject 1
  it(' '1234567' should transform to '1,234,567' '.done= > {
    expect(numberComma(1234567)).to.equal('1234567')
    done()
  })

  // Subitem 2
  it('`123` should never transform'.done= > {
    const num = 123
    expect(numberComma(num)).to.equal(String(num))
    done()
  })
})
Copy the code

If not installed globallymocha, remember to write the commandnpm script, or perform the following operations

./node_modules/mocha/bin/mocha -r ts-node/register test/number-comma.spec.ts

An exception will be thrown indicating that mocha is not a command
mocha -r ts-node/register test/number-comma.spec.ts
Copy the code

One of the nice things about Mocha is that it provides the -r command that lets you manually specify which interpreter to use to execute the test case script, which is set directly to ts-node’s path ts-node/register, followed by a file name (or some wildcard character).

The commands for batch execution of test cases in our project are as follows:

{
  "scripts": {
    "test": "mocha -r ts-node/register test/**/*.spec.ts"}}Copy the code

npm testCan be called directly without addingrunCommand character, and so onstart,build, etc.

With one click, we can get the result we want, and we don’t have to worry about some code changes affecting the logic of other modules (if we write the test cases carefully).

summary

After the previous two steps, our project is 100% TypeScript, enjoying the benefits of statically compiled syntax everywhere. Attached is the updated code content screenshot:

A lot of work has been done on TypeScript recently, from Node.js and React to Webpack and Mocha+Chai. Because TypeScript has a compilation process, it greatly reduces the possibility of bugs and makes applications more stable. A full switch to TypeScript also reduces the unnecessary overhead of switching between the two grammars. Have fun.

Previous notes on TypeScript

  • TypeScript practices in Node projects
  • TypeScript practices in react projects

A complete TypeScript example

typescript-example

Welcome to discuss some of the issues with TypeScript and point out the perceived shortcomings of sedate.

The resources

  • ts-node
  • configuration-languages | webpack
  • mochajs
  • chaijs