🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
[TOC] # ===babel 编译=== ## 借助 CRA: ``` yarn create react-app react-project --template typescript ``` ## 手动安装 ``` npm init npm i react react-dom react-router-dom core-js regenerator-runtime npm i -D webpack webpack-cli webpack-merge html-webpack-plugin webpack-dev-server clean-webpack-plugin @babel/core @babel/preset-react @babel/preset-env babel-loader ``` ## 依赖包 | 包名 | 释义 | | --- | --- | | @babel/core | babel 核心依赖包,将 js 代码分析成 ast,方便各个插件分析语法进行相应的处理 | | @babel/preset-env | 解析 ES 的包,取代了`preset-es20**`系列的babel 预设,会根据配置`.babelrc`的 `env` 只编译那些当前运行环境还不支持的特性。| | @babel/preset-react | 专门为了 react 的包,解析 jsx 的包 | | @babel/plugin-proposal-class-properties | 支持类属性的转化 | | @babel/plugin-proposal-object-rest-spread | 支持对象使用解构,Babel 默认只转换语法,而不转换新的 API,如需使用新的 API,还需要使用对应的转换插件或者 polyfill。更多查看官网 | | @babel/plugin-syntax-dynamic-import | 支持动态导入文件 | | @babel/plugin-proposal-decorators | 装饰器插件 | | @babel/plugin-transform-runtime | 使用 `async/await` 或其他一些功能时,会需要 | | @babel/runtime | `@babel-plugin-transform-runtime`插件所需要的,需要将其作为**依赖项**安装。 | | core-js、regenerator-runtime | 作为 polyfill,供`@babel/preset-env`使用(适当的配置,可以把这2个库的代码,按需打入bundle) | | webpack | webpack 核心包 | | webpack-cli | webpack cli 工具包 | | babel-loader | 和 webpack 结合,用于编译打包 js 文件 | | html-webpack-plugin | webpack 插件,用于将打包后的文件添加到指定的 html | | webpack-dev-server | webpack 开发环境工具 | ## 配置文件 ### `.babelrc`: ``` { presets: [ [ '@babel/preset-env', { "corejs": "3", // 指定core-js的版本,2或者3,这里我们用最新版3 "useBuiltIns": "usage", // usage是最佳实践,会按需把core-js和regenerator引入(所谓按需就是按下面的target和编译的js用到的es6语法来判断 "targets": '> 2% in CN and not ie <= 8 and not dead', // 选择目标环境为:中国区统计数据为2%以上的浏览器,不包括版本号小于8的IE浏览,不包括官方已经不维护的浏览器 }, ], '@babel/preset-react', '@babel/preset-typescript', ], "exclude": [/node_modules/], // 不要编译node_modules,不然会出一些奇奇怪怪的问题 "plugins": ["@babel/plugin-transform-runtime", "@babel/plugin-proposal-object-rest-spread", "@babel/plugin-proposal-class-properties"], "comments": false } ``` ### `webpack.config.js`: ``` const webpack = require('webpack'); ... module.exports = { ... resolve: { extensions: ['.js', '.jsx'], alias: { '@': path.resolve(__dirname, '../src'), }, }, module: { rules: [ ... { test: /\.js(x?)$/, exclude: /[\\/]node_modules[\\/]/, loader: 'babel-loader?cacheDirectory=true', }, ], }, plugins: [ ... new webpack.ProvidePlugin({ React: 'react', // 不用在每个组件文件中都使用一次`import React from 'react'` }), ], optimization: { splitChunks: { cacheGroups: { commons: { test: /[\\/]node_modules[\\/]/, name: 'vendors', chunks: 'all' }, }, }, }, } ``` ## 参考 > [纯手动搭建React项目](https://juejin.im/post/5e7b16b0f265da57187c77a3) # ===Typescript 编译=== Typescript本身具有编译器,可以根据`tsconfig.json`来进行编译。当我们使用 Webpack 进行打包编译的时候,我们需要相应的 loader,Webpack 官网推荐了 ts-loader。而社区也有 awesome-typescript-loader,它针对 ts-loader 做了一些优化,将类型检查和代码生成分离到单独进程中,另外,它还可以直接集成 babel。最后祭出大杀器,Babel 本身是非常强大的语法转换工具,在 babel7 之后开始支持 typescript。 综上,目前转换 Typescript 有三种常用的方式: * 经典的 ts-loader * awesome-typescript-loader * babel7 之后已经支持的 `@babel/preset-typescript ` (目前推荐的) ———————————————— ## 借助 CRA: ``` $ npx create-react-app my-app --typescript $ # 或者 $ yarn create react-app my-app --typescript npm start / yarn start ``` # 手动安装 ```shell mkdir ts-react && cd ts-react npm init -y && tsc --init npm i react react-dom react-router-dom @types/react @types/react-dom @types/react-router-dom npm i -D typescript babel-loader @babel/core @babel/preset-env @babel/preset-react @babel/preset-typescript npm i -D webpack webpack-cli webpack-dev-server html-webpack-plugin npm i -D css-loader sass-loader node-sass mini-css-extract-plugin npm i -D url-loader file-loader npm i -D eslint eslint-loader eslint-plugin-react eslint-plugin-react-hooks @typescript-eslint/parser @typescript-eslint/eslint-plugin ``` ## 依赖包 | 包名 | 释义 | | --- | --- | | @babel/preset-react | 专门为了 react 的包,解析 jsx 的包 | | @babel/preset-typescript | babel 的 preset,用于处理 TypeScript,没有类型检查的能力 | | @babel/preset-env | 解析过 JSX 和 TypeScript 之后得到的 JavaScript 可能依然无法在某些浏览器上正常运行,所以需要使用[@babel/preset-env](https://babeljs.io/docs/en/next/babel-preset-env.html) | | @babel/plugin-transform-typescript | 增加了对 TypeScript 编程语言使用的语法的支持。但是,这个插件没有添加类型检查的能力 | | @typescript-eslint | 配置 ESLint 来达到 TypeScript 类型检查 | | tsx-control-statements | babel 的 preset,用于处理 TypeScript | | awsome-typescript-loader | babel 的 preset,用于处理 TypeScript | | fork-ts-checker-webpack-plugin | 启用 TypeScript 类型检测 | | eslint-plugin-react | 检测和规范 React 代码的书写 | | @typescript-eslint/parser | ESLint 的解析器,用于解析 typescript,从而检查和规范 Typescript 代码 | | @typescript-eslint/eslint-plugin | ESLint 插件,包含了各类定义好的检测 Typescript 代码的规范 | ## `.babelrc` ``` // presets 是自下而上执行的,和 webpack 的 loader 一样 { presets: [ [ '@babel/preset-env', { "targets": '> 2% in CN and not ie <= 8 and not dead', // 选择目标环境为:中国区统计数据为2%以上的浏览器,不包括版本号小于8的IE浏览,不包括官方已经不维护的浏览器 }, ], '@babel/preset-react', '@babel/preset-typescript', ] } ``` ## `.eslintrc.js` ~~~js module.exports = { parser: '@typescript-eslint/parser', extends: [ 'plugin:react/recommended', 'plugin:@typescript-eslint/recommended' ], //使用推荐的React代码检测规范 plugins: ['@typescript-eslint'], env:{ browser: true, node: true, }, settings: { //自动发现React的版本,从而进行规范react代码 "react": { "pragma": "React", "version": "detect" } }, parserOptions: { //指定ESLint可以解析JSX语法 "ecmaVersion": 2019, "sourceType": 'module', "ecmaFeatures":{ jsx:true } }, rules: { //自定义React代码编码规范 } } ~~~ ## `tsconfig.json` ~~~json { "compilerOptions": { "allowSyntheticDefaultImports": true, "jsx": "react", "lib": ["es6", "dom"], "module": "esnext", "experimentalDecorators": true, "emitDecoratorMetadata": true, "allowSyntheticDefaultImports": true, // 允许使用 ES2015 默认的 import 风格 "esModuleInterop": true, // 可调用的CommonJS模块必须被做为默认导入,在已有的“老式”模块模式之间保证最佳的互通性 "moduleResolution": "node", "noImplicitAny": true, "rootDir": "src", "sourceMap": true, "strict": true, "target": "es5" }, "exclude": [ "node_modules", "build" ] } ~~~ ## 目录结构 ~~~ ├── build # 构建结果目录 ├── styles # 样式 └── main.css ├── bundle.ssr.js # SSR应用文件 ├── bundle.web.js # Web应用文件 ├── index.html # Web应用入口HTML ├── public └── index.html # 模板页面 ├── src # 应用源码 ├── components # 组件 └── Header └── Header.js ├── home # 首页 └── index.scss # 首页 scss └── index.tsx # 首页 ├── signin # 登录页 └── index.scss # 登录页 scss └── index.tsx # 登录页 ├── App.tsx # 应用路由设置 ├── main.ssr.tsx # SSR入口文件 ├── index.web.tsx # Web 入口文件 ├── index.js # express服务器入口 ├── package.json ├── tsconfig.json # TypeScript配置文件 ├── webpack.config.js # Web应用webpack配置 ├── webconfig.ssr.config.js # SSR应用Webpack配置 ~~~ ## 参考 > [Microsoft/TypeScript-Babel-Starter](https://github.com/microsoft/TypeScript-Babel-Starter) > [使用Webpack等搭建一个适用于React项目的脚手架(1 - React、TypeScript)](https://juejin.im/post/5e8b3e626fb9a03c546c2e60#heading-6) > [webpack从0开始手动搭建react + typeScript项目(二)](https://www.jianshu.com/p/34af24231d2a) # create-react-app eject 和 不 eject(使用react-app-rewired) 这2种情况下的 antd 组件按需引入配置: * 不 eject(使用 [react-app-rewired](https://github.com/timarney/react-app-rewired))配置: 1. **react-app-rewired2.x 以后,不再支持 injectBabelPlugin 的方式,需要安装 [customize-cra](https://github.com/arackaf/customize-cra)。** 替代项目和分支: [Rescripts](https://github.com/rescripts/rescripts),用于扩展 CRA 配置的替代框架(支持 2.0+) [react-scripts-rewired](https://github.com/marcopeg/create-react-app/blob/master/packages/react-scripts/README.md) 为该项目的一个分支,旨在支持 CRA 2.0 [craco](https://github.com/sharegate/craco) 2. 项目的根目录下,新建名为 `config-overrides.js` 文件,然后进行 webpack 的相关配置。 3. 修改 package.json 文件 ``` /* package.json */ "scripts": { "start": "react-app-rewired start", "build": "react-app-rewired build", "test": "react-app-rewired test", } ``` ant.design 说明:https://ant.design/docs/react/use-with-create-react-app-cn [使用 react-app-rewired2.x 添加 webpack 配置](https://www.cnblogs.com/zyl-Tara/p/10635033.html) * eject 后,配置: 按需引入 antd 的2种方式: 出处:https://blog.csdn.net/well2049/article/details/78801228 推荐使用第2种方式:在`package.json`里面直接添加代码,这种方式简单。 --------------------- # 参考 [ How to set up React with Webpack and Babel](https://www.robinwieruch.de/minimal-react-webpack-babel-setup) [webpack手动搭建React项目](https://juejin.im/post/5cfb8c0051882541b24c3ed3)