preface

As of this writing, the React version is 17.x, Typescript is 4.x, and Webpack is 5.x. However, our group’s business is always busy, so our project template is still REact16.x (no Hook feature is supported), and we do not support TS, and Webpack is only 3.x, which is still the configuration of a few years ago. The configuration of this project is like a broken ship sailing in the sea, which will be broken by a wave if it is not careful. As expected, the more worried about what happened, suddenly when we were packing, we were surprised to find that a package plug-in failed, leading to our packaging 📦 has been failing, and finally we had to change a plug-in to solve the problem, but this is just like a broken ship, I don’t know where there will be problems.

Yes, said so big pile is I this fisherman want to change the boat 🚢. Who doesn’t want to go online without a problem.

Build the TS+React development environment

PlanA: The quickest way to do this is to use create-react-app:

npx create-react-app my-app --template typescript
Copy the code

But that seems a little boring, so let’s use planB to build this project by hand:

Install the React and TS

1. Install related libraries

npm i react react-dom react-redux typescript --save
Copy the code

2. Install the @types declaration library

npm i @types/react @types/react-dom @types/react-redux --save-dev
Copy the code

The version of my package after installation is as follows:

  • react 17.0.1
  • react-dom 17.0.1
  • react-redux 7.2.3
  • typescript 4.1.3

Create tsconfig. Json

Tsconfig. json: tsconfig.json: tsconfig.json: tsconfig.json: tsconfig.json: tsconfig.json

{
  "compilerOptions": {
    "target": "es5".// Target for compilation
    "allowJs": true."skipLibCheck": true."esModuleInterop": true."allowSyntheticDefaultImports": true."strict": true."forceConsistentCasingInFileNames": true."noFallthroughCasesInSwitch": true."noUnusedLocals": false."noUnusedParameters": false."module": "esnext"."moduleResolution": "node"."resolveJsonModule": true."isolatedModules": true."noEmit": false."jsx": "preserve"."baseUrl": ". /"."paths": {
      "@": ["src/"]}},"include": ["./src/**/*"]}Copy the code

Tsconfig partial configuration resolution

Paths: Specifies the mapping between modules and paths based on baseUrl

import a from '.. /.. /src/a.ts'; Is equivalent toimport a from '@/a.ts';
Copy the code

include: The target folder to compilejsx: This configuration is intsxIn the supportjsxThis parameter is optionalpreserve.reactandreact-native. These patterns only work during the code generation phase – type checking is not affected. inpreservePreserved in generated code in modeJSXFor subsequent conversion operations (for example:Babel). In addition, the output file will have.jsxExtension. reactPatterns are generatedReact.createElement, do not need to convert before use, output file extension name.js.react-nativeThe equivalent ofpreserveAnd it keeps all of themJSX, but the extension of the output file is.js.

1. See TS usage for baseUrl and Paths 2. Tsconfig. json for more configuration.

What can we do next to make our project run. TSX files? How can you forget webPack? The next step is to install and configure WebPack.

Install webpack

npm i webpack webpack-cli --save-dev
Copy the code
  • webpack 4.41.2
  • webpack-cli 3.3.10

Configuration webpack

After packing for a long time, as if we hadn’t started writing any code yet, let’s write some code and configure our Webpack.

Webpack directory structure:Yes, you guessed it, I wrote this WebPack configuration file in accordance with the separation of powers principle.webpack.common.js: Stores common configurationswebpack.dev.js: Stores the configuration of the development environmentwebpack.prod.jsStores the configuration of the production environment

You can refer to the webpack website for detailed configuration. Here’s what you need to configure TS. Loader configuration


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

Plugins configuration

const aliasPath = require('.. /tsconfig.json').compilerOptions.paths;

resolve: {
	extensions: ['.ts'.'.tsx'.'.js'.'.jsx'].alias: Object.keys(aliasPath).reduce((alias, key) = > {
	   alias[key] = path.resolve(aliasPath[key][0]) + ' ';
	   returnalias; }}, {})Copy the code

Alias reads the mapping of paths in tsconfig.json.

Now that we need to get the project running, let me add a few commands to package.json:

"scripts": {
	// Development environment
    "dev": "cross-env NODE_ENV=development webpack-dev-server --config ./build/webpack.dev.js".// Production environment packaging
    "build": "cross-env NODE_ENV=production webpack --config ./build/webpack.prod.js".// Package size analysis
    "analyzer": "cross-env Analyzer=on npm run build && webpack-bundle-analyzer --port 8888 ./dist/analyzer.json"
  },
Copy the code

At this point, a simple TS+React environment is set up and the project is ready to run 🎉. However, we need to restrict our code style before putting it into use by the team, otherwise it is really uncomfortable to indent one file with 4 and another file with 2 😭, and we also need to use ESlint for necessary code checks.

Prettier, common code style

1. Install Prettier again:

npm install prettier -D
Copy the code

Once installed we can declare two files,.prettierignoresaidprettierIgnore directories that don’t need to be checked, and.prettierrc.jsIt’s oursprettierWhere rules are defined. .prettierignoreThe configuration is as follows:

