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:
Webpack
Configuration 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
typescript
As 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.
compilerOptions
The 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.
Webpack
It 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
.
Webpack
This 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
.
- 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
- 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
Configuration
is 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 mode
only 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)
chai
Provides 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
TypeScript
Related Installations,npm i -D typescript ts-node
Mocha
, chai
related Installations,npm i -D mocha chai @types/mocha @types/chai
- 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
mocha
It 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 test
Can 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
.
TypeScript
Because 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