This article Demo source: github.com/ysh83737/bl…

1. Module system

Engineering means modularity, simply understanding a few JavaScript language module systems

(1) ES6(ESM)

grammar

// moduleA.ts
export type a = string | number
export const valueA: a = 1

export default function() {
  console.log('defalut')}// moduleB.ts
import func, { a, valueA } from './moduleA.ts'
Copy the code

features

  • Export /import must be at the top of the module and cannot be in any block-level scope
  • The import command is executed at compile time and automatically promoted
  • A reference to an output module, not a copy or cache, whose reference type can be changed dynamically

Application environment

Nodejs, web

(2) CommonJS

grammar

// moduleA.ts
exports.valueA = 1
exports.func = function() {
  console.log('func')}// moduleB.ts
const valueB = 2
module.exports = valueB

// moduleC.ts
const { valueA, func } = require('./moduleA.ts')
const valueB = require('./moduleB.ts')
Copy the code

features

  • Synchronous loading

Application environment

nodejs

Node runs ts code

Install the TS-Node runtime environment to execute ts code directly instead of Node

ts-node ./index.ts
Copy the code

(3) AMD

The AMD (Asynchronous Module Definitions) specification, best known as RequireJS, provides excellent modular programming solutions in the ES5 era

grammar

// Module definition
define(function() {})

// Module import
require([], cb)
Copy the code

features

  • Asynchronous loading
  • Performed in advance

Application environment

web

(4) CMD

CMD (Common Module Definition) specification, the most famous implementation is SeaJS, is a Module development framework provided by taobao team. Syntax is similar to AMD specification, the main difference lies in the module definition way and module loading time, use each has advantages.

grammar

// Module definition
define(function(require.exports.module) {})

// Module import
seajs.use([], cb)
Copy the code

features

  • Asynchronous loading
  • According to the need to perform

Application environment

web

(5) UMD

UMD, the Universal Module Definition, is an integration idea that is compatible with commonJS, AMD, CMD, and Windows global objects when none of these modules are supported

grammar

// Factory function
(function (root, factory) {},this.function () {}))
Copy the code

features

  • Compatible with AMD, CMD, commonJS specifications
  • Compatible global reference

Application environment

Nodejs, web


2. tsconfig

(1) tsconfig.json

This is the configuration file for the TS project. Initialize a TS project by executing the following command:

Install TSC globally
npm install -g typescript

cd the_ts_project
tsc --init
Copy the code
  • When TSC is called to perform compilation, the compiler looks up from the current directorytsconfig.jsonFile, step by step to search the parent directory
  • Exists in directorytsconfig.jsonFiles, this directory isTypeScriptThe root directory of the project

(2) File options

// tsconfig.json
{
  // Specify a list of individual files to compile
  // Use only relative or absolute file paths
  "files": [
    "./a.ts"].// Specify the file or directory to compile
  // Wildcard matches can be used
  "include": [
    "src/**"."b.ts"].// Files or directories to be excluded
  // Wildcard matches can be used
  // Node_modules, boWER_components, jSPM_packages, 
      
        are excluded by default
      
  "exclude": [
    "dist"].// Config file inheritance
  "extends": "./base"
}
Copy the code
  • includeImported files can beexcludefilter
  • filesThe specified file will not beexcludefilter
  • Referenced files will not beexcludefilter
  • extendsIf the configuration is inherited, the same configuration fields are overwritten

For example: if base.json is configured with files, tsconfig.json inherits it and also specifies the files property. Finally, because of overwriting, A.ts is compiled instead of B.ts

// base.json
{
  "files": [
    ".. /b.ts"]}Copy the code

(3) Compilation options

