The migration to
Dynamic type refactoring crematorium code for a while
TypeScript its difference with JavaScript is to provide static type system, some mistakes can compile stage of discovery and solve as soon as possible, improve the robustness of the code, to enhance the readability and maintainability of the code, the dynamic type a great code refactoring crematorium before popular words also can well explain their differences, This is why existing projects are being migrated to the TypeScript language.
- Understand the TypeScript
- JavaScript migration
- React & Webpack
These are some basic tutorials that you can skip if you’re already familiar with the basics of TypeScript and Webpack and start migrating
Add the TypeScript configuration file tsconfig.json
The tsconfig.json file specifies the root file and compilation options to compile this project. First install typescript NPM install typescript or YARN add typescript in your project. Then add the TypeScript configuration file tsconfig.json to the root of the project, which can be configured using NPX TSC –init.
{
"compilerOptions": {
"outDir": "/dist"."module": "esnext"."target": "es6"."lib": ["es6"."dom"]."sourceMap": true."baseUrl": "."."jsx": "react"."allowSyntheticDefaultImports": true."moduleResolution": "node"."rootDirs": ["/src"."/test"."/mock"."./typings"]."forceConsistentCasingInFileNames": true."noImplicitReturns": true."suppressImplicitAnyIndexErrors": true."noUnusedLocals": true."allowJs": true."experimentalDecorators": true."paths": {
"@ / *": ["./src/*"]}},"include": ["./src"]."exclude": [
"node_modules"."build"."scripts"."acceptance-tests"."webpack"."jest"."src/setupTests.ts"."tslint:latest"."tslint-config-prettier"]}Copy the code
- Read all recognizable files in the SRC directory (via include).
- Accept JavaScript as input (via allowJs).
- Use React, set “JSX” to “react”,
- All generated files are placed in the built directory (via outDir).
- Demoting JavaScript code to lower versions such as ECMAScript 5 (via target) ‘ES3’ (default), ‘ES5’, ‘ES2015’, ‘ES2016’, ‘ES2017’, ‘ES2018’, ‘ES2019’ or ‘ESNEXT’.
- “Module “:” esNext “, can be ‘None ‘,’ commonJS ‘, ‘AMD ‘, ‘system’,’ umD ‘, ‘ES2015 ‘, or’ esNext ‘.
More configuration details
Webpack configuration
Webpack.config. js needs to add ts loader rules, TS rules before JS rules, and add file formats for configuration parsing. Tsconfig is converted to ES2016. How to ensure that the compiled code is compiled into ES5 by Babel Loader? TSX files are applied to ts-loader, and TS-loader is used to process TS and TSX files. The following two steps are required to solve this problem
- Use TS-Loader to compile TS code into ES6
- Compile ES6 code and JSX to ES5 using Babel
Webpack is typically configured as follows
{
test: /\.tsx? $/, exclude: /node_modules/, use: [ { loader:'babel-loader'
},
{
loader: 'ts-loader'}]} //.babelrc file configuration {"presets": [
"@babel/env"."@babel/preset-typescript"]."plugins": [
"@babel/proposal-class-properties"."@babel/proposal-object-rest-spread"]}Copy the code
Configuration extensions
The next generation of Babel 7 brings the ability to parse typescript without having to compile twice. Babeljs. IO/docs/en/bab…). .babelrc is configured as follows:
{
"presets": [
"@babel/env"."@babel/react"."@babel/typescript"]}Copy the code
Here are a few ways to check if the packed bulid file contains the =>, const, etc of the arrow function.
The first configuration
module: {
rules: [
{
test: /\.tsx? $/, loader:'babel-loader'}, // babelrc file configuration and the corresponding Babel to upgrade to version 7.4.0 {"presets": [
"@babel/env"."@babel/preset-typescript"]."plugins": [
"@babel/proposal-class-properties"."@babel/proposal-object-rest-spread"]}Copy the code
Upgrade configuration of Babel
Second configuration
module: {
rules: [
{
test: /\.tsx? $/, loader:'ts-loader'
},
Copy the code
The third configuration
module: {
rules: [
{
test: /\.tsx? $/, use: [ { loader:'babel-loader',
},
{
loader: 'ts-loader'}},Copy the code
Tsconfig. json => const; / / tsconfig.json => const; / / tsconfig.json => target: “es2016”; “Es5 “, const, etc.
- Ts-loader supports JSX with a basic configuration of tsconfig.json, and compiles TypeScript to target-specified forms such as ES5, ES2016, etc
- The above are for TS files and JS files separately
After the above experiments and considering the tree Sharking optimization of Webpack, our project adopts the third method.
Cannot find module ‘./style.css
This depends on whether it is a third-party plug-in or its own module. If it is a third-party plug-in, use NPM to install it. If it is a self-written service module, it is the problem of reference path, which should correspond to the configuration of the tsconfig file.
Why does cutting TS affect the way the code is written? Can we write it as import?
Cannot find module ‘./style.css’. This problem, looking for the official explanation is as follows:
Using CSS Modules with TypeScript is not as obvious as with JavaScript. The reason is that TypeScript has special treatment for imports and if you try to use CSS Modules the same way you did in JavaScript:
There are two solutions:
- The easiest way to do this is to use require
const style = require("./style.css");
- Typings – for – using CSS modules – loader
- npm install –save-dev typings-for-css-modules-loader
- Modify the Wepack configuration
/ /... rules: [ {test: /\.css$/,
use: [
'style-loader',
{
loader: 'typings-for-css-modules-loader',
options: {
modules: true,
namedExport: true}}]}]Copy the code
To add the above configuration, import can be used. import style from ‘./style.css’;
Conversion to.tsx files changes accordingly
- Changes to the React component
- Definition of the incoming type of the component
- A declarative definition of a function type
- Both props and state need type restrictions
import React from 'react';
import { connect } from 'react-redux';
import { getAuth } from '.. /.. /.. /modules/app/reducers/user/auth';
// import style from './style.css';
const style = require("./style.css");
interface propTypes{
getAuth: ()=>void;
}
class LoginScene extends React.PureComponent<propTypes> {
handleClick = () => {
this.props.getAuth();
};
render() {
return( <div className={style.login}> // ... </div> ); }}Copy the code