第一个应用

本文将带你一步一步地实现一个最简单的“Hello World”应用。

初始化项目#

你也可以用@reskript/init来初始化项目,以下为手动初始化的过程,着眼于帮助你了解reSKRipt的相关依赖和工作过程。

你需要将一个目录转为一个标准的NodeJS项目,即需要package.json

mkdir my-app
cd my-app
npm init -y

安装依赖#

作为一个简单的应用,我们假设需要使用构建、本地调试、代码检查这几项功能,参考快速上手将相关的依赖安装上:

npm install --save-dev eslint stylelint typescript webpack @reskript/cli @reskript/cli-build @reskript/cli-dev @reskript/cli-lint @reskript/config-lint

另请注意:NodeJS 15.xNPM 7.x现在还录能完全兼容地安装这些依赖,你可能需要切换到NodeJS 14.x,可以考虑使用nvm来管理你的NodeJS版本。

当然需要使用react进行开发,必要的框架也是不可少的:

npm install react react-dom
npm install --save-dev @types/react @types/react-dom

准备一些配置文件#

代码检查#

在项目目录下创建一个.eslintrc.js,内容如下:

module.exports = {
extends: require.resolve('@reskript/config-lint/config/eslint'),
};

再增加一个stylelint.config.js,内容如下:

module.exports = {
extends: require.resolve('@reskript/config-lint/config/stylelint'),
};

可以阅读代码检查来了解各个配置文件的作用。

TypeScript配置#

我们想用TypeScript来编写源码,因此在项目目录下再增加一个tsconfig.json,内容可以简单如下:

{
"include": [
"src",
],
"compilerOptions": {
"module": "CommonJS",
"target": "es2018",
"outDir": "dist",
"noEmit": true,
"jsx": "react-jsx",
"esModuleInterop": true,
"moduleResolution": "node",
"strict": true,
"noUnusedLocals": false,
"noFallthroughCasesInSwitch": true,
"baseUrl": ".",
"keyofStringsOnly": true,
"skipLibCheck": true,
"paths": {
"@/*": ["./src/*"]
}
}
}

浏览器兼容性配置#

在项目根目录增加一个.browserslistrc文件,这个文件用来声明你需要兼容的浏览器,像babel等工具都会参考这个文件,我们随便填一些:

chrome 76
firefox 64

以上是一个比较精简可用的配置,使用emit: false可以让TypeScript不要去处理代码的生成,获得更好的类型检查的性能。

别名配置#

虽然reSKRipt完整地封装了webpack的功能,你不再需要自行做任何的配置。但是也正因为webpack的配置被隐藏在工具内,会让代码编辑器无法正确地读取配置来提供编码辅助,最为典型的是import语句中的路径会因为别名等原因无法找到,显示出预期外的错误。

为此,我们要在项目目录下放一个webpack.config.js,里面内容如下:

const path = require('path');
module.exports = {
resolve: {
alias: {
'@': path.resolve(__dirname, 'src'),
},
},
};

这个文件不需要包含任何的其它配置,仅仅用作编辑器识别路径别名。它和实际的构建也没有关系,任何时候你都不需要改动这个文件

项目配置#

在项目目录下创建一个reskript.config.js文件,简单地填空如下内容:

exports.build = {
appTitle: '我的第一个应用',
};
exports.devServer = {
port: 8081,
};

你可以通过配置文件来了解更多的配置信息。

编写入口代码#

reSKRipt的一大特点是将所有的应用入口放在了src/entries目录下,所以你现在的目录结构大致是这样的:

/src
/entries
index.tsx # 主入口文件
.eslintrc.js
.stylelint.config.js
webpack.config.js
reskript.config.js
package.json
package-lock.json

建立src/entries/index.tsx,并输入以下代码:

import {FC} from 'react';
import {render} from 'react-dom';
const App: FC = () => (
<h1>Hello World</h1>
);
render(
<App />,
document.body.appendChild(document.createElement('div'))
);

配置脚本#

打开package.json,找到scripts这个属性,替换为以下内容:

{
"scripts": {
"start": "skr dev",
"build": "skr build --clean",
"lint": "skr lint",
"lint-staged": "skr lint --staged"
}
}

这样可以让你快速地使用npm startnpm run build来执行脚本,当然你可以在后续灵活地调整这里的参数和脚本内容。

运行应用#

简单地把应用跑起来看看:

npm start

在短暂的等待后,你将看到浏览器自动打开了http://localhost:8081这个地址,页面上出现了“Hello World”字样。同时在命令行上看到一些漂亮的信息:

DONE Compiled successfully in 1608ms
I Your application is running here: http://localhost:8081/
I or: http://192.168.1.10:8081/

这说明一个最简单的应用已经成功了,我们可以在完全不接触webpack之类工具的前提下快速地实现一个React应用。

构建应用#

最后我们再来试一下把代码构建成可上线的产物:

npm run build

等待一段时间,任务完成后,你可以看到一个dist目录,简单看下里面的内容:

dist
├── assets
│   ├── index.2585d1c3d8714afc2ec0.js
│   ├── index.2585d1c3d8714afc2ec0.js.LICENSE.txt
│   └── index.2585d1c3d8714afc2ec0.js.map
└── index-stable.html

我们最终产出的入口页面是index-stable.html,名字有些不那么常见,你可以从特性矩阵了解源由。而dist/assets中则是所有的静态资源,资源都会带上哈希来提供长效缓存的支持。

总结#

截止此刻,我们用约5分钟的时间(假设你复制粘贴够熟练)快速地运行了一个简单的React应用,在后续章节我们会慢慢展开讲解更深入的应用开发模式。