Common compilation and configuration items can be roughly divided into the following parts:

  • Compile the efficiency
  • Compiler output
  • Declaration file
  • Type checking
  • The module reference
  • Log output
{
  "compilerOptions": {
      // ======== compilation efficiency ========
      // "incremental": true, // incremental compilation
      // "tsBuildInfoFile": "./buildFile", // Where incremental compiled files are stored
      // "diagnostics": true, // Prints the diagnostic information

      // ======== Compile output ========
      // "target": "es5", // The target language version
      // "module": "commonjs", // Generate code module standard
      // "outFile": "./app.js", // Generate a file from multiple interdependent files that can be used in AMD modules

      // "lib": [], // TS need to reference library, that is, es5 default "dom", "es5", "scripthost"

      // "allowJs": true, // allows compiling JS files (JS, JSX)
      // "checkJs": true, // Allows errors to be reported in JS files, usually with allowJS
      // "outDir": "./out", // specify the output directory
      // "rootDir": "./", // Specify the input file directory (for output)

      // "removeComments": true, // removeComments

      // "noEmit": true, // no output file
      // "noEmitOnError": true, // do not output files when errors occur

      // "noEmitHelpers": true, // Don't generate helpers, you need to install ts-helpers
      // "importHelpers": true, // Introduce helper functions via tslib. The file must be a module

      // "downlevelIteration": true, // Implementation of degraded iterator (ES3/5)

      // ======== Declaration file related ========
      // "declaration": true, // Generate declaration file
      // "declarationDir": "./d", // declare the file path
      // "emitationOnly ": true, // only the declaration file is generated
      // "sourceMap": true, // Generate the sourceMap of the target file
      // "inlineSourceMap": true, // Generates an inline sourceMap for the target file
      // "declarationMap": true, // Generates the sourceMap of the declaration file
      // "typeRoots": [], // declare the file directory, default node_modules/@types
      // "types": [], // declare file packages

      // ======== Strict type check ========
      // "strict": true, // turn on all strict type checking
      // "alwaysStrict": false, // inject "use strict" into the code;
      // "noImplicitAny": false, // Implicit any type is not allowed
      StrictNullChecks: false, null and undefined are not allowed to be assigned to other types of variables
      // "strictFunctionTypes": false // Bidirectional covariant of function parameters is not allowed
      / / "strictPropertyInitialization" : false, / / class instance attributes must be initialized
      // strictBindCallApply: false, // strict bind/call/apply check
      // "noImplicitThis": false, // This is not allowed to have an implicit any type

      // "noUnusedLocals": true, // Check only declared, unused local variables
      // "noUnusedParameters": true, // Check for unused function parameters
      / / "noFallthroughCasesInSwitch" : true, / / prevent switch statements throughout
      // "noImplicitReturns": true, // Each branch must return a value

      // the ======== module references ========
      // "esModuleInterop": true, // Allow export = export, import from import
      // "allowUmdGlobalAccess": true, // allows access to UMD global variables in modules
      // "moduleResolution": "node", // moduleResolution policy
      // "baseUrl": "./", // Resolve the base address of a non-relative module
      // "paths": {// Path mapping, relative to baseUrl
      // "jquery": ["node_modules/jquery/dist/jquery.slim.min.js"]
      // },
      // "rootDirs": [" SRC ", "out"], // Put multiple directories in one virtual directory for runtime

      // ======== Log output ========
      // "listEmittedFiles": true, // Print the output file
      // "listFiles": true, // Prints compiled files (including referenced declaration files)}}Copy the code

3. Ts compiles to JS

Configuration items

Since the Web or Node environment cannot run TS code directly, even with TS-Node you have to go through the process of compiling from TS to JS, and you are still running JS code. Ts code compilation, there are two basic problems:

  • What es version code to output
  • Output which module system

These two problems are also reflected in the configuration of TS projects

// tsconfig.json
{
  "compilerOptions": {
    "target": "es5"./* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', 'ES2021', or 'ESNEXT'. */
    "module": "commonjs"./* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */}}Copy the code
  • target, the target language version. Support from theES3ES2021ESNEXTVersion, default isES3
  • module, the module specification for generating code. Support for the most common module specifications. fromes2015After that, in fact, all of themESMModule specification.

PS: The default module specification for es3/ ES5 is CommonJS. The default module specification for es2015 is case insensitive. Es6 and ES2015 have the same meaning, but there is no ES7 / ES8

The command line

If tsconfig.json is not configured, you can also pass command line arguments by executing TSC compile time

# Compile output for ES3 compatibility
tsc ./moduleA.ts --target es3
# Compile output es5 compatible
tsc ./moduleA.ts -t es5

# Compiler output CommonJS module system compatible
tsc ./moduleA.ts --module commonjs 
# Compiled output AMD module system compatible
tsc ./moduleA.ts -m amd 
# Compiler output UMD module system compatible
tsc ./moduleA.ts -m umd
Copy the code

4. Project reference

Engineering references are designed to address the following issues

  • Realize the independence of multiple projects in the project
  • Projects reference each other relatively independently

Project configuration

Demo02_projects_references ├ ─ ─ the SRC │ ├ ─ ─ common │ │ ├ ─ ─ but ts │ │ └ ─ ─ tsconfig. Json │ ├ ─ ─ projectA │ │ ├ ─ ─ but ts │ │ ├─ ├─ ├─ trash, ├─ ├─ trashCopy the code

Basic configuration./tsconfig.json

  • Composite must be enabled, and the project can be referenced and incrementally compiled
  • Declaration Must be enabled to automatically create type declaration files and generate corresponding.d.ts files
// ./tsconfig.json
{
  "compilerOptions": {
    "target": "es5"."module": "commonjs"."strict": true."composite": true."declaration": true}}Copy the code

Project configuration. / SRC/client/tsconfig. Json

  • Extends refers to the project on which it depends
  • References specifies the project to reference
  • Compileroptions. outDir specifies the output directory separately
// ./src/projectA/tsconfig.json
// Subproject configuration
{
  "extends": ".. /.. /tsconfig.json".// Base dependency configuration
  "compilerOptions": {
    "outDir": ".. /.. /dist/projectA",},"references": [{"path": ".. /common" } // Reference the public module]}Copy the code

build

Running TSC –build (tSC-b) to build your project automatically handles:

  • Find all referenced projects
  • Check if they are the latest version
  • Build non-latest versions of the project sequentially

Build projectA by executing the following command:

tsc -b ./src/projectA
Copy the code

The built directory

Demo02_projects_references ├ ─ ─ dist │ ├ ─ ─ common │ │ ├ ─ ─ the index, which s / / type declaration documents │ │ ├ ─ ─ index. The js / / output js code │ │ └ ─ ─ Tsconfig. Tsbuildinfo / / incremental compilation information file │ └ ─ ─ projectA │ │ ├ ─ ─ the index, which s │ │ ├ ─ ─ index. The js │ │ └ ─ ─ tsconfig. Tsbuildinfo ├ ─ ─ the SRC └ ─ ─ tsconfig. JsonCopy the code

TSC -b other options

  • --verbose: Prints detailed logs (can be used with other tags)
  • --dry: Shows actions to be performed but does not actually perform them
  • --clean: Deletes the output of the specified project--dryUsed together)
  • --force: Treat all projects as if they are not up to date
  • --watch: Observation mode (can be associated with –-verboseUsed together)

5. Compilation tools

The official TSC compilation tool can help us compile TS code into JS code nicely. But the actual project is much more complex and not just TS code, and we are using other project build tools such as Webpack, gulp, rollup, etc., which need to be used in conjunction with the various TS build tools. Here are some common compilation tools in conjunction with WebPack.

(1) ts-loader

Basic configuration

The simplest configuration file for compiling TS code using Webpack + TS-Loader can compile TS to JS and perform type checking

// webpack.config.js
module.exports = {
  entry: './src/index.ts'.resolve: {
    extensions: ['.js'.'.ts'.'.tsx']},module: {
    rules: [{test: /\.ts$/,
        use: [
          {
            loader: 'ts-loader'.options: {} // Do not add any configuration}].exclude: /node_modules/}}}]Copy the code

Type checking

Ts-loader compiles TS code to handle two things:

  • Perform type checking to check if the output code fails
  • Compile TS code into JS code

Ts-loader processes these two things in the same process. Because the process is blocked, the efficiency is low. We can choose to use the fork-ts-checker-webpack-plugin to use an independent process for TS type check, which can significantly improve the compilation speed

// webpack.config.js
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin')
module.exports = {
  entry: './src/index.ts'.resolve: {
    extensions: ['.js'.'.ts'.'.tsx']},module: {
    rules: [{test: /\.ts$/,
        use: [
          {
            loader: 'ts-loader'.options: {
              transpileOnly: true // TS-loader does not perform type checking}}].exclude: /node_modules/}},plugins: [
    new ForkTsCheckerWebpackPlugin() // Type checking plug-in]}Copy the code

(2) awesome-typescript-loader

A loader similar to TS-Loader can be used in the same way. However, the built-in type checking plug-in has defects, not fixed, the author has discarded the pit, not recommended.

(3) Babel

Since Babel 7, the Babel team has worked closely with the Typescript team to integrate Typescript compilation into Babel, which can greatly improve compilation efficiency and reduce compilation configuration. Babel is highly recommended as a Typescript compilation tool because it is used by almost all JS projects due to its maturity.

Basic configuration

// .babelrc
{
  "presets": [
    "@babel/preset-typescript"]}Copy the code

Add the Babel scaffolding @babel/cli and the core @babel/core, and run the compilation script to complete a simple TS compilation

// package.json
{
  "name": "demo04_babel"."scripts": {
    "build": "babel src --out-dir dist --extensions \".ts\""
    / / the Babel [compile directory] - out - dir/output directory - extensions \ [file] \ ""
  },
  "devDependencies": {
    "@babel/cli": "^ 7.15.4"."@babel/core": "^ 7.15.5"."@babel/preset-typescript": "^ 7.15.0"}}Copy the code

Babel + webpack

Example of the simplest Babel + Webpack compilation configuration.

// Project configuration
// package.json
{
  "name": "demo05_babel_webpack"."scripts": {
    "build": "webpack"
  },
  "dependencies": {
    "@babel/core": "^ 7.15.5"."@babel/plugin-proposal-class-properties": "^ 7.14.5"."@babel/plugin-proposal-object-rest-spread": "^ 7.15.6"."@babel/preset-typescript": "^ 7.15.0"."babel-loader": "^ 8.2.2"."webpack": "^ 5.52.0"."webpack-cli": "^ 4.8.0"}}Copy the code
/ / the Babel configuration
// .babelrc
{
  "presets": [
    "@babel/preset-typescript"]."plugins": [
    "@babel/proposal-class-properties".// class compiler plug-in
    "@babel/proposal-object-rest-spread" // The rest of the arguments and destruct assignments compile the plug-in]}Copy the code
/ / webpack configuration
// webpack.config.js
module.exports = {
  entry: './src/index.ts'.resolve: {
    extensions: ['.ts'.'.js']},module: {
    rules: [{test: /\.ts$/,
        use: [
          {
            loader: 'babel-loader'}].exclude: /node_modules/}}}]Copy the code

Babel + Webpack + framework

On the basis of Babel + Webpack, adding front-end frameworks such as Vue or React, and corresponding webpack compilation and configuration can complete a basic project structure.

Limitations of Babel and optimization strategies

limitations Optimization strategy
BabelOnly TS compilation is performed without type checking Use vscode syntax check

usetsc --watchMode runs syntax checking separately
Unable to compilenamespace Do not use
Unable to compile<typename>Types of assertions To switch toas typename
Unable to compileconst enum Do not use
Unable to compileexport = Do not use

The last

The whole article, if there are mistakes or not rigorous place, please be sure to give correction, thank you!