Module not found:Error Can't resolve

事情起因:最近同事在服务器上编译项目的静态页面时,发现build会报错:

1
2
3
ERROR in ./node_modules/babel-loader/lib!./node_modules/vue-loader/lib/selector.js? type=script&index=0!./src/views/App.vue
Module not found: Error: Can't resolve './common/footer' in '/export/App/jdc-share-client/src/views '
@./node_modules/babel-loader/lib!./ node_modules/vue-loader/lib/selector.js? type=script&index=0!./src/views/App.vue 13:0 - 37

然后让我帮忙看看是什么问题。

查错过程

第一反应应该是代码中引入路径错误了,nodejs项目使用的是import或require来引入一个模块。报错原因是模块路径错误引起的。

查看代码,发现引入代码:

1
const footer = import '@/common/footer'

该项目使用的是webpack 3来构建项目。打开webpack.base.conf.js中可以看到@已经设置为正确的别名。

@路径是正确的项目路径,如果这个alias生效,那么应该能够加载到正确的js模块,在nodejs中js文件即模块。

刚开始我怀疑是webpack的alias没有生效,因为我对webpack3并不是特别熟悉,所以猜想是不是alias没有生效呢?

于是,先沿着这个猜想去网上找找看。也看到一堆关于alias not working的问题,在webpack的github上也有人反馈这个issue,https://github.com/webpack/webpack/issues/4160 有近70多个反馈,但出问题的场景各异。没有一个统一的fix方案,想了想觉得不对。

此时同事给我发来一个链接,说可能是文件名大小写问题。因为他在本地可以正常编译,本地用的是MAC,而服务器是Linux。

卧槽,Linux是严格区分大小写的呀,原因就是它了。他在common/footer目录下有一个Index.vue的文件,在MAC下是不区分大小写就可以正常build。而在Linux下,由于区分大小写,webpack在目录下没有找到index.vue 或 index.js就会报错找不到模块。

解决办法

修改Index.vue 为 index.vue,然后再编译成功了。

思考

  1. 关于nodejs引入目录模块机制
    1
    const myMod = require('./folder')

Node将搜索整个folder目录,Node会假设folder为一个包并试图找到包定义文件package.json。如果folder目录里没有包含package.json文件,Node会假设默认主文件为index.js,即会加载index.js。如果index.js也不存在,那么加载将失败。

  1. 关于文件命名

项目在正式开发之前最好有一个文件或目录的命名约定,比如统一使用驼峰是命名,避免项目后期的一些不必要成本。

规范参考:https://juejin.im/entry/56e8c0c1816dfa0051376758#