记一次前端运行白屏

最近项目开发,dev环境下报了页面白屏,错误如下,You should not use <Link> outside a <Router>

看样子是ReactRouter使用上有问题,但尴尬的是本地Run没事!由此推断构建打包存在问题,但是具体能是什么问题呢?

可能性

有两个可能,1,包版本,2,构建打包脚本。
2的可能性需要排除,因为翻看提交历史,最近都没怎么修改过,那只剩下1的可能性,提交历史上,最近的确动过package文件,但是react-router包及type定义文件都没有变动,除非dev环境安的包就是出现了版本不对!大致确定了方向就继续排查!

我们的前端并不是独立部署的,前后端虽然做了分离,但构件上,都是利用maven进行构建,maven执行打包命令中会执行前端打包命令,最终打包完成war包。

查看POM.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
<plugin>
<groupId>com.github.eirslett</groupId>
<artifactId>frontend-maven-plugin</artifactId>
<executions>
<execution>
<id>install node and npm</id>
<goals>
<goal>install-node-and-npm</goal>
</goals>
<configuration>
<nodeVersion>${node.version}</nodeVersion>
<npmVersion>${npm.version}</npmVersion>
<nodeDownloadRoot>http://cdn.npm.taobao.org/dist/node/</nodeDownloadRoot>
</configuration>
</execution>
<execution>
<id>npm config</id>
<goals>
<goal>npm</goal>
</goals>
<configuration>
<arguments>config set registry https://xx.cn/repository/npm/
</arguments>
</configuration>
</execution>
<execution>
<id>npm install</id>
<goals>
<goal>npm</goal>
</goals>
<configuration>
<arguments>install --registry=https://xx.cn/repository/npm/</arguments>
</configuration>
</execution>
<execution>
<id>webpack build test</id>
<goals>
<goal>npm</goal>
</goals>
<phase>test</phase>
<configuration>
<arguments>run webpack:test</arguments>
<npmInheritsProxyConfigFromMaven>false</npmInheritsProxyConfigFromMaven>
</configuration>
</execution>
<execution>
<id>webpack build prod</id>
<goals>
<goal>npm</goal>
</goals>
<phase>generate-resources</phase>
<configuration>
<arguments>run webpack:prod</arguments>
<npmInheritsProxyConfigFromMaven>false</npmInheritsProxyConfigFromMaven>
</configuration>
</execution>
</executions>
</plugin>

原来构建使用的是npm install安装包,那就明白了,我们项目使用的是yarn进行包安装,yarn.lock进行的包版本依赖管理,而这里使用npm进行安装,没有lock文件约束包版本,所以实际安装的包版本就会与我们本地开发环境有差异,所以才会造成本地不复现这个错误!

找到问题就好了,切换到yarn进行构建即可解决

解决办法

POM.xml文件中改为yarn执行构建

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
<plugin>
<groupId>com.github.eirslett</groupId>
<artifactId>frontend-maven-plugin</artifactId>
<executions>
<execution>
<id>install node and yarn</id>
<goals>
<goal>install-node-and-yarn</goal>
</goals>
<configuration>
<nodeVersion>${node.version}</nodeVersion>
<yarnVersion>${yarn.version}</yarnVersion>
</configuration>
</execution>
<execution>
<id>yarn config</id>
<goals>
<goal>yarn</goal>
</goals>
<configuration>
<arguments>config set registry https://xx.cn/repository/npm/
</arguments>
</configuration>
</execution>
<execution>
<id>yarn install</id>
<goals>
<goal>yarn</goal>
</goals>
</execution>
<execution>
<id>webpack build test</id>
<goals>
<goal>yarn</goal>
</goals>
<phase>test</phase>
<configuration>
<arguments>run webpack:test</arguments>
<yarnInheritsProxyConfigFromMaven>false</yarnInheritsProxyConfigFromMaven>
</configuration>
</execution>
<execution>
<id>webpack build prod</id>
<goals>
<goal>yarn</goal>
</goals>
<phase>generate-resources</phase>
<configuration>
<arguments>run webpack:prod</arguments>
<yarnInheritsProxyConfigFromMaven>false</yarnInheritsProxyConfigFromMaven>
</configuration>
</execution>
</executions>
</plugin>

package.json

script脚本也需要切换到yarn执行,比如原来是npm run build,现在要改成yarn run build. 因为上述配置文件中没有安装npm,当然如果你安装了npm,就大可以这里不改。

两个地方都改好,提交,应该就不再报错了,这次问题的根本原因就是Dev环境的包版本与开发环境不一致。

啰嗦下

问题解决了,但有必要啰嗦下几个知识点

lock文件何用

lock英文单词意思是锁,npm,yarn下的lock文件就是为了锁定包的版本。npm下,我们使用package-lock.json,yarn下`yarn.lock’,你可能要问,我们package.json下,依赖关系里不是已经明确了版本了吗?
是的,但是你也知道。有些包我们写的是范围,但是npm是开源的,不是每个提交的包版本都是严格按照大中小版本号及兼容性去做的,那么这样就容易出现问题,为此,我们用lock来更具体的控制包版本。

贴下yarn install ,官方的描述

1
2
3
4
5
6
7
yarn install
Install all the dependencies listed within package.json in the local node_modules folder.

The yarn.lock file is utilized as follows:

If yarn.lock is present and is enough to satisfy all the dependencies listed in package.json, the exact versions recorded in yarn.lock are installed, and yarn.lock will be unchanged. Yarn will not check for newer versions.
If yarn.lock is absent, or is not enough to satisfy all the dependencies listed in package.json (for example, if you manually add a dependency to package.json), Yarn looks for the newest versions available that satisfy the constraints in package.json. The results are written to yarn.lock.

yarn,npm区别

了解区别,咱先说共通,都是包管理器,yarn是后来出的新的,理论及实际上,速度的确更快点,cli命令也更语义化些。不过用哪个,个人觉得差别不大,看团队整体吧。

frontend-maven-plugin啥玩意?

Java项目,maven作为常用的构建工具,frontend-maven-plugin是一个插件,通过它实现了打包时,前端的构建处理,这样做可以将node环境与系统环境中的nodejs进行物理隔离,提高了服务的可移植性。具体玩法,上述代码块作为部分参考,具体请看官网。

总结

每个小问题,大问题背后都值得我们去思考总结,从而深化理解一个知识点,一个问题,一个现象。

相关引用