Using TypeScript to retrofit build tools and test cases

Source: Internet
Author: User
Tags documentation writing test scripts npm scripts

I've been working on this for TypeScript a while, a giant hard-to-produce language that gives JavaScript language static typing and compilation.
The first TypeScript pure project that completely uses refactoring Node.js is on-line and running stably.
The second front-and-back project is also being refactored, and the front-end-based webpack TypeScript routines have been mentioned before: Typescript's practice in the React project.

But after this is done, I always feel missing something (no fun):


Yes, there are still one-fifth of the code in the JavaScript project, and as an TypeScript example project, the performance is very not pure.
So is it possible to JavaScript replace this code TypeScript ?
The answer must be, first of all, to analyze what the code is all about:

    • WebpackConfiguration files when packaging
    • Some simple test cases (using Mocha and Chai)

Knowing which places are still in use JavaScript , this becomes a good solution, Webpack starting with the build tool (), breaking each one, and replacing all of them TypeScript .

TypeScript implementation version of Webpack

In this 8102 year, very happy, the Webpack official has supported the TypeScript writing configuration file, the document address.
In addition to TypeScript JSX the support and CoffeeScript the interpreter, in this ignore their existence

Dependent installation

The first is to install the TypeScript relevant set of dependencies, including the interpreter and the core modules of the language:

npm install -D typescript ts-node

typescriptAs the core module for this language, it is ts-node used to execute files directly without the .ts need to tsc compile output files like that .js .

ts-node helloworld.ts

Because you want to use the relevant things in the TypeScript environment Webpack , so to install the corresponding types .
The Webpack corresponding ones, which *.d.ts are used to tell TypeScript what the object is and what method to provide.

npm i -D @types/webpack

Some of the commonly used pLugin will have a corresponding @types file, you can simply pass npm info @types/XXX to check whether there is

If it is a small audience plugin , you may need to create a corresponding d.ts file, for example, we have been using qiniu-webpack-plugin , this does not have a corresponding @types package, so we create an empty file to tell what TypeScript this is:

declare module 'qiniu-webpack-plugin' // 就一个简单的定义即可// 如果还有其他的包,直接放到同一个文件就行了// 文件名也没有要求,保证是 d.ts 结尾即可

Placement of the location of no restrictions, casually lost, generally recommended to put types under the folder

Finally, .ts there are some configuration file settings when the file is executed.
The file used for execution has Webpack .ts tsconfig.json some small requirements.
compilerOptionsThe target options below must be es5 , this represents the format of the output.
As well as module requirements for selection commonjs .

{  "compilerOptions": {    "module": "commonjs",    "target": "es5",    "esModuleInterop": true  }}

However, in general, the execution Webpack of the sibling directory already exists tsconfig.json , for the actual front-end code compilation, it is likely that the two configuration file parameters are not the same.
WebpackIt is certainly not advisable to modify the real code configuration parameters because you want to use them.
So we're going to use a package that changes the ts-node configuration files that are dependent on execution: tsconfig-paths

In the Readme discovery of such a statement: If process.env.TS_NODE_PROJECT is set it will be used to resolved tsconfig.json .
WebpackThis is also mentioned in the documentation, so this is a compatible way to specify a path when the command runs and create a configuration to use when the original configuration is not affected Webpack .

    1. Rename the above configuration file to a different name, Webpack as shown in the documentation example tsconfig-for-webpack-config.json , which is followed directly
    2. Then add the npm script following
{  "scripts": {    "build": "TS_NODE_PROJECT=tsconfig-for-webpack-config.json webpack --config configs.ts"  }}
Preparation of documents

With regard to the configuration file, JavaScript there is not much change from switching to TypeScript actual, because Webpack most of the configuration files are written dead text/constants.
Many types are automatically generated and can be used without the need to manually specify a simple example:

import { Configuration } from 'webpack'const config: Configuration = {  mode: process.env.NODE_ENV === 'production' ? 'production' : 'development',}export default config

Configurationis a Webpack defined interface ( interface ) that is used to standardize the behavior of an object.
Press VS Code and hold Command + click to jump directly to the specific webpack.d.ts definition file There, you can see the detailed definition information.

A variety of commonly used rules are written here, TypeScript the use of one advantage is that when you want to implement a function you no longer need to go to the site to query what should be configured, you can directly look at d.ts the definition.
If the comment is written well enough, it can be used as a document, and VS Code there are dynamic hints in the editor, as well as some error corrections, such as the above NODE_ENV , if the direct write process.env.NODE_ENV || 'development' will throw an exception, as d.ts can be seen from the modeonly three valid values production , developemnt and none , process.env.NODE_ENV obviously just a variable of type string.

So we need to use the ternary operator to ensure that the incoming parameters must be what we want.

As well as in the process of writing, if there are some custom plugin and the like, may be used in the process of throwing an exception to say that an object is not a valid Plugin object, a very simple method, the corresponding after plugin adding a as webpack.Plugin can.

What TypeScript you do here is just a static check, and it doesn't have any effect on the actual code execution, even if the type is changed by force, as it's just a compile-time modification, JavaScript or a weak type in the code actually executed.

After you have completed the above operation, npm run XXX you can run the TypeScript version Webpack configuration directly.

An interesting thing during the exploration

Because my project root directory is already installed ts-node , and the front-end project exists as one of these folders, it is not installed again.
This brings a blood-vomiting problem.

