Skip to content
No description, website, or topics provided.
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
.idea
public
src
.gitignore
README.md
build-check.js
config-overrides.js
cp-environment.js
package-lock.json
package.json
tsconfig.json
tsconfig.test.json
tslint.json

README.md

基于React的脚手架搭建

目的

为了能够在工作中更加快速的搭建起开发环境,所以在create-react-app的基础之上结合自身公司业务和个人习惯,搭建了个更加方便的脚手架。

技术栈

react  // mvm框架
typescipt // 开发语言
sass // 预编译语言
anti-mobile // UI框架
axios // http请求
react-router-dom // 路由

目录结构

core // 存放一些工具代码和一些服务
environments  // 存放环境配置文件
pages // app页面存放文件
routing // 路由
components // 公共组件

搭建过程

1 配置typescript使用环境

首先我打算使用typescript作为开发语言,首先我们是用create-react-app来作为基础的脚手架工具,按照github上面的操作方法,进行如下操作:

npm install -g create-react-app
create-react-app my-app --scripts-version=react-scripts-ts
cd my-app/
npm start

这样当我们就可以通过npm start启动应用了

配置scss 参考链接

npm install --save node-sass-chokidar

"scripts": {
+  "build-css": "node-sass-chokidar src/ -o src/",
+  "watch-css": "npm run build-css && node-sass-chokidar src/ -o src/--watch --recursive",
   "start": "react-scripts-ts start",
   "build": "react-scripts-ts build",
   "test": "react-scripts-ts test --env=jsdom",

按照如上操作即可,然后再添加src/**/*.css.gitignore文件中。接下来我们希望项目能够监测scss的变化,从而自动去编译scss文件,显然我们要用到watch-cssbuild-css这两个任务,我们可以使用&&操作符,但是这种跨平台性并不是很好,所以我们采用npm-run-all这个工具。

npm install --save npm-run-all

然后进行如下修改

   "scripts": {
     "build-css": "node-sass-chokidar src/ -o src/",
     "watch-css": "npm run build-css && node-sass-chokidar src/ -o src/ --watch --recursive",
-    "start": "react-scripts-ts start",
-    "build": "react-scripts-ts build",
+    "start-js": "react-scripts-ts start",
+    "start": "npm-run-all -p watch-css start-js",
+    "build-js": "react-scripts-ts build",
+    "build": "npm-run-all build-css build-js",
     "test": "react-scripts-ts test --env=jsdom",
     "eject": "react-scripts-ts eject"
   }

ok,以上我们就搭建好了scss环境

安装anti-mobile

npm install antd-mobile --save
npm install react-app-rewired --save-dev
"scripts": {
	"build-css": "node-sass-chokidar --include-path ./src --include-path ./node_modules src/ -o src/",
	"watch-css": "npm run build-css && node-sass-chokidar --include-path ./src --include-path ./node_modules src/ -o src/ --watch --recursive",
+	"start-js": "react-app-rewired start --scripts-version react-scripts-ts",
    "start": "npm-run-all -p watch-css start-js",
+    "build-js": "react-app-rewired build --scripts-version react-scripts-ts",
    "build": "npm-run-all build-css build-js",
+    "test": "react-app-rewired test --env=jsdom",
    "eject": "react-scripts-ts eject"
  },

这里由于我们使用的是typescript,所以"start-js": "react-app-rewired start --scripts-version react-scripts-ts","build-js": "react-app-rewired build --scripts-version react-scripts-ts",后面要加上react-scripts-ts。接下来我们实现按需加载参考链接

安装npm install babel-plugin-import --save-dev

更改config-overrides.js文件

/* config-overrides.js */
const tsImportPluginFactory = require('ts-import-plugin')
const { getLoader } = require("react-app-rewired");

module.exports = function override(config, env) {
    const tsLoader = getLoader(
        config.module.rules,
        rule =>
            rule.loader &&
            typeof rule.loader === 'string' &&
            rule.loader.includes('ts-loader')
    );

    tsLoader.options = {
        getCustomTransformers: () => ({
            before: [ tsImportPluginFactory({
                libraryName: 'antd-mobile',
                libraryDirectory: 'es',
                style: 'css',
            }) ]
        })
    };

    return config;
};

这样我们就可以直接引入import { Button } from 'antd-mobile';不需要在前面引入import 'antd-mobile/dist/antd-mobile.css';

当我们引入antd-mobile后可能会出现下列错误

E:/MyProjects/frame-work-cli/my-app/node_modules/antd-mobile/lib/picker/PropsType.d.ts (7,15): Parameter 'values' implicitly has an 'any' type.

找到node_modules/antd-mobile/lib/picker/PropsType.d.ts把format?: (values) => void;改成 format?: (values: any) => void;即可当然为了直接省事,直接在tsconfig.json设置"noImplicitAny": false

4 开发环境切换配置

现在公司一般都会有开发环境,预发布环境和正式环境,这些环境所对应的后端地址并不一样,所以我们要来进行一些配置方便切换。实现的思路就是读取命令行参数,根据参数把不同环境的配置文件的内容复制替换掉environment.js这个文件,这里我们用到了shelljscross-env(读取命令行参数)这两个js库。 创建cp-environment.js

const shell = require('shelljs');

const env = process.env.NODE_ENV;
const src = `src/environments/environment.${env}.ts`;
const to = `src/environments/environment.ts`;

shell.cp('-R', src, to);

更改package.json

"scripts": {
    "build-css": "node-sass-chokidar --include-path ./src --include-path ./node_modules src/ -o src/",
    "watch-css": "npm run build-css && node-sass-chokidar --include-path ./src --include-path ./node_modules src/ -o src/ --watch --recursive",
    "start-js": "react-app-rewired start --scripts-version react-scripts-ts",
    "start": "cross-env NODE_ENV=pro npm-run-all cp-environment -p watch-css start-js",
    "startDev": "cross-env NODE_ENV=dev npm-run-all cp-environment -p watch-css start-js",
    "startLocal": "cross-env NODE_ENV=local npm-run-all cp-environment -p watch-css start-js",
    "build-js": "react-app-rewired build --scripts-version react-scripts-ts",
    "build": "cross-env NODE_ENV=pro npm-run-all cp-environment build-css build-js",
    "buildLocal": "cross-env NODE_ENV=Local npm-run-all cp-environment build-css build-js",
    "buildDev": "cross-env NODE_ENV=dev npm-run-all cp-environment build-css build-js",
    "test": "react-app-rewired test --env=jsdom",
    "eject": "react-scripts-ts eject",
    "cp-environment": "node cp-environment.js"
  }

当然我们开发环境上传的代码应该是buildDev后的代码,但是有可能有时进行了误操作,把build后的代码上传上去,我们还可以写一个检测的脚本。 原理就是读取当前分支名,根据分知名和当前的环境变量进行对比。

const branchEnvMap = {
  dev: 'dev',
  test: 'test',
  release: 'prod',
};

const shell = require('shelljs');
const branch = shell.exec('git rev-parse --symbolic-full-name --abbrev-ref HEAD', { silent: true }).toString().trim();
const env = process.argv.slice(2).toString().split('=')[1].toString();

if (branchEnvMap[branch] !== env) {
  shell.echo('该分支对应的编译任务不是这个,请检查执行的命令!', branch, env);
  shell.exit(1);
}

Http

用到就是axios,至于怎么用直接看我的GitHub地址就行,这里进行了一层封装,主要是对返回的结果进行统一的处理。

路由

我用到的是react-router-dom,至于用法还是推荐看github,

1 E:/MyProjects/frame-work-cli/my-app/node_modules/@types/react-dom/node_modules/@types/react/index.d.ts (3631,13): Subsequent property declarations must have the same type. Property 'a' must be of type 'DetailedHTMLProps<AnchorHTMLAttributes, HTMLAnchorElement>', but here has type 'DetailedHTMLProps<AnchorHTMLAttributes, HTMLAnchorElement>'.

当我们启动应用的时候可能会出现如上错误,这是由于我们安装的@types/react@types/react-dom版本并不怎么一致,参考链接, 例如下面的版本

 "@types/react": "^15.6.7",
 "@types/react-dom": "^16.0.3",

所以我们可以换成

"@types/react": "^16.0.36",
"@types/react-dom: "^16.0.3"

2 E:/MyProjects/frame-work-cli/my-app/node_modules/antd-mobile/lib/picker/PropsType.d.ts(7,15): Parameter 'values' implicitly has an 'any' type.

在tsconfig.json设置"noImplicitAny": false

3 error TS1192: Module '"react"' has no default export.

设置 tsconfig.json "allowSyntheticDefaultImports": true,

4 expected parameter: 'props' to have a typedef

在tslint.json设置typedef: false,这个属于tslint相关配置的问题,具体可以看文档

You can’t perform that action at this time.