一個 xxx is not defined 引發的爬坑之路


出處 https://www.cnblogs.com/daysme/

- 2018-01-06

昨晚找了一個代碼解決了我對配置的需求。
高興的拿到手機上測試卻發現點擊沒有效果,電腦上是可以的呀,電腦上的手機模式是可以的呀。

難道是這代碼不兼容手機?可能吧,再找找其他代碼,把關鍵詞下的都看完了,沒有其他可用的。

在手機上搞個 console ,看到是由於手機上顯示 tool is not definedtool 是這個工具的構造函數。難道是轉換后的 js 手機版瀏覽器不支持?可能吧。那么到底是什么代碼不支持呢?
看了生成后的文件,應該是最后一步 tool 沒有被導出。
入口文件源碼是這樣的:

  import tool from './tool';
  module.exports = tool;

下面的文章,都是自己編譯、修改源碼導致的報銷,在瀏覽器上也不能運行,先是 tool is not defined, 后是 exports is not defined

應該是手機不支持轉換后的模塊加載方式。然后我打算把他的代碼放到我之前的項目里去轉換。你問我為什么不使用他自己的項目轉碼?我也想,因為他項目好像不是在 windows 開發的,並且使用了一些非 windows 平台的命令,如 rm 、 mkdir ,我換成 windows 上的 rd 和 md 及對應的語法格式,或刪除這些不支持的命令去手動操作,都沒有用,而且他的項目里幾乎都是使用全局安裝的工具轉換, node-sass 、 babel … 。他執行命令時是通過一條命令把這些命令串連起來的,有些工具全局安裝后不知道如何使用,最后就拋棄了這種方式。

當然,我使用自己的項目去轉換他的代碼,也並沒有成功,報錯還是相同的。

嘗試把他的代碼合並在一起以去除模塊依賴,然后代碼並不能運行。我想如果我對es6了解再熟悉一點的話之條路應該可能走通。但我知道這是一條不歸之路,可不能為了運行代碼,把前沿的東西都給改落后了,對不起作者,自己也沒面子。

嘗試使用在線的 babel 和 require.js 來直接加載未來編譯過的 js ,不知道是不是自己的使用方式不對,報錯還是一樣。

還是繼續看源碼,再百度,發現好像作者使用的是 module.exports ,網上說這是 CommonJS 規范(四個關鍵字, module, exports, require, global),一般用在 node 里比較多, 瀏覽器是不能運行的。 AMD 規范使用的是 require([module], callback); 形式。 require.js 使用的是 AMD 規范,他能在瀏覽器里運行。那么難道是因為作者寫的是 CommonJS ,我卻用 require.js 去加載,才導致的報錯?然后就開始搜索解決 CommonJS 和 AMD 規范之前問題的方法,結果沒有成功,不知道如何使用。

后來想不到其他辦法了,決定沉下心來,看看能不能改寫作者的源碼。我想的只是反正都是規范搞的鬼,那模塊化規范也就那幾句,也一共才導入三四個文件,應該能手動改成之前項目里自己寫過的那種可以編譯在瀏覽器里運行的模塊化方式。隨便看了一下 package.json ,發現好像別一個名字有點可疑 babel-preset-env ,自己以前的項目里沒有遇到過,看起來像是某種轉換方式。百度了一下,發現是用來轉換不同環境的代碼的,比如僅在 node ,僅在 chrome ,而不是把所有代碼通通轉為 es5 ,因為現在大部分瀏覽器都支持很多 es6 語法了,沒必要全部轉換,也的確作者的 package.json 里並沒有 babel-preset-es2015 。 想着為什么作者的示例不能在手機上運行,或許就是故意使用了特定的轉換方式,可是手機瀏覽器不如電腦更新快,支持度不高導致報錯。

遂趕快安裝了 babel-preset-es2015 , 運行 browserify -s tool -e ./src/index.js -o ./dist/tool.js -t [ babelify --presets [env] ] 試試。行一下,官網上的例子 不是 browserify a.js -o b.js 嗎這里多了個 -s 是什么鬼?去官網看了下大概是什么 UMD 規范,之前的搜索 CommonJS 和 AMD 時有記得 UMD 是為了兼容這兩個的規范的。把 -s 去掉 browserify ./src/index.js -o ./dist/configui.js -t [ babelify --presets [env] ] , 果然作者的代碼編譯出來也不能在電腦上用了,還是報了 tool is not defined 這個錯,加上 -s 就好了, 使用 [es2015] 手機能運行了。

原來, 作者本就使用了兼容 CommonJS 和 AMD 的兼容規范 UMD, exports is not defined 這個坑是我自己挖出來的。走了這么多彎路, get 到 browserify 有個 -s 參數可以用來做模塊化兼容,有個 babel 插件 babel-preset-env 可以用來轉換為指定環境代碼。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM