前段时间研究了一下react+typescript开发方式,再加上antd,开发感受还是挺不错的。本篇文章主要讲下在官方推荐的脚手架的基础上搭建脚手架所遇到的问题。
一开始使用的是create-react-app-typescript脚手架(此方案已废弃)
npx create-react-app my-app --scripts-version=react-scripts-ts
cd my-app
npm start
# or with yarn
yarn create react-app my-app --scripts-version=react-scripts-ts
cd my-app
yarn start
复制代码
不过这个脚手架,作者已经停止更新了,github仓库上已经归档:
This repository has been archived by the owner. It is now read-only.
复制代码
由于依赖包webpack-dev-server低版本有漏洞,最好升级到大于3.1.11版本
CVE-2018-14732
Vulnerable versions: < 3.1.11
Patched version: 3.1.11
An issue was discovered in lib/Server.js in webpack-dev-server
before 3.1.11. Attackers are able to steal developer's
code because the origin of requests is not checked by the
WebSocket server, which is used for HMR (Hot Module Replacement).
Anyone can receive the HMR message sent by the WebSocket
server via a ws://127.0.0.1:8080/ connection from any origin.
复制代码
但是升级webpack-dev-server后还要涉及到一系列工具链包的升级,在原有脚手架上升级及后续的配置修改会很麻烦。然后就使用了下面的方法
新的脚手架:create react app 之Adding TypeScript
1、参考文章地址中的方法生成项目
// 使用此命令将配置分离出来,便于后面修改相关配置
yarn eject
复制代码
2、 由于默认的脚手架里并没有tslint,如果要使用tslint,需要在根目录增加tslint.json,然后安装相关包,并修改相关配置
yarn add tslint tslint-config-prettier tslint-react
复制代码
- tslint.json配置(参考)如下:
{
"extends": ["tslint:recommended", "tslint-react", "tslint-config-prettier"],
"rules":{
"no-console":false,
"no-debugger":false,
"indent":[true, "spaces", 2], // 缩进
"no-consecutive-blank-lines": [// 空行不超过两行
true,
2
],
"jsx-no-lambda": false,
// 检查对象中键的排序
"object-literal-sort-keys": false,
// 倒入(import)源的排序规则
"ordered-imports": true
},
"linterOptions": {
"exclude": [
"config/**/*.js",
"node_modules/**/*.ts"
]
}
}
复制代码
- 在paths.js文件中增加
appTsLint: resolveApp("tslint.json")
如下:
module.exports = {
dotenv: resolveApp(".env"),
appPath: resolveApp("."),
appBuild: resolveApp("build"),
appPublic: resolveApp("public"),
appHtml: resolveApp("public/index.html"),
appIndexJs: resolveModule(resolveApp, "src/index"),
appPackageJson: resolveApp("package.json"),
appSrc: resolveApp("src"),
appTsConfig: resolveApp("tsconfig.json"),
+ appTsLint: resolveApp("tslint.json"),
yarnLockFile: resolveApp("yarn.lock"),
testsSetup: resolveModule(resolveApp, "src/setupTests"),
proxySetup: resolveApp("src/setupProxy.js"),
appNodeModules: resolveApp("node_modules"),
publicUrl: getPublicUrl(resolveApp("package.json")),
servedPath: getServedPath(resolveApp("package.json"))
};
复制代码
- webpack.config.js修改插件ForkTsCheckerWebpackPlugin配置,增加
tslint: paths.appTsLint
,如下:
new ForkTsCheckerWebpackPlugin({
typescript: resolve.sync("typescript", {
basedir: paths.appNodeModules
}),
async: false,
checkSyntacticErrors: true,
tsconfig: paths.appTsConfig,
+ tslint: paths.appTsLint,
compilerOptions: {
module: "esnext",
moduleResolution: "node",
resolveJsonModule: true,
isolatedModules: true,
noEmit: true,
jsx: "preserve"
},
reportFiles: [
"**",
"!**/*.json",
"!**/__tests__/**",
"!**/?(*.)(spec|test).*",
"!**/src/setupProxy.*",
"!**/src/setupTests.*"
],
watch: paths.appSrc,
silent: true,
formatter: typescriptFormatter
})
复制代码
使用路径别名
typescript项目的路径别名不是在webpack中配置的,而是在tsconfig.json中配置的。
如在tsconfig.json增加如下配置:
{
"compilerOptions": {
+ "baseUrl": ".",
+ "paths": {
+ "@/*": ["src/*"]
+ },
...
},
...
}
复制代码
index.tsx中使用:
import App from "@/App";
复制代码
此时启动项目
yarn start
复制代码
出现以下编译报错:
Failed to compile.
./src/index.tsx
Module not found: Can't resolve '@/App' in 'dir/dir/src'
复制代码
解决编译报错
yarn add tsconfig-paths-webpack-plugin
复制代码
修改webpack.config.js文件
+ const TsconfigPathsPlugin = require("tsconfig-paths-webpack-plugin");
...
alias: {
// Support React Native Web
// https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/
"react-native": "react-native-web"
},
plugins: [
// Adds support for installing with Plug'n'Play, leading to faster installs and adding
// guards against forgotten dependencies and such.
PnpWebpackPlugin,
// Prevents users from importing files from outside of src/ (or node_modules/).
// This often causes confusion because we only process files within src/ with babel.
// To fix this, we prevent you from importing files out of src/ -- if you'd like to,
// please link the files into your node_modules/ and let module-resolution kick in.
// Make sure your source files are compiled, as they will not be processed in any way.
new ModuleScopePlugin(paths.appSrc, [paths.appPackageJson]),
+ new TsconfigPathsPlugin()
]
复制代码
使用antd
虽然antd已经有一些成熟的脚手架,但是个人感觉太过冗余,或者以后修改起来会很麻烦,所以我还是倾向于自己去结合官方脚手架来弄一套自己熟悉的。
yarn add antd
复制代码
参考antd官方教程,快速上手,即可快速将antd引入我们的react+typescript项目。
当然为了性能,按需加载
还是要做的,安装babel-plugin-import,并增加相关配置
yarn add babel-plugin-import
复制代码
修改webpack.config.js文件
{
test: /\.(js|mjs|jsx|ts|tsx)$/,
include: paths.appSrc,
loader: require.resolve("babel-loader"),
options: {
customize: require.resolve(
"babel-preset-react-app/webpack-overrides"
),
plugins: [
[
require.resolve("babel-plugin-named-asset-import"),
{
loaderMap: {
svg: {
ReactComponent: "@svgr/webpack?-svgo![path]"
}
}
}
],
+ [
+ "import",
+ {
+ libraryName: "antd",
+ style: "css"
+ }
+ ]
],
// This is a feature of `babel-loader` for webpack (not Babel itself).
// It enables caching results in ./node_modules/.cache/babel-loader/
// directory for faster rebuilds.
cacheDirectory: true,
cacheCompression: isEnvProduction,
compact: isEnvProduction
}
},
复制代码
至此整个脚手架就搭建完成了!