# Ignore artifacts:
node_modules
dist
.vscode
.prettierignore
Copy the code

.prettierrc.js is configured as follows:

module.exports = {
  printWidth: 140.tabWidth: 2.semi: true.singleQuote: true.trailingComma: 'none'.bracketSpacing: true.jsxBracketSameLine: true.arrowParens: 'always'.insertPragma: false.requirePragma: false.useTabs: false
};
Copy the code

Everyone’s configuration is different, so follow your team’s specifications.

If you usevscode, must be recommended to everyone to downloadprettierThe plug-in.Of course, after downloading it, it is important to remind everyone that the configuration of this plug-in is global if you want to use the current projectprettierYou are advised to create one in the directory.vscodeFolder, declare one in itsettings.jsonIn thesettings.jsonThe configuration in takes precedence over the editor’s global configuration.

Settings. json is configured as follows:

{
	// Rule prettier uses the.prettierrc.js of the current directory
	"prettier.configPath": ".prettierrc.js".// Automatically formatting when saving
	"editor.formatOnSave": true,}Copy the code

Eslint, a tool for code quality

Of course, the next step to unifying the code style is to solve the problem of code quality.

npm i eslint -D
Copy the code

At this point we need to declare an eslintrc.js file:

module.exports = {
  parser: '@typescript-eslint/parser'.// Define a parser for ESLint
  extends: ['plugin:prettier/recommended'].// Define a subspecification for file inheritance
  plugins: ['@typescript-eslint'.'react-hooks'.'eslint-plugin-react'].// Defines the plugins that the ESLint file depends on
  env: {
    // Specify the environment in which the code is run
    browser: true.node: true
  },
  settings: {
    // Automatically discover the React version to regulate the React code
    react: {
      pragma: 'React'.version: 'detect'}},parserOptions: {
    // Specifies that ESLint can parse JSX syntax
    ecmaVersion: 2019.sourceType: 'module'.ecmaFeatures: {
      jsx: true}},rules: {
  	// Some custom rules
  	'prettier/prettier': 'error'.'linebreak-style': ['error'.'unix'].'react-hooks/rules-of-hooks': 'error'.'react-hooks/exhaustive-deps': 'warn'.'react/jsx-uses-react': 'error'.'react/jsx-uses-vars': 'error'.'react/react-in-jsx-scope': 'error'.'valid-typeof': [
      'warn',
      {
        requireStringLiterals: false}}};Copy the code

Parser configuration: The @typescript-eslint/parser plugin lets ESLint parse typescript.

npm i @typescript-eslint/parser -D
Copy the code

Extends configuration: in order to prevent conflict eslint and prettier rules, we need to integrate the two are set to [‘ plugin: prettier/it ‘].

npm i eslint-config-prettier eslint-plugin-prettier -D
Copy the code

Plugins: @typescript-esLint: contains various specifications that are defined to detect typescript code. React-hooks: Plugins that check for the code specification to detect and regulate react-hooks. Eslint-plugin-react: plugin for detecting and regulating the writing of react code.

npm i eslint-plugin-react eslint-plugin-react-hooks @typescript-eslint/eslint-plugin -D
Copy the code

Finally, we need to modify settings.json

{
	"prettier.configPath": ".prettierrc.js"."eslint.options": {
        "extensions": [".js".".ts".".tsx"."jsx"."html"]},"editor.codeActionsOnSave": {
    	// Save using eslint for formatting
        "source.fixAll.eslint": true}}Copy the code

Here the configuration of ESlint+Prettier is over and we need to commit our code.

Specification Git commit

We want all of our code to be formatted and quality-checked before we commit it to the repository. To do this, we need to use a tool to format the latest changes to our Git cache and verify lint rules.

npm install husky lint-staged -D
Copy the code

Then we need to modify the package.json file:

"husky": {
   "hooks": {
     "pre-commit": "lint-staged",}},"lint-staged": {
   "*.{ts,tsx,js,jsx}": [
     "eslint --config .eslintrc.js"]."* * / *": "prettier --write ."
 }
Copy the code

So we use ESlint to do code quality checks for ts, TSX, JS, JSX ending files, and use Prettier to format all files. Now it’s time to write a COMMIT for this commit.

If you find a bug on the web and need to roll back, you will find that the commit record is full of fixes or code changes.

First we install the required libraries:

npm i @commitlint/cli @commitlint/config-angular -D
Copy the code

Then we create the commitlint.config.js file:

module.exports = { extends: ['@commitlint/config-angular']};Copy the code

We use the Angular COMMIT specification directly, so we don’t need to write more configuration information. See this article for more configurations.

Finally, after configuring pre-commit, add the following information:

"husky": {
    "hooks": {
      "pre-commit": "lint-staged"./ / commit information
      "commit-msg": "commitlint -E HUSKY_GIT_PARAMS"}},Copy the code

HUSKY_GIT_PARAMS is our commit information, and commitLint will verify this information.

conclusion

Finally, we have completed our code submission, which completes the configuration of our TS + React project. We have finished our idea of changing the ship 🚢, and we will learn how to open a new ship later, that is, how to use TS + React Hook in our project.