从零开始开发一个react脚手架(五)
前言:最近天天加班做新项目,Taro版的小程序,还要实现富文本加海报,踩了不少坑,下次专门开个坑说一下。 回到脚手架,说实话从头写一个,即便是参考create-react-app,还是遇到了很多很多问题,这些都是需要自己亲自写过,才能有所体会。
这次会写的有杂乱一点,就说说自己遇到的哪些问题。虽然还没有全部完工,但是已经能够基本使用,最下面会贴git地址
问题一 现在基本实现了两个命令,start和build,start就是启动webpack-dev-server,这是开发环境, build就是构建,是production环境。 不管什么命令都需要依赖 NODE_ENV=development或者production,这样会导致每次npm run 的时候都要加上NODE_ENV,而且这个还不能直接写在script命令里面,因为window是不支持,需要安装第三方库。最后参考create-react-app
直接赋值,简单粗暴。 一开始没想到可以这么简单粗暴,走了歪路,想要通过DefinePlugin来实现赋值,但其实这反倒是错误的路线。需要理解编译工具所依赖的NODE_ENV和业务代码里面的NODE_ENV是不同的,DefinePlugin其实就是个简单的全局变量替换,只能替换chunk里面的。
问题二 优化createWebpack,一开始的做法极为简单,直接export一个对象,导致灵活性很差,后来改成导出一个方法,接收各种配置参数,返回一个webpackConfig。
问题三 webpack-dev-serve,这个问题捣鼓了很久很久。关于webpack-dev-serve的contentBase配置。一开始我设置的是dist目录,也就是打包后的目录,即output设置的path。因为以前都是这样玩的,但是这样意味着服务依赖了一个打包构建后的目录dist,否则没有办法找到index.html。这样就很诡异,难道第一次start都必须先build一下吗?很不合理,而且build的时候NODE_ENV必须是development,否则js的引用地址就成了线上地址。而根据上面一个问题,简单粗暴在代码里面写死NODE_ENV就很难改变环境变量了,build出来的只能是线上。
看了很久的create-react-app的源码,因为这个脚手架并不需要先build,一开始以为他在start的时候做了什么特殊处理,后来才发现压根不是,它的webpack-dev-server配置的cotentbase竟然不是dist,而是原始目录src/index.html。。。
这样我很震惊啊,因为我想的是,js什么的,css什么的引入都必须是在webpack build之后才知道的,因为会做拆分剥离的处理,JS的文件个数和名字不确定,如果引入的是原始目录,那么到底是在哪儿做的JS和CSS插入操作呢,为此寻遍了源码,一个个去找plugin,但最后发现其实压根很简单。
在于html-webpack-plugin,貌似它会先在内存中生成一份html,想要访问内存地址直接就是
localhost:3000,而webpack-dev-server应该是优先去取内存中的index.html,没取到就会去cotentbase中找,也就是说和cotentbase压根没有半毛钱关系。
产生错觉的原因在于,内存中没找到,而cotentbase中同样没找到,就会报404。至于为嘛没有取到内存中的值,在于我闲的没事,设置了publicPath,为/assets/这样导致,想要访问html的地址就变成了localhost:3000/assets/index.html。其实开发环境压根没必要设置assets,没半毛钱作用。
问题四 这个就是很蠢的一个问题了,很粗心。关于dependencies和devDependencies,其实单纯问两者的区别,大家都知道,一个是开发依赖,一个是线上依赖。但是我们实际开发中,不管是你开发依赖还是线上依赖,其实所有的包都会安装,所以有的时候装错地方,也没啥的。but。。。如果你开发的是第三方包,这个问题就大了。。。如果是第三方包,只会安装第三方包的dependencies。因为一开始的开发不规范,导致我随意乱装。。结果查了半天,一直报XXX包找不到。。捣鼓了很久,才发现是个这么简单的问题。
问题五 关于npm publishi的时候如果报权限或者什么其他问题的错,十有八九是 设定了源的路径,如果是淘宝源或者公司源,需要切换回npm默认源,才可以发布。
问题暂时就想到这么多了。其实脚手架最简单的反而是webpack配置了,这些东西一搜索网上一大把,配置消息我就不多说了。说几个值得注意的地方。。第一就是splitChunks,这个设置拆包大小的时候记得注意单位,30000这个是30kb。所以我写的是100000,意味着要拆成独立的包,压缩前必须有100KB,其实还可以设置大一点,你想想100KB压缩后估计就50,再来个GZIP就是20KB左右了。一个包可以再大点。
但如果是http2,也可以不用拆太大,毕竟多路复用吗。 第二就是关于静态资源引用的问题,其实我觉得本地业务代码里面完全不用引入静态资源,通通丢到云服务器就好,比如静态图片,我都是通通扔到七牛服务器,代码里面直接写死,爽歪歪,还能享受CDN加成和http2.
react+router+redux
说的有点乱,想到啥写啥。主要是事件间隔有点久了,最近加班太忙。
脚手架已经实现了三分之一,现在是直接clone git来作为脚手架,到最后效果应该是npx的形式,不过命令内容已经实现 easy-react start和 easy-react build。
代码已经更新到git了,方便给个star。 easy-react即命令的实现源码还没扔上去,等后续完工了再扔上去。毕竟还有服务器端的部分没实现。
脚手架工具很多,我觉得有时间还是自己维护一份的好,想咋玩就咋玩,想升级就升级,自己定制。
git init
git clone https://github.com/417673259/...
npm install
npm run start
有问题就留言,必定回复,给个赞呗