起因
因為准備看element-ui的源碼,會做一些筆記,在源碼中寫一些注釋,甚至對源碼進行一些自定義的修改來查看運行效果。
所以element-ui的文件夾不能直接npm install放在node_modules文件夾下面,node_modules文件夾一般是不同步到svn上的,放在里面的話在另一個電腦上可能重新安裝項目自己的修改就沒有了。
對引入的外部組件,如果要自定義修改,那么都不能放在node_modules下。
過程中遇到的一些問題記錄一下。
element-ui貢獻指南:
https://github.com/ElemeFE/element/blob/master/.github/CONTRIBUTING.zh-CN.md
vue腳手架安裝
vue init webpack element-learn
cd element-learn
npm install
npm run dev
一步步來,建好初始的文件夾。
引入element-ui
https://github.com/ElemeFE/element/tree/master
下載一個master分支。在src文件夾下建立一個element-ui文件夾,將下載的分支解壓到該文件夾下。
此時嘗試在main.js中引入element-ui:
import elementUI from ‘./element-ui’;
Vue.use(elementUI);
報錯:This relative module was not found:
./element-ui in ./src/main.js
這是因為我們直接下載過來的element-ui沒有經過編譯。
node模塊機制從element-ui包的package.json中的讀到的入口文件不存在。所以首先要自己編譯element-ui源代碼。
到element-ui中的操作
cd E:\vue\element-learn\src\element-ui
npm install
npm run dev
然后訪問http://localhost:8085
可以看到示例。
跟官網http://element.eleme.io/#/zh-CN
基本是一樣的。我們也可以直接到這個示例中去修改組件,查看效果。畢竟實時編譯。
然后是編譯,也就是生成我們項目中會使用到的文件。
npm run dist
有可能會報錯package.json
does not exist, have you run lerna init
?
npm install lerna一下。
有時候還會有些別的錯誤,把node_modules刪除了重新npm install就好。
編譯完之后我們就看到多了一個lib文件夾。里面就是編譯生成的文件。
然后
cd E:\vue\element-learn
npm run dev
報這個:
[BABEL] Note: The code generator has deoptimised the styling of “E:/vue/element-learn/src/element-ui/lib/element-ui.common.js” as it exceeds the max of “500KB”.
不過不用管它,這個不影響。
后面還有報錯
* element-ui/lib/button in ./src/element-ui/lib/element-ui.common.js * element-ui/lib/button-group in ./src/element-ui/lib/element-ui.common.js * element-ui/lib/checkbox in ./src/element-ui/lib/element-ui.common.js * element-ui/lib/checkbox-group in ./src/element-ui/lib/element-ui.common.js * element-ui/lib/input in ./src/element-ui/lib/element-ui.common.js * element-ui/lib/input-number in ./src/element-ui/lib/element-ui.common.js * element-ui/lib/locale in ./src/element-ui/lib/element-ui.common.js * element-ui/lib/mixins/emitter in ./src/element-ui/lib/element-ui.common.js * element-ui/lib/mixins/locale in ./src/element-ui/lib/element-ui.common.js * element-ui/lib/mixins/migrating in ./src/element-ui/lib/element-ui.common.js * element-ui/lib/option in ./src/element-ui/lib/element-ui.common.js * element-ui/lib/progress in ./src/element-ui/lib/element-ui.common.js * element-ui/lib/scrollbar in ./src/element-ui/lib/element-ui.common.js * element-ui/lib/select in ./src/element-ui/lib/element-ui.common.js * element-ui/lib/tag in ./src/element-ui/lib/element-ui.common.js * element-ui/lib/tooltip in ./src/element-ui/lib/element-ui.common.js * element-ui/lib/transitions/collapse-transition in ./src/element-ui/lib/element-ui.common.js * element-ui/lib/utils/clickoutside in ./src/element-ui/lib/element-ui.common.js * element-ui/lib/utils/date in ./src/element-ui/lib/element-ui.common.js * element-ui/lib/utils/dom in ./src/element-ui/lib/element-ui.common.js * element-ui/lib/utils/merge in ./src/element-ui/lib/element-ui.common.js * element-ui/lib/utils/popup in ./src/element-ui/lib/element-ui.common.js * element-ui/lib/utils/resize-event in ./src/element-ui/lib/element-ui.common.js * element-ui/lib/utils/scroll-into-view in ./src/element-ui/lib/element-ui.common.js * element-ui/lib/utils/scrollbar-width in ./src/element-ui/lib/element-ui.common.js * element-ui/lib/utils/shared in ./src/element-ui/lib/element-ui.common.js * element-ui/lib/utils/util in ./src/element-ui/lib/element-ui.common.js * element-ui/lib/utils/vdom in ./src/element-ui/lib/element-ui.common.js * element-ui/lib/utils/vue-popper in ./src/element-ui/lib/element-ui.common.js
說明兩點:1.element-ui的入口文件找到了。2.入口文件中路徑配置可能有問題。
路徑問題分析
首先我們到入口文件lib/element-ui.common.js,
發現里面有很多類似這樣的模塊引入:module.exports = require(“element-ui/lib/select”);
這個路徑比較奇怪的是element-ui這一段是哪里來的,它怎么就知道我的目錄是叫這個名字。於是我修改了目錄名重新編譯,發現這個文件里的路徑還是這樣。
然后我把名字改回來,把文件夾移動到node_moudule下,import elementUI from ‘element-ui’;
發現能正常運行。所以編譯的包應該是沒有問題的。問題在路徑上。
然后文件夾移回去,到element-ui的build文件夾搜索一下element-ui。果然發現了不少element-ui。
關鍵在config.js中這里
exports.alias = { main: path.resolve(__dirname, '../src'), packages: path.resolve(__dirname, '../packages'), examples: path.resolve(__dirname, '../examples'), 'element-ui': path.resolve(__dirname, '../') };
可以看到element-ui是這個路徑的別名。所以element-ui這里的webpack是可以識別它的。而我們項目的的webpack是識別不了它的。
那么放到node_modules文件夾下,為什么可以正常識別這個路徑呢,根據nodejs的模塊搜索機制,npm install下來的它的文件夾名字也是element-ui。這個時候element-ui不是一個別名。
直接引入node_modules中的模塊,引入方式是import elementUI from ‘element-ui’,那么lib/element-ui.common.js中的’element-ui’就直接對應到element-ui的根目錄了。
所以在我們項目的webpack配置webpack.base.conf.js中增加別名配置element-ui,把’element-ui’指向我們項目中element-ui根目錄的位置src/element-ui:
alias: { 'vue$': 'vue/dist/vue.esm.js', '@': resolve('src'), 'element-ui':resolve('src')+'/element-ui' }
然后重新運行 npm run dev。運行成功。
於是我們的webpack也能正常地識別lib文件夾里文件中’element-ui’的路徑了。
結尾
然后如果我們修改了element-ui的源碼,只要編譯一下就可以正常在我們自己的項目中應用了。
不過還有一點不好的地方就是我們沒有對element-ui源碼進行實時的編譯,我們項目引用的是它編譯過后的而不是真正的源代碼,也就是沒有把它自己的實時編譯過程寫到我們的項目webpack的配置中來。所以我們項目中npm run dev的時候並不能實時監測到我們對element-ui源碼的修改。這一點后面再優化。
對於一些常見項目的腳手架,其實應該好好學習一下。以后再遇到文件路徑問題,各種配置問題會得心應手很多。
順便推書《深入淺出nodejs》《深入理解es6》。