版权声明:此文首发于我的个人站Angular2开发踩坑系列-生产环境编译,转载请注明出处。
公司移动端项目需要技术选型,此前仅仅是学过ng2会用而已,于是想趁着这个项目,深入学习一下angular2就提议给CTO。最终选择了angular2作为 前端框架,于是填坑之路 开始了....
下边说几个在生产环境编译的时候遇到的天坑..ToT
使用ng build --prod--aot编译出来的文件,部署到服务器之后,在微信内置浏览器和手机谷歌浏览器上可以打开网站,但是在国内安卓手机的系统内置浏览器以及UC浏览器等打不开,始终停留在loading界面
我曾天真以为手机上没有兼容性问题,可以放肆的'玩耍',没想到啊没想到,居然有这么一个巨坑。。
在我费劲心思百谷找寻原因未果之后,在PC上安装了安卓abd调试工具,下载了UC开发者版本,然后连接电脑,在谷歌浏览器控制台查找原因,终于发现了报了一行错
TypeError: 'undefined' is not a function
这是什么鬼??点开具体报错的位置之后发现,在一行编译后的代码里 object.assign()
这个方法报错了,这是一个es6的方法,并且angular-cli配制的转版本无法将object.assign()
转成es5版本,所以UC就不支持了。。
于是,在寻找解决方法。。此处省略一万字
最终在stackoverflow上找到两位大神的回答:
根据这两位大神 所述,安装babel-polyfill的npm包后,引入就好了。
你以为就这么完了??
我在src目录下polyfills.ts中引入,结果编译完放到服务器上又有了新的报错。。
还有引入顺序的问题。。新引入的babel-polyfill把Zone.js的Promise方法覆盖掉了,导致编译又出错了。。
然后我在polyfills.ts中找到引入 zone.js的地方,将babel-polyfill的引入写在了 这里,
/*************************************************************************************************** * Zone JS is required by Angular itself. */ import 'babel-polyfill'; import 'zone.js/dist/zone'; // Included with Angular CLI.
总算 这个问题解决了。手机UC浏览器和安卓系统内置浏览器 终于可以正常打开了。
BUT,每次打开超级慢,网络状况良好,但就是打开的特别慢,在loading界面转十几到二十几秒钟才进来,这次的问题在微信、谷歌、UC、安卓浏览器上无一例外。
又百谷起来。。。此处省略两万字
找了好久,原来angular-cli的ng build --prod--aot
(这是看着大漠穷秋的ng2视频上学的指令)该指令是不正确的,现在我这样执行的仅仅是
ng build 普通编译
所以编译后的文件大小 和 源代码的大小几乎一致。应该使用的是预编译(AOT),现在的angular-cli中已经将预编译(AOT)包含在了ng build --prod
指令中,那么我应该是用的是ng build --prod指令,没错。
于是,我输入ng build --prod
回车,然后,然后就悲剧了。。。
上百条的报错,,我看了一下,报错最多的是:
Property ‘x’ is private and only accessible within class ‘MyComponent’
我在不知道什么网站上找到了解释:
翻译: 使用AOT,类中的私有属性和方法只能在类中访问。 要访问模板中的属性或方法,属性或方法必须声明为public。
使用typescript定义变量时,用到public、private、protect,在不进行预编译(AOT)时,private的变量在html模板中使用是不会报错的,但使用了AOT后,要求的很严格,即使是同一个component中,只要不只是在ts文件中使用,就应该定义为public。
SO,我又将所有ts文件中在本文件之外调用的private定义的变量/函数变成了public。
然后再次执行 ng build --pord
,,又失败了。。
Property ‘x’ is private and only accessible within class ‘MyComponent’
上一个报错没有了,还有不少别的报错
Property 'username' does not exist on type 'UserInfo'
经过再次排查,发现因为typescript是强类型语言,在进行AOT编译时,从后端接口中获取的数据应该有对应的interface与之对应,在开发过程中我们并没有这么做,可以正常运行,但AOT不行。
于是又新建了数个接口文件,将这些用到的对象都按照服务器返回的数据格式进行定义interface,随后再引入组件的ts类中。这里请参考微软typescript中文网文档
改完之后,再次执行ng build --prod
,终于完美编译~~此时的我内牛满面ToT~
编译后的文件比源文件少了一半的大小,编译后的js都是压缩过的
填了三天坑,总算把ng2生产环境编译的坑填平了(暂时的~)