First, when the whole process is finished, I enter it directly on the command line.TS_NODE_PROJECT=XXX.json NODE_ENV=dev webpack --config ./webpack/dev.ts
Run perfectly, then put this line of command into the npm scripts middle:

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

Run again npm start , found that there was a mistake-.-, prompted me to say that the import grammar can not be recognized, this is obviously not applied to the ts_NODE_PROJECT file we specified in config .
At first, I didn't know what the problem was, because it was executed directly on the command line without any problems.
During the period when it was suspected that the environment variable was not set correctly, the plugin was used cross-env , and even the command was written to a sh file for execution.
However, the problem still exists, and later in a group with the small partners to chat about the problem, it was suggested that you are ts-node not a global installation .
The check later found that, sure enough, the command line was executed with a global ts-node , but in- npm scripts use local ts-node .
When the command-line environment executes, it is thought to automatically look for node_modules dependencies underneath the parent folder, which is actually the global package used.
obediently under the client-src folder also installed to ts-node solve the problem.
Globally dependent on harm.

Transformation of test Cases

Most of Webpack the TypeScript reasons for this are caused by obsessive-compulsive disorder.
But the transformation of test cases TypeScript is an operation that can greatly improve the efficiency.

Why use TypeScript in test cases

The use of test cases chai to write,(before the use of the Postman chai syntax)
chaiProvides a series of semantic chained calls to implement assertions.
As mentioned in the previous share, there are so many commands that you don't need to fully remember, only one expect(XXX).to.equal(true) is enough.

But this entire article to.equal(true) is extremely ugly, and if you use those semantic chained calls, it's easy to get it in a less skilled situation:

Error: XXX.XXX is not a function

Because this does have a threshold problem, you have to write a lot to remember the call rules, various not , includes operations.
But after the connection TypeScript , these problems have been solved.
Also mentioned earlier, all the TypeScript modules have their corresponding .d.ts files, to tell us what this module is doing, provide what can be used.
In other words, when writing a test case, we can write the assertion quickly with dynamic hints, without having to combine the documents to "translate".


How to use

If it is previously written mocha and chai the children's shoes, basically modify the file suffix + installation corresponding @types can.
You can jump right here: start writing test scripts
However, if you are interested in the test case, but have not used the child shoes, you can look at a basic step below.

Installation dependencies
    1. TypeScriptRelated Installations,npm i -D typescript ts-node
    2. Mocha, chai related Installations,npm i -D mocha chai @types/mocha @types/chai
    3. If you need to involve some API requests, you can install additional chai-http ,npm i -D chai-http @types/chai-http

The environment depends on the completion, if the additional use of some other plug-ins, remember to install the corresponding @types files.
If you have a plug-in that uses eslint, you may be prompted to modules be present dependencies rather thandevDependencies
This is the result of the Eslint import/no-extraneous-dependencies rule, and for this, our current scenario is to add some exceptions:

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

Do not check for files/folders in these directories. Yes, the use of Webpack will also encounter this problem

Start writing test scripts

If the original test script is modified, no change to the suffix, add some necessary type declaration, no changes to the logic.

A simple example
// number-comma.tsexport default (num: number | string) => String(num).replace(/\B(?=(\d{3})+$)/g, ',')// number-comma.spec.tsimport chai from 'chai'import numberComma from './number-comma'const { expect } = chai// 测试项describe('number-comma', () => {  // 子项目1  it('`1234567` should transform to `1,234,567`', done => {    expect(numberComma(1234567)).to.equal('1,234,567')    done()  })  // 子项目2  it('`123` should never transform', done => {    const num = 123    expect(numberComma(num)).to.equal(String(num))    done()  })})

If the global is not installed mocha , remember to write the command npm script in, or execute it in the following way

./node_modules/mocha/bin/mocha -r ts-node/register test/number-comma.spec.ts# 如果直接这样写,会抛出异常提示 mocha 不是命令mocha -r ts-node/register test/number-comma.spec.ts

mochaIt is a bit better to have a -r command that lets you manually specify the interpreter used to execute the test case script, which is set directly to ts-node the path ts-node/register , and can then be followed directly by a file name (or some wildcard character).

Currently, we have the following commands for batch execution of test cases in a project:

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

npm testCan be called directly without the need to add run a command, similar to start , and build so on

One-click execution will get the results we want, and no more worrying about some code changes will affect the logic of other modules (if you write the test case carefully)

Summary

After doing the above two steps, our project achieved 100% TypeScript , enjoying the benefits of static compilation syntax anywhere.
Attach the updated code content:

Recently it TypeScript has done a lot of things, from Node.js , and React this time Webpack with Mocha+Chai .
TypeScriptBecause there is a compilation process, it greatly reduces the possibility of the code out of the bug, improve the stability of the program.
The overall switch to the TypeScript more can reduce the two grammars between the switching between the unnecessary consumption, I wish everyone to move bricks happy.

Before about TypeScript's notes
    • The practice of typescript in node project
    • The practice of typescript in react project
A complete example of TypeScript

Typescript-example

You are welcome to discuss TypeScript Some of the problems in the use of the stability of the sense of inadequacy is also welcome to point out.

Resources
    • Ts-node
    • Configuration-languages | Webpack
    • Mochajs
    • Chaijs

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.