目前在開發一個生成骨架屏的 webpack
插件,使用 Puppeteer
來將處理腳本經過 addScriptTag
方法來插入到頁面中。webpack
想法是想模仿 webpack
能夠經過配置 plugins
來添加自定義的處理規則,問題就出在這裏,經過 page.evaluate
來執行頁面腳本的時候獲取不到我傳入的 plugins
。git
webpack plugin config
:github
class TestPlugin {
apply(api, ele, options) {
console.log(api, ele, options);
}
}
{
...
port: 8899,
plugins: [
function test(api, ele, options) {
console.log(api, ele, options);
},
new TestPlugin()
],
...
}
複製代碼
使用 puppeteer
的代碼:web
await page.evaluate(options => {
Skeleton.genSkeleton(options);
}, this.options);
複製代碼
在調用 Skeleton.genSkeleton
方法的時候, options.plugins
變成了 [null, {}]
。致使獲取不到傳遞的自定義處理函數。api
webpack
是否接受到參數wepack
已經接受到了配置的參數
Puppeteer
的問題了查看了 puppetter
的官方文檔。數組
evaluate
方法接受的參數必須是能夠被序列化的。
而後去 github
上查看它的源碼發現它使用 JSON.stringify
來進行序列化。bash
JSON.stringify
的問題了。
既然肯定是 JSON.stringify
的問題了, 趕忙去看一波 JSON.stringify
的文檔。 送上 JSON.stringify() 的MDN地址。app
plugins
第二個元素返回
{}
, 當函數出如今數組對象中時,在序列化過程當中會被轉換成
null
,因此
plugins
的第一個元素返回
null
。
思考一下,爲何有些屬性不能被 stringify
序列化。函數
由於 JSON
是一個通用的文本格式,和語言無關。設想若是將函數定義也 stringify
的話,如何判斷是哪一種語言,而且經過合適的方式將其呈現出來將會變得特別複雜。特別是和語言相關的一些特性,好比 JavaScript
中的 Symbol
。ui
ECMASCript官方也特地強調了這一點:
It does not attempt to impose ECMAScript's internal data representations on other programming languages. Instead, it shares a small subset of ECMAScript's textual representations with all other programming languages.
有興趣的小夥伴能夠了解一下如何使用 toJSON
來自定義序列化行爲。