djlxiaoshi / blog

7 stars 0 forks source link

基于React的脚手架搭建 #4

Open djlxiaoshi opened 6 years ago

djlxiaoshi commented 6 years ago

基于React的脚手架搭建

目的

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

技术栈

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相关配置的问题,具体可以看文档

最后(欢迎大家关注我)

DJL箫氏个人博客 博客GitHub地址 简书 掘金