14

前端工程化这些事情现在已经算是深入人心了,即便不清楚具体含义vue-cli creat-react-app之类的脚手架也帮助大家快速开发了不少项目。

今天顺便总结了下之前的一些经验,希望对大家的工作或者学习有一些帮助。
老生常谈的splitChunksDll啥的就不多说了,简单分享些插件和配置功能优化,方便大家更省力地写代码。

配置

1. 代理配置:

很多时候我们为了跨域会给devServer配个proxy啥的,没数据的时候要连接到mock接口上,有数据的时候又要切换到dev上,有时候又要调试复现qa环境的问题,一般像这个时候我们可以简单配个npm script

    # 默认 dev 环境
    npm run dev

    # mock 环境
    npm run dev --mock 

那对webpack怎么配置呢

新建一个proxy.js文件

const config = {
    dev: {
         ... // 你的proxy配置 文档自行参考 https://webpack.js.org/configuration/dev-server/#devserver-proxy  
    },
    mock: {
        ...
    }
};

let proxy = config.dev;

for (const key in proxy) {
    if (process.env[`npm_config_${key}`]) {
        current = { ...proxy, ...config[key] };
    };
};
module.exports = current;

然后导入到你的webpack.config.dev.js中,设置为devServer的proxy

const proxy = require('./proxy.js');

...
devServer: {
    ...
    proxy: proxy
}

然后就完事了,当然了,这是最简单的方式,一般情况下我们是还需要根据当前运行的环境变量再做判定的。业务上的问题这里就不展开了。

2. log信息

很多时候我们会在项目运行或者打包的时候出现一大堆没啥用的信息,
改下webpack里的stats即可
开发环境也可以用friendly-errors-webpack-plugin也是挺方便的

3.sourceMap

开发环境随便配个喜欢的sourceMap就好,但是生产环境就要去掉了,当然为了方便qa调试,最好也为打包做好各种环境设置,
但是别把sourcemap打到业务代码里是每个程序员的基本素养。对,我说的就是inline-source-map这种配置,有的话赶紧改掉,相信我这是为了你的职业生涯考虑。生产环境要用也只能用source-map,然后让运维大哥随手屏蔽下所有.map文件即可。

功能插件

1. 依赖分析

这个是之前在vue-cli上找的,用着感觉也挺顺手的,

# 下载插件
npm i -D webpack-bundle-analyzer
    // 注入webpack.config.prod.js
    const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
    
    // 写入plugin     
    ...
    plugins: [
        process.env.npm_config_report && new BundleAnalyzerPlugin()
    ]

然后你就可以在打完包后来一个依赖分析,用着也挺方便的

    npm run build --report

2. 邮件

有些利用travis 或者jenkins做远端打包的项目,在项目发布前可以简单配置一个邮件功能,包含打包内容、git commit信息什么的, 就不需要专门找人一一告知,方便所有开发人员根据业务,提高开发效率。
推荐nodemailer

工作流程优化

Makefile

很多时候npm script 可能不够用或者说看上去并不怎么直观,因为没法写备注可能也说不清具体什么用
这时候可以使用Makefile
在根目录建个Makefile文件
然后就可以在里面配置一些基本命令,可以理解为对npm script做一个简单的封装,关键是可以写备注

# 开发
start:
    npm run dev

# 打包
build:
    npm run build

# mock环境
mock:
    npm run dev --mock

然后你在当前目录下输入

    make start

就可以开始干活了

异常追踪

线上环境为了保证用户隐私是不允许开发人员直接接触用户信息的,但是有些问题光靠公司现有的测试机也无法完全覆盖,异常跟踪的框架网上挺多,这里简单提一下不做深入讨论。

开源常用的是sentry,具体怎么用自己看,弄个docker镜像跑一下啥的还是挺方便的。
收费的市面上不少,就不打广告了。

其他环境

如果业务中涉及到一些server端的开发的话肯定要解决各类服务端软件的安装比如RedisMySql MongoDB等,而不同项目可能还需要不同版本的数据库,甚至还可能要考虑node的版本,而各种版本的切换是一个让人头疼的事情,甚至因为某些原因还要两个版本同时运行在一台机器上,那怎么办呢?
于是我们开始考虑引入使用docker

Docker

Docker的基本使用就是简单的找个镜像 install 然后 run 就行了,
-v挂上持久化, -p 挂上端口

    # 例 :redis
    $ docker run -d -p 6379:6379 redis

类似这样就能直接在机器上挂上最新的redis镜像并映射到本地6379端口,简单粗暴,再挂下持久化啥的丢到 Makefile 里直接运行就行了,用的人也不需要费时费力地去装redis
同理如果对node也有要求的话

    docker run -t -i -p 8000:8000 -w /project -v $PWD:/project node:11.3.0 /bin/bash

直接运行上面这行命令就可以直接在 docker 中直接运行打开bash输入框运行 node 环境进行开发了,这样即使用户机器上没有 node 也照样可以开发 node 程序,不过以上只是直接创建了同名镜像,容易被其他项目覆盖,真实环境别直接这样做,出问题了我可不负责的啊。而且性能啥的也不是特别好。
有必要的话还是建议学习下 docker 能帮你解决不少事。
另外, Docker 的正规操作常用于服务端项目的发布,增加了不少灵活性,一下子解放了运维大哥。
当然以上的介绍连冰山一角都不到,我也是正在学习Docker。

业务开发的经验教训

之前写了两年 vue 后来又写了一年react
顺便在这里总结下这几年项目开发的经验

在接手一个用了 redux 或者 vuex 的项目的时候是否经常感觉很头大不知道从哪个地方开始看代码,一会要看看view层 一会又要回到model层招model。
而使用那种mvc一样的目录结构导致两个东西间隔了大老远一会要进page目录找组件 一会又要进store目录找状态
这种事情对于一个单人写的短平快的项目还好,对于一个需要长期维护的业务来说是否有时候会让人感到无所适从
产品需求一个接一个的加,接口数量和字段也在一个个地加,而为解决一些老版本的兼容问题,一些老接口的冗余字段已经堆积成山,有的已经废弃,而有的还苟延残喘在你的代码中让你苦不堪言。

所以,我做了哪些思考呢

丢上目录

    package.json
    ...
    
    `src`
        - app.ts                          // 总入口
        - router.ts                       // 路由
        - `store`                         // 公共仓库
            - index.ts                    // 公共仓库总入口
        - `page`                          // 放页面的地方
            - index.ts                    // page总入口,所有页面从这导出
            - `[例:PAGEA]`               
               - README.md                // 说明文档
               - index.ts                 // 入口
               - `view`                   // 业务相关页面组件
                   - index.tsx
                   - componentA.tsx
                   - style.less
               - `service`                // 放接口的地方
                   - index.ts
               - `model`
                   - index.ts
        - `component`                     // 放些杂七杂八的公共组件的,比如编辑器啥的
            - index.ts                    // 总入口,所有组件从这导出
            - `[例:COMPONENTA]`
                - index.tsx       
                - style.less
                - README.md              // 说明文档
        - `util`                         // 工具函数
            - index.ts                   // 工具函数总入口
            - `[例:UTILA]`
                - index.ts
                - README.md              // 说明文档  
    

1. 硬性规定

前端也必须写文档

每个页面在迭代的时候写上更新说明,标上原型地址,接口上附上api文档地址,至少让人家知道这个页面是从哪个年代开始写起来的干了啥不得了的事又砍了啥功能

公共组件也必须写文档,并且不能涉及任何业务相关功能

很多人为了方便把组件抽出来做成一个公共组件啥都不写丢在外面还说别人不懂组件的复用啥的逼叨逼一大堆结果连个基本说明文档都不写,别人好不容易用上了哪天需求一更新又加上点啥功能又担心别人的代码里出啥幺蛾子就写一大堆if else 最后变成一坨越堆越高的翔
个人一直认为,勉强复用的东西不如不用。

不允许写的代码直接打回重做

像啥三几次方元表达式,
obj && obj.list && obj.list[0] && obj.list[0].value之类宁死不赋默认值不做预数据处理的拿过来接口就是干的东西,
value1 , value2 之类的命名习惯统统打回

2. 软件

eslinttslint 能加的都给加上 能标 error 的绝对不标 warning

历史的惨痛经验教训告诉我们,如果有些东西你只是标个warning那么在不久的将来,你在启动项目之后就会看到一条长长的黄色的海洋。
那我要这warning有何用!还不如直接去掉。

GraphQL 挺好但现状依旧不是特别乐观

在用GraphQL之前不大看好这东西,感觉就是一个挂羊头卖狗肉的Restful,放出来好多年社区支持得也不怎么样。
后来在内部自己的小项目中用了以后呢,感觉确实挺香,前端自定义接口内容的意义远比后端给啥用啥来得舒坦...只要后端不随便改声明。。。
但需求这种事情呢,变起来翻天覆地,GraphQL虽然能在小迭代中发挥不少灵活性。

但后端不乐意用啊,甚至如果没有方便的文档工具,后端甚至可能会用word给你写接口文档,一个迭代发你一个doc文件,以前的接口文档能找得到给你发来,等这个后端一离职一交接,这个接口立马原地爆炸。

所以个人感觉GraphQL在现阶段并不是必须要学,学会了也可能用不到,用到了可能在产品疯狂改需求的结果下让你在后端各类神奇的骚操作之下迷失在茫茫query海之中无法自拔,不过也给了你一些找新东家面试的时候和面试官侃侃而谈情到深处抱头痛哭的东西。

TypeScript 真香啊真香

ts之于项目的意义,用any则死,用never则生,宽进严出是无数老前辈总结出来的经验教训,多写几个never总是没错的,大不了以后删。
那么问题来了,从哪开始用,当然是在你拉接口的那一刻起


MaxChan
462 声望29 粉丝

就叫我陈英俊吧